Example #1
0
 def _newMdiSubWindow(self, filterOrService, windowTitle):
     res = NexxTMdiSubWindow(None)
     res.setAttribute(Qt.WA_DeleteOnClose, False)
     self.mdi.addSubWindow(res)
     self._registerWindow(res, res.windowTitleChanged)
     if isinstance(filterOrService, Filter):
         propColl = filterOrService.guiState()
         res.setWindowTitle(
             propColl.objectName() if windowTitle is None else windowTitle)
     else:
         app = Application.activeApplication.getApplication()
         propColl = app.guiState("services/MainWindow")
         res.setWindowTitle(
             "<unnamed>" if windowTitle is None else windowTitle)
     prefix = re.sub(r'[^A-Za-z_0-9]', '_',
                     "MainWindow_MDI_" + res.windowTitle())
     i = dict(window=res, propColl=propColl, prefix=prefix)
     self.managedMdiWindows.append(i)
     window = i["window"]
     propColl = i["propColl"]
     prefix = i["prefix"]
     propColl.defineProperty(prefix + "_geom", "", "Geometry of MDI window")
     b = QByteArray.fromBase64(
         bytes(propColl.getProperty(prefix + "_geom"), "ascii"))
     window.restoreGeometry(b)
     logger.debug("restored geometry %s:%s (%s)", prefix, window.geometry(),
                  b)
     propColl.defineProperty(prefix + "_visible", 1,
                             "Visibility of MDI window")
     if propColl.getProperty(prefix + "_visible"):
         window.show()
     else:
         window.hide()
     self.mdiSubWindowCreated.emit(res)
     return res
Example #2
0
    def get_pixmap(self):
        base64data = b'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'
        byte_array = QByteArray.fromBase64(base64data)
        pixmap = QPixmap()
        pixmap.loadFromData(byte_array)

        return pixmap
Example #3
0
    def load_1_0_0(self, data=dict):
        '''
        Load v1.0.0 of .pii version file.

        Parameters
        ----------
        data: (dict)
            Dictionary of date from .pii file.
        '''
        if data[PII.BACKGROUND]:
            # Import Image Data
            newPix = QPixmap()
            newPix.loadFromData(
                QByteArray.fromBase64(data[PII.BACKGROUND].encode('ascii')),
                "PNG")
            self._backgroundNode.setPixmap(newPix)

        for each in data[PII.NODES]:
            if each["type"] == PIINode.PICK:
                self.create_node(text=each[PIIPick.TEXT],
                                 size=each[PIIPick.SIZE],
                                 textColor=QColor(*each[PIIPick.COLOR]),
                                 bgColor=QColor(*each[PIIPick.BACKGROUND]),
                                 position=QPointF(*each[PIIPick.POSITION]),
                                 items=each[PIIPick.SELECTION],
                                 shape=each[PIIPick.SHAPE])
            elif each["type"] == PIINode.BUTTON:
                self.create_button(position=QPointF(*each[PIIButton.POSITION]),
                                   text=each[PIIButton.TEXT],
                                   size=each[PIIButton.SIZE],
                                   textColor=QColor(*each[PIIButton.COLOR]),
                                   bgColor=QColor(*each[PIIButton.BACKGROUND]),
                                   cmd=each[PIIButton.COMMAND],
                                   cmdType=each[PIIButton.COMMANDTYPE])
Example #4
0
 def _restore_state_from_settings(self, ) -> None:
     if not self._settings.contains('main_state'):
         return
     state = QByteArray.fromBase64(
         cast(QByteArray, self._settings.value('main_state')))
     if state:
         self.restoreState(state, __UI_VERSION__)
Example #5
0
 def _restore_geometry_from_settings(self, ) -> None:
     if not self._settings.contains('main_geometry'):
         return
     geometry = QByteArray.fromBase64(
         cast(QByteArray, self._settings.value('main_geometry')))
     if geometry:
         self.restoreGeometry(geometry)
