Ejemplo n.º 1
0
def ask_confirmation(self, message, title="Mantid Workbench"):
    """
    :param message:
    :return:
    """
    reply = QMessageBox.question(self, title, message, QMessageBox.Yes, QMessageBox.No)
    return True if reply == QMessageBox.Yes else False
Ejemplo n.º 2
0
    def closeEvent(self, event):
        if self.dirty:
            res = QMessageBox.question(
                self,
                QCoreApplication.applicationName(),
                self.tr("Save changes to file '%s'?" %
                        self.filename
                        if self.filename is not None else "unknown"),
                QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel
            )
            if res == QMessageBox.Cancel:
                event.ignore()
                return
            elif res == QMessageBox.Yes:
                self.save_file()

        self.save_settings()

        try:
            self.worker.quit()
        except AttributeError:
            pass

        try:
            self.serial.close()
        except (SerialException, AttributeError):
            pass
Ejemplo n.º 3
0
    def _run_pip_action(self, package_name, action):
        """
        DEPRECATED
        """
        prefix = self.prefix

        if prefix == self.root_prefix:
            name = 'root'
        elif self.api.conda_environment_exists(prefix=prefix):
            name = osp.basename(prefix)
        else:
            name = prefix

        if action == C.ACTION_REMOVE:
            msgbox = QMessageBox.question(self,
                                          "Remove pip package: "
                                          "{0}".format(package_name),
                                          "Do you want to proceed?",
                                          QMessageBox.Yes | QMessageBox.No)
            if msgbox == QMessageBox.Yes:
                self.update_status()
                worker = self.api.pip_remove(prefix=self.prefix,
                                             pkgs=[package_name])
                worker.sig_finished.connect(self._pip_process_ready)
                status = (_('Removing pip package <b>') + package_name +
                          '</b>' + _(' from <i>') + name + '</i>')
                self.update_status(hide=True, message=status,
                                   progress=[0, 0])
    def closeEvent(self, event):
        """
            Executed when the application closes
        """
        if False:
            reply = QMessageBox.question(self, 'Message',
                                               "Are you sure you want to quit this application?",
                                               QMessageBox.Yes, QMessageBox.No)

            if reply == QMessageBox.Yes:
                event.accept()
            else:
                event.ignore()

        # Save application settings
        if self._clear_and_restart:
            self._clear_and_restart = False
            QSettings().clear()
        else:
            settings = QSettings()

            settings.setValue("instrument_name", self._instrument)
            settings.setValue("last_file", self._filename)
            settings.setValue("recent_files", self._recent_files)
            settings.setValue("last_directory", str(self._last_directory))
            settings.setValue("last_export_directory", str(self._last_export_directory))
