Exemplo n.º 1
0
def init_logging(loglevel: int = logging.INFO,
                 logtime: bool = False,
                 trace_loggers: List[str] = []) -> None:
    """Initialize pineboo logging."""
    # ---- LOGGING -----
    log_format = "%(levelname)s: %(name)s: %(message)s"

    if logtime:
        log_format = "%(asctime)s - %(levelname)s: %(name)s: %(message)s"

    app_loglevel = logging.TRACE if trace_loggers else loglevel
    if trace_loggers:
        logging.Logger.set_pineboo_default_level(loglevel)

    logging.basicConfig(format=log_format, level=app_loglevel)
    # LOGGER.info("LOG LEVEL: %s", loglevel)
    disable_loggers = [
        "PyQt5.uic.uiparser", "PyQt5.uic.properties", "blib2to3.pgen2.driver"
    ]
    for loggername in disable_loggers:
        modlogger = logging.getLogger(loggername)
        modlogger.setLevel(logging.WARN)

    for loggername in trace_loggers:
        modlogger = logging.getLogger(loggername)
        modlogger.setLevel(logging.TRACE)
Exemplo n.º 2
0
    def __init__(
        self,
        parent: Optional[QtWidgets.QWidget] = None,
        name: Optional[str] = None,
        embedInParent: bool = False,
        rptEngine: Optional[FLReportEngine] = None,
    ) -> None:
        """Inicialize."""

        super(FLReportViewer, self).__init__(parent)
        self.logger = logging.getLogger("FLReportViewer")
        self.loop_ = False
        self.eventloop = QtCore.QEventLoop()
        self.reportPrinted_ = False
        self.rptEngine_: Optional[Any] = None
        self.report_ = []
        self.slotsPrintDisabled_ = False
        self.slotsExportedDisabled_ = False
        self.printing_ = False
        self.embedInParent_ = True if parent and embedInParent else False
        self.ui_: Dict[str, QtCore.QObject] = {}

        self.Display = 1
        self.Append = 1
        self.PageBreak = 1

        self.rptViewer_ = internalReportViewer(self)
        self.setReportEngine(FLReportEngine(self) if rptEngine is None else rptEngine)

        if self.rptViewer_ is None:
            raise Exception("self.rptViewer_ is empty!")

        self.report_ = self.rptViewer_.reportPages()
Exemplo n.º 3
0
    def __init__(self, parent: Optional[QtWidgets.QWidget] = None) -> None:
        """Inicialize."""

        super().__init__(parent)
        self.d_ = FLReportEngine.FLReportEnginePrivate(self)
        self.relDpi_ = 78.0
        self.report_ = None
        self.rt = ""
        self.rd: Optional[QtXml.QDomDocument] = None
        self.logger = logging.getLogger("FLReportEngine")
        from pineboolib.application.parsers.kugarparser.kut2fpdf import Kut2FPDF

        self.parser_: Kut2FPDF = Kut2FPDF()
Exemplo n.º 4
0
 def __init__(
     self,
     parent: Optional["QtWidgets.QWidget"] = None,
     name: Optional[str] = None,
     multiLang: bool = False,
     sysTrans: bool = False,
 ) -> None:
     """Inicialize."""
     super(FLTranslator, self).__init__()
     self.logger = logging.getLogger("FLTranslator")
     self._prj = parent
     if not name:
         raise Exception("Name is mandatory")
     self._id_module = name[:name.rfind("_")]
     self._lang = name[name.rfind("_") + 1:]
     self._multi_lang = multiLang
     self._sys_trans = sysTrans
     self._ts_translation_contexts = {}
     self._translation_from_qm = config.value(
         "ebcomportamiento/translations_from_qm", False)
Exemplo n.º 5
0
class FormDBWidget(QtWidgets.QWidget):
    """FormDBWidget class."""

    closed = QtCore.pyqtSignal()
    cursor_: Optional["isqlcursor.ISqlCursor"]
    form: Any
    iface: Optional[object]
    signal_test = QtCore.pyqtSignal(str, QtCore.QObject)

    logger = logging.getLogger("q3widgets.formdbwidget.FormDBWidget")

    def __init__(self, action: Optional["xmlaction.XMLAction"] = None):
        """Inicialize."""

        super().__init__()

        self._module = sys.modules[self.__module__]
        self._action = action
        self.iface = None
        self.cursor_ = None
        # self.parent_ = parent or QtWidgets.QWidget()

        # if parent and hasattr(parent, "parentWidget"):
        #    self.parent_ = parent.parentWidget()

        self.form = None  # Limpiar self.form al inicializar... Luego flformdb se asigna..
        # from pineboolib.fllegacy import flformdb

        # if isinstance(parent, flformdb.FLFormDB):
        #    self.form = parent

        self._formconnections: Set[Tuple] = set([])

        self._class_init()

    def module_connect(self, sender: Any, signal: str, receiver: Any,
                       slot: str) -> None:
        """Connect two objects."""

        # print(" > > > connect:", sender, " signal ", str(signal))
        from pineboolib.application import connections

        signal_slot = connections.connect(sender,
                                          signal,
                                          receiver,
                                          slot,
                                          caller=self)
        if not signal_slot:
            return

        self._formconnections.add(signal_slot)

    def module_disconnect(self, sender: Any, signal: str, receiver: Any,
                          slot: str) -> None:
        """Disconnect two objects."""

        # print(" > > > disconnect:", self)
        from pineboolib.application import connections

        signal_slot = connections.disconnect(sender,
                                             signal,
                                             receiver,
                                             slot,
                                             caller=self)
        if not signal_slot:
            return

        for sl in self._formconnections:
            # PyQt5-Stubs misses signal.signal
            if (sl[0].signal == getattr(signal_slot[0], "signal")
                    and sl[1].__name__ == signal_slot[1].__name__):
                self._formconnections.remove(sl)
                break

    def obj(self) -> "FormDBWidget":
        """Return self."""
        return self

    def parent(self) -> QtWidgets.QWidget:
        """Return parent widget."""

        return self.parentWidget()

    def _class_init(self) -> None:
        """Initialize the class."""
        pass

    # def init(self):
    #    """Evento init del motor. Llama a interna_init en el QS"""
    #    pass

    def closeEvent(self, event: QtCore.QEvent) -> None:
        """Close event."""

        if self._action is None:
            self._action = getattr(self.parent(), "_action")

        if self._action is not None:
            self.logger.debug("closeEvent para accion %r", self._action.name)
        self.closed.emit()
        event.accept()  # let the window close
        self.doCleanUp()

    def doCleanUp(self) -> None:
        """Cleanup gabange and connections."""

        self.clear_connections()
        iface = getattr(self, "iface", None)
        if iface is not None and self._action is not None:
            from pineboolib.core.garbage_collector import check_gc_referrers

            check_gc_referrers(
                "FormDBWidget.iface:" + iface.__class__.__name__,
                weakref.ref(self.iface),
                self._action.name,
            )

            delattr(self.iface, "ctx")

            del self._action.formrecord_widget

            self.iface = None
            self._action.formrecord_widget = None

    def clear_connections(self) -> None:
        """Clear al conecctions established on the module."""

        # Limpiar todas las conexiones hechas en el script
        for signal, slot in self._formconnections:
            try:
                signal.disconnect(slot)
                self.logger.debug("Señal desconectada al limpiar: %s %s" %
                                  (signal, slot))
            except Exception:
                # self.logger.exception("Error al limpiar una señal: %s %s" % (signal, slot))
                pass
        self._formconnections.clear()

    def child(self, child_name: str) -> Any:
        """Return child from name."""
        ret = None
        if self.form:
            ret = self.form.child(child_name)

            if ret is None:
                if child_name == super().objectName():
                    return self.form
                else:
                    ret = getattr(self.form, child_name, None)

        if ret is None:
            parent = self.parent()
            if parent is not None:
                ret = getattr(parent, child_name, None)

        if ret is None:
            raise Exception("control %s not found!" % child_name)

        return ret

    def cursor(
        self
    ) -> "isqlcursor.ISqlCursor":  # type: ignore [override] # noqa F821
        """Return cursor associated."""

        if not self.cursor_:
            if self.form is not None:
                self.cursor_ = self.form.cursor_

            if not self.cursor_:
                if self._action:
                    action = application.PROJECT.conn_manager.manager().action(
                        self._action.name)
                    self.cursor_ = pnsqlcursor.PNSqlCursor(action.name())
                else:
                    raise Exception("_action is empty!.")

        return self.cursor_

    def __getattr__(self, name: str) -> QtWidgets.QWidget:
        """Guess if attribute can be found in other related objects."""
        ret_ = getattr(self.cursor_, name, None)
        if ret_ is None and self.parent():
            parent_ = self.parent()
            ret_ = getattr(parent_, name, None)
            if ret_ is None:
                script = getattr(parent_, "script", None)
                if script is not None:
                    ret_ = getattr(script, name, None)

            if ret_ is None and not TYPE_CHECKING:
                # FIXME: q3widgets should not interact with fllegacy
                from pineboolib.fllegacy import flapplication

                ret_ = getattr(flapplication.aqApp, name, None)
                if ret_ is not None:
                    self.logger.warning(
                        "FormDBWidget: Coearcing attribute %r from aqApp (should be avoided)"
                        % name)

        if ret_ is None:
            raise AttributeError("FormDBWidget: Attribute does not exist: %r" %
                                 name)

        return ret_
Exemplo n.º 6
0
"""Fllistview module."""
# -*- coding: utf-8 -*-

from PyQt5 import Qt  # type: ignore
from pineboolib.core import decorators
from pineboolib import logging
from pineboolib.q3widgets import qlistview
from typing import Any, Optional, cast, TYPE_CHECKING

if TYPE_CHECKING:
    from PyQt5 import QtWidgets  # noqa: F401

logger = logging.getLogger("FLListViewItem")


class FLListViewItem(Qt.QStandardItem):
    """FLListView class."""

    _expandable: bool
    _key: str
    _open: bool
    _root: bool
    _index_child: int

    def __init__(self, parent: Optional["QtWidgets.QWidget"] = None) -> None:
        """Inicialize."""

        super().__init__()
        self._root = False
        self.setOpen(False)
        self.setExpandable(False)
Exemplo n.º 7
0
"""Qgroupbox module."""

# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets, QtCore  # type: ignore
from pineboolib.core import decorators

from pineboolib.core import settings

from pineboolib import logging

from typing import Any

logger = logging.getLogger("QGroupBox")


class QGroupBox(QtWidgets.QGroupBox):
    """QGroupBox class."""

    # style_str: str
    # _line_width: int
    presset = QtCore.pyqtSignal(int)
    selectedId: int
    line_width: int = 1

    def __init__(self, *args, **kwargs) -> None:
        """Inicialize."""

        super(QGroupBox, self).__init__(*args, **kwargs)

        if not settings.config.value("ebcomportamiento/spacerLegacy", False):
            self.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