Example #6
0
    def runReport(self, pid, method, par):
        self.boolDirect = True
        self.mtypeCall = "report"
        self.mpid = pid
        self.mmethod = method
        self.mparams = par
        #
        bparams = self.prepareParams()
        request = self.prepareRequest()
        #
        reply = self.data_request(request, bparams)
        data = reply.readAll()
        parseError = QJsonParseError()
        resultObject = {}
        resultObject["data"] = "error"
        document = QJsonDocument.fromJson(data, parseError)
        if parseError.error == True:
            resultObject["data"] = "error"
        else:
            if document.isObject():
                jv = document.object()
                if jv.__contains__(
                        "result") == True and jv["result"].__class__() == []:
                    #tryton 4.0
                    #'result': ['pdf', {'base64':wwwwww, '__class__':'bytes'}, False,'Printis']
                    jre = jv["result"]
                    namesecs = "tryton_" + self.mpid + str(
                        QDateTime.currentMSecsSinceEpoch()) + "." + jre[0]

                    mdir = QDir(self.mDir + QDir.separator() + "tempReports")
                    if mdir.exists() == False:
                        s = QDir(self.mDir)
                        s.mkdir("tempReports")

                    filename = self.mDir + QDir.separator(
                    ) + "tempReports" + QDir.separator() + namesecs
                    file = QFile(filename)
                    if file.open(QIODevice.WriteOnly) == False:
                        #error
                        self.signalResponse.emit(self.mpid, 7, {})
                        print("error", filename, file.errorString())
                    else:
                        bafile = QByteArray.fromBase64(
                            jre[1]["base64"].encode())
                        file.write(bafile)
                        file.close()
                        QDesktopServices.openUrl(QUrl(filename))
            else:
                if document.isArray() == True:
                    self.signalResponse.emit(self.mpid, 7, {})
        self.processingData(data, reply)
Example #7
0
def decode_image(text: str) -> QImage:
    encoded_bytes = QByteArray(text.encode('utf8'))
    image_bytes = QByteArray.fromBase64(encoded_bytes)
    image = QImage.fromData(image_bytes)
    return image