Ejemplo n.º 5
0
 def synchronize(self):
     """
     Synchronize Spyder's path list with PYTHONPATH environment variable
     Only apply to: current user, on Windows platforms
     """
     answer = QMessageBox.question(self, _("Synchronize"),
         _("This will synchronize Spyder's path list with "
                 "<b>PYTHONPATH</b> environment variable for current user, "
                 "allowing you to run your Python modules outside Spyder "
                 "without having to configure sys.path. "
                 "<br>Do you want to clear contents of PYTHONPATH before "
                 "adding Spyder's path list?"),
         QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
     if answer == QMessageBox.Cancel:
         return
     elif answer == QMessageBox.Yes:
         remove = True
     else:
         remove = False
     from spyder.utils.environ import (get_user_env, set_user_env,
                                       listdict2envdict)
     env = get_user_env()
     if remove:
         ppath = self.active_pathlist+self.ro_pathlist
     else:
         ppath = env.get('PYTHONPATH', [])
         if not isinstance(ppath, list):
             ppath = [ppath]
         ppath = [path for path in ppath
                  if path not in (self.active_pathlist+self.ro_pathlist)]
         ppath.extend(self.active_pathlist+self.ro_pathlist)
     env['PYTHONPATH'] = ppath
     set_user_env(listdict2envdict(env), parent=self)
Ejemplo n.º 6
0
    def save_if_required(self, prompt_for_confirm=True, force_save=False):
        """
        Save the editor's contents to a file. The function has the following options:
        - if prompt_for_confirmation is True -> then show the yes/no dialog
        - if force_save is True, and prompt_for_confirmation is False -> then save the file anyway
        - if prompt_for_confirmation and force_save are both False -> then do NOT save the file, discard all changes

        :param prompt_for_confirmation: If this is True, then the user will be prompted with a yes/no dialog to
                                        decide whether to save or discard the file.
                                        If this parameter is True, force_save will be ignored!
        :param force_save: If this is True, then if the user is NOT being prompted, the file will be saved anyway!
                           This is used for the File > Save Script (Ctrl + S) action.
        :returns: True if either saving was successful or no save was requested. Returns False if
        the operation should be cancelled
        """
        if prompt_for_confirm:
            button = QMessageBox.question(self.editor, "",
                                          "Save changes to document before closing?",
                                          buttons=(QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel),
                                          defaultButton=QMessageBox.Cancel)
            if button == QMessageBox.Yes:
                return self.write()
            elif button == QMessageBox.No:
                return True
            else:
                # Cancelled
                return False
        elif force_save:
            return self.write()
        else:
            # pretend the user clicked No on the dialog
            return True
Ejemplo n.º 7
0
    def restart_kernel(self):
        """
        Restart the associanted kernel

        Took this code from the qtconsole project
        Licensed under the BSD license
        """
        message = _('Are you sure you want to restart the kernel?')
        buttons = QMessageBox.Yes | QMessageBox.No
        result = QMessageBox.question(self, _('Restart kernel?'),
                                      message, buttons)
        if result == QMessageBox.Yes:
            sw = self.shellwidget
            if sw.kernel_manager:
                try:
                    sw.kernel_manager.restart_kernel()
                except RuntimeError as e:
                    sw._append_plain_text(
                        _('Error restarting kernel: %s\n') % e,
                        before_prompt=True
                    )
                else:
                    sw._append_html(_("<br>Restarting kernel...\n<hr><br>"),
                        before_prompt=True,
                    )
            else:
                sw._append_plain_text(
                    _('Cannot restart a kernel not started by Spyder\n'),
                    before_prompt=True
                )
Ejemplo n.º 8
0
 def _offer_overwriting_gui():
     """
     Offers up a overwriting QMessageBox giving the option to overwrite a project, and returns the reply.
     :return: QMessaageBox.Yes or QMessageBox.No; The value is the value selected by the user.
     """
     return QMessageBox.question(None, "Overwrite project?",
                                 "Would you like to overwrite the selected project?",
                                 QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
Ejemplo n.º 9
0
    def send_report(self, title, body, application_log=None):
        _logger().debug('sending bug report on github\ntitle=%s\nbody=%s',
                        title, body)

        # Credentials
        credentials = self.get_user_credentials()
        username = credentials['username']
        password = credentials['password']
        remember = credentials['remember']
        token = credentials['token']
        remember_token = credentials['remember_token']

        if username is None and password is None and token is None:
            return False
        _logger().debug('got user credentials')

        # upload log file as a gist
        if application_log:
            url = self.upload_log_file(application_log)
            body += '\nApplication log: %s' % url
        try:
            if token:
                gh = github.GitHub(access_token=token)
            else:
                gh = github.GitHub(username=username, password=password)
            repo = gh.repos(self.gh_owner)(self.gh_repo)
            ret = repo.issues.post(title=title, body=body)
        except github.ApiError as e:
            _logger().warning('Failed to send bug report on Github. '
                              'response=%r', e.response)
            # invalid credentials
            if e.response.code == 401:
                if self._show_msgbox:
                    QMessageBox.warning(
                        self.parent_widget, _('Invalid credentials'),
                        _('Failed to create Github issue, '
                          'invalid credentials...'))
            else:
                # other issue
                if self._show_msgbox:
                    QMessageBox.warning(
                        self.parent_widget,
                        _('Failed to create issue'),
                        _('Failed to create Github issue. Error %d') %
                        e.response.code)
            return False
        else:
            issue_nbr = ret['number']
            if self._show_msgbox:
                ret = QMessageBox.question(
                    self.parent_widget, _('Issue created on Github'),
                    _('Issue successfully created. Would you like to open the '
                      'issue in your web browser?'))
            if ret in [QMessageBox.Yes, QMessageBox.Ok]:
                webbrowser.open(
                    'https://github.com/%s/%s/issues/%d' % (
                        self.gh_owner, self.gh_repo, issue_nbr))
            return True
Ejemplo n.º 10
0
 def _offer_save_message_box(self, parent):
     if self.prompt_save_on_close:
         return QMessageBox.question(parent, 'Unsaved Project',
                                     "The project is currently unsaved. Would you like to "
                                     "save before closing?",
                                     QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel,
                                     QMessageBox.Yes)
     else:
         return QMessageBox.No
Ejemplo n.º 11
0
    def _submit_to_github(self):
        """Action to take when pressing the submit button."""
        # Get reference to the main window
        if self.parent() is not None:
            if getattr(self.parent(), 'main', False):
                # This covers the case when the dialog is attached
                # to the internal console
                main = self.parent().main
            else:
                # Else the dialog is attached to the main window
                # directly
                main = self.parent()
        else:
            main = None

        # Getting description and traceback
        title = self.title.text()
        description = self.input_description.toPlainText()
        traceback = self.error_traceback[:-1]  # Remove last EOL

        # Render issue
        if main is not None:
            issue_text = main.render_issue(description=description,
                                           traceback=traceback)
        else:
            issue_text = description

        try:
            if main is None:
                org = 'ccordoba12'
            else:
                org = 'spyder-ide'
            github_backend = GithubBackend(org, 'spyder', parent_widget=main)
            github_report = github_backend.send_report(title, issue_text)
            if github_report:
                self.close()
        except Exception:
            ret = QMessageBox.question(
                      self, _('Error'),
                      _("An error occurred while trying to send the issue to "
                        "Github automatically. Would you like to open it "
                        "manually?<br><br>"
                        "If so, please make sure to paste your clipboard "
                        "into the issue report box that will appear in a new "
                        "browser tab before clicking <i>Submit</i> on that "
                        "page."))
            if ret in [QMessageBox.Yes, QMessageBox.Ok]:
                QApplication.clipboard().setText(issue_text)
                issue_body = (
                    " \n<!---   *** BEFORE SUBMITTING: PASTE CLIPBOARD HERE "
                    "TO COMPLETE YOUR REPORT ***   ---!>\n")
                if main is not None:
                    main.report_issue(body=issue_body, title=title,
                                      open_webpage=True)
                else:
                    pass
Ejemplo n.º 12
0
    def reset_namespace(self):
        """Resets the namespace by removing all names defined by the user"""

        reply = QMessageBox.question(
            self,
            _("Reset IPython namespace"),
            _("All user-defined variables will be removed." "<br>Are you sure you want to reset the namespace?"),
            QMessageBox.Yes | QMessageBox.No,
        )

        if reply == QMessageBox.Yes:
            self.execute("%reset -f")
Ejemplo n.º 13
0
 def _check_unsaved_comments(self):
     if self.textChangedAt is None:
         return #Nothing to be changed
     i = self.toolbar.source_select.currentIndex()
     i = self._index_hash(i)
     if self.textChangedAt == i:
         self.textChangedAt = None
         return #This is a refresh
     info = "Comments or flags changed but were not saved. Would you like to save them?"
     reply = QMessageBox.question(self, '', info, QMessageBox.Yes | QMessageBox.No)
     if reply == QMessageBox.Yes:
         self.update_comments(True)
     self.textChangedAt = None
Ejemplo n.º 14
0
    def reject(self):
        """ """
        if self.busy:
            answer = QMessageBox.question(
                self,
                'Quit Conda Manager?',
                'Conda is still busy.\n\nDo you want to quit?',
                buttons=QMessageBox.Yes | QMessageBox.No)

            if answer == QMessageBox.Yes:
                QDialog.reject(self)
                # Do some cleanup?
        else:
            QDialog.reject(self)
Ejemplo n.º 15
0
    def closing_plugin(self, cancelable=False):
        """Perform actions before parent main window is closed."""
        if self.busy:
            answer = QMessageBox.question(
                self,
                'Conda Manager',
                'Conda Manager is still busy.\n\nDo you want to quit?',
                buttons=QMessageBox.Yes | QMessageBox.No)

            if answer == QMessageBox.Yes:
                return True
            else:
                return False
        else:
            return True
Ejemplo n.º 16
0
    def closeEvent(self, event):
        """ """
        if self.packages.busy:
            answer = QMessageBox.question(
                self,
                'Quit Conda Manager?',
                'Conda is still busy.\n\nDo you want to quit?',
                buttons=QMessageBox.Yes | QMessageBox.No)

            if answer == QMessageBox.Yes:
                QMainWindow.closeEvent(self, event)
                # Do some cleanup?
            else:
                event.ignore()
        else:
            QMainWindow.closeEvent(self, event)
Ejemplo n.º 17
0
    def close(self):
        while self.dirty is True:  # While avoids data loss, in case save operation is aborted
            if self.filename == "":
                text = "Save unsaved changes?"
            else:
                text = "Save %s?" % self.filename
 
            ans = QMessageBox.question(self, 'Save', text, QMessageBox.Yes, QMessageBox.Cancel, QMessageBox.No)
 
            if ans == QMessageBox.Cancel:
                return
            elif ans == QMessageBox.Yes:
                self.parent.actionSave(False)
            elif ans == QMessageBox.No:
                break
        self.tabWidget.removeTab(self.index())
Ejemplo n.º 18
0
    def restart_kernel(self):
        """
        Restart the associated kernel.

        Took this code from the qtconsole project
        Licensed under the BSD license
        """
        sw = self.shellwidget

        if not running_under_pytest() and self.ask_before_restart:
            message = _('Are you sure you want to restart the kernel?')
            buttons = QMessageBox.Yes | QMessageBox.No
            result = QMessageBox.question(self, _('Restart kernel?'),
                                          message, buttons)
        else:
            result = None

        if (result == QMessageBox.Yes or
                running_under_pytest() or
                not self.ask_before_restart):
            if sw.kernel_manager:
                if self.infowidget.isVisible():
                    self.infowidget.hide()
                    sw.show()
                try:
                    sw.kernel_manager.restart_kernel(
                        stderr=self.stderr_handle)
                except RuntimeError as e:
                    sw._append_plain_text(
                        _('Error restarting kernel: %s\n') % e,
                        before_prompt=True
                    )
                else:
                    # For issue 6235.  IPython was changing the setting of
                    # %colors on windows by assuming it was using a dark
                    # background.  This corrects it based on the scheme.
                    self.set_color_scheme(sw.syntax_style)
                    sw._append_html(_("<br>Restarting kernel...\n<hr><br>"),
                                    before_prompt=False)
            else:
                sw._append_plain_text(
                    _('Cannot restart a kernel not started by Spyder\n'),
                    before_prompt=True
                )
Ejemplo n.º 19
0
 def path_selection_changed(self):
     """Handles when the current index of the combobox changes."""
     idx = self.currentIndex()
     if idx == SELECT_OTHER:
         external_path = self.select_directory()
         if len(external_path) > 0:
             self.add_external_path(external_path)
             self.setCurrentIndex(self.count() - 1)
         else:
             self.setCurrentIndex(CWD)
     elif idx == CLEAR_LIST:
         reply = QMessageBox.question(
                 self, _("Clear other directories"),
                 _("Do you want to clear the list of other directories?"),
                 QMessageBox.Yes | QMessageBox.No)
         if reply == QMessageBox.Yes:
             self.clear_external_paths()
         self.setCurrentIndex(CWD)
     elif idx >= EXTERNAL_PATHS:
         self.external_path = to_text_string(self.itemText(idx))
Ejemplo n.º 20
0
 def add_path(self):
     self.redirect_stdio.emit(False)
     directory = getexistingdirectory(self, _("Select directory"),
                                      self.last_path)
     self.redirect_stdio.emit(True)
     if directory:
         directory = osp.abspath(directory)
         self.last_path = directory
         if directory in self.pathlist:
             answer = QMessageBox.question(self, _("Add path"),
                 _("This directory is already included in Spyder path "
                         "list.<br>Do you want to move it to the top of "
                         "the list?"),
                 QMessageBox.Yes | QMessageBox.No)
             if answer == QMessageBox.Yes:
                 self.pathlist.remove(directory)
             else:
                 return
         self.pathlist.insert(0, directory)
         self.update_list()
Ejemplo n.º 21
0
    def save_if_required(self, confirm=True):
        """Asks the user if the contents should be saved.

        :param confirm: If True then show a confirmation dialog first to check we should save
        :returns: True if either saving was successful or no save was requested. Returns False if
        the operation should be cancelled
        """
        if confirm:
            button = QMessageBox.question(self.editor, "",
                                          "Save changes to document before closing?",
                                          buttons=(QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel),
                                          defaultButton=QMessageBox.Cancel)
            if button == QMessageBox.Yes:
                return self.write()
            elif button == QMessageBox.No:
                return True
            else:
                # Cancelled
                return False
        else:
            return self.write()
Ejemplo n.º 22
0
    def main(self):
        """
        Main metod that will take input from the user, make a
        MOSViz Table and save it to a file. It will use the information
        in the headers of the spectra files to fill in rows of the table.
        If the user has cutout, it will look for an image file with the
        corresponding object name and add it to the Table.
        """
        success = self.verify_input()
        if not success:
            self.statusBar().showMessage("Input error")
            return

        self.generate_table_button.setDisabled(True)
        self.statusBar().showMessage("Making Table")
        QApplication.processEvents()

        output_path = os.path.join(self.save_file_dir, self.save_file_name)

        source_catalog = nirspec_table_generator(self.spec_path,
                                                 cutout_path=self.cutout_path,
                                                 output_path=output_path)

        self.statusBar().showMessage("DONE!")

        info = QMessageBox.information(self, "Status", "Catalog saved at:\n"+output_path)

        if self.session is not None:
            usr_ans = QMessageBox.question(self, '',
                                           "Would you like to open {}?".format(self.save_file_name),
                                           QMessageBox.Yes | QMessageBox.No)

            if usr_ans == QMessageBox.Yes:
                self.hide()
                data = load_data(output_path)
                self.session.data_collection.append(data)
                self.session.application.new_data_viewer(MOSVizViewer, data=self.session.data_collection[-1])

        self.close()
        return
Ejemplo n.º 23
0
 def add_path(self):
     self.redirect_stdio.emit(False)
     directory = getexistingdirectory(self, _("Select directory"),
                                      self.last_path)
     self.redirect_stdio.emit(True)
     if directory:
         is_unicode = False
         if PY2:
             try:
                 directory.decode('ascii')
             except UnicodeEncodeError:
                 is_unicode = True
             if is_unicode:
                 QMessageBox.warning(self, _("Add path"),
                                     _("You are using Python 2 and the path"
                                       " selected has Unicode characters. "
                                       "The new path will not be added."),
                                     QMessageBox.Ok)
                 return
         directory = osp.abspath(directory)
         self.last_path = directory
         if directory in self.pathlist:
             item = self.listwidget.findItems(directory, Qt.MatchExactly)[0]
             item.setCheckState(Qt.Checked)
             answer = QMessageBox.question(
                         self, _("Add path"),
                         _("This directory is already included in Spyder "
                           "path list.<br>Do you want to move it to the "
                           "top of the list?"),
                         QMessageBox.Yes | QMessageBox.No)
             if answer == QMessageBox.Yes:
                 self.pathlist.remove(directory)
             else:
                 return
         self.pathlist.insert(0, directory)
         self.update_list()
Ejemplo n.º 24
0
 def process_files(self):
     '''
     Creates the output content.
     '''
     self.__preferences.set(BEQ_CONFIG_FILE, self.configFile.text())
     self.__preferences.set(BEQ_MERGE_DIR, self.outputDirectory.text())
     self.__preferences.set(BEQ_MINIDSP_TYPE, self.dspType.currentText())
     self.__preferences.set(BEQ_EXTRA_DIR, self.userSourceDir.text())
     selected_channels = [
         item.text() for item in self.outputChannels.selectedItems()
     ]
     self.__preferences.set(BEQ_OUTPUT_CHANNELS,
                            "|".join(selected_channels))
     if self.outputMode.isVisible():
         self.__preferences.set(BEQ_OUTPUT_MODE,
                                self.outputMode.currentText())
     if self.__clear_output_directory():
         self.filesProcessed.setValue(0)
         optimise_filters = False
         dsp_type = DspType.parse(self.dspType.currentText())
         should_process = True
         if dsp_type.is_minidsp and dsp_type.is_fixed_point_hardware():
             result = QMessageBox.question(
                 self, 'Are you feeling lucky?',
                 f"Do you want to automatically optimise filters to fit in the 6 biquad limit? \n\n"
                 f"Note this feature is experimental. \n"
                 f"You are strongly encouraged to review the generated filters to ensure they are safe to use.\n"
                 f"USE AT YOUR OWN RISK!\n\n"
                 f"Are you sure you want to continue?",
                 QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
             optimise_filters = result == QMessageBox.Yes
         elif dsp_type.is_experimental:
             result = QMessageBox.question(
                 self, 'Generate HTP-1 Config Files?',
                 f"Support for HTP-1 config files is experimental and currently untested on an actual device. \n\n"
                 f"USE AT YOUR OWN RISK!\n\n"
                 f"Are you sure you want to continue?",
                 QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
             should_process = result == QMessageBox.Yes
         if should_process:
             self.__start_spinning()
             self.errors.clear()
             self.errors.setEnabled(False)
             self.copyErrorsButton.setEnabled(False)
             self.optimised.clear()
             self.optimised.setEnabled(False)
             self.copyOptimisedButton.setEnabled(False)
             self.optimised.setVisible(optimise_filters)
             self.copyOptimisedButton.setVisible(optimise_filters)
             self.optimisedLabel.setVisible(optimise_filters)
             in_out_split = None
             if self.outputMode.isVisible(
             ) and not self.outputChannels.isVisible():
                 import re
                 m = re.search('Input ([1-9]) / Output ([1-9])',
                               self.outputMode.currentText())
                 if m:
                     in_out_split = (m.group(1), m.group(2))
             QThreadPool.globalInstance().start(
                 XmlProcessor(self.__beq_dir, self.userSourceDir.text(),
                              self.outputDirectory.text(),
                              self.configFile.text(), dsp_type,
                              self.__on_file_fail, self.__on_file_ok,
                              self.__on_complete, self.__on_optimised,
                              optimise_filters, selected_channels,
                              in_out_split))
Ejemplo n.º 25
0
    def main(self):
        """
        Construct a catalog and make cutouts.
        """

        success = self.verify_input()
        if not success:
            self.statusBar().showMessage("Please fill in all fields")
            return

        # self.start_button.setText("Abort")
        # self.start_button.clicked.disconnect()
        # self.start_button.clicked.connect(self.abort)

        # temporary fix for non-existing abort functionality.
        self.start_button.setText("Working...")
        self.start_button.setEnabled(False)

        self.statusBar().showMessage("Making a list of files")
        QApplication.processEvents()

        t = self.make_catalog_table()

        #Change working path to save path
        cwd = os.getcwd()
        os.chdir(self.save_path)
        self.statusBar().showMessage("Making catalog")

        programName, file_extension = os.path.splitext(self.img_path)
        programName = os.path.basename(programName)

        #Make cutouts using info in catalog.
        self.statusBar().showMessage("Making cutouts")
        fits_cutouts, success_counter, success_table = go_make_cutouts(
            t,
            self.img_path,
            programName,
            output_file_format=self.output_file_format,
            output_dir_format=self.output_dir_format,
            clobber=True,
            apply_rotation=True,
            report=self.report)

        if self.kill:
            self.kill = False
            self.progress_bar.reset()
            self.statusBar().showMessage("Waiting for user input")
            return

        self.statusBar().showMessage("DONE!")
        directory = self.output_dir_format.format(programName)
        output_path = os.path.abspath(os.path.join(self.save_path, directory))

        #Give notice to user on status.
        string = "Cutouts were made for %s out of %s files\n\nSaved at: %s" % (
            success_counter, len(t), output_path)

        #If some spectra files do not have a cutout, a list of their names will be saved to
        # 'skipped_cutout_files.txt' in the save dir as the MOSViz Table file.
        if success_counter != len(t):
            self.write_skipped(t)
            string += "\n\nA list of spectra files"
            string += "without cutouts is saved in"
            string += "'skipped_cutout_files.txt'"
            string += "\n\nSaved at: %s" % os.path.join(
                self.save_path, "skipped_cutout_files.txt")

        info = QMessageBox.information(self, "Status:", string)

        #Change back dir.
        os.chdir(cwd)

        usr_ans = QMessageBox.question(
            self, '',
            "Would you like to load all generated cutouts into glue?",
            QMessageBox.Yes | QMessageBox.No)

        if usr_ans == QMessageBox.Yes:
            os.chdir(self.save_path)
            data = []
            for i, flag in enumerate(success_table):
                if flag:
                    path = self.output_dir_format.format(programName)
                    this_id = t["id"][i]
                    fname = os.path.join(
                        path,
                        self.output_file_format.format(this_id, programName))
                    data.append(load_data(fname))
            self.session.data_collection.merge(*data,
                                               label="%s_Cutouts" %
                                               programName)
            os.chdir(cwd)

        self.close()
        return
Ejemplo n.º 26
0
 def ask_before_close(self):
     reply = QMessageBox.question(self, self.presenter.ASK_BEFORE_CLOSE_TITLE,
                                  self.presenter.ASK_BEFORE_CLOSE_MESSAGE, QMessageBox.Yes, QMessageBox.No)
     return True if reply == QMessageBox.Yes else False
Ejemplo n.º 27
0
    def verify_input(self):
        """
        Process information in the input boxes.
        Checks if user inputs are functional.

        Returns
        -------
        success : bool
            True if no input errors, False otherwise.

        """
        self.statusBar().showMessage("Reading input")

        success = True
        self.spec_path = self.spectra_user_input.text()
        self.save_file_name = self.filename_user_input.text()

        if self.spec_path == "":
            self.spectra_user_input.setStyleSheet("background-color: rgba(255, 0, 0, 128);")
            success = False
        else:
            self.spectra_user_input.setStyleSheet("")

        if self.save_file_name == "" or "/" in self.save_file_name or "\\" in self.save_file_name:
            self.filename_user_input.setStyleSheet("background-color: rgba(255, 0, 0, 128);")
            success = False
        else:
            self.filename_user_input.setStyleSheet("")

        if self.add_cutout_radio.isChecked():
            self.cutout_path = self.cutout_path_display.text()
            if self.cutout_path == "":
                self.cutout_path_display.setStyleSheet("background-color: rgba(255, 0, 0, 128);")
                success = False
            else:
                self.cutout_path_display.setStyleSheet("background-color: rgba(255, 255, 255, 0);")

        if success:
            if not os.path.isdir(self.spec_path):
                info = QMessageBox.information(self, "Error", "Broken path:\n\n"+self.spec_path)
                self.spectra_user_input.setStyleSheet("background-color: rgba(255, 0, 0, 128);")
                success = False
            else:
                if not self.custom_save_path:
                    self.save_file_dir = self.spec_path

            if self.add_cutout_radio.isChecked():
                if not os.path.isdir(self.cutout_path):
                    info = QMessageBox.information(self, "Error", "Broken path:\n\n"+self.cutout_path)
                    self.cutout_path_display.setStyleSheet("background-color: rgba(255, 0, 0, 128);")
                    success = False

                if (not os.path.samefile(self.spec_path,
                    os.path.dirname(self.cutout_path)) and
                    not self.abs_path and not self.cutout_path):
                    usr_ans = QMessageBox.question(self, "Path Warning",
                        "The cutout directory is not in the spectra directory, "
                        "this will generate a MOSViz Table "
                        "that is unique to your computer "
                        "(you will not be able to share it). Continue?",
                        QMessageBox.Yes | QMessageBox.No)

                    if usr_ans == QMessageBox.Yes:
                        self.abs_path = True
                    else:
                        success = False
        return success
Ejemplo n.º 28
0
    def __synthesis(self) -> None:
        """Start synthesis."""
        # Check if the amount of the target points are same
        length = -1
        for path in self.path.values():
            if length < 0:
                length = len(path)
            if len(path) != length:
                QMessageBox.warning(
                    self, "Target Error",
                    "The length of target paths should be the same.")
                return
        # Get the algorithm type
        for option, button in self.algorithm_options.items():
            if button.isChecked():
                algorithm = option
                break
        else:
            raise ValueError("no option")
        mech = deepcopy(self.mech)
        mech['shape_only'] = self.shape_only_option.isChecked()
        if mech['shape_only']:
            if QMessageBox.question(
                    self, "Elliptical Fourier Descriptor",
                    "An even distribution will make the comparison more accurate.\n"
                    "Do you make sure yet?", QMessageBox.Yes | QMessageBox.No,
                    QMessageBox.Yes) == QMessageBox.No:
                return
        mech['expression'] = parse_vpoints(mech.pop('expression', []))
        mech['target'] = deepcopy(self.path)

        def name_in_table(target_name: str) -> int:
            """Find a target_name and return the row from the table."""
            for r in range(self.parameter_list.rowCount()):
                if self.parameter_list.item(r, 0).text() == target_name:
                    return r
            return -1

        placement: Dict[int, Tuple[float, float, float]] = mech['placement']
        for name in placement:
            row = name_in_table(f"P{name}")
            placement[name] = (
                self.parameter_list.cellWidget(row, 2).value(),
                self.parameter_list.cellWidget(row, 3).value(),
                self.parameter_list.cellWidget(row, 4).value(),
            )
        # Start progress dialog
        dlg = ProgressDialog(algorithm, mech, self.alg_options, self)
        dlg.show()
        if not dlg.exec_():
            dlg.deleteLater()
            return
        mechanisms_plot: List[Mapping[str, Any]] = []
        for data in dlg.mechanisms:
            mechanisms_plot.append({
                'time_fitness': data.pop('time_fitness'),
                'algorithm': data['algorithm'],
            })
            self.mechanism_data.append(data)
            self.__add_result(data)
        self.__set_time(dlg.time_spend)
        self.project_no_save()
        dlg.deleteLater()
        dlg = ChartDialog("Convergence Data", mechanisms_plot, self)
        dlg.show()
        dlg.exec_()
        dlg.deleteLater()
Ejemplo n.º 29
0
    def add_path(self, directory=None):
        """
        Add path to list widget.

        If `directory` is provided, the folder dialog is overriden.
        """
        if directory is None:
            self.redirect_stdio.emit(False)
            directory = getexistingdirectory(self, _("Select directory"),
                                             self.last_path)
            self.redirect_stdio.emit(True)

        if PY2:
            is_unicode = False
            try:
                directory.decode('ascii')
            except (UnicodeEncodeError, UnicodeDecodeError):
                is_unicode = True

            if is_unicode:
                QMessageBox.warning(
                    self, _("Add path"),
                    _("You are using Python 2 and the selected path has "
                      "Unicode characters."
                      "<br> "
                      "Therefore, this path will not be added."),
                    QMessageBox.Ok)
                return

        directory = osp.abspath(directory)
        self.last_path = directory

        if directory in self.get_path_dict():
            item = self.listwidget.findItems(directory, Qt.MatchExactly)[0]
            item.setCheckState(Qt.Checked)
            answer = QMessageBox.question(
                self, _("Add path"),
                _("This directory is already included in the list."
                  "<br> "
                  "Do you want to move it to the top of it?"),
                QMessageBox.Yes | QMessageBox.No)

            if answer == QMessageBox.Yes:
                item = self.listwidget.takeItem(self.listwidget.row(item))
                self.listwidget.insertItem(0, item)
                self.listwidget.setCurrentRow(0)
        else:
            if self.check_path(directory):
                item = self._create_item(directory)
                self.listwidget.insertItem(0, item)
                self.listwidget.setCurrentRow(0)
            else:
                answer = QMessageBox.warning(
                    self, _("Add path"),
                    _("This directory cannot be added to the path!"
                      "<br><br>"
                      "If you want to set a different Python interpreter, "
                      "please go to <tt>Preferences > Main interpreter</tt>"
                      "."), QMessageBox.Ok)

        self.refresh()
Ejemplo n.º 30
0
    def main(self):
        """
        Construct a catalog and make cutouts.
        """

        success = self.verify_input()
        if not success:
            self.statusBar().showMessage("Please fill in all fields")
            return

        # self.start_button.setText("Abort")
        # self.start_button.clicked.disconnect()
        # self.start_button.clicked.connect(self.abort)

        # temporary fix for non-existing abort functionality.
        self.start_button.setText("Working...")
        self.start_button.setEnabled(False)

        self.statusBar().showMessage("Making a list of files")
        QApplication.processEvents()

        t = self.make_catalog_table()

        #Change working path to save path
        cwd = os.getcwd()
        os.chdir(self.save_path)
        self.statusBar().showMessage("Making catalog")

        programName, file_extension = os.path.splitext(self.img_path)
        programName = os.path.basename(programName)

        #Make cutouts using info in catalog.
        self.statusBar().showMessage("Making cutouts")
        fits_cutouts, success_counter, success_table = go_make_cutouts(
            t, self.img_path, programName,
            output_file_format=self.output_file_format,
            output_dir_format=self.output_dir_format, clobber=True,
            apply_rotation=True, report=self.report)

        if self.kill:
            self.kill = False
            self.progress_bar.reset()
            self.statusBar().showMessage("Waiting for user input")
            return

        self.statusBar().showMessage("DONE!")
        directory = self.output_dir_format.format(programName)
        output_path = os.path.abspath(
            os.path.join(self.save_path, directory))

        #Give notice to user on status.
        string = "Cutouts were made for %s out of %s files\n\nSaved at: %s" %(
            success_counter, len(t), output_path)

        #If some spectra files do not have a cutout, a list of their names will be saved to
        # 'skipped_cutout_files.txt' in the save dir as the MOSViz Table file.
        if success_counter != len(t):
            self.write_skipped(t, success_table)
            string += "\n\nA list of spectra files"
            string += "without cutouts is saved in"
            string += "'skipped_cutout_files.txt'"
            string += "\n\nSaved at: %s" % os.path.join(
                self.save_path,
                "skipped_cutout_files.txt")

        info = QMessageBox.information(self, "Status:", string)

        #Change back dir.
        os.chdir(cwd)

        usr_ans = QMessageBox.question(self, '',
            "Would you like to load all generated cutouts into glue?",
            QMessageBox.Yes | QMessageBox.No)

        if usr_ans == QMessageBox.Yes:
            os.chdir(self.save_path)
            data = []
            for i, flag in enumerate(success_table):
                if flag:
                    path = self.output_dir_format.format(programName)
                    this_id = t["id"][i]
                    fname = os.path.join(
                        path, self.output_file_format.format(this_id, programName))
                    data.append(load_data(fname))
            self.session.data_collection.merge(*data, label="%s_Cutouts" %programName)
            os.chdir(cwd)

        self.close()
        return
Ejemplo n.º 31
0
def openssh_tunnel(self, lport, rport, server, remoteip='127.0.0.1',
                   keyfile=None, password=None, timeout=0.4):
    """
    We decided to replace pyzmq's openssh_tunnel method to work around
    issue https://github.com/zeromq/pyzmq/issues/589 which was solved
    in pyzmq https://github.com/zeromq/pyzmq/pull/615
    """
    ssh = "ssh "
    if keyfile:
        ssh += "-i " + keyfile

    if ':' in server:
        server, port = server.split(':')
        ssh += " -p %s" % port

    cmd = "%s -O check %s" % (ssh, server)
    (output, exitstatus) = pexpect.run(cmd, withexitstatus=True)
    if not exitstatus:
        pid = int(output[output.find("(pid=")+5:output.find(")")])
        cmd = "%s -O forward -L 127.0.0.1:%i:%s:%i %s" % (
            ssh, lport, remoteip, rport, server)
        (output, exitstatus) = pexpect.run(cmd, withexitstatus=True)
        if not exitstatus:
            atexit.register(_stop_tunnel, cmd.replace("-O forward",
                                                      "-O cancel",
                                                      1))
            return pid
    cmd = "%s -f -S none -L 127.0.0.1:%i:%s:%i %s sleep %i" % (
                                  ssh, lport, remoteip, rport, server, timeout)

    # pop SSH_ASKPASS from env
    env = os.environ.copy()
    env.pop('SSH_ASKPASS', None)

    ssh_newkey = 'Are you sure you want to continue connecting'
    tunnel = pexpect.spawn(cmd, env=env)
    failed = False
    while True:
        try:
            i = tunnel.expect([ssh_newkey, '[Pp]assword:'], timeout=.1)
            if i == 0:
                host = server.split('@')[-1]
                question = _("The authenticity of host <b>%s</b> can't be "
                             "established. Are you sure you want to continue "
                             "connecting?") % host
                reply = QMessageBox.question(self, _('Warning'), question,
                                             QMessageBox.Yes | QMessageBox.No,
                                             QMessageBox.No)
                if reply == QMessageBox.Yes:
                    tunnel.sendline('yes')
                    continue
                else:
                    tunnel.sendline('no')
                    raise RuntimeError(
                       _("The authenticity of the host can't be established"))
            if i == 1 and password is not None:
                tunnel.sendline(password)
        except pexpect.TIMEOUT:
            continue
        except pexpect.EOF:
            if tunnel.exitstatus:
                raise RuntimeError(_("Tunnel '%s' failed to start") % cmd)
            else:
                return tunnel.pid
        else:
            if failed or password is None:
                raise RuntimeError(_("Could not connect to remote host"))
                # TODO: Use this block when pyzmq bug #620 is fixed
                # # Prompt a passphrase dialog to the user for a second attempt
                # password, ok = QInputDialog.getText(self, _('Password'),
                #             _('Enter password for: ') + server,
                #             echo=QLineEdit.Password)
                # if ok is False:
                #      raise RuntimeError('Could not connect to remote host.')
            tunnel.sendline(password)
            failed = True
Ejemplo n.º 32
0
    def main(self):
        """
        Main function that uses information provided
        by the user and in the headers of spectra files
        to construct a catalog and make cutouts.
        """

        success = self.verify_input()
        if not success:
            self.statusBar().showMessage("Please fill in all fields")
            return

        self.start_button.setText("Abort")
        self.start_button.clicked.disconnect()
        self.start_button.clicked.connect(self.abort)

        self.statusBar().showMessage("Making a list of files")
        QApplication.processEvents()

        fb, target_names = self.get_file_base()
        if len(fb) == 0:
            return

        #Change working path to save path
        cwd = os.getcwd()
        os.chdir(self.save_path)
        self.statusBar().showMessage("Making catalog")

        programName = os.path.basename(fb[0]).split("_")[0]
        t, skipped = self.make_catalog_table(fb, target_names, programName)
        if t is None:
            raise Exception(
                "All input spectra files have bad WCS and/or headers.")

        #Make cutouts using info in catalog.
        self.statusBar().showMessage("Making cutouts")
        success_counter, success_table = self.make_cutouts(t,
                                                           self.img_path,
                                                           programName,
                                                           clobber=True,
                                                           apply_rotation=True)

        if self.kill:
            self.kill = False
            self.progress_bar.reset()
            self.statusBar().showMessage("Waiting for user input")
            return

        self.statusBar().showMessage("DONE!")

        #If some spectra files do not have a cutout, a list of their names will be saved to
        # 'skipped_cutout_files.txt' in the save dir as the MOSViz Table file.
        directory = self.output_dir_format.format(programName)
        output_path = os.path.abspath(os.path.join(self.save_path, directory))

        #Give notice to user on status.
        string = "Cutouts were made for %s out of %s files\n\nSaved at: %s" % (
            success_counter, len(fb), output_path)

        if success_counter != len(fb):
            self.write_skipped(t, success_table, skipped)
            string += "\n\nA list of spectra files"
            string += "without cutouts is saved in"
            string += "'skipped_cutout_files.txt'"
            string += "\n\nSaved at: %s" % os.path.join(
                self.save_path, "skipped_cutout_files.txt")

        info = QMessageBox.information(self, "Status:", string)

        #Change back dir.
        os.chdir(cwd)

        usr_ans = QMessageBox.question(
            self, '',
            "Would you like to load all generated cutouts into glue?",
            QMessageBox.Yes | QMessageBox.No)

        if usr_ans == QMessageBox.Yes:
            os.chdir(self.save_path)
            data = []
            for i, flag in enumerate(success_table):
                if flag:
                    path = self.output_dir_format.format(programName)
                    this_id = t["id"][i]
                    fname = os.path.join(
                        path,
                        self.output_file_format.format(this_id, programName))
                    data.append(load_data(fname))
            self.session.data_collection.merge(*data,
                                               label="%s_Cutouts" %
                                               programName)
            os.chdir(cwd)

        if self.tableGen and self.TableGen is not None:
            self.TableGen.cutout_response(output_path, self.custom_save_path)

        self.close()
        return
Ejemplo n.º 33
0
    def start(self,
              fname,
              wdir=None,
              args='',
              interact=False,
              debug=False,
              python=True,
              python_args='',
              post_mortem=True):
        """
        Start new console

        fname:
          string: filename of script to run
          None: open an interpreter
        wdir: working directory
        args: command line options of the Python script
        interact: inspect script interactively after its execution
        debug: run pdb
        python: True: Python interpreter, False: terminal
        python_args: additionnal Python interpreter command line options
                   (option "-u" is mandatory, see widgets.externalshell package)
        """
        # Note: fname is None <=> Python interpreter
        if fname is not None and not is_text_string(fname):
            fname = to_text_string(fname)
        if wdir is not None and not is_text_string(wdir):
            wdir = to_text_string(wdir)

        if fname is not None and fname in self.filenames:
            index = self.filenames.index(fname)
            if self.get_option('single_tab'):
                old_shell = self.shellwidgets[index]
                if old_shell.is_running():
                    runconfig = get_run_configuration(fname)
                    if runconfig is None or runconfig.show_kill_warning:
                        if PYQT5:
                            answer = QMessageBox.question(
                                self, self.get_plugin_title(),
                                _("%s is already running in a separate process.\n"
                                  "Do you want to kill the process before starting "
                                  "a new one?") % osp.basename(fname),
                                QMessageBox.Yes | QMessageBox.Cancel)
                        else:
                            mb = QMessageBox(self)
                            answer = mb.question(
                                mb, self.get_plugin_title(),
                                _("%s is already running in a separate process.\n"
                                  "Do you want to kill the process before starting "
                                  "a new one?") % osp.basename(fname),
                                QMessageBox.Yes | QMessageBox.Cancel)
                    else:
                        answer = QMessageBox.Yes

                    if answer == QMessageBox.Yes:
                        old_shell.process.kill()
                        old_shell.process.waitForFinished()
                    else:
                        return
                self.close_console(index)
        else:
            index = self.tabwidget.count()

        # Creating a new external shell
        pythonpath = self.main.get_spyder_pythonpath()
        light_background = self.get_option('light_background')
        show_elapsed_time = self.get_option('show_elapsed_time')
        if python:
            if CONF.get('main_interpreter', 'default'):
                pythonexecutable = get_python_executable()
                external_interpreter = False
            else:
                pythonexecutable = CONF.get('main_interpreter', 'executable')
                external_interpreter = True
            if self.get_option('pythonstartup/default'):
                pythonstartup = None
            else:
                pythonstartup = self.get_option('pythonstartup', None)
            monitor_enabled = self.get_option('monitor/enabled')
            mpl_backend = self.get_option('matplotlib/backend/value')
            ets_backend = self.get_option('ets_backend')
            qt_api = self.get_option('qt/api')
            if qt_api not in ('pyqt', 'pyside', 'pyqt5'):
                qt_api = None
            merge_output_channels = self.get_option('merge_output_channels')
            colorize_sys_stderr = self.get_option('colorize_sys_stderr')
            umr_enabled = CONF.get('main_interpreter', 'umr/enabled')
            umr_namelist = CONF.get('main_interpreter', 'umr/namelist')
            umr_verbose = CONF.get('main_interpreter', 'umr/verbose')

            sa_settings = None
            shellwidget = ExternalPythonShell(
                self,
                fname,
                wdir,
                interact,
                debug,
                post_mortem=post_mortem,
                path=pythonpath,
                python_args=python_args,
                arguments=args,
                stand_alone=sa_settings,
                pythonstartup=pythonstartup,
                pythonexecutable=pythonexecutable,
                external_interpreter=external_interpreter,
                umr_enabled=umr_enabled,
                umr_namelist=umr_namelist,
                umr_verbose=umr_verbose,
                ets_backend=ets_backend,
                monitor_enabled=monitor_enabled,
                mpl_backend=mpl_backend,
                qt_api=qt_api,
                merge_output_channels=merge_output_channels,
                colorize_sys_stderr=colorize_sys_stderr,
                light_background=light_background,
                menu_actions=self.menu_actions,
                show_buttons_inside=False,
                show_elapsed_time=show_elapsed_time)
            shellwidget.sig_pdb.connect(
                lambda fname, lineno, shellwidget=shellwidget: self.
                pdb_has_stopped(fname, lineno, shellwidget))
            self.register_widget_shortcuts(shellwidget.shell)
        else:
            if os.name == 'posix':
                cmd = 'gnome-terminal'
                args = []
                if programs.is_program_installed(cmd):
                    if wdir:
                        args.extend(['--working-directory=%s' % wdir])
                    programs.run_program(cmd, args)
                    return
                cmd = 'konsole'
                if programs.is_program_installed(cmd):
                    if wdir:
                        args.extend(['--workdir', wdir])
                    programs.run_program(cmd, args)
                    return
            shellwidget = ExternalSystemShell(
                self,
                wdir,
                path=pythonpath,
                light_background=light_background,
                menu_actions=self.menu_actions,
                show_buttons_inside=False,
                show_elapsed_time=show_elapsed_time)

        # Code completion / calltips
        shellwidget.shell.setMaximumBlockCount(
            self.get_option('max_line_count'))
        shellwidget.shell.set_font(self.get_plugin_font())
        shellwidget.shell.toggle_wrap_mode(self.get_option('wrap'))
        shellwidget.shell.set_calltips(self.get_option('calltips'))
        shellwidget.shell.set_codecompletion_auto(
            self.get_option('codecompletion/auto'))
        shellwidget.shell.set_codecompletion_case(
            self.get_option('codecompletion/case_sensitive'))
        shellwidget.shell.set_codecompletion_enter(
            self.get_option('codecompletion/enter_key'))
        if python and self.help is not None:
            shellwidget.shell.set_help(self.help)
            shellwidget.shell.set_help_enabled(
                CONF.get('help', 'connect/python_console'))
        if self.historylog is not None:
            self.historylog.add_history(shellwidget.shell.history_filename)
            shellwidget.shell.append_to_history.connect(
                self.historylog.append_to_history)
            shellwidget.shell.go_to_error.connect(self.go_to_error)
            shellwidget.shell.focus_changed.connect(
                lambda: self.focus_changed.emit())
        if python:
            if self.main.editor is not None:
                shellwidget.open_file.connect(self.open_file_in_spyder)
            if fname is None:
                self.python_count += 1
                tab_name = "Python %d" % self.python_count
                tab_icon1 = ima.icon('python')
                tab_icon2 = ima.icon('python_t')
                self.filenames.insert(index, fname)
            else:
                self.filenames.insert(index, fname)
                tab_name = self.get_tab_text(fname)
                self.update_tabs_text()
                tab_icon1 = ima.icon('run')
                tab_icon2 = ima.icon('terminated')
        else:
            fname = id(shellwidget)
            if os.name == 'nt':
                tab_name = _("Command Window")
            else:
                tab_name = _("Terminal")
            self.terminal_count += 1
            tab_name += (" %d" % self.terminal_count)
            tab_icon1 = ima.icon('cmdprompt')
            tab_icon2 = ima.icon('cmdprompt_t')
            self.filenames.insert(index, fname)
        self.shellwidgets.insert(index, shellwidget)
        self.icons.insert(index, (tab_icon1, tab_icon2))
        if index is None:
            index = self.tabwidget.addTab(shellwidget, tab_name)
        else:
            self.tabwidget.insertTab(index, shellwidget, tab_name)

        shellwidget.started.connect(
            lambda sid=id(shellwidget): self.process_started(sid))
        shellwidget.sig_finished.connect(
            lambda sid=id(shellwidget): self.process_finished(sid))
        self.find_widget.set_editor(shellwidget.shell)
        self.tabwidget.setTabToolTip(index, fname if wdir is None else wdir)
        self.tabwidget.setCurrentIndex(index)
        if self.dockwidget and not self.ismaximized:
            self.dockwidget.setVisible(True)
            self.dockwidget.raise_()

        shellwidget.set_icontext_visible(self.get_option('show_icontext'))

        # Start process and give focus to console
        shellwidget.start_shell()
Ejemplo n.º 34
0
    def save_result(self):
        if self.settings.image_path is not None and QMessageBox.Yes == QMessageBox.question(
                self, "Copy", "Copy name to clipboard?",
                QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes):
            clipboard = QGuiApplication.clipboard()
            clipboard.setText(
                os.path.splitext(os.path.basename(
                    self.settings.image_path))[0])

        if self.settings.segmentation is None or len(self.settings.sizes) == 1:
            QMessageBox.warning(self, "No components", "No components to save")
            return
        dial = SaveDialog(
            io_functions.save_components_dict,
            False,
            history=self.settings.get_path_history(),
            file_mode=QFileDialog.Directory,
        )
        dial.setDirectory(
            self.settings.get("io.save_components_directory",
                              str(Path.home())))
        dial.selectFile(
            os.path.splitext(os.path.basename(self.settings.image_path))[0])
        if not dial.exec_():
            return
        res = dial.get_result()
        potential_names = self.settings.get_file_names_for_save_result(
            res.save_destination)
        conflict = []
        for el in potential_names:
            if os.path.exists(el):
                conflict.append(el)
        if len(conflict) > 0:
            # TODO modify because of long lists
            conflict_str = "\n".join(conflict)
            if QMessageBox.No == QMessageBox.warning(
                    self,
                    "Overwrite",
                    f"Overwrite files:\n {conflict_str}",
                    QMessageBox.Yes | QMessageBox.No,
                    QMessageBox.No,
            ):
                self.save_result()
                return

        self.settings.set("io.save_components_directory",
                          os.path.dirname(str(res.save_destination)))
        self.settings.add_path_history(
            os.path.dirname(str(res.save_destination)))

        def exception_hook(exception):
            QMessageBox.critical(
                self, "Save error",
                f"Error on disc operation. Text: {exception}", QMessageBox.Ok)

        dial = ExecuteFunctionDialog(
            res.save_class.save,
            [
                res.save_destination,
                self.settings.get_project_info(), res.parameters
            ],
            text="Save components",
            exception_hook=exception_hook,
        )
        dial.exec()
Ejemplo n.º 35
0
    def import_data(self, filenames=None):
        """Import data from text file."""
        title = _("Import data")
        if filenames is None:
            if self.filename is None:
                basedir = getcwd()
            else:
                basedir = osp.dirname(self.filename)
            filenames, _selfilter = getopenfilenames(self, title, basedir,
                                                     iofunctions.load_filters)
            if not filenames:
                return
        elif is_text_string(filenames):
            filenames = [filenames]

        for filename in filenames:
            self.filename = to_text_string(filename)
            ext = osp.splitext(self.filename)[1].lower()

            if ext not in iofunctions.load_funcs:
                buttons = QMessageBox.Yes | QMessageBox.Cancel
                answer = QMessageBox.question(
                    self, title,
                    _("<b>Unsupported file extension '%s'</b><br><br>"
                      "Would you like to import it anyway "
                      "(by selecting a known file format)?") % ext, buttons)
                if answer == QMessageBox.Cancel:
                    return
                formats = list(iofunctions.load_extensions.keys())
                item, ok = QInputDialog.getItem(self, title,
                                                _('Open file as:'), formats, 0,
                                                False)
                if ok:
                    ext = iofunctions.load_extensions[to_text_string(item)]
                else:
                    return

            load_func = iofunctions.load_funcs[ext]

            # 'import_wizard' (self.setup_io)
            if is_text_string(load_func):
                # Import data with import wizard
                error_message = None
                try:
                    text, _encoding = encoding.read(self.filename)
                    base_name = osp.basename(self.filename)
                    editor = ImportWizard(
                        self,
                        text,
                        title=base_name,
                        varname=fix_reference_name(base_name))
                    if editor.exec_():
                        var_name, clip_data = editor.get_data()
                        self.set_value(var_name, clip_data)
                except Exception as error:
                    error_message = str(error)
            else:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                QApplication.processEvents()
                if self.is_ipyclient:
                    error_message = self.shellwidget.load_data(
                        self.filename, ext)
                    self.shellwidget._kernel_reply = None
                else:
                    error_message = monitor_load_globals(
                        self._get_sock(), self.filename, ext)
                QApplication.restoreOverrideCursor()
                QApplication.processEvents()

            if error_message is not None:
                QMessageBox.critical(
                    self, title,
                    _("<b>Unable to load '%s'</b>"
                      "<br><br>Error message:<br>%s") %
                    (self.filename, error_message))
            self.refresh_table()
Ejemplo n.º 36
0
    def verify_input(self):
        """
        Process information in the input boxes.
        Checks if user inputs are functional.

        Returns
        -------
        success : bool
            True if no input errors, False otherwise.

        """
        self.statusBar().showMessage("Reading input")

        success = True
        self.spec_path = self.spectra_user_input.text()
        self.save_file_name = self.filename_user_input.text()

        if self.spec_path == "":
            self.spectra_user_input.setStyleSheet(
                "background-color: rgba(255, 0, 0, 128);")
            success = False
        else:
            self.spectra_user_input.setStyleSheet("")

        if self.save_file_name == "" or "/" in self.save_file_name or "\\" in self.save_file_name:
            self.filename_user_input.setStyleSheet(
                "background-color: rgba(255, 0, 0, 128);")
            success = False
        else:
            self.filename_user_input.setStyleSheet("")

        if self.add_cutout_radio.isChecked():
            self.cutout_path = self.cutout_path_display.text()
            if self.cutout_path == "":
                self.cutout_path_display.setStyleSheet(
                    "background-color: rgba(255, 0, 0, 128);")
                success = False
            else:
                self.cutout_path_display.setStyleSheet(
                    "background-color: rgba(255, 255, 255, 0);")

        if success:
            if not os.path.isdir(self.spec_path):
                info = QMessageBox.information(
                    self, "Error", "Broken path:\n\n" + self.spec_path)
                self.spectra_user_input.setStyleSheet(
                    "background-color: rgba(255, 0, 0, 128);")
                success = False
            else:
                if not self.custom_save_path:
                    self.save_file_dir = self.spec_path

            if self.add_cutout_radio.isChecked():
                if not os.path.isdir(self.cutout_path):
                    info = QMessageBox.information(
                        self, "Error", "Broken path:\n\n" + self.cutout_path)
                    self.cutout_path_display.setStyleSheet(
                        "background-color: rgba(255, 0, 0, 128);")
                    success = False

                if (not os.path.samefile(self.spec_path,
                                         os.path.dirname(self.cutout_path))
                        and not self.abs_path and not self.cutout_path):
                    usr_ans = QMessageBox.question(
                        self, "Path Warning",
                        "The cutout directory is not in the spectra directory, "
                        "this will generate a MOSViz Table "
                        "that is unique to your computer "
                        "(you will not be able to share it). Continue?",
                        QMessageBox.Yes | QMessageBox.No)

                    if usr_ans == QMessageBox.Yes:
                        self.abs_path = True
                    else:
                        success = False
        return success
Ejemplo n.º 37
0
    def remove_rows(self, rows):
        """
        We just hide the row to delete things to prevent refreshing
        the window and changing which items have been expanded

        Parameters
        ----------
        rows : List[int]
            the trace on the data/form block

        form = [
            ['Geometry', None, [
                ('NodeID', 0, []),
                ('ElementID', 1, []),
                ('PropertyID', 2, []),
                ('MaterialID', 3, []),
                ('E', 4, []),
                ('Element Checks', None, [
                    ('ElementDim', 5, []),
                    ('Min Edge Length', 6, []),
                    ('Min Interior Angle', 7, []),
                    ('Max Interior Angle', 8, [])],
                 ),],
             ],
        ]

        # delete Geometry
        data[0] = ('Geometry', None, [...])
        >>> remove_rows([0])

        # delete MaterialID
        data[0][3] = ('MaterialID', 3, [])
        >>> remove_rows([0, 3])

        # delete ElementChecks
        data[0][5] = ('Element Checks', None, [...])
        >>> remove_rows([0, 5])

        # delete Min Edge Length
        data[0][5][1] = ('Min Edge Length', 6, [])
        >>> remove_rows([0, 5, 1])
        """
        # find the row the user wants to delete
        data = self.data
        for row in rows[:-1]:
            data = data[row][2]

        # we got our data block
        # now we need to get 1+ results
        last_row = rows[-1]
        cases_to_delete = get_many_cases(data[last_row])

        cases_to_delete = list(set(cases_to_delete) - self.cases_deleted)
        cases_to_delete.sort()
        if len(cases_to_delete) == 0:  # can this happen?
            # this happens when you cleared out a data block by
            # deleting to entries, but not the parent
            #
            # we'll just hide the row now
            msg = ''
            return
        elif len(cases_to_delete) == 1:
            msg = 'Are you sure you want to delete 1 result case load_case=%s' % cases_to_delete[
                0]
        else:
            msg = 'Are you sure you want to delete %s result cases %s' % (
                len(cases_to_delete), str(cases_to_delete))

        if msg:
            widget = QMessageBox()
            title = 'Delete Cases'
            result = QMessageBox.question(widget, title, msg,
                                          QMessageBox.Yes | QMessageBox.No,
                                          QMessageBox.No)

            if result != QMessageBox.Yes:
                return

            self.cases_deleted.update(set(cases_to_delete))
            self.on_delete_parent_cases(cases_to_delete)

        # hide the line the user wants to delete
        row = rows[-1]
        indexes = self.selectedIndexes()
        self.setRowHidden(row, indexes[-1].parent(), True)
        self.update()
Ejemplo n.º 38
0
    def main(self):
        """
        Main function that uses information provided
        by the user and in the headers of spectra files
        to construct a catalog and make cutouts.
        """
        success = self.verify_input()
        if not success:
            self.statusBar().showMessage("Please fill in all fields")
            return

        # self.start_button.setText("Abort")
        # self.start_button.clicked.disconnect()
        # self.start_button.clicked.connect(self.abort)

        # temporary fix for non-existing abort functionality.
        self.start_button.setText("Working...")
        self.start_button.setEnabled(False)

        self.statusBar().showMessage("Making a list of files")
        QApplication.processEvents()

        t = self.make_catalog_table()

        if t is None:
            raise Exception("Spectra files were not found.")

        # Make cutouts using info in catalog.
        self.statusBar().showMessage("Making cutouts")

        output_path = os.path.join(self.save_path, self.output_dir_format)

        fits_cutouts, success_counter, success_table = go_make_cutouts(
            t, self.img_path, "cutouts",
            output_file_format=self.output_file_format,
            output_dir_format=output_path,
            clobber=True,
            apply_rotation=True,
            report=self.report)

        self.statusBar().showMessage("DONE!")

        # Give notice to user on status.
        string = "Cutouts were made for %s out of %s files\n\nSaved at: %s" %(
            success_counter, len(t), output_path)

        # save a list of failed cutouts
        if success_counter != len(t):
            self.write_skipped(t, success_table)
            string += "\n\nA list of spectra files "
            string += "without cutouts is saved in "
            string += "'skipped_cutout_files.txt' "
            string += "\n\nSaved at: %s" %os.path.join(
                self.save_path,
                "skipped_cutout_files.txt")

        info = QMessageBox.information(self, "Status:", string)

        if success_counter == 0:
            usr_ans = QMessageBox.question(self, '',
                                           "Would you like to load all generated cutouts into glue?",
                                           QMessageBox.Yes | QMessageBox.No)

            if usr_ans == QMessageBox.Yes:
                data = []
                for i, flag in enumerate(success_table):
                    if flag:
                        path = output_path
                        this_id = t["id"][i]
                        fname = os.path.join(
                            path, self.output_file_format.format(this_id))
                        data.append(load_data(fname))
                self.session.data_collection.merge(*data, label=self.output_dir_format)

        if self.tableGen and self.TableGen is not None:
            self.TableGen.cutout_response(output_path, self.custom_save_path)

        self.close()
        return
Ejemplo n.º 39
0
 def ask_before_close(self):
     reply = QMessageBox.question(self,
                                  self.presenter.ASK_BEFORE_CLOSE_TITLE,
                                  self.presenter.ASK_BEFORE_CLOSE_MESSAGE,
                                  QMessageBox.Yes, QMessageBox.No)
     return True if reply == QMessageBox.Yes else False
Ejemplo n.º 40
0
    def import_data(self, filenames=None):
        """Import data from text file"""
        title = _("Import data")
        if filenames is None:
            if self.filename is None:
                basedir = getcwd()
            else:
                basedir = osp.dirname(self.filename)
            filenames, _selfilter = getopenfilenames(self, title, basedir,
                                                     iofunctions.load_filters)
            if not filenames:
                return
        elif is_text_string(filenames):
            filenames = [filenames]

        for filename in filenames:
            self.filename = to_text_string(filename)
            ext = osp.splitext(self.filename)[1].lower()

            if ext not in iofunctions.load_funcs:
                buttons = QMessageBox.Yes | QMessageBox.Cancel
                answer = QMessageBox.question(self, title,
                            _("<b>Unsupported file extension '%s'</b><br><br>"
                              "Would you like to import it anyway "
                              "(by selecting a known file format)?"
                              ) % ext, buttons)
                if answer == QMessageBox.Cancel:
                    return
                formats = list(iofunctions.load_extensions.keys())
                item, ok = QInputDialog.getItem(self, title,
                                                _('Open file as:'),
                                                formats, 0, False)
                if ok:
                    ext = iofunctions.load_extensions[to_text_string(item)]
                else:
                    return

            load_func = iofunctions.load_funcs[ext]
                
            # 'import_wizard' (self.setup_io)
            if is_text_string(load_func):
                # Import data with import wizard
                error_message = None
                try:
                    text, _encoding = encoding.read(self.filename)
                    if self.is_internal_shell:
                        self.editor.import_from_string(text)
                    else:
                        base_name = osp.basename(self.filename)
                        editor = ImportWizard(self, text, title=base_name,
                                      varname=fix_reference_name(base_name))
                        if editor.exec_():
                            var_name, clip_data = editor.get_data()
                            monitor_set_global(self._get_sock(),
                                               var_name, clip_data)
                except Exception as error:
                    error_message = str(error)
            else:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                QApplication.processEvents()
                if self.is_internal_shell:
                    namespace, error_message = load_func(self.filename)
                    interpreter = self.shellwidget.interpreter
                    for key in list(namespace.keys()):
                        new_key = fix_reference_name(key,
                                     blacklist=list(interpreter.namespace.keys()))
                        if new_key != key:
                            namespace[new_key] = namespace.pop(key)
                    if error_message is None:
                        interpreter.namespace.update(namespace)
                else:
                    error_message = monitor_load_globals(self._get_sock(),
                                                         self.filename, ext)
                QApplication.restoreOverrideCursor()
                QApplication.processEvents()
    
            if error_message is not None:
                QMessageBox.critical(self, title,
                                     _("<b>Unable to load '%s'</b>"
                                       "<br><br>Error message:<br>%s"
                                       ) % (self.filename, error_message))
            self.refresh_table()
Ejemplo n.º 41
0
 def ask_confirmation(self, message, title="Mantid Workbench"):
     reply = QMessageBox.question(self, title, message, QMessageBox.Yes,
                                  QMessageBox.No)
     return True if reply == QMessageBox.Yes else False
Ejemplo n.º 42
0
    def contextMenuEvent(self, event):
        action = self.contextMenu.exec_(self.mapToGlobal(event.pos()))

        if action == self.action_update_formulas:
            index = self.currentIndex()
            if index.isValid():
                item = index.internalPointer()
                if isinstance(item, SpaceItem):
                    pass
                else:
                    if index.parent().isValid():
                        item = index.parent().internalPointer()
                    else:
                        return

                self.shell.update_codelist(item.itemData['fullname'])

        elif action == self.action_update_properties:
            index = self.currentIndex()
            if index.isValid():
                item = self.currentIndex().internalPointer()
                if not isinstance(item, ViewItem):
                    self.shell.update_mxproperty(item.itemData['fullname'])

        elif action == self.action_import_names:
            index = self.currentIndex()
            if index.isValid():
                item = self.currentIndex().internalPointer()

                if isinstance(item, SpaceItem):
                    has_children = True
                elif isinstance(item, CellsItem) or isinstance(item, RefItem):
                    has_children = False
                else:
                    return
            else:
                return

            if has_children:
                dialog = ImportNamesDialog(self)
                dialog.exec()

                if self.reply['accepted']:
                    import_selected = self.reply['import_selected']
                    import_children = self.reply['import_children']
                    replace_existing = self.reply['replace_existing']
                    self.reply = None
                else:
                    self.reply = None
                    return
            else:
                import_selected = True
                import_children = False
                replace_existing = True

            self.shell.import_names(item.itemData['fullname'],
                                    import_selected,
                                    import_children,
                                    replace_existing
                                    )

        elif action == self.action_analyze_selected:
            index = self.currentIndex()
            if index.isValid():
                item = self.currentIndex().internalPointer()
                if isinstance(item, CellsItem):
                    self.shell.mxanalyzer.update_object(item.itemData)

        elif action == self.action_new_model:
            dialog = NewModelDialog(self)
            dialog.exec()

            if self.reply['accepted']:
                name = self.reply['name']
                define_var = self.reply['define_var']
                if define_var:
                    varname = self.reply['varname']
                else:
                    varname = ''
                self.reply = None
                self.shell.new_model(name, define_var, varname)
            else:
                self.reply = None

        elif action == self.action_new_space:
            if self.model():
                parentList = self.model().rootItem.getSpaceContainerList()
            else:
                parentList = []

            # Find current item
            index = self.currentIndex()
            if index.isValid():
                name = index.internalPointer().itemData['fullname']
                try:
                    currIndex = parentList.index(name)
                except ValueError:
                    currIndex = 0
            else:
                currIndex = 0

            if self.model():
                model = self.model().rootItem.itemData['name']
            else:
                model = ''

            dialog = NewSpaceDialog(self, parentList, currIndex)
            dialog.exec()

            if self.reply['accepted']:
                name = self.reply['name']
                parent = self.reply['parent']
                bases = self.reply['bases']
                define_var = self.reply['define_var']
                if define_var:
                    varname = self.reply['varname']
                else:
                    varname = ''
                self.reply = None
                self.shell.new_space(
                    model, parent, name, bases, define_var, varname)
            else:
                self.reply = None

        elif action == self.action_new_cells:
            if self.model():
                parentList = self.model().rootItem.getChildSpaceList()
            else:
                parentList = []

            # Find current item
            index = self.currentIndex()
            if index.isValid():
                name = index.internalPointer().itemData['namedid']
                try:
                    currIndex = parentList.index(name)
                except ValueError:
                    currIndex = 0
            else:
                currIndex = 0

            if self.model():
                model = self.model().rootItem.itemData['name']
            else:
                model = ''

            dialog = NewCellsDialog(self, parentList, currIndex)
            dialog.exec()

            if self.reply['accepted']:
                name = self.reply['name']
                parent = self.reply['parent']
                formula = self.reply['formula']
                define_var = self.reply['define_var']
                if define_var:
                    varname = self.reply['varname']
                else:
                    varname = ''
                self.reply = None
                self.shell.new_cells(
                    model, parent, name, formula, define_var, varname)
            else:
                self.reply = None

        elif action == self.action_read_model:
            dialog = ReadModelDialog(self, modelpath=self.mx_widget.last_modelpath)
            dialog.exec()

            if self.reply['accepted']:
                modelpath = self.reply['directory']
                name = self.reply['name']
                define_var = self.reply['define_var']
                if define_var:
                    varname = self.reply['varname']
                else:
                    varname = ''
                self.reply = None
                self.shell.read_model(modelpath, name, define_var, varname)
                self.mx_widget.last_modelpath = modelpath
            else:
                self.reply = None

        elif action == self.action_write_model:
            model = self.container.current_widget().model_selector.get_selected_model()
            if not model:
                QMessageBox.critical(self, "Error", "No model exits.")
                return

            dialog = WriteModelDialog(self, modelpath=self.mx_widget.last_modelpath)
            dialog.exec()

            if self.reply['accepted']:
                modelpath = self.reply['directory'] + "/" + self.reply['name']
                backup = self.reply['backup']
                zipmodel = self.reply['zipmodel']
                self.reply = None
                self.shell.write_model(model, modelpath, backup, zipmodel)
                self.mx_widget.last_modelpath = modelpath
            else:
                self.reply = None

        elif action == self.action_delete_model:
            model = self.container.current_widget().model_selector.get_selected_model()
            if model:
                answer = QMessageBox.question(
                    self, _("Delete Model"),
                    _("Do you want to delete %s?" % model),
                    QMessageBox.Yes | QMessageBox.No)
                if answer == QMessageBox.Yes:
                    self.shell.del_model(model)
                else:
                    return
            else:
                QMessageBox.critical(self, "Error", "No model exits.")
        elif action == self.action_delete_selected:
            index = self.currentIndex()
            if index.isValid():
                item = index.internalPointer()
                if isinstance(item, ViewItem) or isinstance(item, ItemSpaceItem):
                    pass
                else:
                    if index.parent().isValid():
                        parent = index.parent().internalPointer().fullname
                    else:
                        parent = self.container.current_widget().model_selector.get_selected_model()
                    assert parent

                    answer = QMessageBox.question(
                        self, _("Delete Selected"),
                        _("Do you want to delete %s?" % item.name),
                        QMessageBox.Yes | QMessageBox.No)

                    if answer == QMessageBox.Yes:
                        self.shell.del_object(parent, item.name)

                        QMessageBox.information(
                            self, "Notice",
                            "'%s' is deleted from '%s'" % (item.name, parent))
Ejemplo n.º 43
0
def openssh_tunnel(self,
                   lport,
                   rport,
                   server,
                   remoteip='127.0.0.1',
                   keyfile=None,
                   password=None,
                   timeout=0.4):
    """
    We decided to replace pyzmq's openssh_tunnel method to work around
    issue https://github.com/zeromq/pyzmq/issues/589 which was solved
    in pyzmq https://github.com/zeromq/pyzmq/pull/615
    """
    ssh = "ssh "
    if keyfile:
        ssh += "-i " + keyfile

    if ':' in server:
        server, port = server.split(':')
        ssh += " -p %s" % port

    cmd = "%s -O check %s" % (ssh, server)
    (output, exitstatus) = pexpect.run(cmd, withexitstatus=True)
    if not exitstatus:
        pid = int(output[output.find("(pid=") + 5:output.find(")")])
        cmd = "%s -O forward -L 127.0.0.1:%i:%s:%i %s" % (ssh, lport, remoteip,
                                                          rport, server)
        (output, exitstatus) = pexpect.run(cmd, withexitstatus=True)
        if not exitstatus:
            atexit.register(_stop_tunnel,
                            cmd.replace("-O forward", "-O cancel", 1))
            return pid
    cmd = "%s -f -S none -L 127.0.0.1:%i:%s:%i %s sleep %i" % (
        ssh, lport, remoteip, rport, server, timeout)

    # pop SSH_ASKPASS from env
    env = os.environ.copy()
    env.pop('SSH_ASKPASS', None)

    ssh_newkey = 'Are you sure you want to continue connecting'
    tunnel = pexpect.spawn(cmd, env=env)
    failed = False
    while True:
        try:
            i = tunnel.expect([ssh_newkey, '[Pp]assword:'], timeout=.1)
            if i == 0:
                host = server.split('@')[-1]
                question = _("The authenticity of host <b>%s</b> can't be "
                             "established. Are you sure you want to continue "
                             "connecting?") % host
                reply = QMessageBox.question(self, _('Warning'), question,
                                             QMessageBox.Yes | QMessageBox.No,
                                             QMessageBox.No)
                if reply == QMessageBox.Yes:
                    tunnel.sendline('yes')
                    continue
                else:
                    tunnel.sendline('no')
                    raise RuntimeError(
                        _("The authenticity of the host can't be established"))
            if i == 1 and password is not None:
                tunnel.sendline(password)
        except pexpect.TIMEOUT:
            continue
        except pexpect.EOF:
            if tunnel.exitstatus:
                raise RuntimeError(_("Tunnel '%s' failed to start") % cmd)
            else:
                return tunnel.pid
        else:
            if failed or password is None:
                raise RuntimeError(_("Could not connect to remote host"))
                # TODO: Use this block when pyzmq bug #620 is fixed
                # # Prompt a passphrase dialog to the user for a second attempt
                # password, ok = QInputDialog.getText(self, _('Password'),
                #             _('Enter password for: ') + server,
                #             echo=QLineEdit.Password)
                # if ok is False:
                #      raise RuntimeError('Could not connect to remote host.')
            tunnel.sendline(password)
            failed = True
Ejemplo n.º 44
0
    def __on_mso(self, mso):
        '''
        Handles mso message from the device sent after a getmso is issued.
        :param mso: the mso.
        '''
        version = mso['versions']['swVer']
        version = version[1:] if version[0] == 'v' else version
        try:
            self.__supports_shelf = semver.parse_version_info(
                version) > semver.parse_version_info('1.4.0')
        except:
            logger.error(f"Unable to parse version {mso['versions']['swVer']}")
            result = QMessageBox.question(
                self, 'Supports Shelf Filters?',
                f"Reported software version is "
                f"\n\n    {version}"
                f"\n\nDoes this version support shelf filters?",
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            self.__supports_shelf = result == QMessageBox.Yes

        speakers = mso['speakers']['groups']
        channels = ['lf', 'rf']
        for group in [
                s for s, v in speakers.items()
                if 'present' in v and v['present'] is True
        ]:
            if group[0:2] == 'lr' and len(group) > 2:
                channels.append('l' + group[2:])
                channels.append('r' + group[2:])
            else:
                channels.append(group)

        peq_slots = mso['peq']['slots']

        class Filters(dict):
            def __init__(self):
                super().__init__()

            def __missing__(self, key):
                self[key] = CompleteFilter(fs=HTP1_FS, sort_by_id=True)
                return self[key]

        tmp1 = Filters()
        tmp2 = Filters()
        raw_filters = {c: [] for c in channels}
        unknown_channels = set()
        for idx, s in enumerate(peq_slots):
            for c in channels:
                if c in s['channels']:
                    tmp1[c].save(
                        self.__convert_to_filter(s['channels'][c], idx))
                    tmp2[c].save(
                        self.__convert_to_filter(s['channels'][c], idx))
                    raw_filters[c].append(s['channels'][c])
                else:
                    unknown_channels.add(c)
        if unknown_channels:
            peq_channels = peq_slots[0]['channels'].keys()
            logger.error(
                f"Unknown channels encountered [peq channels: {peq_channels}, unknown: {unknown_channels}]"
            )

        from model.report import block_signals
        with block_signals(self.filtersetSelector):
            now = self.filtersetSelector.currentText()
            self.filtersetSelector.clear()
            now_idx = -1
            for idx, c in enumerate(channels):
                self.filtersetSelector.addItem(c)
                if c == now:
                    now_idx = idx
            if now_idx > -1:
                self.filtersetSelector.setCurrentIndex(now_idx)

        self.__filters_by_channel = tmp1
        self.__current_device_filters_by_channel = tmp2
        self.__filters.filter = self.__filters_by_channel[
            self.filtersetSelector.itemText(0)]
        if not self.__channel_to_signal:
            self.load_from_signals()
        self.__magnitude_model.redraw()
        self.syncStatus.setIcon(qta.icon('fa5s.link'))
        self.__last_received_msoupdate = None
        self.__last_requested_msoupdate = None
        self.showDetailsButton.setEnabled(False)
Ejemplo n.º 45
0
 def send_filters_to_device(self):
     '''
     Sends the selected filters to the device
     '''
     if self.__in_complex_mode():
         ops, unsupported_filter_types_per_channel = self.__convert_filter_mappings_to_ops(
         )
         channels_to_update = [
             i.text().split(' ')[1]
             for i in self.filterMapping.selectedItems()
         ]
         unsynced_channels = []
         for c, s in self.__channel_to_signal.items():
             if s is not None:
                 if c not in channels_to_update:
                     if c in self.__current_device_filters_by_channel:
                         current = s.filter
                         device = self.__current_device_filters_by_channel[
                             c]
                         if current != device:
                             unsynced_channels.append(c)
         if unsynced_channels:
             result = QMessageBox.question(
                 self, 'Sync all changed channels?',
                 f"Filters in {len(unsynced_channels)} channels have changed but will not be "
                 f"synced to the HTP-1."
                 f"\n\nChannels: {', '.join(sorted([k for k in unsynced_channels]))}"
                 f"\n\nDo you want to sync all changed channels? ",
                 QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
             if result == QMessageBox.Yes:
                 for c in unsynced_channels:
                     for i in range(self.filterMapping.count()):
                         item: QListWidgetItem = self.filterMapping.item(i)
                         if c == item.text().split(' ')[1]:
                             item.setSelected(True)
                 self.send_filters_to_device()
                 return
     else:
         ops, unsupported_filter_types_per_channel = self.__convert_current_filter_to_ops(
         )
     do_send = True
     if unsupported_filter_types_per_channel:
         printed = '\n'.join([
             f"{k} - {', '.join(v)}"
             for k, v in unsupported_filter_types_per_channel.items()
         ])
         result = QMessageBox.question(
             self, 'Unsupported Filters Detected',
             f"Unsupported filter types found in the filter set:"
             f"\n\n{printed}"
             f"\n\nDo you want sync the supported filters only? ",
             QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
         do_send = result == QMessageBox.Yes
     if do_send:
         from app import wait_cursor
         with wait_cursor():
             all_ops = [op for slot_ops in ops for op in slot_ops]
             self.__last_requested_msoupdate = all_ops
             msg = f"changemso {json.dumps(self.__last_requested_msoupdate)}"
             logger.debug(f"Sending to {self.ipAddress.text()} -> {msg}")
             self.__spinner = StoppableSpin(self.syncStatus, 'sync')
             spin_icon = qta.icon('fa5s.spinner',
                                  color='green',
                                  animation=self.__spinner)
             self.syncStatus.setIcon(spin_icon)
             self.__ws_client.sendTextMessage(msg)
Ejemplo n.º 46
0
    def apply_multiple_actions(self):
        """
        """
        logger.debug('')

        self.conda_errors = []

        prefix = self.prefix

        if prefix == self.root_prefix:
            name = 'root'
        elif self.api.conda_environment_exists(prefix=prefix):
            name = osp.basename(prefix)
        else:
            name = prefix

        actions = self.table.get_actions()

        if actions is None:
            return

        self._multiple_process = deque()

        pip_actions = actions[C.PIP_PACKAGE]
        conda_actions = actions[C.CONDA_PACKAGE]

        pip_remove = pip_actions.get(C.ACTION_REMOVE, [])
        conda_remove = conda_actions.get(C.ACTION_REMOVE, [])
        conda_install = conda_actions.get(C.ACTION_INSTALL, [])
        conda_upgrade = conda_actions.get(C.ACTION_UPGRADE, [])
        conda_downgrade = conda_actions.get(C.ACTION_DOWNGRADE, [])

        message = ''
        template_1 = '<li><b>{0}={1}</b></li>'
        template_2 = '<li><b>{0}: {1} -> {2}</b></li>'

        if pip_remove:
            temp = [template_1.format(i['name'], i['version_to']) for i in
                    pip_remove]
            message += ('The following pip packages will be removed: '
                        '<ul>' + ''.join(temp) + '</ul>')
        if conda_remove:
            temp = [template_1.format(i['name'], i['version_to']) for i in
                    conda_remove]
            message += ('<br>The following conda packages will be removed: '
                        '<ul>' + ''.join(temp) + '</ul>')
        if conda_install:
            temp = [template_1.format(i['name'], i['version_to']) for i in
                    conda_install]
            message += ('<br>The following conda packages will be installed: '
                        '<ul>' + ''.join(temp) + '</ul>')
        if conda_downgrade:
            temp = [template_2.format(
                    i['name'], i['version_from'], i['version_to']) for i in
                    conda_downgrade]
            message += ('<br>The following conda packages will be downgraded: '
                        '<ul>' + ''.join(temp) + '</ul>')
        if conda_upgrade:
            temp = [template_2.format(
                    i['name'], i['version_from'], i['version_to']) for i in
                    conda_upgrade]
            message += ('<br>The following conda packages will be upgraded: '
                        '<ul>' + ''.join(temp) + '</ul>')
        message += '<br>'

        if self.apply_actions_dialog:
            dlg = self.apply_actions_dialog(message, parent=self)
            dlg.update_style_sheet(style_sheet=self.style_sheet)
            reply = dlg.exec_()
        else:
            reply = QMessageBox.question(self,
                                         'Proceed with the following actions?',
                                         message,
                                         buttons=QMessageBox.Ok |
                                         QMessageBox.Cancel)

        if reply:
            # Pip remove
            for pkg in pip_remove:
                status = (_('Removing pip package <b>') + pkg['name'] +
                          '</b>' + _(' from <i>') + name + '</i>')
                pkgs = [pkg['name']]

                def trigger(prefix=prefix, pkgs=pkgs):
                    return lambda: self.api.pip_remove(prefix=prefix,
                                                       pkgs=pkgs)

                self._multiple_process.append([status, trigger()])

            # Process conda actions
            if conda_remove:
                status = (_('Removing conda packages <b>') +
                          '</b>' + _(' from <i>') + name + '</i>')
                pkgs = [i['name'] for i in conda_remove]

                def trigger(prefix=prefix, pkgs=pkgs):
                    return lambda: self.api.conda_remove(pkgs=pkgs,
                                                         prefix=prefix)
                self._multiple_process.append([status, trigger()])

            if conda_install:
                pkgs = ['{0}={1}'.format(i['name'], i['version_to']) for i in
                        conda_install]

                status = (_('Installing conda packages <b>') +
                          '</b>' + _(' on <i>') + name + '</i>')

                def trigger(prefix=prefix, pkgs=pkgs):
                    return lambda: self.api.conda_install(
                        prefix=prefix,
                        pkgs=pkgs,
                        channels=self._active_channels,
                        token=self.token)
                self._multiple_process.append([status, trigger()])

            # Conda downgrade
            if conda_downgrade:
                status = (_('Downgrading conda packages <b>') +
                          '</b>' + _(' on <i>') + name + '</i>')

                pkgs = ['{0}={1}'.format(i['name'], i['version_to']) for i in
                        conda_downgrade]

                def trigger(prefix=prefix, pkgs=pkgs):
                    return lambda: self.api.conda_install(
                        prefix=prefix,
                        pkgs=pkgs,
                        channels=self._active_channels,
                        token=self.token)

                self._multiple_process.append([status, trigger()])

            # Conda update
            if conda_upgrade:
                status = (_('Upgrading conda packages <b>') +
                          '</b>' + _(' on <i>') + name + '</i>')

                pkgs = ['{0}={1}'.format(i['name'], i['version_to']) for i in
                        conda_upgrade]

                def trigger(prefix=prefix, pkgs=pkgs):
                    return lambda: self.api.conda_install(
                        prefix=prefix,
                        pkgs=pkgs,
                        channels=self._active_channels,
                        token=self.token)

                self._multiple_process.append([status, trigger()])

            self._run_multiple_actions()
Ejemplo n.º 47
0
 def _confirm_quit(self, callback):
     quit_message = QMessageBox.question(self, 'Quitting Application',
                                         'Exit Application?',
                                         QMessageBox.Yes | QMessageBox.No)
     if quit_message == QMessageBox.Yes:
         callback()