예제 #1
0
    def __init__(self, main_win, lib):
        AbstractWidget.__init__(self, main_win=main_win, lib=lib)

        settings = QtCore.QSettings()
        settings.setValue("input_buttons/seacat_plugin",
                          settings.value("input_buttons/seacat_plugin", 0))
        settings.setValue("editor_buttons/reference",
                          settings.value("editor_buttons/reference", 1))
        settings.setValue("editor_buttons/spreadsheet",
                          settings.value("editor_buttons/spreadsheet", 0))
        settings.setValue("editor_buttons/metadata",
                          settings.value("editor_buttons/metadata", 1))
        settings.setValue("editor_buttons/filter",
                          settings.value("editor_buttons/filter", 1))
        settings.setValue("editor_buttons/thinning",
                          settings.value("editor_buttons/thinning", 0))
        settings.setValue("editor_buttons/restart",
                          settings.value("editor_buttons/restart", 1))
        settings.setValue("editor_buttons/export",
                          settings.value("editor_buttons/export", 1))
        settings.setValue("editor_buttons/transmit",
                          settings.value("editor_buttons/transmit", 1))
        settings.setValue("editor_buttons/database",
                          settings.value("editor_buttons/database", 0))

        self.input_bar = self.addToolBar('Input')
        self.input_bar.setIconSize(QtCore.QSize(40, 40))

        # import
        self.input_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'input.png')),
            'Import Input Data', self)
        self.input_act.setShortcut('Alt+I')
        # noinspection PyUnresolvedReferences
        self.input_act.triggered.connect(self.on_input_data)
        self.input_bar.addAction(self.input_act)
        self.main_win.file_menu.addAction(self.input_act)

        # import
        self.create_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'constant_gradient.png')),
            'Constant-gradient Profile', self)
        # self.create_act.setShortcut('Alt+G')
        # noinspection PyUnresolvedReferences
        self.create_act.triggered.connect(self.on_create_data)
        # self.input_bar.addAction(self.create_act)
        self.main_win.file_menu.addAction(self.create_act)

        # clear
        self.clear_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'clear.png')), 'Clear Data',
            self)
        self.clear_act.setShortcut('Alt+C')
        # noinspection PyUnresolvedReferences
        self.clear_act.triggered.connect(self.on_clear_data)
        # set hidden, but the whole action is candidate to deletion
        self.clear_act.setVisible(False)
        self.input_bar.addAction(self.clear_act)

        # set ref
        self.set_ref_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'ref.png')), 'Reference Cast',
            self)
        self.set_ref_act.setShortcut('Alt+R')
        # noinspection PyUnresolvedReferences
        self.set_ref_act.triggered.connect(self.on_set_ref)
        if settings.value("editor_buttons/reference", 1) == 1:
            self.input_bar.addAction(self.set_ref_act)
        self.main_win.file_menu.addAction(self.set_ref_act)

        # seacat
        self.seacat_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'seacat.png')),
            'Seabird CTD Setup', self)
        self.seacat_act.setShortcut('Alt+B')
        # noinspection PyUnresolvedReferences
        self.seacat_act.triggered.connect(self.on_seacat)
        if settings.value("input_buttons/seacat_plugin", 1) == 1:
            self.input_bar.addAction(self.seacat_act)
        self.main_win.file_menu.addAction(self.seacat_act)

        self.process_bar = self.addToolBar('Process')
        self.process_bar.setIconSize(QtCore.QSize(40, 40))

        # spreadsheet
        self.spreadsheet_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'grid.png')),
            'Show/Edit Data Spreadsheet', self)
        self.spreadsheet_act.setShortcut('Alt+S')
        # noinspection PyUnresolvedReferences
        self.spreadsheet_act.triggered.connect(self.on_spreadsheet)
        if settings.value("editor_buttons/spreadsheet", 0) == 1:
            self.process_bar.addAction(self.spreadsheet_act)
        self.main_win.edit_menu.addAction(self.spreadsheet_act)

        # metadata
        self.metadata_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'metadata.png')),
            'Show/Edit Cast Metadata', self)
        self.metadata_act.setShortcut('Alt+M')
        # noinspection PyUnresolvedReferences
        self.metadata_act.triggered.connect(self.on_metadata)
        if settings.value("editor_buttons/metadata", 1) == 1:
            self.process_bar.addAction(self.metadata_act)
        self.main_win.edit_menu.addAction(self.metadata_act)

        # - separator
        self.process_bar.addSeparator()
        self.main_win.edit_menu.addSeparator()

        # filter
        self.filter_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'filter.png')),
            'Filter/Smooth Data', self)
        self.filter_act.setShortcut('Alt+F')
        # noinspection PyUnresolvedReferences
        self.filter_act.triggered.connect(self.on_data_filter)
        if settings.value("editor_buttons/filter", 1) == 1:
            self.process_bar.addAction(self.filter_act)
        self.main_win.edit_menu.addAction(self.filter_act)

        # retrieve sal
        self.sal_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'sal.png')),
            'Retrieve Salinity', self)
        # self.sal_act.setShortcut('Alt+A')
        # noinspection PyUnresolvedReferences
        self.sal_act.triggered.connect(self.on_retrieve_sal)
        self.process_bar.addAction(self.sal_act)

        # retrieve temp/sal
        self.temp_sal_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'temp_sal.png')),
            'Retrieve Temperature/Salinity', self)
        # self.temp_sal_act.setShortcut('Alt+T')
        # noinspection PyUnresolvedReferences
        self.temp_sal_act.triggered.connect(self.on_retrieve_temp_sal)
        self.process_bar.addAction(self.temp_sal_act)
        self.main_win.edit_menu.addAction(self.temp_sal_act)

        # retrieve transducer sound speed
        self.tss_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'tss.png')),
            'Retrieve Transducer Sound Speed', self)
        # self.tss_act.setShortcut('Alt+W')
        # noinspection PyUnresolvedReferences
        self.tss_act.triggered.connect(self.on_retrieve_tss)
        self.process_bar.addAction(self.tss_act)
        self.main_win.edit_menu.addAction(self.tss_act)

        # extend profile
        self.extend_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'extend.png')),
            'Extend Profile', self)
        # self.extend_act.setShortcut('Alt+E')
        # noinspection PyUnresolvedReferences
        self.extend_act.triggered.connect(self.on_extend_profile)
        self.process_bar.addAction(self.extend_act)
        self.main_win.edit_menu.addAction(self.extend_act)

        # preview thinning
        self.thin_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'thinning.png')),
            'Preview Thinning', self)
        # self.thin_act.setShortcut('Alt+T')
        # noinspection PyUnresolvedReferences
        self.thin_act.triggered.connect(self.on_preview_thinning)
        # self.thin_act.setVisible(False)
        if settings.value("editor_buttons/thinning", 0) == 1:
            self.process_bar.addAction(self.thin_act)
        self.main_win.edit_menu.addAction(self.thin_act)

        # - separator
        self.process_bar.addSeparator()

        # restart processing
        self.restart_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'restart.png')),
            'Restart Processing', self)
        # self.restart_act.setShortcut('Alt+N')
        # noinspection PyUnresolvedReferences
        self.restart_act.triggered.connect(self.on_restart_proc)
        if settings.value("editor_buttons/restart", 1) == 1:
            self.process_bar.addAction(self.restart_act)
        self.main_win.edit_menu.addAction(self.restart_act)

        self.output_bar = self.addToolBar('Output')
        self.output_bar.setIconSize(QtCore.QSize(40, 40))

        self.main_win.edit_menu.addSeparator()

        # export
        self.export_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'export.png')), 'Export Data',
            self)
        self.export_act.setShortcut('Alt+X')
        # noinspection PyUnresolvedReferences
        self.export_act.triggered.connect(self.on_export_single_profile)
        if settings.value("editor_buttons/export", 1) == 1:
            self.output_bar.addAction(self.export_act)
        self.main_win.edit_menu.addAction(self.export_act)

        # transmit
        self.transmit_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'transmit.png')),
            'Transmit Data', self)
        self.transmit_act.setShortcut('Alt+T')
        # noinspection PyUnresolvedReferences
        self.transmit_act.triggered.connect(self.on_transmit_data)
        if settings.value("editor_buttons/transmit", 1) == 1:
            self.output_bar.addAction(self.transmit_act)
        self.main_win.edit_menu.addAction(self.transmit_act)

        # save db
        self.save_db_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'db_save.png')),
            'Save to Database', self)
        self.save_db_act.setShortcut('Alt+D')
        # noinspection PyUnresolvedReferences
        self.save_db_act.triggered.connect(self.on_save_db)
        if settings.value("editor_buttons/database", 0) == 1:
            self.output_bar.addAction(self.save_db_act)
        self.main_win.edit_menu.addAction(self.save_db_act)

        self.main_win.edit_menu.addSeparator()

        # automate steps
        self.automate_processing_acts = QtWidgets.QAction(
            "Automate processing", self)
        self.automate_processing_acts.setShortcut("Ctrl+A")
        self.automate_processing_acts.setStatusTip(
            "Automate the processing steps")
        # noinspection PyUnresolvedReferences
        self.automate_processing_acts.triggered.connect(
            self.on_automate_processing)
        self.main_win.edit_menu.addAction(self.automate_processing_acts)

        # buttons visibility
        self.buttons_visibility_acts = QtWidgets.QAction(
            "Change buttons visibility", self)
        self.buttons_visibility_acts.setStatusTip(
            "Define which buttons are displayed on the toolbar")
        # noinspection PyUnresolvedReferences
        self.buttons_visibility_acts.triggered.connect(
            self.on_buttons_visibility)
        self.main_win.edit_menu.addAction(self.buttons_visibility_acts)

        # exit action
        exit_action = QtWidgets.QAction("Exit", self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.setStatusTip("Exit application")
        # noinspection PyUnresolvedReferences
        exit_action.triggered.connect(self.main_win.close)
        self.main_win.file_menu.addSeparator()
        self.main_win.file_menu.addAction(exit_action)

        # plots
        self.dataplots = DataPlots(main_win=self.main_win, lib=self.lib)
        self.setCentralWidget(self.dataplots)
예제 #2
0
class Editor(AbstractWidget):
    here = os.path.abspath(os.path.join(
        os.path.dirname(__file__)))  # to be overloaded
    media = os.path.join(here, os.pardir, 'media')

    def __init__(self, main_win, lib):
        AbstractWidget.__init__(self, main_win=main_win, lib=lib)

        settings = QtCore.QSettings()
        settings.setValue("input_buttons/seacat_plugin",
                          settings.value("input_buttons/seacat_plugin", 0))
        settings.setValue("editor_buttons/reference",
                          settings.value("editor_buttons/reference", 1))
        settings.setValue("editor_buttons/spreadsheet",
                          settings.value("editor_buttons/spreadsheet", 0))
        settings.setValue("editor_buttons/metadata",
                          settings.value("editor_buttons/metadata", 1))
        settings.setValue("editor_buttons/filter",
                          settings.value("editor_buttons/filter", 1))
        settings.setValue("editor_buttons/thinning",
                          settings.value("editor_buttons/thinning", 0))
        settings.setValue("editor_buttons/restart",
                          settings.value("editor_buttons/restart", 1))
        settings.setValue("editor_buttons/export",
                          settings.value("editor_buttons/export", 1))
        settings.setValue("editor_buttons/transmit",
                          settings.value("editor_buttons/transmit", 1))
        settings.setValue("editor_buttons/database",
                          settings.value("editor_buttons/database", 0))

        self.input_bar = self.addToolBar('Input')
        self.input_bar.setIconSize(QtCore.QSize(40, 40))

        # import
        self.input_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'input.png')),
            'Import Input Data', self)
        self.input_act.setShortcut('Alt+I')
        # noinspection PyUnresolvedReferences
        self.input_act.triggered.connect(self.on_input_data)
        self.input_bar.addAction(self.input_act)
        self.main_win.file_menu.addAction(self.input_act)

        # import
        self.create_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'constant_gradient.png')),
            'Constant-gradient Profile', self)
        # self.create_act.setShortcut('Alt+G')
        # noinspection PyUnresolvedReferences
        self.create_act.triggered.connect(self.on_create_data)
        # self.input_bar.addAction(self.create_act)
        self.main_win.file_menu.addAction(self.create_act)

        # clear
        self.clear_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'clear.png')), 'Clear Data',
            self)
        self.clear_act.setShortcut('Alt+C')
        # noinspection PyUnresolvedReferences
        self.clear_act.triggered.connect(self.on_clear_data)
        # set hidden, but the whole action is candidate to deletion
        self.clear_act.setVisible(False)
        self.input_bar.addAction(self.clear_act)

        # set ref
        self.set_ref_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'ref.png')), 'Reference Cast',
            self)
        self.set_ref_act.setShortcut('Alt+R')
        # noinspection PyUnresolvedReferences
        self.set_ref_act.triggered.connect(self.on_set_ref)
        if settings.value("editor_buttons/reference", 1) == 1:
            self.input_bar.addAction(self.set_ref_act)
        self.main_win.file_menu.addAction(self.set_ref_act)

        # seacat
        self.seacat_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'seacat.png')),
            'Seabird CTD Setup', self)
        self.seacat_act.setShortcut('Alt+B')
        # noinspection PyUnresolvedReferences
        self.seacat_act.triggered.connect(self.on_seacat)
        if settings.value("input_buttons/seacat_plugin", 1) == 1:
            self.input_bar.addAction(self.seacat_act)
        self.main_win.file_menu.addAction(self.seacat_act)

        self.process_bar = self.addToolBar('Process')
        self.process_bar.setIconSize(QtCore.QSize(40, 40))

        # spreadsheet
        self.spreadsheet_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'grid.png')),
            'Show/Edit Data Spreadsheet', self)
        self.spreadsheet_act.setShortcut('Alt+S')
        # noinspection PyUnresolvedReferences
        self.spreadsheet_act.triggered.connect(self.on_spreadsheet)
        if settings.value("editor_buttons/spreadsheet", 0) == 1:
            self.process_bar.addAction(self.spreadsheet_act)
        self.main_win.edit_menu.addAction(self.spreadsheet_act)

        # metadata
        self.metadata_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'metadata.png')),
            'Show/Edit Cast Metadata', self)
        self.metadata_act.setShortcut('Alt+M')
        # noinspection PyUnresolvedReferences
        self.metadata_act.triggered.connect(self.on_metadata)
        if settings.value("editor_buttons/metadata", 1) == 1:
            self.process_bar.addAction(self.metadata_act)
        self.main_win.edit_menu.addAction(self.metadata_act)

        # - separator
        self.process_bar.addSeparator()
        self.main_win.edit_menu.addSeparator()

        # filter
        self.filter_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'filter.png')),
            'Filter/Smooth Data', self)
        self.filter_act.setShortcut('Alt+F')
        # noinspection PyUnresolvedReferences
        self.filter_act.triggered.connect(self.on_data_filter)
        if settings.value("editor_buttons/filter", 1) == 1:
            self.process_bar.addAction(self.filter_act)
        self.main_win.edit_menu.addAction(self.filter_act)

        # retrieve sal
        self.sal_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'sal.png')),
            'Retrieve Salinity', self)
        # self.sal_act.setShortcut('Alt+A')
        # noinspection PyUnresolvedReferences
        self.sal_act.triggered.connect(self.on_retrieve_sal)
        self.process_bar.addAction(self.sal_act)

        # retrieve temp/sal
        self.temp_sal_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'temp_sal.png')),
            'Retrieve Temperature/Salinity', self)
        # self.temp_sal_act.setShortcut('Alt+T')
        # noinspection PyUnresolvedReferences
        self.temp_sal_act.triggered.connect(self.on_retrieve_temp_sal)
        self.process_bar.addAction(self.temp_sal_act)
        self.main_win.edit_menu.addAction(self.temp_sal_act)

        # retrieve transducer sound speed
        self.tss_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'tss.png')),
            'Retrieve Transducer Sound Speed', self)
        # self.tss_act.setShortcut('Alt+W')
        # noinspection PyUnresolvedReferences
        self.tss_act.triggered.connect(self.on_retrieve_tss)
        self.process_bar.addAction(self.tss_act)
        self.main_win.edit_menu.addAction(self.tss_act)

        # extend profile
        self.extend_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'extend.png')),
            'Extend Profile', self)
        # self.extend_act.setShortcut('Alt+E')
        # noinspection PyUnresolvedReferences
        self.extend_act.triggered.connect(self.on_extend_profile)
        self.process_bar.addAction(self.extend_act)
        self.main_win.edit_menu.addAction(self.extend_act)

        # preview thinning
        self.thin_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'thinning.png')),
            'Preview Thinning', self)
        # self.thin_act.setShortcut('Alt+T')
        # noinspection PyUnresolvedReferences
        self.thin_act.triggered.connect(self.on_preview_thinning)
        # self.thin_act.setVisible(False)
        if settings.value("editor_buttons/thinning", 0) == 1:
            self.process_bar.addAction(self.thin_act)
        self.main_win.edit_menu.addAction(self.thin_act)

        # - separator
        self.process_bar.addSeparator()

        # restart processing
        self.restart_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'restart.png')),
            'Restart Processing', self)
        # self.restart_act.setShortcut('Alt+N')
        # noinspection PyUnresolvedReferences
        self.restart_act.triggered.connect(self.on_restart_proc)
        if settings.value("editor_buttons/restart", 1) == 1:
            self.process_bar.addAction(self.restart_act)
        self.main_win.edit_menu.addAction(self.restart_act)

        self.output_bar = self.addToolBar('Output')
        self.output_bar.setIconSize(QtCore.QSize(40, 40))

        self.main_win.edit_menu.addSeparator()

        # export
        self.export_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'export.png')), 'Export Data',
            self)
        self.export_act.setShortcut('Alt+X')
        # noinspection PyUnresolvedReferences
        self.export_act.triggered.connect(self.on_export_single_profile)
        if settings.value("editor_buttons/export", 1) == 1:
            self.output_bar.addAction(self.export_act)
        self.main_win.edit_menu.addAction(self.export_act)

        # transmit
        self.transmit_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'transmit.png')),
            'Transmit Data', self)
        self.transmit_act.setShortcut('Alt+T')
        # noinspection PyUnresolvedReferences
        self.transmit_act.triggered.connect(self.on_transmit_data)
        if settings.value("editor_buttons/transmit", 1) == 1:
            self.output_bar.addAction(self.transmit_act)
        self.main_win.edit_menu.addAction(self.transmit_act)

        # save db
        self.save_db_act = QtWidgets.QAction(
            QtGui.QIcon(os.path.join(self.media, 'db_save.png')),
            'Save to Database', self)
        self.save_db_act.setShortcut('Alt+D')
        # noinspection PyUnresolvedReferences
        self.save_db_act.triggered.connect(self.on_save_db)
        if settings.value("editor_buttons/database", 0) == 1:
            self.output_bar.addAction(self.save_db_act)
        self.main_win.edit_menu.addAction(self.save_db_act)

        self.main_win.edit_menu.addSeparator()

        # automate steps
        self.automate_processing_acts = QtWidgets.QAction(
            "Automate processing", self)
        self.automate_processing_acts.setShortcut("Ctrl+A")
        self.automate_processing_acts.setStatusTip(
            "Automate the processing steps")
        # noinspection PyUnresolvedReferences
        self.automate_processing_acts.triggered.connect(
            self.on_automate_processing)
        self.main_win.edit_menu.addAction(self.automate_processing_acts)

        # buttons visibility
        self.buttons_visibility_acts = QtWidgets.QAction(
            "Change buttons visibility", self)
        self.buttons_visibility_acts.setStatusTip(
            "Define which buttons are displayed on the toolbar")
        # noinspection PyUnresolvedReferences
        self.buttons_visibility_acts.triggered.connect(
            self.on_buttons_visibility)
        self.main_win.edit_menu.addAction(self.buttons_visibility_acts)

        # exit action
        exit_action = QtWidgets.QAction("Exit", self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.setStatusTip("Exit application")
        # noinspection PyUnresolvedReferences
        exit_action.triggered.connect(self.main_win.close)
        self.main_win.file_menu.addSeparator()
        self.main_win.file_menu.addAction(exit_action)

        # plots
        self.dataplots = DataPlots(main_win=self.main_win, lib=self.lib)
        self.setCentralWidget(self.dataplots)

    def on_input_data(self):
        """Import a data file"""
        logger.debug('user wants to input data')

        self.main_win.switch_to_editor_tab()
        dlg = ImportSingleProfileDialog(lib=self.lib,
                                        main_win=self.main_win,
                                        parent=self)
        ret = dlg.exec_()
        if ret != QtWidgets.QDialog.Accepted:
            return

        if not self.lib.has_ssp():
            msg = "Unable to retrieve a profile"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Input Data", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        if self.lib.cur.data.num_samples == 0:
            msg = "Unable to retrieve samples from the profile"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Input Data", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        self.main_win.data_imported()

        # auto-apply options
        self._auto_apply_to_current_profile()

    def on_create_data(self):
        """Import a data file"""
        logger.debug('user wants to create data')

        self.main_win.switch_to_editor_tab()
        dlg = ConstantGradientProfileDialog(lib=self.lib,
                                            main_win=self.main_win,
                                            parent=self)
        ret = dlg.exec_()
        if ret != QtWidgets.QDialog.Accepted:
            return

        if not self.lib.has_ssp():
            msg = "Unable to retrieve a profile"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Input Data", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        if self.lib.cur.data.num_samples == 0:
            msg = "Unable to retrieve samples from the profile"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Input Data", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        self.main_win.data_imported()

        # auto-apply options
        self._auto_apply_to_current_profile()

    def _auto_apply_to_current_profile(self):
        settings = QtCore.QSettings()
        if settings.value("auto_smooth_filter") == "true":
            logger.info("auto apply smooth/filter")
            self.on_data_filter()
        if settings.value("auto_sal_temp") == "true":
            if self.temp_sal_act.isEnabled():
                logger.info("auto retrieve temp/sal")
                self.on_retrieve_temp_sal()
            elif self.sal_act.isEnabled():
                logger.info("auto retrieve sal")
                self.on_retrieve_sal()
        if settings.value("auto_tss") == "true":
            logger.info("auto retrieve TSS")
            self.on_retrieve_tss()
        if settings.value("auto_extend") == "true":
            logger.info("auto extend cast")
            self.on_extend_profile()

    def on_clear_data(self):
        logger.debug('user wants to clear data')
        self.lib.clear_data()
        self.main_win.data_cleared()

    def on_seacat(self):
        logger.debug("Open Seabird CTD dialog")
        dlg = SeacatDialog(lib=self.lib, main_win=self.main_win, parent=self)
        ret = dlg.exec_()
        if ret != QtWidgets.QDialog.Accepted:
            logger.info("Seabird CTD dialog closed without selection")
            return

    def on_set_ref(self):
        logger.debug('user wants to set as a reference')

        self.main_win.switch_to_editor_tab()
        dlg = ReferenceDialog(lib=self.lib,
                              main_win=self.main_win,
                              parent=self)
        success = dlg.exec_()
        if success:
            self.main_win.data_imported()

    def on_restart_proc(self):
        logger.debug('user wants to restart processing')

        self.main_win.switch_to_editor_tab()
        self.lib.restart_proc()
        self.main_win.data_imported()

    def on_data_filter(self):
        logger.debug('user wants to filter/smooth data')

        self.main_win.switch_to_editor_tab()

        if not self.lib.filter_cur_data():
            msg = "Issue in filtering/smoothing the profile"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Filter/Smooth", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        self.dataplots.update_data()
        self.dataplots.update_speed_limits()
        self.dataplots.update_temp_limits()
        self.dataplots.update_sal_limits()

    def on_retrieve_sal(self):
        logger.debug('user wants to retrieve salinity')

        self.main_win.switch_to_editor_tab()

        if self.lib.cur.meta.sensor_type not in [
                Dicts.sensor_types['XBT'],
        ]:
            msg = "This is a XBT-specific function!"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Salinity", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        if not self.lib.replace_cur_salinity():
            msg = "Issue in replacing the salinity"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Salinity", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        self.dataplots.update_data()
        self.dataplots.update_speed_limits()
        self.dataplots.update_sal_limits()

    def on_retrieve_temp_sal(self):
        logger.debug('user wants to retrieve temp/sal')

        self.main_win.switch_to_editor_tab()

        if self.lib.cur.meta.sensor_type not in [
                Dicts.sensor_types['XSV'], Dicts.sensor_types['SVP'],
                Dicts.sensor_types['MVP']
        ]:
            msg = "This is a XSV- and SVP-specific function!"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Temperature/Salinity", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        if not self.lib.replace_cur_temp_sal():
            msg = "Issue in replacing temperature and salinity"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Temperature/Salinity", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        self.dataplots.update_data()
        self.dataplots.update_speed_limits()
        self.dataplots.update_temp_limits()
        self.dataplots.update_sal_limits()

    def on_retrieve_tss(self):
        logger.debug('user wants to retrieve transducer sound speed')

        self.main_win.switch_to_editor_tab()

        if not self.lib.add_cur_tss():
            msg = "Issue in retrieving transducer sound speed"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Sound speed", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        self.dataplots.update_data()

    def on_extend_profile(self):
        logger.debug('user wants to extend the profile')

        self.main_win.switch_to_editor_tab()

        if not self.lib.extend_profile():
            msg = "Issue in extending the profile!\n\n" \
                  "Possible causes:\n" \
                  "- The extension source is not active. Look at Setup/Input!\n" \
                  "- The profile from the extension source is too short. Check it on the plots!\n" \
                  "- The extension source does not have a profile at the geographic location.\n" \
                  "Use another source or manually extend the profile!"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Profile extension", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        self.dataplots.update_data()
        self.dataplots.update_depth_limits()
        self.dataplots.update_speed_limits()
        self.dataplots.update_temp_limits()
        self.dataplots.update_sal_limits()

    def on_preview_thinning(self):
        logger.debug('user wants to preview thinning')

        self.main_win.switch_to_editor_tab()

        tolerances = [0.01, 0.1, 0.5]
        for tolerance in tolerances:

            if not self.lib.prepare_sis(thin_tolerance=tolerance):
                msg = "Issue in preview the thinning"
                # noinspection PyCallByClass
                QtWidgets.QMessageBox.warning(self, "Thinning preview", msg,
                                              QtWidgets.QMessageBox.Ok)
                return

            # checking for number of samples
            si = self.lib.cur.sis_thinned
            thin_profile_length = self.lib.cur.sis.flag[si].size
            logger.debug("thin profile size: %d (with tolerance: %.3f)" %
                         (thin_profile_length, tolerance))
            if thin_profile_length < 1000:
                break

            logger.info("too many samples, attempting with a lower tolerance")

        self.dataplots.update_data()

    def on_spreadsheet(self):
        logger.debug('user wants to read/edit spreadsheet')

        self.main_win.switch_to_editor_tab()

        if not self.lib.has_ssp():
            msg = "Import data before visualize them in a spreadsheet!"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Spreadsheet warning", msg,
                                          QtWidgets.QMessageBox.Ok)
            return
        dlg = SpreadSheetDialog(lib=self.lib,
                                main_win=self.main_win,
                                parent=self)
        dlg.exec_()

    def on_metadata(self):
        logger.debug('user wants to read/edit metadata')

        self.main_win.switch_to_editor_tab()

        if not self.lib.has_ssp():
            msg = "Import data before visualize metadata!"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Metadata warning", msg,
                                          QtWidgets.QMessageBox.Ok)
            return
        dlg = MetadataDialog(lib=self.lib, main_win=self.main_win, parent=self)
        dlg.exec_()

    def _run_safety_checks_on_output(self):
        logger.debug('running safety checks on output')

        if not self.lib.has_ssp():
            msg = "You need to first import data!"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Data Warning", msg,
                                          QtWidgets.QMessageBox.Ok)
            return False

        min_samples = 5

        if len(self.lib.cur.proc.temp) < min_samples:

            msg = "Suspect short temperature profile detected!\n\n" \
                  "Do you really want to continue?"
            # noinspection PyCallByClass
            ret = QtWidgets.QMessageBox.warning(
                self, "Data Warning", msg,
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if ret == QtWidgets.QMessageBox.No:
                return False

        elif all(i == 0 for i in self.lib.cur.proc.temp[
                self.lib.cur.proc_valid][:min_samples]):

            msg = "Suspect zero values in the temperature profile detected!\n" \
                  "Invalid values can heavily affect the quality of sonar data.\n\n" \
                  "Do you really want to continue?"
            # noinspection PyCallByClass
            ret = QtWidgets.QMessageBox.warning(
                self, "Data Warning", msg,
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if ret == QtWidgets.QMessageBox.No:
                return False

        if len(self.lib.cur.proc.sal) < min_samples:

            msg = "Suspect short salinity profile detected!\n\n" \
                  "Do you really want to continue?"
            # noinspection PyCallByClass
            ret = QtWidgets.QMessageBox.warning(
                self, "Data Warning", msg,
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if ret == QtWidgets.QMessageBox.No:
                return False

        elif all(i == 0 for i in self.lib.cur.proc.sal[self.lib.cur.proc_valid]
                 [:min_samples]):

            msg = "Suspect zero values in the salinity profile detected!\n" \
                  "Invalid values can heavily affect the quality of sonar data.\n\n" \
                  "Do you really want to continue?"
            # noinspection PyCallByClass
            ret = QtWidgets.QMessageBox.warning(
                self, "Data Warning", msg,
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if ret == QtWidgets.QMessageBox.No:
                return False

        if len(self.lib.cur.proc.speed) < min_samples:

            msg = "Suspect short sound speed profile detected!\n\n" \
                  "Do you really want to continue?"
            # noinspection PyCallByClass
            ret = QtWidgets.QMessageBox.warning(
                self, "Data Warning", msg,
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if ret == QtWidgets.QMessageBox.No:
                return False

        elif all(i == 0 for i in self.lib.cur.proc.speed[
                self.lib.cur.proc_valid][:min_samples]):

            msg = "Suspect zero values in the sound speed profile detected!\n" \
                  "Invalid values can heavily affect the quality of sonar data.\n\n" \
                  "Do you really want to continue?"
            # noinspection PyCallByClass
            ret = QtWidgets.QMessageBox.warning(
                self, "Data Warning", msg,
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if ret == QtWidgets.QMessageBox.No:
                return False

        return True

    def on_export_single_profile(self):
        logger.debug('user wants to export a single profile')

        self.main_win.switch_to_editor_tab()

        valid = self._run_safety_checks_on_output()
        if not valid:
            return

        if self.lib.cur.meta.sensor_type in [
                Dicts.sensor_types['Synthetic'],
        ]:

            msg = "Do you really want to export a profile\nbased on synthetic %s data?" \
                  % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type)
            # noinspection PyCallByClass
            ret = QtWidgets.QMessageBox.warning(
                self, "Synthetic source warning", msg,
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if ret == QtWidgets.QMessageBox.No:
                return

        if self.lib.cur.meta.probe_type in [
                Dicts.probe_types['ASVP'], Dicts.probe_types['CARIS'],
                Dicts.probe_types['ELAC'], Dicts.probe_types['HYPACK']
        ]:

            msg = "Do you really want to export a profile\nbased on pre-processed %s data?" \
                  % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type)
            # noinspection PyCallByClass
            ret = QtWidgets.QMessageBox.warning(
                self, "Pre-processed source warning", msg,
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if ret == QtWidgets.QMessageBox.No:
                return

        dlg = ExportSingleProfileDialog(lib=self.lib,
                                        main_win=self.main_win,
                                        parent=self)
        result = dlg.exec_()
        if result == QtWidgets.QDialog.Accepted:
            self.on_save_db(auto_save=True)

        self.dataplots.update_data()

    def on_transmit_data(self):
        logger.debug('user wants to transmit the data')

        self.main_win.switch_to_editor_tab()

        valid = self._run_safety_checks_on_output()
        if not valid:
            return

        if self.lib.cur.meta.sensor_type in [
                Dicts.sensor_types['Synthetic'],
        ]:

            msg = "Do you really want to transmit a profile\nbased on synthetic %s data?" \
                  % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type)
            # noinspection PyCallByClass
            ret = QtWidgets.QMessageBox.warning(
                self, "Synthetic source warning", msg,
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if ret == QtWidgets.QMessageBox.No:
                return

        if self.lib.cur.meta.probe_type in [
                Dicts.probe_types['ASVP'], Dicts.probe_types['CARIS'],
                Dicts.probe_types['ELAC'], Dicts.probe_types['HYPACK']
        ]:

            msg = "Do you really want to transmit a profile\nbased on pre-processed %s data?" \
                  % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type)
            # noinspection PyCallByClass
            ret = QtWidgets.QMessageBox.warning(
                self, "Pre-processed source warning", msg,
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if ret == QtWidgets.QMessageBox.No:
                return

        if not self.lib.transmit_ssp():
            msg = "Possible issue in profile transmission."
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Profile transmission", msg,
                                          QtWidgets.QMessageBox.Ok)

        self.on_save_db(auto_save=True)
        self.dataplots.update_data()

    def on_save_db(self, auto_save=False):

        if auto_save:
            logger.debug('auto-save data to db')
        else:
            logger.debug('user wants to save data to db')
            self.main_win.switch_to_editor_tab()

            # since auto-save the same checks and questions have been asked!

            valid = self._run_safety_checks_on_output()
            if not valid:
                return

            if self.lib.cur.meta.sensor_type in [
                    Dicts.sensor_types['Synthetic'],
            ]:

                msg = "Do you really want to store a profile based \non synthetic %s data?\n" \
                      % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type)
                # noinspection PyCallByClass
                ret = QtWidgets.QMessageBox.warning(
                    self, "Synthetic source warning", msg,
                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
                if ret == QtWidgets.QMessageBox.No:
                    return

            if self.lib.cur.meta.probe_type in [
                    Dicts.probe_types['ASVP'], Dicts.probe_types['CARIS'],
                    Dicts.probe_types['ELAC'], Dicts.probe_types['HYPACK']
            ]:

                msg = "Do you really want to store a profile based \non pre-processed %s data?\n\n" \
                      "This operation may OVERWRITE existing raw data \nin the database!" \
                      % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type)
                # noinspection PyCallByClass
                ret = QtWidgets.QMessageBox.warning(
                    self, "Pre-processed source warning", msg,
                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
                if ret == QtWidgets.QMessageBox.No:
                    return

        if not self.lib.store_data():
            msg = "Unable to save to db!"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Database warning", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        self.main_win.data_stored()

    def on_automate_processing(self):

        logger.debug('open automate processing dialog')

        self.main_win.switch_to_editor_tab()

        dlg = AutomateDialog(lib=self.lib, main_win=self.main_win, parent=self)
        dlg.exec_()

    def on_buttons_visibility(self):

        logger.debug('open buttons visibility dialog')

        self.main_win.switch_to_editor_tab()

        dlg = ButtonsDialog(lib=self.lib, main_win=self.main_win, parent=self)
        dlg.exec_()

    def data_cleared(self):
        # bars
        self.process_bar.hide()
        self.output_bar.hide()

        # dialogs
        # self.clear_act.setDisabled(True)
        self.set_ref_act.setVisible(False)
        self.restart_act.setVisible(False)
        self.spreadsheet_act.setVisible(False)
        self.filter_act.setVisible(False)
        self.sal_act.setVisible(False)
        self.temp_sal_act.setVisible(False)
        self.tss_act.setVisible(False)
        self.extend_act.setVisible(False)
        self.thin_act.setVisible(False)
        self.metadata_act.setVisible(False)
        self.export_act.setVisible(False)
        self.transmit_act.setVisible(False)
        self.save_db_act.setVisible(False)
        # data plots
        self.dataplots.setHidden(True)

    def data_imported(self):
        # bars
        self.process_bar.show()
        self.output_bar.show()

        # dialogs
        # self.clear_act.setDisabled(False)
        self.set_ref_act.setVisible(True)
        self.restart_act.setVisible(True)
        self.spreadsheet_act.setVisible(True)
        self.metadata_act.setVisible(True)

        self.filter_act.setVisible(True)
        if self.lib.cur.meta.sensor_type in [
                Dicts.sensor_types['XBT'],
        ]:
            self.sal_act.setVisible(True)
        else:
            self.sal_act.setVisible(False)

        if self.lib.cur.meta.sensor_type in [
                Dicts.sensor_types['XSV'], Dicts.sensor_types['SVP']
        ]:
            self.temp_sal_act.setVisible(True)

        elif self.lib.cur.meta.sensor_type in [
                Dicts.sensor_types['MVP'],
        ]:

            if (np.sum(self.lib.cur.proc.temp) == 0) and (np.sum(
                    self.lib.cur.proc.sal) == 0):
                self.temp_sal_act.setVisible(True)
            else:
                self.temp_sal_act.setVisible(False)

        else:
            self.temp_sal_act.setVisible(False)

        if self.lib.use_sis():
            self.tss_act.setVisible(True)
        else:
            self.tss_act.setVisible(False)

        self.extend_act.setVisible(True)
        self.thin_act.setVisible(True)
        self.export_act.setVisible(True)
        self.transmit_act.setVisible(True)
        self.save_db_act.setVisible(True)

        # data plots
        self.dataplots.reset()
        self.dataplots.on_first_draw()
        self.dataplots.setVisible(True)

        # call required to set a flag that a profile was viewed (and hopefully QC)
        self.lib.cur_plotted()

    def server_started(self):
        self.setDisabled(True)

    def server_stopped(self):
        self.setEnabled(True)
예제 #3
0
class Server(AbstractWidget):
    here = os.path.abspath(os.path.join(
        os.path.dirname(__file__)))  # to be overloaded
    media = os.path.join(here, os.pardir, 'media')

    def __init__(self, main_win, lib):
        AbstractWidget.__init__(self, main_win=main_win, lib=lib)

        # create the overall layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.frame.setLayout(self.main_layout)

        # info box
        hbox = QtWidgets.QHBoxLayout()
        self.main_layout.addLayout(hbox)
        hbox.addStretch()
        self.group_box = QtWidgets.QGroupBox("Synthetic Profile Server")
        self.group_box.setMaximumHeight(120)
        self.group_box.setFixedWidth(500)
        hbox.addWidget(self.group_box)
        hbox.addStretch()

        # image and text
        group_layout = QtWidgets.QHBoxLayout()
        self.group_box.setLayout(group_layout)
        group_layout.addStretch()
        # - image
        img_label = QtWidgets.QLabel()
        img = QtGui.QImage(os.path.join(self.media, 'server.png'))
        if img.isNull():
            raise RuntimeError("unable to open server image")
        # noinspection PyCallByClass,PyArgumentList
        img_label.setPixmap(QtGui.QPixmap.fromImage(img))
        group_layout.addWidget(img_label)
        # - text
        info_label = QtWidgets.QLabel(
            "This tool delivers WOA/model-derived synthetic profiles to one or more network\n"
            "clients in a continuous manner, enabling opportunistic mapping while underway.\n\n"
            "Given the uncertainty of such an approach, this mode is expected to ONLY be used\n"
            "in transit, capturing the position from SIS to lookup into the oceanographic atlas."
        )
        info_label.setStyleSheet("color: #96A8A8;")
        info_label.setWordWrap(True)
        group_layout.addWidget(info_label)
        group_layout.addStretch()

        # - buttons
        hbox = QtWidgets.QHBoxLayout()
        self.main_layout.addLayout(hbox)
        hbox.addStretch()
        # -- start
        self.start_btn = QtWidgets.QPushButton("Start server")
        # noinspection PyUnresolvedReferences
        self.start_btn.clicked.connect(self.on_start_server)
        self.start_btn.setToolTip("Start server mode")
        hbox.addWidget(self.start_btn)
        self.start_server_act = QtWidgets.QAction('Start Server', self)
        # self.start_server_act.setShortcut('Ctrl+Alt+S')
        # noinspection PyUnresolvedReferences
        self.start_server_act.triggered.connect(self.on_start_server)
        self.main_win.server_menu.addAction(self.start_server_act)

        # -- force
        self.force_btn = QtWidgets.QPushButton("Send SSP now")
        # noinspection PyUnresolvedReferences
        self.force_btn.clicked.connect(self.on_force_server)
        self.force_btn.setToolTip(
            "Force the transmission of a synthethic profile")
        hbox.addWidget(self.force_btn)
        self.force_server_act = QtWidgets.QAction('Force Transmission', self)
        # self.force_server_act.setShortcut('Ctrl+Alt+T')
        # noinspection PyUnresolvedReferences
        self.force_server_act.triggered.connect(self.on_force_server)
        self.main_win.server_menu.addAction(self.force_server_act)

        # -- stop
        self.stop_btn = QtWidgets.QPushButton("Stop server")
        # noinspection PyUnresolvedReferences
        self.stop_btn.clicked.connect(self.on_stop_server)
        self.stop_btn.setToolTip("Stop server mode")
        hbox.addWidget(self.stop_btn)
        self.stop_server_act = QtWidgets.QAction('Stop Server', self)
        # self.stop_server_act.setShortcut('Ctrl+Alt+E')
        # noinspection PyUnresolvedReferences
        self.stop_server_act.triggered.connect(self.on_stop_server)
        self.main_win.server_menu.addAction(self.stop_server_act)

        hbox.addStretch()

        # - plots
        self.dataplots = DataPlots(main_win=self.main_win,
                                   lib=self.lib,
                                   server_mode=True)
        self.main_layout.addWidget(self.dataplots)
        self.hidden = QtWidgets.QFrame()
        self.main_layout.addWidget(self.hidden)

        self._deactivate_gui(also_main_win=False)

        self.activated_server = False
        timer = QtCore.QTimer(self)
        # noinspection PyUnresolvedReferences
        timer.timeout.connect(self.update_gui)
        # noinspection PyArgumentList
        timer.start(2000)

    def on_start_server(self):
        logger.debug('start server')

        if self.lib.server_is_alive():
            msg = "The server mode is already started!"
            # noinspection PyCallByClass,PyArgumentList
            QtWidgets.QMessageBox.warning(self, "Server mode", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        self.main_win.switch_to_server_tab()

        msg = "Do you really want to start the Server Mode?\n\n" \
              "The Server Mode creates sound speed profiles based on oceanographic models.\n" \
              "Thus, it is meant for use in transit, NOT for systematic seabed mapping.\n" \
              "This Mode will OVERWRITE the current SIS SSP.\n"
        # noinspection PyCallByClass,PyArgumentList
        ret = QtWidgets.QMessageBox.warning(
            self, "Server mode", msg,
            QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
        if ret == QtWidgets.QMessageBox.No:
            return

        uni_clients = self.lib.server.list_uni_clients()
        use_uni_clients = False
        if len(uni_clients) > 0:
            msg = "The following clients do NOT provide acknowledgment of the received profiles:\n"
            for uni_client in uni_clients:
                msg += "- %s\n" % uni_client
            msg += "\nDo you still want to transmit the profiles to them?\n"
            # noinspection PyCallByClass,PyArgumentList
            ret = QtWidgets.QMessageBox.warning(
                self, "Server mode", msg,
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if ret == QtWidgets.QMessageBox.Yes:
                use_uni_clients = True
            elif ret == QtWidgets.QMessageBox.No:
                use_uni_clients = False
            else:
                logger.debug("Cancelled by user.")
                return

        if not self.lib.server.check_settings(use_uni_clients=use_uni_clients):
            msg = "Unable to start the server mode!\n"
            for err in self.lib.server.settings_errors:
                msg += "Reason: %s\n" % err
            msg += "\nDouble-check the server settings and be sure that SIS is properly configured."
            # noinspection PyCallByClass,PyArgumentList
            QtWidgets.QMessageBox.critical(self, "Server mode", msg,
                                           QtWidgets.QMessageBox.Ok)
            return

        self.lib.start_server()

        self.activated_server = True
        self._activate_gui()

    def on_force_server(self):
        logger.debug('force server')

        self.main_win.switch_to_server_tab()

        if not self.lib.server_is_alive():
            msg = "First start the server mode!"
            # noinspection PyCallByClass,PyArgumentList
            QtWidgets.QMessageBox.warning(self, "Server mode", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        self.lib.force_server()
        self.main_win.data_stored()

    def on_stop_server(self):
        logger.debug('stop server')

        self.main_win.switch_to_server_tab()

        if not self.lib.server_is_alive():
            msg = "First start the server mode!"
            # noinspection PyCallByClass,PyArgumentList
            QtWidgets.QMessageBox.warning(self, "Server mode", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

        self.lib.stop_server()

        self.activated_server = False
        self._deactivate_gui()

    def update_gui(self):
        if self.activated_server and not self.lib.server_is_alive():
            self._deactivate_gui()
            self.activated_server = False
            msg = "Server Mode automatically stopped!\n"
            for err in self.lib.server.runtime_errors:
                msg += "Reason: %s\n" % err
            # noinspection PyCallByClass,PyArgumentList
            QtWidgets.QMessageBox.warning(self, "Server mode", msg,
                                          QtWidgets.QMessageBox.Ok)
            return

    def _activate_gui(self):
        self.dataplots.setVisible(True)
        self.hidden.setHidden(True)
        self.group_box.setHidden(True)

        self.start_btn.setDisabled(True)
        self.force_btn.setEnabled(True)
        self.stop_btn.setEnabled(True)

        self.main_win.server_started()

    def _deactivate_gui(self, also_main_win=True):
        self.dataplots.setHidden(True)
        self.hidden.setVisible(True)
        self.group_box.setVisible(True)

        self.start_btn.setEnabled(True)
        self.force_btn.setDisabled(True)
        self.stop_btn.setDisabled(True)

        if also_main_win:
            self.main_win.data_stored()
            self.main_win.server_stopped()
예제 #4
0
    def __init__(self, main_win, lib):
        AbstractWidget.__init__(self, main_win=main_win, lib=lib)

        # create the overall layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.frame.setLayout(self.main_layout)

        # info box
        hbox = QtWidgets.QHBoxLayout()
        self.main_layout.addLayout(hbox)
        hbox.addStretch()
        self.group_box = QtWidgets.QGroupBox("Synthetic Profile Server")
        self.group_box.setMaximumHeight(120)
        self.group_box.setFixedWidth(500)
        hbox.addWidget(self.group_box)
        hbox.addStretch()

        # image and text
        group_layout = QtWidgets.QHBoxLayout()
        self.group_box.setLayout(group_layout)
        group_layout.addStretch()
        # - image
        img_label = QtWidgets.QLabel()
        img = QtGui.QImage(os.path.join(self.media, 'server.png'))
        if img.isNull():
            raise RuntimeError("unable to open server image")
        # noinspection PyCallByClass,PyArgumentList
        img_label.setPixmap(QtGui.QPixmap.fromImage(img))
        group_layout.addWidget(img_label)
        # - text
        info_label = QtWidgets.QLabel(
            "This tool delivers WOA/model-derived synthetic profiles to one or more network\n"
            "clients in a continuous manner, enabling opportunistic mapping while underway.\n\n"
            "Given the uncertainty of such an approach, this mode is expected to ONLY be used\n"
            "in transit, capturing the position from SIS to lookup into the oceanographic atlas."
        )
        info_label.setStyleSheet("color: #96A8A8;")
        info_label.setWordWrap(True)
        group_layout.addWidget(info_label)
        group_layout.addStretch()

        # - buttons
        hbox = QtWidgets.QHBoxLayout()
        self.main_layout.addLayout(hbox)
        hbox.addStretch()
        # -- start
        self.start_btn = QtWidgets.QPushButton("Start server")
        # noinspection PyUnresolvedReferences
        self.start_btn.clicked.connect(self.on_start_server)
        self.start_btn.setToolTip("Start server mode")
        hbox.addWidget(self.start_btn)
        self.start_server_act = QtWidgets.QAction('Start Server', self)
        # self.start_server_act.setShortcut('Ctrl+Alt+S')
        # noinspection PyUnresolvedReferences
        self.start_server_act.triggered.connect(self.on_start_server)
        self.main_win.server_menu.addAction(self.start_server_act)

        # -- force
        self.force_btn = QtWidgets.QPushButton("Send SSP now")
        # noinspection PyUnresolvedReferences
        self.force_btn.clicked.connect(self.on_force_server)
        self.force_btn.setToolTip(
            "Force the transmission of a synthethic profile")
        hbox.addWidget(self.force_btn)
        self.force_server_act = QtWidgets.QAction('Force Transmission', self)
        # self.force_server_act.setShortcut('Ctrl+Alt+T')
        # noinspection PyUnresolvedReferences
        self.force_server_act.triggered.connect(self.on_force_server)
        self.main_win.server_menu.addAction(self.force_server_act)

        # -- stop
        self.stop_btn = QtWidgets.QPushButton("Stop server")
        # noinspection PyUnresolvedReferences
        self.stop_btn.clicked.connect(self.on_stop_server)
        self.stop_btn.setToolTip("Stop server mode")
        hbox.addWidget(self.stop_btn)
        self.stop_server_act = QtWidgets.QAction('Stop Server', self)
        # self.stop_server_act.setShortcut('Ctrl+Alt+E')
        # noinspection PyUnresolvedReferences
        self.stop_server_act.triggered.connect(self.on_stop_server)
        self.main_win.server_menu.addAction(self.stop_server_act)

        hbox.addStretch()

        # - plots
        self.dataplots = DataPlots(main_win=self.main_win,
                                   lib=self.lib,
                                   server_mode=True)
        self.main_layout.addWidget(self.dataplots)
        self.hidden = QtWidgets.QFrame()
        self.main_layout.addWidget(self.hidden)

        self._deactivate_gui(also_main_win=False)

        self.activated_server = False
        timer = QtCore.QTimer(self)
        # noinspection PyUnresolvedReferences
        timer.timeout.connect(self.update_gui)
        # noinspection PyArgumentList
        timer.start(2000)
예제 #5
0
class Server(AbstractWidget):
    here = os.path.abspath(os.path.join(os.path.dirname(__file__)))  # to be overloaded
    media = os.path.join(here, os.pardir, 'media')

    def __init__(self, main_win, lib):
        AbstractWidget.__init__(self, main_win=main_win, lib=lib)

        # create the overall layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.frame.setLayout(self.main_layout)

        # info box
        hbox = QtWidgets.QHBoxLayout()
        self.main_layout.addLayout(hbox)
        hbox.addStretch()
        self.group_box = QtWidgets.QGroupBox("Synthetic Profile Server")
        self.group_box.setMaximumHeight(120)
        self.group_box.setFixedWidth(500)
        hbox.addWidget(self.group_box)
        hbox.addStretch()

        # image and text
        group_layout = QtWidgets.QHBoxLayout()
        self.group_box.setLayout(group_layout)
        group_layout.addStretch()
        # - image
        img_label = QtWidgets.QLabel()
        img = QtGui.QImage(os.path.join(self.media, 'server.png'))
        if img.isNull():
            raise RuntimeError("unable to open server image")
        # noinspection PyCallByClass
        img_label.setPixmap(QtGui.QPixmap.fromImage(img))
        group_layout.addWidget(img_label)
        # - text
        info_label = QtWidgets.QLabel(
            "This tool delivers WOA/RTOFS-derived synthetic profiles to one or more network\n"
            "clients in a continuous manner, enabling opportunistic mapping while underway.\n\n"
            "Given the uncertainty of such an approach, this mode is expected to ONLY be used\n"
            "in transit, capturing the position from SIS to lookup into the oceanographic atlas."
        )
        info_label.setStyleSheet("color: #96A8A8;")
        info_label.setWordWrap(True)
        group_layout.addWidget(info_label)
        group_layout.addStretch()

        # - buttons
        hbox = QtWidgets.QHBoxLayout()
        self.main_layout.addLayout(hbox)
        hbox.addStretch()
        # -- start
        btn = QtWidgets.QPushButton("Start server")
        # noinspection PyUnresolvedReferences
        btn.clicked.connect(self.on_start_server)
        btn.setToolTip("Start server mode")
        hbox.addWidget(btn)
        self.start_server_act = QtWidgets.QAction('Start Server', self)
        # self.start_server_act.setShortcut('Ctrl+Alt+S')
        # noinspection PyUnresolvedReferences
        self.start_server_act.triggered.connect(self.on_start_server)
        self.main_win.server_menu.addAction(self.start_server_act)

        # -- force
        btn = QtWidgets.QPushButton("Send now")
        # noinspection PyUnresolvedReferences
        btn.clicked.connect(self.on_force_server)
        btn.setToolTip("Force the transmission of a synthethic profile")
        hbox.addWidget(btn)
        self.force_server_act = QtWidgets.QAction('Force Transmission', self)
        # self.force_server_act.setShortcut('Ctrl+Alt+T')
        # noinspection PyUnresolvedReferences
        self.force_server_act.triggered.connect(self.on_force_server)
        self.main_win.server_menu.addAction(self.force_server_act)

        # -- refresh
        btn = QtWidgets.QPushButton("Refresh DB")
        # noinspection PyUnresolvedReferences
        btn.clicked.connect(self.on_refresh_db)
        btn.setToolTip("Refresh the database tab")
        hbox.addWidget(btn)
        self.refresh_db_act = QtWidgets.QAction('Refresh Database', self)
        # noinspection PyUnresolvedReferences
        self.refresh_db_act.triggered.connect(self.on_refresh_db)
        self.main_win.server_menu.addAction(self.refresh_db_act)

        # -- stop
        btn = QtWidgets.QPushButton("Stop server")
        # noinspection PyUnresolvedReferences
        btn.clicked.connect(self.on_stop_server)
        btn.setToolTip("Stop server mode")
        hbox.addWidget(btn)
        self.stop_server_act = QtWidgets.QAction('Stop Server', self)
        # self.stop_server_act.setShortcut('Ctrl+Alt+E')
        # noinspection PyUnresolvedReferences
        self.stop_server_act.triggered.connect(self.on_stop_server)
        self.main_win.server_menu.addAction(self.stop_server_act)

        hbox.addStretch()

        # - plots
        self.dataplots = DataPlots(main_win=self.main_win, lib=self.lib, server_mode=True)
        self.main_layout.addWidget(self.dataplots)
        self.dataplots.setHidden(True)
        self.hidden = QtWidgets.QFrame()
        self.main_layout.addWidget(self.hidden)
        self.hidden.setVisible(True)

    def on_start_server(self):
        logger.debug('start server')

        self.main_win.switch_to_server_tab()

        msg = "Do you really want to start the Server Mode?\n\n" \
              "The Server Mode creates sound speed profiles based on oceanographic models.\n" \
              "Thus, it is meant for use in transit, NOT for systematic seabed mapping.\n" \
              "This Mode will OVERWRITE the current SIS SSP.\n"
        # noinspection PyCallByClass
        ret = QtWidgets.QMessageBox.warning(self, "Server mode", msg,
                                            QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.No)
        if ret == QtWidgets.QMessageBox.No:
            return

        if not self.lib.server.check_settings():
            msg = "Unable to start the server mode.\n\n" \
                  "Double-check the server settings and be sure that SIS is properly configured."
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.critical(self, "Server mode", msg, QtWidgets.QMessageBox.Ok)
            return

        self.lib.start_server()

        self.dataplots.setVisible(True)
        self.hidden.setHidden(True)
        self.group_box.setHidden(True)
        self.main_win.server_started()

    def on_force_server(self):
        logger.debug('force server')

        self.main_win.switch_to_server_tab()

        if not self.lib.server_is_alive():
            msg = "First start the server mode!"
            # noinspection PyCallByClass
            QtWidgets.QMessageBox.warning(self, "Server mode", msg, QtWidgets.QMessageBox.Ok)
            return

        self.lib.force_server()
        self.main_win.data_stored()

    def on_refresh_db(self):
        logger.debug('refresh db')
        self.main_win.data_stored()
        self.main_win.switch_to_database_tab()

    def on_stop_server(self):
        logger.debug('stop server')

        self.main_win.switch_to_server_tab()

        self.lib.stop_server()

        self.dataplots.setHidden(True)
        self.hidden.setVisible(True)
        self.group_box.setVisible(True)
        self.main_win.server_stopped()
        self.main_win.data_stored()