Example #8
0
    def rechargeNet(self, preferences, username):
        #version 1.1 up thesamodule
        data = self.m_qjsonnetwork.callDirect(
            "version internal", "model.thesamodule.config.search_read",
            [[], 0, 1, [], ["internal_version"], preferences])
        if not data["data"] == "error":
            self.internal_version = data["data"]["result"][0][
                "internal_version"]
            if float(self.internal_version) > 1.0:
                data = self.m_qjsonnetwork.callDirect(
                    "cachedel", "model.thesamodule.config.search_read",
                    [[], 0, 1, [], ["deletecache"], preferences])
                if not data["data"] == "error":
                    if data["data"]["result"][0]["deletecache"] == True:
                        self.actionCache_ = "deleteOnCompleted"
                    else:
                        self.actionCache_ = "notDelete"
        sysdir = QDir(self.mDir + QDir.separator() + _dirSystem)
        DIR_QML_SYS = sysdir.path()
        DIR_QML_SYS_LOST = DIR_QML_SYS + QDir.separator() + "lost"
        sysdirlost = QDir(DIR_QML_SYS_LOST)
        #revisar folder systemnet
        if sysdir.exists() == False:
            s = QDir(self.mDir)
            s.mkdir(_dirSystem)
        #revisar folder systemnet lost
        if sysdirlost.exists() == False:
            sl = QDir(DIR_QML_SYS)
            sl.mkdir("lost")
        #find all files en folder net
        listSysFiles = os.listdir(DIR_QML_SYS)
        if "lost" in listSysFiles:
            listSysFiles.remove("lost")
        #
        data = {}
        data["data"] = "error"
        if float(self.internal_version) > 1.1:
            data = self.m_qjsonnetwork.callDirect(
                "findforuser", "model.thesamodule.usersfolder.search_read", [[
                    "AND", ["users.user.name", "=", username],
                    ["activefolder", "=", True]
                ], 0, 1, [], ["qmlfiles"], preferences])
            if not data["data"] == "error":
                result = data["data"]["result"]
                if len(result) > 0:
                    idfiles = result[0]["qmlfiles"]
                    data = self.m_qjsonnetwork.callDirect(
                        "rechargeNetStep1",
                        "model.thesamodule.thesamodule.read",
                        [idfiles, [
                            "checksum",
                            "filename",
                        ], preferences])
                    if len(idfiles) == 0:
                        self.m_qjsonnetwork.signalResponse.emit(
                            "systemnet", 15, {"noqmlfiles": ""})
                else:  #buscar default
                    data = self.m_qjsonnetwork.callDirect(
                        "findforuser",
                        "model.thesamodule.usersfolder.search_read", [[
                            "AND", ["type", "=", "default"],
                            ["activefolder", "=", True]
                        ], 0, 1, [], ["qmlfiles"], preferences])
                    if not data["data"] == "error":
                        result = data["data"]["result"]
                        if len(result) > 0:
                            idfiles = result[0]["qmlfiles"]
                            data = self.m_qjsonnetwork.callDirect(
                                "rechargeNetStep1",
                                "model.thesamodule.thesamodule.read", [
                                    idfiles, [
                                        "checksum",
                                        "filename",
                                    ], preferences
                                ])
                            if len(idfiles) == 0:
                                self.m_qjsonnetwork.signalResponse.emit(
                                    "systemnet", 15, {"noqmlfiles": ""})
                        else:
                            self.m_qjsonnetwork.signalResponse.emit(
                                "systemnet", 12, {"noqmlfiles": ""})
                    else:
                        self.m_qjsonnetwork.signalResponse.emit(
                            "systemnet", 13, {"error": ""})
            else:
                self.m_qjsonnetwork.signalResponse.emit(
                    "systemnet", 13, {"error": ""})

        else:
            data = self.m_qjsonnetwork.callDirect(
                "rechargeNetStep1",
                "model.thesamodule.thesamodule.search_read",
                [[], 0, 1000, [], ["checksum", "filename"], preferences])
        if not data["data"] == "error":
            resultnet = data["data"]["result"]
            mapnet = {}
            mapids = {}
            listNetFiles = []
            for file in resultnet:
                mapnet[file["filename"]] = file["checksum"]
                mapids[file["filename"]] = file["id"]
                listNetFiles.append(file["filename"])
            #buscar faltantes en system y los updates
            #buscar los que ya no deben estar
            mapsysnet = {}
            listToUpdate = set()  #new or update
            listToErase = []
            for file in listSysFiles:
                try:
                    with open(DIR_QML_SYS + QDir.separator() + file,
                              "rb") as binary_file:
                        data = binary_file.read()
                        chek = hashlib.md5(data).hexdigest()
                        mapsysnet[file] = chek
                except:
                    listToUpdate.add(file)

            for file in listNetFiles:
                if file in listSysFiles:
                    if mapnet[file] != mapsysnet[file]:
                        listToUpdate.add(file)  # update
                else:
                    listToUpdate.add(file)  # new
            for file in listSysFiles:
                if not file in listNetFiles:
                    listToErase.append(file)  # erase

            listToUpdate = list(listToUpdate)
            ids = []
            for file in listToUpdate:
                ids.append(mapids[file])

            data = self.m_qjsonnetwork.callDirect(
                "rechargeNetStep2", "model.thesamodule.thesamodule.read",
                [ids, [
                    "filebinary",
                    "filename",
                ], preferences])
            errors = []
            if not data["data"] == "error":
                resultnet = data["data"]["result"]
                for file in resultnet:
                    filename = DIR_QML_SYS + QDir.separator(
                    ) + file["filename"]
                    qfile = QFile(filename)
                    if qfile.open(QIODevice.WriteOnly) == False:
                        errors.append(filename)
                        print("error", filename, qfile.errorString())
                    else:
                        print("update", file["filename"])
                        bafile = QByteArray.fromBase64(
                            file["filebinary"]["base64"].encode())
                        qfile.write(bafile)
                        qfile.close()
            if len(errors) > 0:
                self.m_qjsonnetwork.signalResponse.emit(
                    "systemnet", 33, {"error": errors})
                return False

            #erase
            for file in listToErase:
                print("moviendo", file)
                shutil.move(DIR_QML_SYS + QDir.separator() + file,
                            DIR_QML_SYS_LOST + QDir.separator() + file)
            return True
        else:
            #erase all files, no conexion con thesa module
            for file in listSysFiles:
                print("moviendo", file)
                shutil.move(DIR_QML_SYS + QDir.separator() + file,
                            DIR_QML_SYS_LOST + QDir.separator() + file)
            self.m_qjsonnetwork.signalResponse.emit("systemnet", 34,
                                                    {"error": ""})
            return False
    def __init__(self, parent=None, post_stats: bool = True):

        # instantiation
        super().__init__(parent, post_stats)

        self.ui.p1_layout = QVBoxLayout(self.ui.page_1)
        self.ui.p1_layout.setContentsMargins(0, 0, 0, 0)
        self.ui.p1_description = QLabel(
            'This app calculates the mean flame height in accordance with '
            '"PD 7974-1:2019 Application of fire safety engineering principles to the design of buildings. Part 1: '
            'Initiation and development of fire within the enclosure of origin (Sub-system 1)".'
        )
        self.ui.p1_description.setFixedWidth(350)
        self.ui.p1_description.setWordWrap(True)
        self.ui.p1_layout.addWidget(self.ui.p1_description)
        self.ui.p1_figure = QLabel()
        self.ui.p1_figure.setPixmap(join(fsetoolsGUI.__root_dir__, 'gui', 'images', f'{self.app_id}-1.png'))
        self.ui.p1_layout.addWidget(self.ui.p1_figure)

        self.ui.p2_layout = QGridLayout(self.ui.page_2)
        self.ui.p2_layout.setVerticalSpacing(5), self.ui.p2_layout.setHorizontalSpacing(5)
        self.ui.p2_layout.addWidget(QLabel('<b>Inputs</b>'), 0, 0, 1, 3)
        self.add_lineedit_set_to_grid(self.ui.p2_layout, 1, 'p2_in_Q_dot_or_Q_dot_l', 'Total HRR', 'kW')
        self.add_lineedit_set_to_grid(self.ui.p2_layout, 2, 'p2_in_L_A_or_D', 'Fire diameter', 'm')
        self.add_lineedit_set_to_grid(self.ui.p2_layout, 3, 'p2_in_L_B', 'Fire shorter dimension', 'm')
        self.add_lineedit_set_to_grid(self.ui.p2_layout, 4, 'p2_in_rho_0', 'Air density', 'kg/m<sup>3</sup>')
        self.add_lineedit_set_to_grid(self.ui.p2_layout, 5, 'p2_in_c_p_0', 'Air heat capacity', 'kJ/kg/K')
        self.add_lineedit_set_to_grid(self.ui.p2_layout, 6, 'p2_in_T_0', 'Air temperature', 'K')
        self.add_lineedit_set_to_grid(self.ui.p2_layout, 7, 'p2_in_g', 'Gravity', 'm/s<sup>2</sup>')
        self.ui.p2_in_fire_shape = QComboBox()
        self.ui.p2_in_fire_shape.addItems(['Circular fire', 'Rectangular fire', 'Line fire'])
        self.ui.p2_layout.addWidget(self.ui.p2_in_fire_shape, 8, 0, 1, 3)
        self.ui.p2_in_fuel_type = QComboBox()
        self.ui.p2_in_fuel_type.addItems(['Natural gas (Zukoski)', 'Wood cribs', 'Gas, liquids and solids (Heskestad)'])
        self.ui.p2_layout.addWidget(self.ui.p2_in_fuel_type, 9, 0, 1, 3)
        self.ui.p2_layout.addWidget(QLabel('<b>Outputs</b>'), 10, 0, 1, 3)
        self.add_lineedit_set_to_grid(self.ui.p2_layout, 11, 'p2_out_Q_dot_star', 'Dimensionless HRR', '')
        self.ui.p2_out_Q_dot_star.setReadOnly(True)
        self.add_lineedit_set_to_grid(self.ui.p2_layout, 12, 'p2_out_Z_f', 'Flame height', 'm')
        self.ui.p2_out_Z_f.setReadOnly(True)

        # ==============
        # instantiate ui
        # ==============
        self.ui.p2_in_Q_dot_or_Q_dot_l.setToolTip(
            'Total fire heat release rate (per unit length for line fire shape)')
        self.ui.p2_in_L_A_or_D.setToolTip('Fire longer dimension (diameter for circular fire shape)')
        self.ui.p2_in_L_B.setToolTip('Fire shorter dimension (only for rectangular fire shape)')
        self.ui.p2_out_Q_dot_star.setToolTip('Solved dimensionless heat release rate, double click to select')
        self.ui.p2_out_Z_f.setToolTip('Solved mean flame height, double click to select')

        # construct pixmaps that are used in this app
        self.dict_images_pixmap = dict(image_context=image_context,
                                       image_figure=image_figure, )
        for k, v in self.dict_images_pixmap.items():
            ba = QByteArray.fromBase64(v)
            self.dict_images_pixmap[k] = QtGui.QPixmap()
            self.dict_images_pixmap[k].loadFromData(ba)

        # set default values
        # todo
        self.change_fire_shape()

        # signal and slots
        self.ui.p2_in_fire_shape.currentIndexChanged.connect(self.change_fire_shape)