Exemplo n.º 8
0
Generate .ods files (Opendocument Spreadsheet)
"""
from typing import Union, List, Any, Tuple, Optional, TYPE_CHECKING


import odf  # type: ignore
from odf import table, style  # type: ignore

from pineboolib import logging
from pineboolib.core import decorators

if TYPE_CHECKING:
    from odf.opendocument import OpenDocumentSpreadsheet  # type: ignore


logger = logging.getLogger("AQOds")

"""
Generador de ficheros ODS
"""


class OdsStyleFlags(object):
    """OdsStyleFlags."""

    ODS_NONE = 0
    ODS_BORDER_BOTTOM = 10
    ODS_BORDER_LEFT = 11
    ODS_BORDER_RIGHT = 12
    ODS_BORDER_TOP = 13
    ODS_ALIGN_LEFT = 14
Exemplo n.º 9
0
from pineboolib import application
from pineboolib.application import database
from pineboolib.application.qsatypes import sysbasetype
from pineboolib.application.acls import pnaccesscontrollists

from . import fltranslator

from typing import Any, Optional, List, cast, TYPE_CHECKING

if TYPE_CHECKING:
    from pineboolib.application.database import pnsqlcursor  # noqa: F401
    from pineboolib.application.database import pnsqlquery  # noqa: F401
    from PyQt5 import QtXml  # noqa: F401

logger = logging.getLogger("FLApplication")


class FLPopupWarn(QtCore.QObject):
    """FLPoppupWarn Class."""

    # FIXME: Incomplete class!
    def __init__(self, mainwindow) -> None:
        """Inicialize."""

        self.mainWindow = mainwindow


class FLApplication(QtCore.QObject):
    """FLApplication Class."""
Exemplo n.º 10
0
"""Manage cached xpm."""

import os
import os.path

from pineboolib.core.settings import config
from pineboolib import logging, application

LOGGER = logging.getLogger("xpm")


def cache_xpm(value: str) -> str:
    """
    Return a path to a file with the content of the specified string.

    @param value. text string with the xpm or path to this.
    @return file path contains Xpm
    """

    if not value:
        LOGGER.warning("the value is empty!")
        return ""

    xpm_name = value[:value.find("[]")]
    xpm_name = xpm_name[xpm_name.rfind(" ") + 1:]

    conn = application.PROJECT.conn_manager.mainConn()
    if conn is None:
        raise Exception("Project is not connected yet")

    cache_dir = "%s/cache/%s/cacheXPM" % (application.PROJECT.tmpdir,
Exemplo n.º 11
0
"""Dgi_schema module."""
# -*- coding: utf-8 -*-
from importlib import import_module
from typing import List, cast, Optional, Any
from PyQt5 import QtCore, QtWidgets

from pineboolib.application.utils.mobilemode import is_mobile_mode
from pineboolib import logging

logger = logging.getLogger(__name__)


class dgi_schema(object):
    """dgi_schema class."""

    _desktopEnabled: bool
    _mLDefault: bool
    _name: str
    _alias: str
    _localDesktop: bool
    _mobile: bool
    _clean_no_python: bool
    # FIXME: Guess this is because there is conditional code we don't want to run on certain DGI
    # .... this is really obscure. Please avoid at all costs. Having __NO_PYTHON__ is bad enough.
    _alternative_content_cached: bool

    def __init__(self) -> None:
        """Inicialize."""

        # FIXME: This init is intended to be called only on certain conditions.
        # ... Worse than it seems: looks like this class is prepared to be constructed without
Exemplo n.º 12
0
from pineboolib.core import settings

from pineboolib.application.acls import pnaccesscontrollists

from pineboolib.fllegacy.aqsobjects import aqs
from pineboolib.fllegacy import flapplication, flworkspace, flformdb
from pineboolib.application import pncore
from pineboolib import application
from pineboolib import logging

from typing import Any, cast, List, Optional, Dict, TYPE_CHECKING

if TYPE_CHECKING:
    from pineboolib.application.database import pnconnectionmanager

logger = logging.getLogger("mainForm_%s" % __name__)


class MainForm(QtWidgets.QMainWindow):
    """MainForm class."""

    acl_: pnaccesscontrollists.PNAccessControlLists
    is_closing_: bool
    mdi_enable_: bool
    container_: Optional[QtWidgets.QMainWindow]
    w_: QtWidgets.QMainWindow
    exit_button: QtWidgets.QPushButton
    _p_work_space: Any
    mdi_toolbuttons: List[QtWidgets.QToolButton]
    _dict_main_widgets: Dict[str, QtWidgets.QWidget]
    debugLevel: int
Exemplo n.º 13
0
class FLFormSearchDB(flformdb.FLFormDB):
    """
    Subclass of the FLFormDB class, designed to search for a record in a table.

    The behavior of choosing a record is modified for only
    close the form and so the object that invokes it can get
    of the cursor said record.

    It also adds OK and Cancel buttons. Accept indicates that it has been
    chosen the active record (same as double clicking on it or
    press the Enter key) and Cancel abort the operation.

    @author InfoSiAL S.L.
    """
    """
    Boton Aceptar
    """
    pushButtonAccept: Optional[QtWidgets.QToolButton]
    """
    Almacena si se ha abierto el formulario con el método FLFormSearchDB::exec()
    """

    acceptingRejecting_: bool

    logger = logging.getLogger("FLFormSearchDB")

    def __init__(self, *args) -> None:
        """
        Initialize.
        """
        action: "pnaction.PNAction"
        parent: Optional["QtWidgets.QWidget"] = None
        cursor: "pnsqlcursor.PNSqlCursor"

        if isinstance(args[0], str):
            action = application.PROJECT.conn_manager.manager().action(args[0])
            cursor = pnsqlcursor.PNSqlCursor(action.table())
            if len(args) > 1 and args[1]:
                parent = args[1]

        elif isinstance(args[1], str):
            action = application.PROJECT.conn_manager.manager().action(args[1])
            cursor = args[0]
            if len(args) > 2 and args[2]:
                parent = args[2]
        else:
            raise Exception("Wrong size of arguments")

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

        if cursor is None:
            self.logger.warning(
                "Se ha llamado a FLFormSearchDB sin nombre de action o cursor")
            return

        if application.PROJECT.conn_manager is None:
            raise Exception("Project is not connected yet")

        super().__init__(action, parent, load=False)

        self.setWindowModality(QtCore.Qt.ApplicationModal)

        self.setCursor(cursor)

        self.accepted_ = False
        self.inExec_ = False
        self.loop = False
        self.acceptingRejecting_ = False
        self.pushButtonAccept = None

        self.load()
        self.initForm()
        self.setFocusPolicy(QtCore.Qt.NoFocus)

    def setAction(self, a: "pnaction.PNAction") -> None:
        """Set a action."""

        if self.cursor_:
            self.cursor_.setAction(a)

    # def __delattr__(self, *args, **kwargs) -> None:
    #    """Delete attributes."""

    #    if self.cursor_:
    #        self.cursor_.restoreEditionFlag(self)
    #        self.cursor_.restoreBrowseFlag(self)

    #    super().__delattr__(self, *args, **kwargs)
    """
    formReady = QtCore.pyqtSignal()
    """

    def loadControls(self) -> None:
        """Load form controls."""

        self.bottomToolbar = QtWidgets.QFrame()
        if self.bottomToolbar:
            self.bottomToolbar.setMaximumHeight(64)
            self.bottomToolbar.setMinimumHeight(16)
            hblay = QtWidgets.QHBoxLayout()
            hblay.setContentsMargins(0, 0, 0, 0)
            hblay.setSpacing(0)
            hblay.addStretch()
            self.bottomToolbar.setLayout(hblay)
            self.bottomToolbar.setFocusPolicy(QtCore.Qt.NoFocus)
            self.layout_.addWidget(self.bottomToolbar)

        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy(0),
                                           QtWidgets.QSizePolicy.Policy(0))
        sizePolicy.setHeightForWidth(True)

        pbSize = self.iconSize
        if settings.config.value("application/isDebuggerMode", False):

            pushButtonExport = QtWidgets.QToolButton(self)
            pushButtonExport.setObjectName("pushButtonExport")
            pushButtonExport.setSizePolicy(sizePolicy)
            pushButtonExport.setMinimumSize(pbSize)
            pushButtonExport.setMaximumSize(pbSize)
            pushButtonExport.setIcon(
                QtGui.QIcon(
                    utils_base.filedir("./core/images/icons",
                                       "gtk-properties.png")))
            pushButtonExport.setShortcut(Qt.QKeySequence(self.tr("F3")))
            pushButtonExport.setWhatsThis("Exportar a XML(F3)")
            pushButtonExport.setToolTip("Exportar a XML(F3)")
            pushButtonExport.setFocusPolicy(QtCore.Qt.NoFocus)
            self.bottomToolbar.layout().addWidget(pushButtonExport)
            pushButtonExport.clicked.connect(self.exportToXml)

            if settings.config.value("ebcomportamiento/show_snaptshop_button",
                                     False):
                push_button_snapshot = QtWidgets.QToolButton(self)
                push_button_snapshot.setObjectName("pushButtonSnapshot")
                push_button_snapshot.setSizePolicy(sizePolicy)
                push_button_snapshot.setMinimumSize(pbSize)
                push_button_snapshot.setMaximumSize(pbSize)
                push_button_snapshot.setIcon(
                    QtGui.QIcon(
                        utils_base.filedir("./core/images/icons",
                                           "gtk-paste.png")))
                push_button_snapshot.setShortcut(Qt.QKeySequence(
                    self.tr("F8")))
                push_button_snapshot.setWhatsThis("Capturar pantalla(F8)")
                push_button_snapshot.setToolTip("Capturar pantalla(F8)")
                push_button_snapshot.setFocusPolicy(QtCore.Qt.NoFocus)
                self.bottomToolbar.layout().addWidget(push_button_snapshot)
                push_button_snapshot.clicked.connect(self.saveSnapShot)

            spacer = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Fixed,
                                           QtWidgets.QSizePolicy.Fixed)
            self.bottomToolbar.layout().addItem(spacer)

        if not self.pushButtonAccept:
            self.pushButtonAccept = QtWidgets.QToolButton(self)
            self.pushButtonAccept.setObjectName("pushButtonAccept")
            self.pushButtonAccept.clicked.connect(self.accept)

        self.pushButtonAccept.setSizePolicy(sizePolicy)
        self.pushButtonAccept.setMaximumSize(pbSize)
        self.pushButtonAccept.setMinimumSize(pbSize)
        self.pushButtonAccept.setIcon(
            QtGui.QIcon(
                utils_base.filedir("./core/images/icons", "gtk-save.png")))
        # pushButtonAccept->setAccel(Qt.QKeySequence(Qt::Key_F10)); FIXME
        self.pushButtonAccept.setFocus()
        self.pushButtonAccept.setWhatsThis(
            "Seleccionar registro actual y cerrar formulario (F10)")
        self.pushButtonAccept.setToolTip(
            "Seleccionar registro actual y cerrar formulario (F10)")
        self.pushButtonAccept.setFocusPolicy(QtCore.Qt.NoFocus)
        self.bottomToolbar.layout().addWidget(self.pushButtonAccept)
        self.pushButtonAccept.show()

        if not self.pushButtonCancel:
            self.pushButtonCancel = QtWidgets.QToolButton(self)
            self.pushButtonCancel.setObjectName("pushButtonCancel")
            self.pushButtonCancel.clicked.connect(self.reject)

        self.pushButtonCancel.setSizePolicy(sizePolicy)
        self.pushButtonCancel.setMaximumSize(pbSize)
        self.pushButtonCancel.setMinimumSize(pbSize)
        self.pushButtonCancel.setIcon(
            QtGui.QIcon(
                utils_base.filedir("./core/images/icons", "gtk-stop.png")))
        self.pushButtonCancel.setFocusPolicy(QtCore.Qt.NoFocus)
        # pushButtonCancel->setAccel(Esc); FIXME
        self.pushButtonCancel.setWhatsThis(
            "Cerrar formulario sin seleccionar registro (Esc)")
        self.pushButtonCancel.setToolTip(
            "Cerrar formulario sin seleccionar registro (Esc)")
        self.bottomToolbar.layout().addWidget(self.pushButtonCancel)
        self.pushButtonCancel.show()
        if self.cursor_ is None:
            raise Exception("Cursor is empty!.")
        self.cursor_.setEdition(False)
        self.cursor_.setBrowse(False)
        self.cursor_.recordChoosed.connect(self.accept)

    def exec_(self, valor: Optional[str] = None) -> bool:
        """
        Show the form and enter a new event loop to wait, to select record.

        The name of a cursor field is expected
        returning the value of that field if the form is accepted
        and a QVariant :: Invalid if canceled.

        @param valor Name of a form cursor field
        @return The value of the field if accepted, or False if canceled
        """

        if not self.cursor_:
            return False

        if self.cursor_.isLocked():
            self.cursor_.setModeAccess(pnsqlcursor.PNSqlCursor.Browse)

        if self.loop or self.inExec_:
            print(
                "FLFormSearchDB::exec(): Se ha detectado una llamada recursiva"
            )
            if self.isHidden():
                super().show()
            if self.initFocusWidget_:
                self.initFocusWidget_.setFocus()
            return False

        self.inExec_ = True
        self.acceptingRejecting_ = False
        self.accepted_ = False

        super().show()
        if self.initFocusWidget_:
            self.initFocusWidget_.setFocus()

        if self.iface:
            try:
                QtCore.QTimer.singleShot(50, self.iface.init)
            except Exception:
                pass

        if not self.isClosing_:
            QtCore.QTimer.singleShot(0, self.emitFormReady)

        self.loop = True
        if self.eventloop:
            self.eventloop.exec_()
        self.loop = False
        self.inExec_ = False

        if self.accepted_ and valor:
            return self.cursor_.valueBuffer(valor)
        else:
            self.close()
            return False

    def setFilter(self, f: str) -> None:
        """Apply a filter to the cursor."""

        if not self.cursor_:
            return
        previousF = self.cursor_.mainFilter()
        newF = None
        if previousF == "":
            newF = f
        elif f is None or previousF.find(f) > -1:
            return
        else:
            newF = "%s AND %s" % (previousF, f)
        self.cursor_.setMainFilter(newF)

    def formClassName(self) -> str:
        """Return the class name of the form at runtime."""

        return "FormSearchDB"

    def formName(self) -> str:
        """
        Return internal form name.
        """

        return "formSearch%s" % self.idMDI_

    def closeEvent(self, e: QtCore.QEvent) -> None:
        """Capture event close."""

        self.frameGeometry()
        # if self.focusWidget():
        #    fdb = self.focusWidget().parentWidget()
        #    try:
        #        if fdb and fdb.autoComFrame_ and fdb.autoComFrame_.isvisible():
        #            fdb.autoComFrame_.hide()
        #            return
        #    except Exception:
        #        pass

        if self.cursor_ and self.pushButtonCancel:
            if not self.pushButtonCancel.isEnabled():
                return

            self.isClosing_ = True
            self.setCursor(None)
        else:
            self.isClosing_ = True

        if self.isHidden():
            # self.saveGeometry()
            # self.closed.emit()
            super().closeEvent(e)
            # self.deleteLater()
        else:
            self.reject()

    @decorators.pyqtSlot()
    def callInitScript(self) -> None:
        """Call the "init" function of the "masterprocess" script associated with the form."""

        pass

    @decorators.pyqtSlot()
    def hide(self) -> None:
        """Redefined for convenience."""

        if self.loop:
            self.loop = False
            self.eventloop.exit()

        if self.isHidden():
            return

        super().hide()

    @decorators.pyqtSlot()
    def accept(self) -> None:
        """Activate pressing the accept button."""

        if self.acceptingRejecting_:
            return
        self.frameGeometry()
        if self.cursor_:
            try:
                self.cursor_.recordChoosed.disconnect(self.accept)
            except Exception:
                pass
        self.acceptingRejecting_ = True
        self.accepted_ = True
        self.saveGeometry()
        self.hide()

        parent = self.parent()
        if isinstance(parent, QtWidgets.QMdiSubWindow):
            parent.hide()

    @decorators.pyqtSlot()
    def reject(self) -> None:
        """Activate pressing the accept button."""

        if self.acceptingRejecting_:
            return
        self.frameGeometry()
        if self.cursor_:
            try:
                self.cursor_.recordChoosed.disconnect(self.accept)
            except Exception:
                pass
        self.acceptingRejecting_ = True
        self.hide()

    @decorators.pyqtSlot()
    def show(self) -> None:
        """Redefined for convenience."""
        self.exec_()

    def setMainWidget(self, w: QtWidgets.QWidget = None) -> None:
        """
        Set widget as the main form.
        """

        if not self.cursor_:
            return

        if w:
            w.hide()
            self.mainWidget_ = w
Exemplo n.º 14
0
class DelayedObjectProxyLoader(object):
    """
    Delay load of an object until its first accessed.

    This is used to create entities such "formclientes" or "flfactppal" ahead of time and
    publish them in pineboolib.qsa.qsa so the code can freely call flfactppal.iface.XXX.

    Once the first attribute is called, the object is loaded.

    QSA Code should avoid calling directly "formclientes" and instead use QSADictModules or SafeQSA
    """

    logger = logging.getLogger("application.DelayedObjectProxyLoader")

    def __init__(self,
                 obj: Callable[..., "FLFormDB"],
                 name: Optional[str] = None,
                 *args: str,
                 **kwargs: str) -> None:
        """
        Constructor.
        """
        self.logger.trace("obj: %r", obj)
        self._name: str = name or "unnamed-loader"
        self._obj = obj
        self._args = args
        self._kwargs = kwargs
        self.loaded_obj: Optional["FLFormDB"] = None

    def __load(self) -> "FLFormDB":
        """
        Load a new object.

        @return objeto nuevo o si ya existe , cacheado
        """
        if (self.loaded_obj is not None and self.loaded_obj._loaded
            ):  # Si no está _loaded lo sobrecarga también
            return self.loaded_obj
        self.logger.debug(
            "DelayedObjectProxyLoader: loading %s %s( *%s **%s)",
            self._name,
            self._obj,
            self._args,
            self._kwargs,
        )

        self.loaded_obj = self._obj(*self._args, **self._kwargs)
        self.logger.trace("loaded object: %r", self.loaded_obj)
        if self.loaded_obj is None:
            raise Exception("Failed to load object")
        return self.loaded_obj

    def __getattr__(
            self,
            name: str) -> Any:  # Solo se lanza si no existe la propiedad.
        """
        Return attribute or method from internal object.

        @param name. Nombre del la función buscada
        @return el objecto del XMLAction afectado
        """

        obj_ = self.__load()
        return getattr(obj_, name, getattr(obj_.widget, name, None))
Exemplo n.º 15
0
"""Preload Module."""

from pineboolib import logging
from typing import Container, Any

LOGGER = logging.getLogger("loader.preload_actions")


def preload_actions(project: Any, forceload: Container = None) -> None:
    """
    Preload actions for warming up the pythonizer cache.

    forceload: When passed an string, it filters and loads all
        actions that match "*forceload*". If None, all actions
        are loaded.
    """
    LOGGER.info("Precarga ...")
    for action in project.actions:
        if forceload and action not in forceload:
            continue
        LOGGER.debug("* * * Cargando acción %s . . . " % action)
        try:
            project.actions[action].load()
        except Exception:
            LOGGER.exception("Failure trying to load action %s", action)
            project.conn_manager.mainConn().rollback(
            )  # FIXME: Proper transaction handling using with context
        try:
            project.actions[action].loadRecord(None)
        except Exception:
            LOGGER.exception("Failure trying to loadRecord action %s", action)
Exemplo n.º 16
0
"""