Example #10
0
class MainWindow(QMainWindow):  # pylint: disable=R0902
    """Main window of application"""

    log = False
    trayIconMessageSignal = Signal(str, str, object)

    def __init__(self, parent=None, palette=None):
        super(MainWindow, self).__init__(parent)

        self.defaultPalette = palette
        self.parent = parent

        # Language Setup
        self.setLanguageInWidgets = SetLanguage()
        self.uiSetLanguage = UiSetLanguage(self)
        configLanguage(self)

        # initialize the gazillion variables
        self._initVars()

        # Widow Title self.appDirectory on _initVars()
        self.setWindowTitle(config.APPNAME + ": " + config.DESCRIPTION)
        self.setWindowIcon(QIcon(QPixmap(":/images/Itsue256x256.png")))

        # Setup User Interface
        self._initMenu()
        self._initControls()
        self._initUI()
        self._initHelper()

        # Restore configuration elements
        self.configuration(action=config.Action.Restore)
        # self.setLanguage()

        # tray icon
        self.trayIcon = QSystemTrayIconWidget(self, self.windowIcon())
        self.trayIcon.show()

        # for taskbar icon to work show must be called in __init__
        self.show()

        # Must init after show call
        self.progressBar.initTaskbarButton()

        # tray Icon message
        self.trayIconMessageSignal.connect(self.trayIcon.showMessage)

    def _initVars(self):

        #
        # Where am I running from
        #

        # if getattr(sys, "frozen", False):
        if sys.pyside_uses_embedding:
            # Running in a pyinstaller bundle
            self.appDirectory = Path(os.path.dirname(__file__))
        else:
            self.appDirectory = Path(os.path.realpath(__file__))

        self.controlQueue = deque()
        self.jobsQueue = JobQueue(self, controlQueue=self.controlQueue)

        # Progress information setup
        self.progressBar = DualProgressBar(self, align=Qt.Horizontal)
        self.jobsLabel = QFormatLabel(
            Text.txt0085,
            init=[0, 0, 0, 0, 0],
        )
        self.progress = Progress(self, self.progressBar, self.jobsLabel)
        self.jobsQueue.progress = self.progress
        self.progressSpin = QProgressIndicator(self)

        # Model view
        headers = tableHeaders()
        self.tableData = TableData(headerList=headers, dataList=[])
        self.model = JobsTableModel(self.tableData, self.jobsQueue)
        self.proxyModel = TableProxyModel(self.model)
        self.jobsQueue.proxyModel = self.proxyModel

        # Preferences menu
        self.setPreferences = PreferencesDialogWidget(self)
        self.fileMenu = None
        self.helpMenu = None
        self.menuItems = None

    def _initMenu(self):  # pylint: disable=too-many-statements

        menuBar = QMenuBar()
        self.menuItems = []

        # File SubMenu
        self.fileMenu = QMenuWidget(Text.txt0020)
        exitIcon = self.style().standardIcon(QStyle.SP_DialogCloseButton)

        # Preferences
        actPreferences = QActionWidget(
            Text.txt0050,
            self,
            shortcut=Text.txt0026,
            statusTip=Text.txt0051,
        )
        actPreferences.triggered.connect(self.setPreferences.getPreferences)

        # Exit application
        actExit = QActionWidget(
            exitIcon,
            Text.txt0021,
            self,
            shortcut=Text.txt0022,
            statusTip=Text.txt0023,
        )
        actExit.triggered.connect(self.close)

        # Abort
        actAbort = QActionWidget(Text.txt0024, self, statusTip=Text.txt0025)
        actAbort.triggered.connect(abort)

        # Add actions to SubMenu
        self.fileMenu.addAction(actPreferences)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(actExit)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(actAbort)
        menuBar.addMenu(self.fileMenu)
        self.menuItems.append(self.fileMenu)
        self.menuItems.append(actPreferences)
        self.menuItems.append(actExit)
        self.menuItems.append(actAbort)

        # Help Menu
        actHelpContents = QActionWidget(Text.txt0061, self, textSuffix="...")
        actHelpContents.triggered.connect(lambda: _help(self.appDirectory, 0))
        actHelpUsing = QActionWidget(Text.txt0062, self)
        actHelpUsing.triggered.connect(lambda: _help(self.appDirectory, 1))
        actAbout = QActionWidget(Text.txt0063, self)
        actAbout.triggered.connect(self.about)
        actAboutQt = QActionWidget(Text.txt0064, self)
        actAboutQt.triggered.connect(self.aboutQt)
        self.helpMenu = QMenuWidget(Text.txt0060)
        self.helpMenu.addAction(actHelpContents)
        self.helpMenu.addAction(actHelpUsing)
        self.helpMenu.addSeparator()
        self.helpMenu.addAction(actAbout)
        self.helpMenu.addAction(actAboutQt)
        menuBar.addMenu(self.helpMenu)
        self.menuItems.append(self.helpMenu)
        self.menuItems.append(actHelpContents)
        self.menuItems.append(actHelpUsing)
        self.menuItems.append(actAbout)
        self.menuItems.append(actAboutQt)

        # Init status var
        statusBar = QStatusBar()
        statusBar.addPermanentWidget(VerticalLine())
        statusBar.addPermanentWidget(self.jobsLabel)
        statusBar.addPermanentWidget(VerticalLine())
        statusBar.addPermanentWidget(self.progressBar)
        statusBar.addPermanentWidget(self.progressSpin)

        self.setMenuBar(menuBar)
        self.setStatusBar(statusBar)

    def _initControls(self):
        """
        Here the variables for widgets are declared and the setup
        for them is done
        """

        # Widgets for tabs
        self.tableViewWidget = JobsTableViewWidget(self, self.proxyModel,
                                                   self.controlQueue,
                                                   _(Text.txt0130))
        self.tableViewWidget.tableView.sortByColumn(0, Qt.AscendingOrder)
        self.renameWidget = RenameWidget(self)
        self.commandWidget = CommandWidget(self, self.proxyModel)
        self.jobsOutputWidget = JobsOutputWidget(self)
        self.errorOutputWidget = JobsOutputErrorsWidget(self)

        # historyWidget and logViewerWidget cannot have parent declared
        # They don't always display and create artifacts when not shown
        self.historyWidget = JobsHistoryViewWidget(self,
                                                   groupTitle=_(Text.txt0130))
        self.historyWidget.tableView.sortByColumn(0, Qt.DescendingOrder)
        self.logViewerWidget = LogViewerWidget()

        # Setup tabs for TabWidget
        self.tabs = TabWidget(self)

        tabsList = []
        tabsList.append([
            self.commandWidget,
            _(Text.txt0133),
            _(Text.txt0148),
        ])
        tabsList.append([
            self.tableViewWidget,
            _(Text.txt0140),
            _(Text.txt0144),
        ])
        tabsList.append([
            self.jobsOutputWidget,
            _(Text.txt0141),
            _(Text.txt0145),
        ])
        tabsList.append([
            self.errorOutputWidget,
            _(Text.txt0142),
            _(Text.txt0146),
        ])
        tabsList.append([
            self.renameWidget,
            _(Text.txt0143),
            _(Text.txt0147),
        ])
        if config.data.get(config.ConfigKey.LogViewer):
            tabsList.append([
                self.logViewerWidget,
                _(Text.txt0149),
                _(Text.txt0151),
            ])
        else:
            self.logViewerWidget.tab = -1
            self.logViewerWidget.tabWidget = self.tabs
            self.logViewerWidget.title = _(Text.txt0149)
        if config.data.get(config.ConfigKey.JobHistory):
            tabsList.append(
                [self.historyWidget,
                 _(Text.txt0241),
                 _(Text.txt0168)])
        else:
            self.historyWidget.tab = -1
            self.historyWidget.tabWidget = self.tabs
            self.historyWidget.title = _(Text.txt0241)

        self.tabs.addTabs(tabsList)

    def _initHelper(self):
        """
        _initHelper setup signals, do any late binds and misc configuration
        """

        # work in progress spin
        self.progressSpin.displayedWhenStopped = True
        self.progressSpin.color = checkColor(
            QColor(42, 130, 218), config.data.get(config.ConfigKey.DarkMode))
        self.progressSpin.delay = 60

        # Set output to contain output windows objects
        self.output = OutputWindows(
            self.commandWidget.outputWindow,
            self.jobsOutputWidget,
            self.errorOutputWidget,
        )
        self.commandWidget.output = self.output
        self.tableViewWidget.output = self.output
        self.jobsQueue.output = self.output
        self.commandWidget.outputWindow.setReadOnly(True)
        self.jobsOutputWidget.setReadOnly(True)
        self.errorOutputWidget.setReadOnly(True)
        self.historyWidget.output.setReadOnly(True)
        self.jobsOutputWidget.textChanged.connect(
            self.commandWidget.resetButtonState)

        # Give commandWidget access to renameWidget
        self.commandWidget.rename = self.renameWidget

        # setup widgets setLanguage to SetLanguage change signal
        self.setLanguageInWidgets.addSlot(self.tableViewWidget.setLanguage)
        self.setLanguageInWidgets.addSlot(self.commandWidget.setLanguage)
        self.setLanguageInWidgets.addSlot(self.tabs.setLanguage)
        self.setLanguageInWidgets.addSlot(self.renameWidget.setLanguage)
        self.setLanguageInWidgets.addSlot(self.historyWidget.setLanguage)
        self.setLanguageInWidgets.addSlot(self.setPreferences.retranslateUi)

        # connect to tabs widget tab change Signal
        self.tabs.currentChanged.connect(tabChange)

        # connect to runJobs Start/Stop SigNal
        self.jobsQueue.runJobs.startSignal.connect(
            self.progressSpin.startAnimation)
        self.jobsQueue.runJobs.finishedSignal.connect(
            self.progressSpin.stopAnimation)

        # connect log viewer
        config.logViewer.connect(self.logViewerWidget.logMessage)

        # connect JobHistory and commandWidget
        self.historyWidget.pasteCommandSignal.connect(
            self.commandWidget.updateCommand)
        self.historyWidget.updateAlgorithmSignal.connect(
            self.commandWidget.updateAlgorithm)

    def _initUI(self):

        # Create Widgets
        widget = QWidget()
        layout = QVBoxLayout(widget)
        layout.addWidget(self.tabs)
        widget.setLayout(layout)
        self.setCentralWidget(widget)

    #
    # Events override
    #
    def closeEvent(self, event):
        """
        Override QMainWindow.closeEvent

        Save configuration state before exit
        """

        language = config.data.get(config.ConfigKey.Language)
        bAnswer = False
        title = _(Text.txt0080)
        leadQuestionMark = "¿" if language == "es" else ""

        if threading.activeCount() > 1:
            msg = _(Text.txt0089) + ". " + leadQuestionMark + _(
                Text.txt0090) + "?"
        else:
            msg = leadQuestionMark + _(Text.txt0081) + "?"

        bAnswer = yesNoDialog(self, msg, title)

        if bAnswer:
            self.configuration(action=config.Action.Save)
            event.accept()
        else:
            event.ignore()

    def moveEvent(self, event):

        # Update geometry includes position
        base64Geometry = self.saveGeometry().toBase64()
        b = base64Geometry.data()  # b is a bytes string
        config.data.set(config.ConfigKey.Geometry, b)
        event.ignore()

    def resizeEvent(self, event):

        # Update geometry includes position
        base64Geometry = self.saveGeometry().toBase64()
        b = base64Geometry.data()  # b is a bytes string
        config.data.set(config.ConfigKey.Geometry, b)
        event.ignore()

    def setVisible(self, visible):
        """ Override setVisible """

        self.trayIcon.setMenuEnabled(visible)
        super().setVisible(visible)

    # @Slot(str)
    # def iconActivated(self, reason):
    #    """Systray Icon"""

    #    print("main is icon activated")
    #    if reason == QSystemTrayIcon.Trigger:
    #        pass
    #    if reason == QSystemTrayIcon.DoubleClick:
    #        pass
    #    if reason == QSystemTrayIcon.MiddleClick:
    #        pass
    #
    # Events override End
    #

    def configuration(self, action=None):
        """
        Read and write configuration
        """

        defaultFont = QFont()
        defaultFont.fromString(config.data.get(config.ConfigKey.SystemFont))
        defaultFont.setPointSize(14)
        bLogging = False

        if action == config.Action.Reset:
            # Font
            self.setFont(defaultFont)
            self.setAppFont(defaultFont)
            # Logging
            self.enableLogging(bLogging)
            # Geometry
            self.setGeometry(0, 0, 1280, 720)
            centerWidget(self)

        elif action == config.Action.Restore:
            # Font
            if strFont := config.data.get(config.ConfigKey.Font):
                restoreFont = QFont()
                restoreFont.fromString(strFont)
                self.setFont(restoreFont)
                self.setAppFont(restoreFont)
            else:
                self.setFont(defaultFont)
                self.setAppFont(defaultFont)

            # Logging
            if bLogging := config.data.get(config.ConfigKey.Logging):
                self.enableLogging(bLogging)

            # Geometry
            if byteGeometry := config.data.get(config.ConfigKey.Geometry):
                self.restoreGeometry(
                    QByteArray.fromBase64(QByteArray(byteGeometry)))
Example #11
0
 def icon(base64=None, icon=None):
     if not icon:
         icon = QPixmap()
         base64 = bytes(base64, encoding='utf-8')
         icon.loadFromData(QByteArray.fromBase64(base64))
     return QIcon(icon)