from pineboolib.core import decorators

from pineboolib.interfaces import itablemetadata
from pineboolib import logging
import copy

from typing import Optional, List, Dict, Union, TYPE_CHECKING
from . import pnfieldmetadata
from . import pncompoundkeymetadata

if TYPE_CHECKING:
    from . import pnrelationmetadata  # noqa

LOGGER = logging.getLogger("CursorTableModel")


class PNTableMetaData(itablemetadata.ITableMetaData):
    """PNTableMetaData Class."""

    private: "PNTableMetaDataPrivate"

    def __init__(
        self,
        name_or_metadata: Union[str, "PNTableMetaData"] = "",
        alias: Optional[str] = None,
        query_name: Optional[str] = None,
    ) -> None:
        """
        Collect the data to start.
Exemplo n.º 17
0
 def __init__(self) -> None:
     """Create base class for tools."""
     self.logger = logging.getLogger("ParseTools")
     self.pagina = 0
     self._fix_ratio_h = 0.927  # Corrector de altura 0.927
     self._fix_ratio_w = 0.92
Exemplo n.º 18
0
    def __init__(self) -> None:
        """Initialize."""

        super(FLTranslations, self).__init__()
        self.logger = logging.getLogger("FLTranslations")
Exemplo n.º 19
0
class FLFormDB(QtWidgets.QDialog):
    """
    Represents a form that links to a table.

    It is used as a container of components that want
    link to the database and access the records
    of the cursor. This structure greatly simplifies
    measure access to data since many tasks are
    Automatically managed by this container form.

    At first the form is created empty and we must invoke
    the FLFormDB :: setMainWidget () method, passing it as a parameter
    another widget (usually a form created with QtDesigner),
    which contains different components, this widget will be displayed
    inside this container, self-configuring all the components
    It contains, with the cursor data and metadata. Generally the
    Components will be plugins, such as FLFieldDB or FLTableDB
    """
    """
    Cursor, con los registros, utilizado por el formulario
    """

    cursor_: Optional["isqlcursor.ISqlCursor"]
    """
    Nombre de la tabla, contiene un valor no vacío cuando
    la clase es propietaria del cursor
    """
    name_: str
    """
    Capa principal del formulario
    """
    layout_: QtWidgets.QVBoxLayout
    """
    Widget principal del formulario
    """
    mainWidget_: Optional[QtWidgets.QWidget]
    """
    Identificador de ventana MDI.

    Generalmente es el nombre de la acción que abre el formulario
    """
    idMDI_: str
    """
    Capa para botones
    """
    layoutButtons: QtWidgets.QHBoxLayout
    """
    Boton Cancelar
    """
    pushButtonCancel: Optional[QtWidgets.QToolButton]
    """
    Indica que la ventana ya ha sido mostrada una vez
    """
    showed: bool
    """
    Guarda el contexto anterior que tenia el cursor
    """
    oldCursorCtxt: Any
    """
    Indica que el formulario se está cerrando
    """
    isClosing_: bool
    """
    Componente con el foco inicial
    """
    initFocusWidget_: Optional[QtWidgets.QWidget]
    """
    Guarda el último objeto de formulario unido a la interfaz de script (con bindIface())
    """
    oldFormObj: Any
    """
    Boton Debug Script
    """
    pushButtonDebug: Optional[QtWidgets.QToolButton]
    """
    Almacena que se aceptado, es decir NO se ha pulsado, botón cancelar
    """
    accepted_: bool
    """
    Nombre del formulario relativo a la acción (form / formRecrd + nombre de la acción)
    """
    actionName_: str
    """
    Interface para scripts
    """
    iface: Any
    """
    Tamaño de icono por defecto
    """
    iconSize: QtCore.QSize

    # protected slots:
    """
    Uso interno
    """
    oldFormObjDestroyed = QtCore.pyqtSignal()

    # 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()
    formClosed = QtCore.pyqtSignal()

    known_instances: Dict[Tuple[Type["FLFormDB"], str], "FLFormDB"] = {}

    bottomToolbar: Optional[QtWidgets.QFrame]

    toolButtonClose: Optional[QtWidgets.QToolButton]

    _uiName: str
    _scriptForm: Union[Any, str]

    loop: bool
    _action: "pnaction.PNAction"
    logger = logging.getLogger("FLFormDB")

    def __init__(
        self,
        action_or_name: Union["pnaction.PNAction", str],
        parent: Optional[Union[QtWidgets.QWidget, int]] = None,
        load: Union[bool, int] = False,
    ) -> None:
        """Create a new FLFormDB for given action."""
        # self.tiempo_ini = time.time()
        parent_widget: QtWidgets.QWidget

        if isinstance(load, int):
            load = load == 1

        if parent is None or isinstance(parent, int):
            parent_widget = flapplication.aqApp.mainWidget()
        else:
            parent_widget = parent

        super().__init__(parent_widget)

        self._loaded = False

        if isinstance(action_or_name, str):
            self._action = application.PROJECT.conn_manager.manager().action(
                action_or_name)
        else:
            self._action = action_or_name

        self.known_instances[(self.__class__, self._action.name())] = self

        self.actionName_ = script_name = self._action.name()

        if self._action.table():
            if type(self).__name__ == "FLFormRecordDB":
                self.actionName_ = "formRecord%s" % self.actionName_
                script_name = self._action.scriptFormRecord()
            else:
                self.actionName_ = "form%s" % self.actionName_
                script_name = self._action.scriptForm()

        # self.mod = self._action.mod
        self.loop = False
        self.eventloop = QtCore.QEventLoop()

        self.layout_ = QtWidgets.QVBoxLayout()
        self.layout_.setContentsMargins(1, 1, 1, 1)
        self.layout_.setSpacing(1)
        self.layout_.setContentsMargins(1, 1, 1, 1)
        self.layout_.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize)
        self.setLayout(self.layout_)
        self._uiName = self._action.form()
        self.pushButtonCancel = None
        self.toolButtonClose = None
        self.bottomToolbar = None
        self.cursor_ = None
        self.initFocusWidget_ = None
        self.showed = False
        self.isClosing_ = False
        self.accepted_ = False
        self.mainWidget_ = None
        self.iface = None
        self.oldFormObj = None
        self.oldCursorCtxt = None

        self.idMDI_ = self._action.name()

        self.logger.info("init: Action: %s", self._action)

        self.script = load_script.load_script(
            script_name, application.PROJECT.actions[self._action.name()])
        self.widget = self.script.form
        self.widget.form = self
        if hasattr(self.widget, "iface"):
            self.iface = self.widget.iface

        self.iconSize = application.PROJECT.DGI.iconSize()

        if load:
            self.load()
            self.initForm()

    def load(self) -> None:
        """Load control."""
        if self._loaded:
            return

        # self.resize(550,350)
        if self.layout_ is None:
            return

        self.layout_.insertWidget(0, self.widget)
        self.layout_.setSpacing(1)
        self.layout_.setContentsMargins(1, 1, 1, 1)
        self.layout_.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize)

        if self._uiName:

            if application.PROJECT.conn_manager is None:
                raise Exception("Project is not connected yet")

            application.PROJECT.conn_manager.managerModules().createUI(
                self._uiName, None, self)

        self._loaded = True

    def loaded(self) -> bool:
        """Return if the control is initialized."""

        return self._loaded

    @decorators.pyqtSlot()
    def initScript(self) -> bool:
        """
        Call the "init" function of the masterprocess script associated with the form.
        """

        if self._loaded:
            if not getattr(self.widget, "iface", None):
                self.iface = (
                    self.widget
                )  # Es posible que no tenga ifaceCtx, así hacemos que sea polivalente

            if self.widget:
                self.widget.clear_connections()

            if hasattr(self.iface, "init"):
                try:
                    self.iface.init()
                except Exception:
                    from pineboolib.core.error_manager import error_manager

                    flapplication.aqApp.msgBoxWarning(
                        error_manager(
                            traceback.format_exc(limit=-6, chain=False)),
                        application.PROJECT.DGI,
                    )
                    return False

            return True

        return False

    def __del__(self) -> None:
        """
        Destroyer.
        """
        # TODO: Esto hay que moverlo al closeEvent o al close()
        # ..... los métodos __del__ de python son muy poco fiables.
        # ..... Se lanzan o muy tarde, o nunca.
        # (De todos modos creo que ya hice lo mismo a mano en el closeEvent en commits anteriores)

        self.unbindIface()

    def setCursor(
            self,
            cursor: "isqlcursor.ISqlCursor" = None) -> None:  # type: ignore
        """Change current cursor binded to this control."""
        if cursor is not self.cursor_ and self.cursor_ and self.oldCursorCtxt:
            self.cursor_.setContext(self.oldCursorCtxt)

        if not cursor:
            return

        if self.cursor_ and self.cursor_ is not cursor:
            if type(self).__name__ == "FLFormRecodDB":
                self.cursor_.restoreEditionFlag(self.objectName())
                self.cursor_.restoreBrowseFlag(self.objectName())

        if self.cursor_:

            cast(QtCore.pyqtSignal,
                 self.cursor_.destroyed).disconnect(self.cursorDestroyed)

        self.widget.cursor_ = cursor
        self.cursor_ = cursor

        if type(self).__name__ == "FLFormRecodDB":
            self.cursor_.setEdition(False, self.objectName())
            self.cursor_.setBrowse(False, self.objectName())

        cast(QtCore.pyqtSignal,
             self.cursor_.destroyed).connect(self.cursorDestroyed)
        if self.iface and self.cursor_:
            self.oldCursorCtxt = self.cursor_.context()
            self.cursor_.setContext(self.iface)

    def cursor(
        self
    ) -> "isqlcursor.ISqlCursor":  # type: ignore [override] # noqa F821
        """
        To get the cursor used by the form.
        """
        if self.cursor_ is None:
            raise Exception("cursor_ is empty!.")

        return self.cursor_

    def mainWidget(self) -> Optional[QtWidgets.QWidget]:
        """
        To get the form's main widget.
        """

        return self.mainWidget_

    def setIdMDI(self, id_: str) -> None:
        """
        Set the MDI ID.
        """

        self.idMDI_ = id_

    def idMDI(self) -> str:
        """
        Return the MDI ID.
        """

        return self.idMDI_

    def setMainWidget(self, w: Optional[QtWidgets.QWidget] = None) -> None:
        """
        Set widget as the main form.
        """

        self.mainWidget_ = self

    def snapShot(self) -> QtGui.QImage:
        """
        Return the image or screenshot of the form.
        """
        pix = self.grab()
        return pix.toImage()

    def saveSnapShot(self, path_file: Optional[str] = None) -> None:
        """
        Save the image or screenshot of the form in a PNG format file.
        """
        if not path_file:

            tmp_file = "%s/snap_shot_%s.png" % (
                flapplication.aqApp.tmp_dir(),
                QtCore.QDateTime.currentDateTime().toString(
                    "ddMMyyyyhhmmsszzz"),
            )

            ret = QtWidgets.QFileDialog.getSaveFileName(
                QtWidgets.QApplication.activeWindow(), "Pineboo", tmp_file,
                "PNG(*.png)")
            path_file = ret[0] if ret else None

        if path_file:
            fi = QtCore.QFile(path_file)
            if not fi.OpenMode(QtCore.QIODevice.WriteOnly):
                self.tr("Error I/O al intentar escribir el fichero %s" %
                        path_file)
                return

            self.snapShot().save(fi, "PNG")

    def saveGeometry(self) -> QtCore.QByteArray:
        """Save current window size into settings."""
        # pW = self.parentWidget()
        # if not pW:
        geo = QtCore.QSize(self.width(), self.height())
        if self.isMinimized():
            geo.setWidth(1)
        elif self.isMaximized():
            geo.setWidth(9999)
        # else:
        #    geo = QtCore.QSize(pW.width(), pW.height())

        geometry.save_geometry_form(self.geoName(), geo)
        return super().saveGeometry()

    def setCaptionWidget(self, text: str) -> None:
        """
        Set the window title.
        """
        if not text:
            return

        self.setWindowTitle(text)

    def accepted(self) -> bool:  # type: ignore
        """
        Return if the form has been accepted.
        """
        # FIXME: QtWidgets.QDialog.accepted() is a signal. We're shadowing it.
        return self.accepted_

    def formClassName(self) -> str:
        """
        Return the class name of the form at runtime.
        """
        return "FormDB"

    def exec_(self) -> bool:
        """
        Only to be compatible with FLFormSearchDB. By default, just call QWidget.show.
        """

        super().show()
        return True

    def hide(self) -> None:
        """Hide control."""
        super().hide()

    @decorators.pyqtSlot()
    def close(self) -> bool:
        """
        Close the form.
        """
        if self.isClosing_ or not self._loaded:
            return True

        self.isClosing_ = True

        super().close()
        self.isClosing_ = False
        return True

    @decorators.pyqtSlot()
    def accept(self) -> None:
        """
        Activated by pressing the accept button.
        """
        pass

    @decorators.pyqtSlot()
    def reject(self) -> None:
        """
        Activated by pressing the cancel button.
        """
        pass

    @decorators.pyqtSlot()
    def showForDocument(self) -> None:
        """
        Show the form without calling the script "init".

        Used in documentation to avoid conflicts when capturing forms.
        """
        self.showed = True
        if self.mainWidget_:
            self.mainWidget_.show()
            self.resize(self.mainWidget_.size())
        super().show()

    @decorators.pyqtSlot()
    @decorators.NotImplementedWarn
    def debugScript(self) -> bool:
        """
        Show the script associated with the form in the Workbench to debug.
        """

        return True

    @decorators.pyqtSlot()
    def get_script(self) -> Optional[str]:
        """
        Return the script associated with the form.
        """

        ifc = self.iface
        if ifc:
            return str(ifc)
        return None

    # private slots:

    @decorators.pyqtSlot()
    def callInitScript(self) -> None:
        """Call QS Script related to this control."""
        if not self.initScript():
            raise Exception("Error initializing the module.")

        if not self.isClosing_:
            QtCore.QTimer.singleShot(0, self.emitFormReady)

    def emitFormReady(self) -> None:
        """Emit formReady signal, after the form has been loaded."""
        from pineboolib.application.qsatypes.sysbasetype import SysBaseType

        qsa_sys = SysBaseType()
        if qsa_sys.isLoadedModule("fltesttest"):

            flapplication.aqApp.call("fltesttest.iface.recibeEvento",
                                     ("formReady", self.actionName_), None)
        self.formReady.emit()

    # protected_:

    def emitFormClosed(self) -> None:
        """Emit formClosed signal."""

        if application.PROJECT.conn_manager is None:
            raise Exception("Project is not connected yet")

        if "fltesttest" in application.PROJECT.conn_manager.managerModules(
        ).listAllIdModules():
            application.PROJECT.call("fltesttest.iface.recibeEvento",
                                     ["formClosed", self.actionName_], None)

        self.formClosed.emit()
        if self.widget:
            self.widget.closed.emit()

    def action(self) -> "pnaction.PNAction":
        """Get form PNAction."""
        return self._action

    def initForm(self) -> None:
        """
        Initialize the associated script.
        """
        from pineboolib.fllegacy import flapplication

        acl = flapplication.aqApp.acl()

        if acl:
            acl.process(self)

        self.loadControls()

        if self._action is None:
            raise Exception("_action is empty!")

        if self._action.table():
            if (not self.cursor_ or not self.cursor_._action or
                    self.cursor_._action.table() is not self._action.table()):
                cursor = pnsqlcursor.PNSqlCursor(self._action.table())
                self.setCursor(cursor)

            v = None

            preload_main_filter = getattr(self.iface, "preloadMainFilter",
                                          None)

            if preload_main_filter:
                v = preload_main_filter()

            if v is not None and self.cursor_:
                self.cursor_.setMainFilter(v, False)

            # if self._loaded and not self.__class__.__name__ == "FLFormRecordDB":
            # application.PROJECT.conn_manager.managerModules().loadFLTableDBs(self)

            if self._action.description() not in ("", None):
                self.setWhatsThis(self._action.description())

            caption = self._action.caption()

            if caption in ("",
                           None) and self.cursor_ and self.cursor_.metadata():
                caption = self.cursor_.metadata().alias()

            if caption in ("", None):
                caption = QtWidgets.QApplication.translate(
                    "FLFormDB", "No hay metadatos")
            self.setCaptionWidget(caption)

    def loadControls(self) -> None:
        """Load form controls."""

        if self.pushButtonCancel:
            self.pushButtonCancel.hide()

        if self.bottomToolbar and self.toolButtonClose:
            self.toolButtonClose.hide()
        self.bottomToolbar = QtWidgets.QFrame()

        if self.bottomToolbar is None:
            raise Exception("bottomToolBar is empty!")

        if self.iconSize is not None:
            self.bottomToolbar.setMinimumSize(self.iconSize)

        hblay = QtWidgets.QHBoxLayout()

        hblay.setContentsMargins(0, 0, 0, 0)
        hblay.setSpacing(0)
        hblay.addStretch()
        self.bottomToolbar.setLayout(hblay)
        self.bottomToolbar.setFocusPolicy(QtCore.Qt.NoFocus)
        if self.layout_ is not None:
            self.layout_.addWidget(self.bottomToolbar)
        # if self.layout:
        #    self.layout = None
        # Limpiamos la toolbar

        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy(0),
                                           QtWidgets.QSizePolicy.Policy(0))
        sizePolicy.setHeightForWidth(True)

        pbSize = self.iconSize

        if settings.config.value("application/isDebuggerMode", False):

            pushButtonExport = QtWidgets.QToolButton()
            pushButtonExport.setObjectName("pushButtonExport")
            pushButtonExport.setSizePolicy(sizePolicy)
            pushButtonExport.setMinimumSize(pbSize)
            pushButtonExport.setMaximumSize(pbSize)
            pushButtonExport.setIcon(
                QtGui.QIcon(
                    utils_base.filedir("./core/images/icons",
                                       "gtk-properties.png")))
            pushButtonExport.setShortcut(QtGui.QKeySequence(self.tr("F3")))
            pushButtonExport.setWhatsThis(
                QtWidgets.QApplication.translate("FLFormDB",
                                                 "Exportar a XML(F3)"))
            pushButtonExport.setToolTip(
                QtWidgets.QApplication.translate("FLFormDB",
                                                 "Exportar a XML(F3)"))
            pushButtonExport.setFocusPolicy(QtCore.Qt.NoFocus)
            self.bottomToolbar.layout().addWidget(pushButtonExport)
            pushButtonExport.clicked.connect(self.exportToXml)

            if settings.config.value("ebcomportamiento/show_snaptshop_button",
                                     False):
                push_button_snapshot = QtWidgets.QToolButton()
                push_button_snapshot.setObjectName("pushButtonSnapshot")
                push_button_snapshot.setSizePolicy(sizePolicy)
                push_button_snapshot.setMinimumSize(pbSize)
                push_button_snapshot.setMaximumSize(pbSize)
                push_button_snapshot.setIcon(
                    QtGui.QIcon(
                        utils_base.filedir("./core/images/icons",
                                           "gtk-paste.png")))
                push_button_snapshot.setShortcut(
                    QtGui.QKeySequence(self.tr("F8")))
                push_button_snapshot.setWhatsThis("Capturar pantalla(F8)")
                push_button_snapshot.setToolTip("Capturar pantalla(F8)")
                push_button_snapshot.setFocusPolicy(QtCore.Qt.NoFocus)
                self.bottomToolbar.layout().addWidget(push_button_snapshot)
                push_button_snapshot.clicked.connect(self.saveSnapShot)

            spacer = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Fixed,
                                           QtWidgets.QSizePolicy.Fixed)
            self.bottomToolbar.layout().addItem(spacer)

        if not self.pushButtonCancel:
            self.pushButtonCancel = QtWidgets.QToolButton()
            self.pushButtonCancel.setObjectName("pushButtonCancel")
            cast(QtCore.pyqtSignal, self.pushButtonCancel.clicked).connect(
                cast(Callable, self.close))

        self.pushButtonCancel.setSizePolicy(sizePolicy)
        self.pushButtonCancel.setMaximumSize(pbSize)
        self.pushButtonCancel.setMinimumSize(pbSize)
        self.pushButtonCancel.setIcon(
            QtGui.QIcon(
                utils_base.filedir("./core/images/icons", "gtk-stop.png")))
        # self.pushButtonCancel.setFocusPolicy(QtCore.Qt.StrongFocus)
        # self.pushButtonCancel.setFocus()
        self.pushButtonCancel.setShortcut(QtGui.QKeySequence(self.tr("Esc")))
        self.pushButtonCancel.setWhatsThis("Cerrar formulario (Esc)")
        self.pushButtonCancel.setToolTip("Cerrar formulario (Esc)")
        self.bottomToolbar.layout().addWidget(self.pushButtonCancel)
        self.setFocusPolicy(QtCore.Qt.NoFocus)

    def formName(self) -> str:
        """
        Return internal form name.
        """

        return "form%s" % self.idMDI_

    def name(self) -> str:
        """Get name of the form."""

        return self.formName()

    def geoName(self) -> str:
        """Get name of the form."""
        # FIXME: What this should do exactly?
        return self.formName()

    def bindIface(self) -> None:
        """
        Join the script interface to the form object.
        """

        if self.iface:
            self.oldFormObj = self.iface

    def unbindIface(self) -> None:
        """
        Disconnect the script interface to the form object.
        """
        if not self.iface:
            return

        self.iface = self.oldFormObj

    def isIfaceBind(self) -> bool:
        """
        Indicate if the script interface is attached to the form object.
        """

        if self.iface:
            return True
        else:
            return False

    def closeEvent(self, e: Any) -> None:
        """
        Capture event close.
        """
        self.frameGeometry()

        self.saveGeometry()
        self.setCursor(None)
        # self.closed.emit()
        self.hide()
        self.emitFormClosed()
        # super().closeEvent(e)
        # self._action.mainform_widget = None
        self.deleteLater()
        self._loaded = False
        # from PyQt5.QtWidgets import qApp

        # qApp.processEvents() #Si se habilita pierde mucho tiempo!

        # self.hide()
        try:
            # if hasattr(self.script, "form"):
            #    print("Borrando self.script.form", self.script.form)
            #    self.script.form = None
            if self.widget is not None and type(
                    self).__name__ != "FLFormSearchDB":
                self.widget.close()
                self.widget = None
                # del self.widget

            # self.iface = None
            # del self.iface
            # if hasattr(self, "widget"):
            #    print("Borrando self.widget", self.widget)
            #    self.widget.close()
            #    del self.widget
            instance_name = (self.__class__, self._action.name())
            if instance_name in self.known_instances.keys():
                del self.known_instances[instance_name]

            # if hasattr(self, "script"):
            #    print("Borrando self.script", self.script)
            self.script = None
        except Exception:

            self.logger.error(
                "El FLFormDB %s no se cerró correctamente:\n%s",
                self.formName(),
                traceback.format_exc(),
            )

        parent = self.parent()

        if isinstance(parent, QtWidgets.QMdiSubWindow):
            parent.close()

    def showEvent(self, e: Any) -> None:
        """
        Capture event show.
        """
        # --> Para mostrar form sin negro previo
        # QtWidgets.QApplication.processEvents()
        # <--
        if not self.loaded():
            return

        if not self.showed:
            self.showed = True

            # self.initMainWidget()

            self.callInitScript()

            if not self._loaded:
                return

            self.bindIface()

        size = geometry.load_geometry_form(self.geoName())
        if size:
            self.resize(size)

            parent = self.parent()

            if parent and isinstance(parent, QtWidgets.QMdiSubWindow):
                parent.resize(size)
                parent.repaint()

    def cursorDestroyed(self, obj_: Optional[Any] = None) -> None:
        """Clean up. Called when cursor has been deleted."""
        if not obj_:
            obj_ = self.sender()

        if not obj_ or obj_ is self.cursor_:
            return

        del self.cursor_

    """
    Captura evento ocultar


    def hideEvent(self, h):
        pW = self.parentWidget()
        if not pW:
            geo = QtCore.QSize(self.width(), self.height())
            if self.isMinimized():
                geo.setWidth(1)
            elif self.isMaximized():
                geo.setWidth(9999)
        else:
            geo = QtCore.QSize(pW.width(), pW.height())

        #geometry.saveGeometryForm(self.geoName(), geo)
    """

    def focusInEvent(self, f: Any) -> None:
        """
        Capture Focus Enter Event.
        """

        super().focusInEvent(f)
        if not self.isIfaceBind():
            self.bindIface()

    def show(self) -> None:
        """
        Initialize components of the main widget.

        @param w Widget to initialize. If not set use
        by default the current main widget.
        """

        if hasattr(application.PROJECT.main_window, "_dict_main_widgets"):
            module_name = application.PROJECT.conn_manager.managerModules(
            ).activeIdModule()
            if (module_name and module_name in
                    application.PROJECT.main_window._dict_main_widgets.keys()):
                module_window = application.PROJECT.main_window._dict_main_widgets[
                    module_name]

                mdi_area = module_window.centralWidget()
                if isinstance(mdi_area, QtWidgets.QMdiArea):

                    for sub_window in mdi_area.subWindowList():
                        if cast(FLFormDB, sub_window.widget()).formName(
                        ) == self.formName():
                            mdi_area.setActiveSubWindow(sub_window)
                            return

                    if type(self).__name__ == "FLFormDB":
                        # if not isinstance(self.parent(), QtWidgets.QMdiSubWindow):
                        # size = self.size()
                        mdi_area.addSubWindow(self)

        if self.initFocusWidget_ is None:
            self.initFocusWidget_ = self.focusWidget()

        if self.initFocusWidget_:
            self.initFocusWidget_.setFocus()

        # if not self.tiempo_ini:
        #    self.tiempo_ini = time.time()
        super().show()
        # tiempo_fin = time.time()
        parent_ = self.parent()
        if parent_ and parent_.parent() is None:

            qt_rectangle = self.frameGeometry()
            center_point = QtWidgets.QDesktopWidget().availableGeometry(
            ).center()
            qt_rectangle.moveCenter(center_point)
            self.move(qt_rectangle.topLeft())
        # if settings.readBoolEntry("application/isDebuggerMode", False):
        #    self.logger.warning("INFO:: Tiempo de carga de %s: %.3fs %s (iface %s)" %
        #                     (self.actionName_, tiempo_fin - self.tiempo_ini, self, self.iface))
        # self.tiempo_ini = None

    def initMainWidget(self, w: Optional[QtWidgets.QWidget] = None) -> None:
        """Initialize widget."""
        if not self.showed:
            self.show()

    def child(self, child_name: str) -> QtWidgets.QWidget:
        """Get child by name."""
        ret = cast(
            QtWidgets.QWidget,
            self.findChild(QtWidgets.QWidget, child_name,
                           QtCore.Qt.FindChildrenRecursively),
        )
        if ret is not None:
            from . import flfielddb, fltabledb

            if isinstance(ret, (flfielddb.FLFieldDB, fltabledb.FLTableDB)):
                if ret._loaded is False:
                    ret.load()

        return ret

    # def __getattr__(self, name):
    # if getattr(self.script, "form", None):
    #    return getattr(self.script.form, name)
    # else:
    #    qWarning("%s (%s):No se encuentra el atributo %s" % (self, self.iface, name))

    @decorators.NotImplementedWarn
    def exportToXml(self, b: bool) -> None:
        """Export this widget into an xml."""
        from pineboolib.fllegacy.aqsobjects.aqs import AQS

        xml = AQS.toXml(self, True, True)
        print(xml.toString(2))
        pass
Exemplo n.º 20
0
    def __init__(self) -> None:
        """Initialize a new instance."""

        self._logger = logging.getLogger(__name__)
Exemplo n.º 21
0
class FLFormRecordDB(flformdb.FLFormDB):
    """
    FLFormRecordDBInterface Class.

    FLFormDB subclass designed to edit records.

    Basically this class does the same as its class
    FLFormDB base, the only thing you add is two buttons
    Accept and / or Cancel to confirm or cancel
    the changes that are made to the components of
    data it contains.

    This class is suitable for loading forms
    editing records defined in metadata
    (FLTableMetaData).

    @author InfoSiAL S.L.
    """

    logger = logging.getLogger("FLFormRecordDB")
    """
    Boton Aceptar
    """

    pushButtonAccept: Optional[QtWidgets.QToolButton]
    """
    Boton Aceptar y continuar
    """
    pushButtonAcceptContinue: Optional[QtWidgets.QToolButton]
    """
    Boton Primero
    """
    pushButtonFirst: Optional[QtWidgets.QToolButton]
    """
    Boton Anterior
    """
    pushButtonPrevious: Optional[QtWidgets.QToolButton]
    """
    Boton Siguiente
    """
    pushButtonNext: Optional[QtWidgets.QToolButton]
    """
    Boton Ultimo
    """
    pushButtonLast: Optional[QtWidgets.QToolButton]
    """
    Indica si se debe mostrar el botón Aceptar y Continuar
    """
    showAcceptContinue_: bool
    """
    Indica que se está intentando aceptar los cambios
    """
    accepting: bool
    """
    Modo en el que inicialmente está el cursor
    """
    initialModeAccess: int
    """
    Registra el nivel de anidamiento de transacciones en el que se entra al iniciar el formulario
    """
    initTransLevel: int

    def __init__(
        self,
        action: "pnaction.PNAction",
        parent_or_cursor: Optional[Union[QtWidgets.QWidget,
                                         "isqlcursor.ISqlCursor", int]] = None,
        load: bool = False,
    ) -> None:
        """
        Inicialize.
        """
        self.logger.trace("__init__: parent_or_cursor=%s, action=%s, load=%s",
                          parent_or_cursor, action, load)

        cursor: Optional[pnsqlcursor.PNSqlCursor] = None
        parent: Optional[QtWidgets.QWidget] = None

        if isinstance(parent_or_cursor, pnsqlcursor.PNSqlCursor):
            cursor = parent_or_cursor
        elif isinstance(parent_or_cursor, QtWidgets.QWidget):
            parent = parent_or_cursor

        super().__init__(action, parent, load)

        self.setWindowModality(QtCore.Qt.ApplicationModal)

        if cursor:
            self.setCursor(cursor)
        self.logger.trace("__init__: load formRecord")
        self._uiName = action.formRecord()
        self._scriptForm = action.scriptFormRecord() or "emptyscript"
        self.bottomToolbar = None
        self.pushButtonAccept = None
        self.pushButtonAcceptContinue = None
        self.pushButtonFirst = None
        self.pushButtonPrevious = None
        self.pushButtonNext = None
        self.pushButtonLast = None

        self.accepting = False
        self.showAcceptContinue_ = True
        self.initialModeAccess = pnsqlcursor.PNSqlCursor.Browse

        if self.cursor_:
            self.initialModeAccess = self.cursor_.modeAccess()

        self.logger.trace("__init__: load form")
        self.load()
        self.logger.trace("__init__: init form")
        self.initForm()
        self.logger.trace("__init__: done")
        self.loop = False

    def setCaptionWidget(self, text: Optional[str] = None) -> None:
        """
        Set the window title.
        """
        if not self.cursor_:
            return

        if not text:
            text = self.cursor_.metadata().alias()

        if self.cursor_.modeAccess() == self.cursor_.Insert:
            self.setWindowTitle("Insertar %s" % text)
        elif self.cursor_.modeAccess() == self.cursor_.Edit:
            self.setWindowTitle("Editar %s" % text)
        elif self.cursor_.modeAccess() == self.cursor_.Browse:
            self.setWindowTitle("Visualizar %s" % text)

    def formClassName(self) -> str:
        """
        Return the class name of the form at runtime.
        """

        return "FormRecordDB"

    def initForm(self) -> None:
        """
        Initialize the form.
        """

        if self.cursor_ and self.cursor_.metadata():
            # caption = None
            if self._action:
                self.cursor().setAction(self._action)
                if self._action.description():
                    self.setWhatsThis(self._action.description())
                self.idMDI_ = self._action.name()

            # self.bindIface()
            # self.setCursor(self.cursor_)

        else:
            self.setCaptionWidget("No hay metadatos")

        acl = flapplication.aqApp.acl()
        if acl:
            acl.process(self)

    def loadControls(self) -> None:
        """Load widgets for this form."""
        if self.pushButtonAcceptContinue:
            self.pushButtonAcceptContinue.hide()

        if self.pushButtonAccept:
            self.pushButtonAccept.hide()

        if self.pushButtonCancel:
            self.pushButtonCancel.hide()

        if self.pushButtonFirst:
            self.pushButtonFirst.hide()

        if self.pushButtonPrevious:
            self.pushButtonPrevious.hide()

        if self.pushButtonNext:
            self.pushButtonNext.hide()

        if self.pushButtonLast:
            self.pushButtonLast.hide()

        if self.bottomToolbar and self.toolButtonClose:
            self.toolButtonClose.hide()

        self.bottomToolbar = QtWidgets.QFrame()

        if self.bottomToolbar:
            self.bottomToolbar.setMinimumSize(self.iconSize)
            hblay = QtWidgets.QHBoxLayout()
            hblay.setContentsMargins(0, 0, 0, 0)
            hblay.setSpacing(0)
            hblay.addStretch()
            self.bottomToolbar.setLayout(hblay)
            self.bottomToolbar.setFocusPolicy(QtCore.Qt.NoFocus)
            self.layout_.addWidget(self.bottomToolbar)

        else:
            raise Exception("bottomToolbar is missing!")
        # if self.layout:
        #    self.layout = None
        # Limpiamos la toolbar

        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy(0),
                                           QtWidgets.QSizePolicy.Policy(0))
        sizePolicy.setHeightForWidth(True)

        pbSize = self.iconSize

        if settings.config.value("application/isDebuggerMode", False):

            pushButtonExport = QtWidgets.QToolButton()
            pushButtonExport.setObjectName("pushButtonExport")
            pushButtonExport.setSizePolicy(sizePolicy)
            pushButtonExport.setMinimumSize(pbSize)
            pushButtonExport.setMaximumSize(pbSize)
            pushButtonExport.setIcon(
                QtGui.QIcon(
                    utils_base.filedir("./core/images/icons",
                                       "gtk-properties.png")))
            pushButtonExport.setShortcut(Qt.QKeySequence(self.tr("F3")))
            pushButtonExport.setWhatsThis("Exportar a XML(F3)")
            pushButtonExport.setToolTip("Exportar a XML(F3)")
            pushButtonExport.setFocusPolicy(QtCore.Qt.NoFocus)
            self.bottomToolbar.layout().addWidget(pushButtonExport)
            pushButtonExport.clicked.connect(self.exportToXml)

            if settings.config.value("ebcomportamiento/show_snaptshop_button",
                                     False):
                push_button_snapshot = QtWidgets.QToolButton()
                push_button_snapshot.setObjectName("pushButtonSnapshot")
                push_button_snapshot.setSizePolicy(sizePolicy)
                push_button_snapshot.setMinimumSize(pbSize)
                push_button_snapshot.setMaximumSize(pbSize)
                push_button_snapshot.setIcon(
                    QtGui.QIcon(
                        utils_base.filedir("./core/images/icons",
                                           "gtk-paste.png")))
                push_button_snapshot.setShortcut(Qt.QKeySequence(
                    self.tr("F8")))
                push_button_snapshot.setWhatsThis("Capturar pantalla(F8)")
                push_button_snapshot.setToolTip("Capturar pantalla(F8)")
                push_button_snapshot.setFocusPolicy(QtCore.Qt.NoFocus)
                self.bottomToolbar.layout().addWidget(push_button_snapshot)
                push_button_snapshot.clicked.connect(self.saveSnapShot)

            spacer = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Fixed,
                                           QtWidgets.QSizePolicy.Fixed)
            self.bottomToolbar.layout().addItem(spacer)

        if self.cursor().modeAccess() in (self.cursor().Edit,
                                          self.cursor().Browse):
            if not self.pushButtonFirst:
                self.pushButtonFirst = QtWidgets.QToolButton()
                self.pushButtonFirst.setObjectName("pushButtonFirst")
                self.pushButtonFirst.setIcon(
                    QtGui.QIcon(
                        utils_base.filedir("./core/images/icons",
                                           "gtk-goto-first-ltr.png")))
                self.pushButtonFirst.clicked.connect(self.firstRecord)
                self.pushButtonFirst.setSizePolicy(sizePolicy)
                self.pushButtonFirst.setMaximumSize(pbSize)
                self.pushButtonFirst.setMinimumSize(pbSize)
                self.pushButtonFirst.setShortcut(Qt.QKeySequence(
                    self.tr("F5")))
                self.pushButtonFirst.setWhatsThis(
                    "Aceptar los cambios e ir al primer registro (F5)")
                self.pushButtonFirst.setToolTip(
                    "Aceptar los cambios e ir al primer registro (F5)")
                self.pushButtonFirst.setFocusPolicy(QtCore.Qt.NoFocus)
                self.bottomToolbar.layout().addWidget(self.pushButtonFirst)
                # self.pushButtonFirst.show()

            if not self.pushButtonPrevious:
                self.pushButtonPrevious = QtWidgets.QToolButton()
                self.pushButtonPrevious.setObjectName("pushButtonPrevious")
                self.pushButtonPrevious.setIcon(
                    QtGui.QIcon(
                        utils_base.filedir("./core/images/icons",
                                           "gtk-go-back-ltr.png")))
                self.pushButtonPrevious.clicked.connect(self.previousRecord)
                self.pushButtonPrevious.setSizePolicy(sizePolicy)
                self.pushButtonPrevious.setMaximumSize(pbSize)
                self.pushButtonPrevious.setMinimumSize(pbSize)
                self.pushButtonPrevious.setShortcut(
                    Qt.QKeySequence(self.tr("F6")))
                self.pushButtonPrevious.setWhatsThis(
                    "Aceptar los cambios e ir al registro anterior (F6)")
                self.pushButtonPrevious.setToolTip(
                    "Aceptar los cambios e ir al registro anterior (F6)")
                self.pushButtonPrevious.setFocusPolicy(QtCore.Qt.NoFocus)
                self.bottomToolbar.layout().addWidget(self.pushButtonPrevious)
                # self.pushButtonPrevious.show()

            if not self.pushButtonNext:
                self.pushButtonNext = QtWidgets.QToolButton()
                self.pushButtonNext.setObjectName("pushButtonNext")
                self.pushButtonNext.setIcon(
                    QtGui.QIcon(
                        utils_base.filedir("./core/images/icons",
                                           "gtk-go-back-rtl.png")))
                self.pushButtonNext.clicked.connect(self.nextRecord)
                self.pushButtonNext.setSizePolicy(sizePolicy)
                self.pushButtonNext.setMaximumSize(pbSize)
                self.pushButtonNext.setMinimumSize(pbSize)
                self.pushButtonNext.setShortcut(Qt.QKeySequence(self.tr("F7")))
                self.pushButtonNext.setWhatsThis(
                    "Aceptar los cambios e ir al registro siguiente (F7)")
                self.pushButtonNext.setToolTip(
                    "Aceptar los cambios e ir al registro siguiente (F7)")
                self.pushButtonNext.setFocusPolicy(QtCore.Qt.NoFocus)
                self.bottomToolbar.layout().addWidget(self.pushButtonNext)
                # self.pushButtonNext.show()

            if not self.pushButtonLast:
                self.pushButtonLast = QtWidgets.QToolButton()
                self.pushButtonLast.setObjectName("pushButtonLast")
                self.pushButtonLast.setIcon(
                    QtGui.QIcon(
                        utils_base.filedir("./core/images/icons",
                                           "gtk-goto-last-ltr.png")))
                self.pushButtonLast.clicked.connect(self.lastRecord)
                self.pushButtonLast.setSizePolicy(sizePolicy)
                self.pushButtonLast.setMaximumSize(pbSize)
                self.pushButtonLast.setMinimumSize(pbSize)
                self.pushButtonLast.setShortcut(Qt.QKeySequence(self.tr("F8")))
                self.pushButtonLast.setWhatsThis(
                    "Aceptar los cambios e ir al último registro (F8)")
                self.pushButtonLast.setToolTip(
                    "Aceptar los cambios e ir al último registro (F8)")
                self.pushButtonLast.setFocusPolicy(QtCore.Qt.NoFocus)
                self.bottomToolbar.layout().addWidget(self.pushButtonLast)
                # self.pushButtonLast.show()

        if not self.cursor().modeAccess() == self.cursor().Browse:
            self.pushButtonAcceptContinue = QtWidgets.QToolButton()
            self.pushButtonAcceptContinue.setObjectName(
                "pushButtonAcceptContinue")
            self.pushButtonAcceptContinue.clicked.connect(self.acceptContinue)
            self.pushButtonAcceptContinue.setSizePolicy(sizePolicy)
            self.pushButtonAcceptContinue.setMaximumSize(pbSize)
            self.pushButtonAcceptContinue.setMinimumSize(pbSize)
            self.pushButtonAcceptContinue.setIcon(
                QtGui.QIcon(
                    utils_base.filedir("./core/images/icons",
                                       "gtk-refresh.png")))
            self.pushButtonAcceptContinue.setShortcut(
                Qt.QKeySequence(self.tr("F9")))
            self.pushButtonAcceptContinue.setWhatsThis(
                "Aceptar los cambios y continuar con la edición de un nuevo registro (F9)"
            )
            self.pushButtonAcceptContinue.setToolTip(
                "Aceptar los cambios y continuar con la edición de un nuevo registro (F9)"
            )
            self.pushButtonAcceptContinue.setFocusPolicy(QtCore.Qt.NoFocus)
            self.bottomToolbar.layout().addWidget(
                self.pushButtonAcceptContinue)
            if not self.showAcceptContinue_:
                self.pushButtonAcceptContinue.close()
                # self.pushButtonAcceptContinue.show()

            if not self.pushButtonAccept:
                self.pushButtonAccept = QtWidgets.QToolButton()
                self.pushButtonAccept.setObjectName("pushButtonAccept")
                self.pushButtonAccept.clicked.connect(self.accept)

            self.pushButtonAccept.setSizePolicy(sizePolicy)
            self.pushButtonAccept.setMaximumSize(pbSize)
            self.pushButtonAccept.setMinimumSize(pbSize)
            self.pushButtonAccept.setIcon(
                QtGui.QIcon(
                    utils_base.filedir("./core/images/icons", "gtk-save.png")))
            self.pushButtonAccept.setShortcut(Qt.QKeySequence(self.tr("F10")))
            self.pushButtonAccept.setWhatsThis(
                "Aceptar los cambios y cerrar formulario (F10)")
            self.pushButtonAccept.setToolTip(
                "Aceptar los cambios y cerrar formulario (F10)")
            self.pushButtonAccept.setFocusPolicy(QtCore.Qt.NoFocus)
            self.bottomToolbar.layout().addWidget(self.pushButtonAccept)
            # self.pushButtonAccept.show()

        if not self.pushButtonCancel:
            self.pushButtonCancel = QtWidgets.QToolButton()
            self.pushButtonCancel.setObjectName("pushButtonCancel")
            try:
                self.cursor().autoCommit.connect(self.disablePushButtonCancel)
            except Exception:
                pass

            self.pushButtonCancel.clicked.connect(self.reject)

        self.pushButtonCancel.setSizePolicy(sizePolicy)
        self.pushButtonCancel.setMaximumSize(pbSize)
        self.pushButtonCancel.setMinimumSize(pbSize)
        self.pushButtonCancel.setShortcut(Qt.QKeySequence(self.tr("Esc")))
        self.pushButtonCancel.setIcon(
            QtGui.QIcon(
                utils_base.filedir("./core/images/icons", "gtk-stop.png")))
        if not self.cursor().modeAccess() == self.cursor().Browse:
            self.pushButtonCancel.setFocusPolicy(QtCore.Qt.NoFocus)
            self.pushButtonCancel.setWhatsThis(
                "Cancelar los cambios y cerrar formulario (Esc)")
            self.pushButtonCancel.setToolTip(
                "Cancelar los cambios y cerrar formulario (Esc)")
        else:
            self.pushButtonCancel.setFocusPolicy(QtCore.Qt.StrongFocus)
            self.pushButtonCancel.setFocus()
            # pushButtonCancel->setAccel(4096); FIXME
            self.pushButtonCancel.setWhatsThis(
                "Aceptar y cerrar formulario (Esc)")
            self.pushButtonCancel.setToolTip(
                "Aceptar y cerrar formulario (Esc)")

        # pushButtonCancel->setDefault(true);
        self.bottomToolbar.layout().addItem(
            QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Fixed,
                                  QtWidgets.QSizePolicy.Fixed))
        self.bottomToolbar.layout().addWidget(self.pushButtonCancel)
        # self.pushButtonAccept.show()

        self.setFocusPolicy(QtCore.Qt.NoFocus)

        # self.toolButtonAccept = QtGui.QToolButton()
        # self.toolButtonAccept.setIcon(QtGui.QIcon(utils_base.filedir("./core/images/icons","gtk-add.png")))
        # self.toolButtonAccept.clicked.connect(self.validateForm)
        # self.bottomToolbar.layout.addWidget(self.toolButtonAccept)
        self.inicializeControls()

    def formName(self) -> str:
        """
        Return internal form name.
        """

        return "formRecord%s" % self.idMDI_

    def closeEvent(self, e: QtCore.QEvent) -> None:
        """
        Capture event close.
        """
        self.frameGeometry()
        if self.focusWidget():
            parent = self.focusWidget().parentWidget()
            if parent:
                fdb = cast(flfielddb.FLFieldDB, parent)
                acf_ = getattr(fdb, "autoComFrame_", None)
                if acf_ and acf_.autoComFrame_.isVisible():
                    acf_.hide()
                    return

        if self.cursor_:

            try:
                levels = self.cursor_.transactionLevel() - self.initTransLevel
                if levels > 0:
                    self.cursor_.rollbackOpened(
                        levels,
                        "Se han detectado transacciones no finalizadas en la última operación.\n"
                        "Se van a cancelar las transacciones pendientes.\n"
                        "Los últimos datos introducidos no han sido guardados, por favor\n"
                        "revise sus últimas acciones y repita las operaciones que no\n"
                        "se han guardado.\n"
                        "FLFormRecordDB::closeEvent: %s %s" %
                        (levels, self.name()),
                    )
            except Exception:
                print(
                    "ERROR: FLFormRecordDB @ closeEvent :: las transacciones aún no funcionan."
                )

            if self.accepted_:
                if not self.cursor_.commit():
                    return
                self.afterCommitTransaction()
            else:
                if not self.cursor_.rollback():
                    e.ignore()
                    return
                # else:
                #    self.cursor_.select()

            self.closed.emit()
            self.setCursor(None)
        else:
            self.closed.emit()

        super(FLFormRecordDB, self).closeEvent(e)
        self.deleteLater()

    def validateForm(self) -> bool:
        """
        Form validation.

        Call the "validateForm" function of the associated script when the
        form and only continue with the commit commit when that function
        of script returns TRUE.

        If FLTableMetaData :: concurWarn () is true and two or more sessions / users are.
        Modifying the same fields will display a warning notice.

        @return TRUE if the form has been validated correctly.
        """
        if not self.cursor_:
            return True
        mtd = self.cursor_.metadata()
        if not mtd:
            return True

        if self.cursor_.modeAccess(
        ) == pnsqlcursor.PNSqlCursor.Edit and mtd.concurWarn():
            colFields = self.cursor_.concurrencyFields()

            if colFields:
                pKN = mtd.primaryKey()
                pKWhere = (self.cursor_.db().connManager().manager().
                           formatAssignValue(mtd.field(pKN),
                                             self.cursor_.valueBuffer(pKN)))
                q = pnsqlquery.PNSqlQuery(None,
                                          self.cursor_.db().connectionName())
                q.setTablesList(mtd.name())
                q.setSelect(colFields)
                q.setFrom(mtd.name())
                q.setWhere(pKWhere)
                q.setForwardOnly(True)

                if q.exec_() and q.next():
                    i = 0
                    for field in colFields:
                        # msg = "El campo '%s' con valor '%s' ha sido modificado\npor otro usuario con el valor '%s'" % (
                        #    mtd.fieldNameToAlias(field), self.cursor_.valueBuffer(field), q.value(i))
                        res = QtWidgets.QMessageBox.warning(
                            QtWidgets.QApplication.focusWidget(),
                            "Aviso de concurrencia",
                            "\n\n ¿ Desea realmente modificar este campo ?\n\n"
                            "Sí : Ignora el cambio del otro usuario y utiliza el valor que acaba de introducir\n"
                            "No : Respeta el cambio del otro usuario e ignora el valor que ha introducido\n"
                            "Cancelar : Cancela el guardado del registro y vuelve a la edición del registro\n\n",
                            cast(
                                QtWidgets.QMessageBox.StandardButtons,
                                QtWidgets.QMessageBox.Yes
                                | QtWidgets.QMessageBox.Default,
                            ),
                            cast(
                                QtWidgets.QMessageBox.StandardButton,
                                QtWidgets.QMessageBox.No
                                | QtWidgets.QMessageBox.Cancel
                                | QtWidgets.QMessageBox.Escape,
                            ),
                        )
                        if res == QtWidgets.QMessageBox.Cancel:
                            return False

                        if res == QtWidgets.QMessageBox.No:
                            self.cursor_.setValueBuffer(field, q.value(i))

        if (self.iface
                and self.cursor_.modeAccess() == pnsqlcursor.PNSqlCursor.Insert
                or self.cursor_.modeAccess() == pnsqlcursor.PNSqlCursor.Edit):
            ret_ = True
            fun_ = getattr(self.iface, "validateForm", None)
            if fun_ is not None and fun_ != self.validateForm:
                try:
                    ret_ = fun_()
                except Exception:
                    # script_name = self.iface.__module__
                    from pineboolib.core.error_manager import error_manager
                    from pineboolib import application

                    flapplication.aqApp.msgBoxWarning(
                        error_manager(
                            traceback.format_exc(limit=-6, chain=False)),
                        application.PROJECT.DGI,
                    )

            return ret_ if isinstance(ret_, bool) else True
        return True

    def acceptedForm(self) -> None:
        """
        Accept of form.

        Call the "acceptedForm" function of the script associated with the form, when
        the form is accepted and just before committing the registration.
        """

        if self.iface:
            try:
                self.iface.acceptedForm()
            except Exception:
                pass

    def afterCommitBuffer(self) -> None:
        """
        After setting the changes of the current record buffer.

        Call the "afterCommitBuffer" function of the script associated with the form
        right after committing the registry buffer.
        """
        if self.iface:
            try:
                self.iface.afterCommitBuffer()
            except Exception:
                pass

    def afterCommitTransaction(self) -> None:
        """
        After fixing the transaction.

        Call the "afterCommitTransaction" function of the script associated with the form,
        right after finishing the current transaction accepting.
        """
        if self.iface:
            try:
                self.iface.afterCommitTransaction()
            except Exception:
                pass

    def canceledForm(self) -> None:
        """
        Form Cancellation.

        Call the "canceledForm" function of the script associated with the form, when
        cancel the form.
        """
        if self.iface:
            try:
                self.iface.canceledForm()
            except Exception:
                pass

    @decorators.pyqtSlot()
    def accept(self) -> None:
        """
        Activate pressing the accept button.
        """

        if self.accepting:
            return

        self.accepting = True

        if not self.cursor_:
            self.close()
            self.accepting = False
            return

        if not self.validateForm():
            self.accepting = False
            return

        if self.cursor_.checkIntegrity():
            self.acceptedForm()
            self.cursor_.setActivatedCheckIntegrity(False)
            if not self.cursor_.commitBuffer():
                self.accepting = False
                return
            else:
                self.cursor_.setActivatedCheckIntegrity(True)
        else:
            self.accepting = False
            return

        self.afterCommitBuffer()
        self.accepted_ = True
        self.close()
        self.accepting = False

    @decorators.pyqtSlot()
    def acceptContinue(self) -> None:
        """
        Activate pressing the accept and continue button.
        """
        if self.accepting:
            return

        self.accepting = True
        if not self.cursor_:
            self.close()
            self.accepting = False
            return

        if not self.validateForm():
            self.accepting = False
            return

        if self.cursor_.checkIntegrity():
            self.acceptedForm()
            self.cursor_.setActivatedCheckIntegrity(False)
            if self.cursor_.commitBuffer():
                self.cursor_.setActivatedCheckIntegrity(True)
                self.cursor_.commit()
                self.cursor_.setModeAccess(pnsqlcursor.PNSqlCursor.Insert)
                self.accepted_ = False
                caption = None
                if self._action:
                    caption = self._action.name()
                if not caption:
                    caption = self.cursor_.metadata().alias()
                self.cursor_.transaction()
                self.setCaptionWidget(caption)
                if self.initFocusWidget_:
                    self.initFocusWidget_.setFocus()
                self.cursor_.refreshBuffer()
                self.initScript()

        self.accepting = False

    @decorators.pyqtSlot()
    def reject(self) -> None:
        """
        Activate pressing the cancel button.
        """
        self.accepted_ = False
        self.canceledForm()
        self.close()

    @decorators.pyqtSlot()
    @decorators.NotImplementedWarn
    def script(self) -> None:
        """
        Return the script associated with the form.
        """

        pass

    @decorators.pyqtSlot()
    def firstRecord(self) -> None:
        """
        Go to the first record.
        """
        if self.cursor_ and not self.cursor_.at() == 0:
            if not self.validateForm():
                return

            if self.cursor_.checkIntegrity():
                self.acceptedForm()
                self.cursor_.setActivatedCheckIntegrity(False)
                if self.cursor_.commitBuffer():
                    self.cursor_.setActivatedCheckIntegrity(True)
                    self.cursor_.commit()
                    self.cursor_.setModeAccess(self.initialModeAccess)
                    self.accepted_ = False
                    self.cursor_.transaction()
                    self.cursor_.first()
                    self.setCaptionWidget()
                    self.initScript()

    @decorators.pyqtSlot()
    def previousRecord(self) -> None:
        """
        Go to the previous record.
        """
        if self.cursor_ and self.cursor_.isValid():
            if self.cursor_.at() == 0:
                self.lastRecord()
                return

            if not self.validateForm():
                return

            if self.cursor_.checkIntegrity():
                self.acceptedForm()
                self.cursor_.setActivatedCheckIntegrity(False)
                if self.cursor_.commitBuffer():
                    self.cursor_.setActivatedCheckIntegrity(True)
                    self.cursor_.commit()
                    self.cursor_.setModeAccess(self.initialModeAccess)
                    self.accepted_ = False
                    self.cursor_.transaction()
                    self.cursor_.prev()
                    self.setCaptionWidget()
                    self.initScript()

    @decorators.pyqtSlot()
    def nextRecord(self) -> None:
        """
        Go to the next record.
        """
        if self.cursor_ and self.cursor_.isValid():
            if self.cursor_.at() == (self.cursor_.size() - 1):
                self.firstRecord()
                return

            if not self.validateForm():
                return

            if self.cursor_.checkIntegrity():
                self.acceptedForm()
                self.cursor_.setActivatedCheckIntegrity(False)
                if self.cursor_.commitBuffer():
                    self.cursor_.setActivatedCheckIntegrity(True)
                    self.cursor_.commit()
                    self.cursor_.setModeAccess(self.initialModeAccess)
                    self.accepted_ = False
                    self.cursor_.transaction()
                    self.cursor_.next()
                    self.setCaptionWidget()
                    self.initScript()

    @decorators.pyqtSlot()
    def lastRecord(self) -> None:
        """
        Go to the last record.
        """
        if self.cursor_ and not self.cursor_.at() == (self.cursor_.size() - 1):
            if not self.validateForm():
                return

            if self.cursor_.checkIntegrity():
                self.acceptedForm()
                self.cursor_.setActivatedCheckIntegrity(False)
                if self.cursor_.commitBuffer():
                    self.cursor_.setActivatedCheckIntegrity(True)
                    self.cursor_.commit()
                    self.cursor_.setModeAccess(self.initialModeAccess)
                    self.accepted_ = False
                    self.cursor_.transaction()
                    self.cursor_.last()
                    self.setCaptionWidget()
                    self.initScript()

    @decorators.pyqtSlot()
    def disablePushButtonCancel(self) -> None:
        """
        Turn off the cancel button.
        """

        if self.pushButtonCancel:
            self.pushButtonCancel.setDisabled(True)

    def show(self) -> None:
        """Show this widget."""

        caption = self._action.caption()
        if not caption:
            caption = self.cursor().metadata().alias()

        cur = self.cursor_

        iface = getattr(self.script, "iface", None)

        if cur:
            if not cur.isValid():
                cur.model().refresh()

            if cur.modeAccess() in (cur.Insert, cur.Edit, cur.Browse):
                cur.transaction()
                self.initTransLevel = cur.transactionLevel()

            if cur.modeAccess() == pnsqlcursor.PNSqlCursor.Insert:
                self.showAcceptContinue_ = True
            else:
                self.showAcceptContinue_ = False

            self.loadControls()

            if iface is not None:
                cur.setContext(iface)

        self.setCaptionWidget(caption)
        super().show()

    def inicializeControls(self) -> None:
        """Initialize UI controls for this form."""
        from pineboolib.fllegacy.flfielddb import FLFieldDB

        for child_ in self.findChildren(QtWidgets.QWidget):
            if isinstance(child_, FLFieldDB):
                loaded = getattr(child_, "_loaded", None)
                if loaded is False:
                    QtCore.QTimer.singleShot(0, child_.load)

    def show_and_wait(self) -> None:
        """Show this form blocking for exit."""
        if self.loop:
            raise Exception(
                "show_and_wait(): Se ha detectado una llamada recursiva")

        self.loop = True
        self.show()
        if self.eventloop:
            self.eventloop.exec_()

        self.loop = False

    def hide(self) -> None:
        """Hide this form."""
        if self.loop:
            self.eventloop.exit()
Exemplo n.º 22
0
from pineboolib.application.utils.path import _path
from pineboolib.core.utils.utils_base import filedir
from pineboolib.core.settings import config
from importlib import machinery

from sqlalchemy import String  # type: ignore

import importlib
import traceback
import sys
import os
from pineboolib import logging, application

from typing import Any

LOGGER = logging.getLogger("PNORMModelsFactory")

# processed_: List[str] = []


def base_model(name: str) -> Any:
    """Import and return sqlAlchemy model for given table name."""
    # print("Base", name)

    if application.PROJECT.conn_manager is None:
        raise Exception("Project is not connected yet")

    path = _path("%s.mtd" % name, False)
    if path is None:
        return None
    if path.find("system_module/tables") > -1:
Exemplo n.º 23
0
"""Test Eneboo module."""

import unittest
from PyQt5 import QtWidgets

from pineboolib.loader.main import init_testing, finish_testing

from pineboolib.core.settings import config
from pineboolib import application
from . import fixture_path
from pineboolib import logging

logger = logging.getLogger("eneboo_%s" % __name__)


class TestEnebooGUI(unittest.TestCase):
    """Tes EnebooGUI class."""

    prev_main_window_name: str

    @classmethod
    def setUpClass(cls) -> None:
        """Ensure pineboo is initialized for testing."""

        config.set_value("application/isDebuggerMode", True)
        config.set_value("application/dbadmin_enabled", True)
        cls.prev_main_window_name = config.value(
            "ebcomportamiento/main_form_name", "eneboo")
        config.set_value("ebcomportamiento/main_form_name", "eneboo")

        init_testing()
Exemplo n.º 24
0
"""conn_dialog module."""

from pineboolib import logging

from PyQt5 import QtWidgets
from pineboolib.loader.projectconfig import ProjectConfig
from typing import Optional

LOGGER = logging.getLogger("loader.conn_dialog")


def show_connection_dialog(
        app: QtWidgets.QApplication) -> Optional[ProjectConfig]:
    """Show the connection dialog, and configure the project accordingly."""
    from .dlgconnect import DlgConnect

    connection_window = DlgConnect()
    connection_window.load()
    connection_window.show()
    app.exec_()  # FIXME: App should be started before this function
    connection_window.close()
    return connection_window.selected_project_config
Exemplo n.º 25
0
from pineboolib.application.utils import check_dependencies
from pineboolib import application, logging

from pineboolib.core import settings

from . import flmysql_myisam

import traceback

from typing import Any, Dict, cast, List, TYPE_CHECKING

if TYPE_CHECKING:
    from pineboolib.application.metadata import pntablemetadata  # noqa: F401

LOGGER = logging.getLogger(__name__)


class FLMYSQL_MYISAM2(flmysql_myisam.FLMYSQL_MYISAM):
    """MYISAM2 Driver class."""

    cursorsArray_: Dict[str, Any]  # IApiCursor
    rowsFetched: Dict[str, List]

    def __init__(self):
        """Create empty driver."""
        super().__init__()
        self.name_ = "FLMYSQL_MyISAM2"
        self.alias_ = "MySQL MyISAM (PyMySQL)"
        self.cursorsArray_ = {}
        self.mobile_ = True
Exemplo n.º 26
0
"""
Finalize pineboo setup and load.
"""
from pineboolib import logging
from typing import Any

LOGGER = logging.getLogger("loader.init_project")


def init_project(dgi: Any, options: Any, project: Any, main_form: Any, app: Any) -> Any:
    """Initialize the project and start it."""
    # from PyQt5 import QtCore  # type: ignore

    # if dgi.useDesktop() and dgi.localDesktop() and splash:
    #     splash.showMessage("Iniciando proyecto ...", QtCore.Qt.AlignLeft, QtCore.Qt.white)
    #     dgi.processEvents()

    LOGGER.info("Iniciando proyecto ...")

    if options.preload:
        from .preload import preload_actions

        preload_actions(project, options.forceload)

        LOGGER.info("Finished preloading")
        return

    if options.action:
        list = options.action.split(":")
        action_name = list[0].split(".")[0]
        # FIXME: Why is commented out?