def launch_error_message(self, error_type, error=None): """Launch a message box with a predefined error message. Parameters ---------- error_type : int [CLOSE_ERROR, RESET_ERROR, RESTART_ERROR] Possible error codes when restarting/reseting spyder. error : Exception Actual Python exception error caught. """ messages = {CLOSE_ERROR: _("It was not possible to close the previous " "Spyder instance.\nRestart aborted."), RESET_ERROR: _("Spyder could not reset to factory " "defaults.\nRestart aborted."), RESTART_ERROR: _("It was not possible to restart Spyder.\n" "Operation aborted.")} titles = {CLOSE_ERROR: _("Spyder exit error"), RESET_ERROR: _("Spyder reset error"), RESTART_ERROR: _("Spyder restart error")} if error: e = error.__repr__() message = messages[error_type] + "\n\n{0}".format(e) else: message = messages[error_type] title = titles[error_type] self.splash.hide() QMessageBox.warning(self, title, message, QMessageBox.Ok) raise RuntimeError(message)
def set_user_env(reg, parent=None): """Set HKCU (current user) environment variables""" reg = listdict2envdict(reg) types = dict() key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Environment") for name in reg: try: _x, types[name] = winreg.QueryValueEx(key, name) except WindowsError: types[name] = winreg.REG_EXPAND_SZ key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Environment", 0, winreg.KEY_SET_VALUE) for name in reg: winreg.SetValueEx(key, name, 0, types[name], reg[name]) try: from win32gui import SendMessageTimeout from win32con import (HWND_BROADCAST, WM_SETTINGCHANGE, SMTO_ABORTIFHUNG) SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, "Environment", SMTO_ABORTIFHUNG, 5000) except ImportError: QMessageBox.warning(parent, _("Warning"), _("Module <b>pywin32 was not found</b>.<br>" "Please restart this Windows <i>session</i> " "(not the computer) for changes to take effect."))
def set_umr_namelist(self): """Set UMR excluded modules name list""" arguments, valid = QInputDialog.getText(self, _('UMR'), _("Set the list of excluded modules as " "this: <i>numpy, scipy</i>"), QLineEdit.Normal, ", ".join(self.get_option('umr/namelist'))) if valid: arguments = to_text_string(arguments) if arguments: namelist = arguments.replace(' ', '').split(',') fixed_namelist = [module_name for module_name in namelist if programs.is_module_installed(module_name)] invalid = ", ".join(set(namelist)-set(fixed_namelist)) if invalid: QMessageBox.warning(self, _('UMR'), _("The following modules are not " "installed on your machine:\n%s" ) % invalid, QMessageBox.Ok) QMessageBox.information(self, _('UMR'), _("Please note that these changes will " "be applied only to new Python/IPython " "consoles"), QMessageBox.Ok) else: fixed_namelist = [] self.set_option('umr/namelist', fixed_namelist)
def _sel_to_text(self, cell_range): """Copy an array portion to a unicode string""" if not cell_range: return row_min, row_max, col_min, col_max = get_idx_rect(cell_range) if col_min == 0 and col_max == (self.model().cols_loaded-1): # we've selected a whole column. It isn't possible to # select only the first part of a column without loading more, # so we can treat it as intentional and copy the whole thing col_max = self.model().total_cols-1 if row_min == 0 and row_max == (self.model().rows_loaded-1): row_max = self.model().total_rows-1 _data = self.model().get_data() if PY3: output = io.BytesIO() else: output = io.StringIO() try: np.savetxt(output, _data[row_min:row_max+1, col_min:col_max+1], delimiter='\t') except: QMessageBox.warning(self, _("Warning"), _("It was not possible to copy values for " "this array")) return contents = output.getvalue().decode('utf-8') output.close() return contents
def show_message(is_checked): if is_checked or not msg_if_enabled: if msg_warning is not None: QMessageBox.warning(self, self.get_name(), msg_warning, QMessageBox.Ok) if msg_info is not None: QMessageBox.information(self, self.get_name(), msg_info, QMessageBox.Ok)
def _on_fit_clicked(self, eq_pop_up=True): if eq_pop_up: self._on_equation_edit_button_clicked() # Grab the currently selected plot data item from the data list plot_data_item = self.hub.plot_item # If this item is not a model data item, bail if not isinstance(plot_data_item.data_item, ModelDataItem): return data_item = self._get_selected_data_item() if data_item is None: return spectral_region = self.hub.spectral_regions # Compose the compound model from the model editor sub model tree view model_editor_model = plot_data_item.data_item.model_editor_model result = model_editor_model.evaluate() if result is None: QMessageBox.warning(self, "Please add models to fit.", "Models can be added by clicking the" " green \"add\" button and selecting a" " model from the drop-down menu") return # Load options fitter = FITTERS[self.fitting_options["fitter"]] output_formatter = "{:0.%sg}" % self.fitting_options['displayed_digits'] kwargs = {} if isinstance(fitter, fitting.LevMarLSQFitter): kwargs['maxiter'] = self.fitting_options['max_iterations'] kwargs['acc'] = self.fitting_options['relative_error'] kwargs['epsilon'] = self.fitting_options['epsilon'] # Run the compound model through the specutils fitting routine. Ensure # that the returned values are always in units of the current plot by # passing in the spectrum with the spectral axis and flux # converted to plot units. spectrum = data_item.spectrum.with_spectral_unit( plot_data_item.spectral_axis_unit) spectrum = spectrum.new_flux_unit(plot_data_item.data_unit) # Setup the thread and begin execution. self.fit_model_thread = FitModelThread( spectrum=spectrum, model=result, fitter=fitter(), fitter_kwargs=kwargs, window=spectral_region) self.fit_model_thread.result.connect( lambda x, r=result: self._on_fit_model_finished(x, result=r)) self.fit_model_thread.start()
def get_user_credentials(self): """Get user credentials with the login dialog.""" password = None token = None (username, remember_me, remember_token) = self._get_credentials_from_settings() valid_py_os = not (PY2 and sys.platform.startswith('linux')) if username and remember_me and valid_py_os: # Get password from keyring try: password = keyring.get_password('github', username) except Exception: # No safe keyring backend if self._show_msgbox: QMessageBox.warning(self.parent_widget, _('Failed to retrieve password'), _('It was not possible to retrieve ' 'your password. Please introduce ' 'it again.')) if remember_token and valid_py_os: # Get token from keyring try: token = keyring.get_password('github', 'token') except Exception: # No safe keyring backend if self._show_msgbox: QMessageBox.warning(self.parent_widget, _('Failed to retrieve token'), _('It was not possible to retrieve ' 'your token. Please introduce it ' 'again.')) if not running_under_pytest(): credentials = DlgGitHubLogin.login(self.parent_widget, username, password, token, remember_me, remember_token) if (credentials['username'] and credentials['password'] and valid_py_os): self._store_credentials(credentials['username'], credentials['password'], credentials['remember']) CONF.set('main', 'report_error/remember_me', credentials['remember']) if credentials['token'] and valid_py_os: self._store_token(credentials['token'], credentials['remember_token']) CONF.set('main', 'report_error/remember_token', credentials['remember_token']) else: return dict(username=username, password=password, token='', remember=remember_me, remember_token=remember_token) return credentials
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
def set_state(self, state): """ Populate the UI elements with the data from the given state. @param state: Transmission object """ popup_warning = "" # Beam finder if state.x_position is not None and state.y_position is not None: self._content.x_pos_edit.setText(str("%6.4f" % state.x_position)) self._content.y_pos_edit.setText(str("%6.4f" % state.y_position)) self._content.use_beam_finder_checkbox.setChecked(state.use_finder) self._content.beam_data_file_edit.setText(state.beam_file) self._content.beam_radius_edit.setText(str(state.beam_radius)) if not self._settings.debug and not self._settings.advanced and not state.use_direct_beam: # Warn the user if we're about to set an option that is not seen! popup_warning += "The reduction you are loading has advanced options for finding the beam center.\n" popup_warning += "Use the advanced interface to see all option. Those options will now be skipped." state.use_direct_beam = True self._content.direct_beam.setChecked(state.use_direct_beam) self._content.scattering_data.setChecked(not state.use_direct_beam) self._content.beam_radius_edit.setEnabled(not state.use_direct_beam) self._use_beam_finder_changed(state.use_finder) # Sensitivity self._content.sensitivity_file_edit.setText(state.sensitivity_data) self._content.sensitivity_chk.setChecked(state.sensitivity_corr) self._sensitivity_clicked(state.sensitivity_corr) self._content.min_sensitivity_edit.setText(str(state.min_sensitivity)) self._content.max_sensitivity_edit.setText(str(state.max_sensitivity)) if not self._use_sample_dc: self._content.sensitivity_dark_file_edit.setText(state.sensitivity_dark) if not self._settings.debug and not self._settings.advanced and not state.use_sample_beam_center: # Warn the user if we're about to set an option that is not seen! popup_warning += "The reduction you are loading has advanced options for the flood field beam center.\n" popup_warning += "Use the advanced interface to see all option. Those options will now be skipped." state.use_sample_beam_center = True self._content.use_sample_center_checkbox.setChecked(state.use_sample_beam_center) self._content.x_pos_edit_2.setText(str("%6.4f" % state.flood_x_position)) self._content.y_pos_edit_2.setText(str("%6.4f" % state.flood_y_position)) self._content.use_beam_finder_checkbox_2.setChecked(state.flood_use_finder) self._content.beam_data_file_edit_2.setText(state.flood_beam_file) self._content.beam_radius_edit_2.setText(str(state.flood_beam_radius)) self._content.direct_beam_2.setChecked(state.flood_use_direct_beam) self._content.scattering_data_2.setChecked(not state.flood_use_direct_beam) self._content.beam_radius_edit_2.setEnabled(not state.flood_use_direct_beam) self._sensitivity_clicked(self._content.sensitivity_chk.isChecked()) self._use_sample_center_changed(self._content.use_sample_center_checkbox.isChecked()) if len(popup_warning)>0: QMessageBox.warning(self, "Turn ON advanced interface", popup_warning)
def _on_remove(self): selection = self._table.selectionModel().selection().indexes() if len(selection) == 0: QMessageBox.warning(self, "Specimen position", "Select a position") return model = self._table.model() for row in sorted(map(methodcaller('row'), selection), reverse=True): model.removeRow(row)
def edit_expression(self): """Edit selected expression in main dialog""" if not self.list_derived_components.currentItem(): QMessageBox.warning(self, "No Spectrum1D Objects", "No selected expression to edit!") else: current_item = self.list_derived_components.currentItem() label = current_item.text(0) equation = current_item.text(1) self.editor = EquationEditor(self, label=label, equation=equation, parent=self)
def _warning(self, title, message): """ Pop up a dialog and warn the user @param title: dialog box title @param message: message to be displayed #TODO: change this to signals and slots mechanism """ if len(self.widgets)>0: QMessageBox.warning(self.widgets[0], title, message)
def remove_expression(self): """Remove selected expression in main diaglog""" if not self.list_derived_components.currentItem(): QMessageBox.warning(self, "No Spectrum1D Objects", "No selected expression to remove!") else: # Get current selected item and it's index in the QTreeWidget. current_item = self.list_derived_components.currentItem() index = self.list_derived_components.indexOfTopLevelItem(current_item) self.list_derived_components.takeTopLevelItem(index)
def open_output_file_if_writable(self, full_output_file_name): _o_file = FileHandler(filename=full_output_file_name) if _o_file.is_file_writable(): outfile = open(full_output_file_name, "w") else: title = "No write permissions!" error_msg = "Unable to write cached table. " + \ "Will not be able to write output files to this directory. " + \ "\n\nCheck file and directory for write permissions!" QMessageBox.warning(self.parent, title, error_msg) outfile = None return outfile
def run(self): try: o_generate = GenerateSumthing(parent=self.parent, folder=self.parent.current_folder) o_generate.create_sum_inp_file() self.read_auto_sum_file() self.populate_table() except IOError: QMessageBox.warning(self.parent, "File does not exist!", "Check your folder! ") self.error_reported = True
def open_file(self, file_path=None): """ Open an XML file and populate the UI @param file_path: path to the file to be loaded """ if file_path is None: action = self.sender() if isinstance(action, QAction): file_path = action.data() if not file_path: return # don't try to load if the file doesn't exist file_path = str(file_path) if not os.path.exists(file_path): return # Check whether the file describes the current instrument try: found_instrument = self._interface.scripter.verify_instrument(file_path) except: msg = "The file you attempted to load doesn't have a recognized format:\n" \ + file_path+"\n\n" \ + "Please make sure it has been produced by this application." QMessageBox.warning(self, "Error loading reduction parameter file", msg) print(sys.exc_info()[1]) return if not found_instrument == self._instrument: self._instrument = found_instrument self.setup_layout() self.reduce_button.setEnabled(False) self.export_button.setEnabled(False) self.save_button.setEnabled(False) self.interface_chk.setEnabled(False) self._interface.load_file(file_path) self.reduce_button.setEnabled(True) self.export_button.setEnabled(True) self.save_button.setEnabled(True) self.interface_chk.setEnabled(True) self._filename = file_path self._update_file_menu() self._set_window_title() if file_path in self._recent_files: self._recent_files.remove(file_path) self._recent_files.insert(0,file_path) while len(self._recent_files) > 10: self._recent_files.pop()
def _on_create_new_model(self): if self.hub.data_item is None: QMessageBox.warning(self, "No item selected, cannot create model.", "There is currently no item selected. Please " "select an item before attempting to create " "a new model.") return # Grab the currently selected plot data item new_spec = Spectrum1D(flux=np.zeros(self.hub.data_item.spectral_axis.size) * self.hub.data_item.flux.unit, spectral_axis=self.hub.data_item.spectral_axis) self.create_model_data_item(new_spec, data_item=self.hub.data_item)
def python_executable_changed(self, pyexec): """Custom Python executable value has been changed""" if not self.cus_exec_radio.isChecked(): return if not is_text_string(pyexec): pyexec = to_text_string(pyexec.toUtf8(), 'utf-8') if programs.is_python_interpreter(pyexec): self.warn_python_compatibility(pyexec) else: QMessageBox.warning(self, _('Warning'), _("You selected an invalid Python interpreter for the " "console so the previous interpreter will stay. Please " "make sure to select a valid one."), QMessageBox.Ok) self.pyexec_edit.setText(get_python_executable()) return
def _get_selected_data_item(self): # The spectrum_data_item would be the data item that this model is to # be fit to. This selection is done via the data_selection_combo. combo_index = self.data_selection_combo.currentIndex() data_item = self.data_selection_combo.itemData(combo_index) # If user chooses a model instead of a data item, notify and return if isinstance(data_item, ModelDataItem): QMessageBox.warning(self, "Selected data is a model.", "The currently selected data " "is a model. Please select a " "data item containing spectra.") return None return data_item
def _do_plot_spectrum(self, names, errors, overplot): """ Plot spectra from the selected workspaces :param names: A list of workspace names :param errors: If true then error bars will be plotted on the points :param overplot: If true then the add to the current figure if one exists and it is a compatible figure """ if overplot: compatible, error_msg = can_overplot() if not compatible: QMessageBox.warning(self, "", error_msg) return plot_from_names(names, errors, overplot)
def rename_file(self, fname): """Rename file""" path, valid = QInputDialog.getText(self, _('Rename'), _('New name:'), QLineEdit.Normal, osp.basename(fname)) if valid: path = osp.join(osp.dirname(fname), to_text_string(path)) if path == fname: return if osp.exists(path): if QMessageBox.warning(self, _("Rename"), _("Do you really want to rename <b>%s</b> and " "overwrite the existing file <b>%s</b>?" ) % (osp.basename(fname), osp.basename(path)), QMessageBox.Yes|QMessageBox.No) == QMessageBox.No: return try: misc.rename_file(fname, path) self.parent_widget.renamed.emit(fname, path) return path except EnvironmentError as error: QMessageBox.critical(self, _("Rename"), _("<b>Unable to rename file <i>%s</i></b>" "<br><br>Error message:<br>%s" ) % (osp.basename(fname), to_text_string(error)))
def converter(self, parent=None, convert_data=False): """ Launch Converter GUI :param parent: application :param values: convert data values if True. Only displayed units if False. :return: ConvertFluxUnitGUI instance :raise: Exception: If wavelength info is missing """ if self.wavelengths is None: message = "Could not launch conversion ui because" \ "wavelength information is missing." info = QMessageBox.critical(parent, "Error", message) raise Exception(message) if convert_data: message = "You are about to launch the data flux units converter. " \ "This will modify the actual values stored in components " \ "according to the unit conversions selected. If you would rather" \ " change the displayed units, please select the Convert" \ " Displayed Units option." info = QMessageBox.warning(parent, "Info", message) if hasattr(u.spectral_density, "pixel_area"): u.spectral_density.pixel_area = self.pixel_area ex = ConvertFluxUnitGUI(self, parent, convert_data) return ex
def _on_equation_edit_button_clicked(self): # Get the current model model_data_item = self.hub.data_item if not isinstance(model_data_item, ModelDataItem): QMessageBox.warning(self, "No model available.", "The currently selected item does not" " contain a fittable model. Create a new" " one, or select an item containing a model.") return equation_editor_dialog = ModelEquationEditorDialog( model_data_item.model_editor_model) equation_editor_dialog.accepted.connect(self.hub.plot_item.set_data) equation_editor_dialog.exec_()
def delete_scheme(self): """Deletes the currently selected custom color scheme.""" scheme_name = self.current_scheme answer = QMessageBox.warning(self, _("Warning"), _("Are you sure you want to delete " "this scheme?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: # Put the combobox in Spyder by default, when deleting a scheme names = self.get_option('names') self.set_scheme('spyder') self.schemes_combobox.setCurrentIndex(names.index('spyder')) self.set_option('selected', 'spyder') # Delete from custom_names custom_names = self.get_option('custom_names', []) if scheme_name in custom_names: custom_names.remove(scheme_name) self.set_option('custom_names', custom_names) # Delete config options for key in syntaxhighlighters.COLOR_SCHEME_KEYS: option = "{0}/{1}".format(scheme_name, key) CONF.remove_option(self.CONF_SECTION, option) CONF.remove_option(self.CONF_SECTION, "{0}/name".format(scheme_name)) self.update_combobox() self.update_preview()
def delete_project(self): """ Delete the current project without deleting the files in the directory. """ if self.current_active_project: self.switch_to_plugin() path = self.current_active_project.root_path buttons = QMessageBox.Yes | QMessageBox.No answer = QMessageBox.warning( self, _("Delete"), _("Do you really want to delete <b>{filename}</b>?<br><br>" "<b>Note:</b> This action will only delete the project. " "Its files are going to be preserved on disk." ).format(filename=osp.basename(path)), buttons) if answer == QMessageBox.Yes: try: self.close_project() shutil.rmtree(osp.join(path, '.spyproject')) except EnvironmentError as error: QMessageBox.critical( self, _("Project Explorer"), _("<b>Unable to delete <i>{varpath}</i></b>" "<br><br>The error message was:<br>{error}" ).format(varpath=path, error=to_text_string(error)))
def delete_file(self, fname, multiple, yes_to_all): """Delete file""" if multiple: buttons = QMessageBox.Yes|QMessageBox.YesAll| \ QMessageBox.No|QMessageBox.Cancel else: buttons = QMessageBox.Yes|QMessageBox.No if yes_to_all is None: answer = QMessageBox.warning(self, _("Delete"), _("Do you really want " "to delete <b>%s</b>?" ) % osp.basename(fname), buttons) if answer == QMessageBox.No: return yes_to_all elif answer == QMessageBox.Cancel: return False elif answer == QMessageBox.YesAll: yes_to_all = True try: if osp.isfile(fname): misc.remove_file(fname) self.parent_widget.removed.emit(fname) else: self.remove_tree(fname) self.parent_widget.removed_tree.emit(fname) return yes_to_all except EnvironmentError as error: action_str = _('delete') QMessageBox.critical(self, _("Project Explorer"), _("<b>Unable to %s <i>%s</i></b>" "<br><br>Error message:<br>%s" ) % (action_str, fname, to_text_string(error))) return False
def remove_path(self): answer = QMessageBox.warning(self, _("Remove path"), _("Do you really want to remove selected path?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: self.pathlist.pop(self.listwidget.currentRow()) self.update_list()
def _store_token(self, token, remember=False): """Store token for future use.""" if token and remember: try: keyring.set_password('github', 'token', token) except Exception: if self._show_msgbox: QMessageBox.warning(self.parent_widget, _('Failed to store token'), _('It was not possible to securely ' 'save your token. You will be ' 'prompted for your Github token ' 'next time you want to report ' 'an issue.')) remember = False CONF.set('main', 'report_error/remember_token', remember)
def _paste(self, _cut=False): _copy_selection = self.main_window.table_selection_buffer _copy_left_column = _copy_selection['left_column'] # make sure selection start at the same column _paste_selection = self.main_window.postprocessing_ui.table.selectedRanges() _paste_left_column = _paste_selection[0].leftColumn() if not (_copy_left_column == _paste_left_column): QMessageBox.warning(self.main_window, "Check copy/paste selection!", "Check your selection! ") return _copy_right_column = _copy_selection["right_column"] _copy_top_row = _copy_selection["top_row"] _copy_bottom_row = _copy_selection["bottom_row"] _paste_top_row = _paste_selection[0].topRow() index = 0 for _row in range(_copy_top_row, _copy_bottom_row+1): _paste_row = _paste_top_row + index for _column in range(_copy_left_column, _copy_right_column + 1): if _column in np.arange(1, 7): if _cut: _item_text = '' else: _item_text = self.retrieve_item_text(_row, _column) self.paste_item_text(_paste_row, _column, _item_text) if _column == 7: if _cut: _widget_index = 0 else: _widget_index = self.retrieve_sample_shape_index(_row) self.set_widget_index(_widget_index, _paste_row) if _column == 8: if _cut: _widget_state = Qt.Unchecked else: _widget_state = self.retrieve_do_abs_correction_state(_row) self.set_widget_state(_widget_state, _paste_row) index += 1
def save_namespace(self, filename): if self._reading: message = _("Saving data while debugging is not supported.") QMessageBox.warning(self, _("Warning"), message) return # Wait until the kernel tries to save the file wait_loop = QEventLoop() self.sig_got_reply.connect(wait_loop.quit) self.silent_exec_method(r"get_ipython().kernel.save_namespace('%s')" % filename) wait_loop.exec_() # Remove loop connection and loop self.sig_got_reply.disconnect(wait_loop.quit) wait_loop = None return self._kernel_reply
def save_pipeline(self): history = self._settings.get_history() if not history: QMessageBox.information(self, "No mask created", "There is no new mask created", QMessageBox.Ok) return mask_history = [] for el in history: mask = el.mask_property segmentation = ROIExtractionProfile( name="Unknown", algorithm=el.roi_extraction_parameters["algorithm_name"], values=el.roi_extraction_parameters["values"], ) new_el = SegmentationPipelineElement(mask_property=mask, segmentation=segmentation) mask_history.append(new_el) name = self._settings.last_executed_algorithm if not name: QMessageBox.information(self, "No segmentation", "No segmentation executed", QMessageBox.Ok) return values = self._settings.get(f"algorithms.{name}", {}) if len(values) == 0: QMessageBox.information(self, "Some problem", "Pleas run execution again", QMessageBox.Ok) return current_segmentation = ROIExtractionProfile(name="Unknown", algorithm=name, values=values) while True: text, ok = QInputDialog.getText(self, "Pipeline name", "Input pipeline name here") if not ok: return if text in self._settings.roi_pipelines and QMessageBox.No == QMessageBox.warning( self, "Already exists", "Profile with this name already exist. Overwrite?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No, ): continue profile = SegmentationPipeline(name=text, segmentation=current_segmentation, mask_history=mask_history) self._settings.roi_pipelines[text] = profile self._settings.dump() self.choose_pipe.addItem(text) break
def _check_number_of_plots(self, selection): index_length = len( selection.wksp_indices) if selection.wksp_indices else len( selection.spectra) number_of_lines_to_plot = len(selection.workspaces) * index_length if selection.plot_type == SpectraSelection.Tiled and number_of_lines_to_plot > 12: response = QMessageBox.warning( self, 'Mantid Workbench', 'Are you sure you want to plot {} subplots?'.format( number_of_lines_to_plot), QMessageBox.Ok | QMessageBox.Cancel) return response == QMessageBox.Ok elif selection.plot_type != SpectraSelection.Tiled and number_of_lines_to_plot > 10: response = QMessageBox.warning( self, 'Mantid Workbench', 'You selected {} spectra to plot. Are you sure ' 'you want to plot this many?'.format(number_of_lines_to_plot), QMessageBox.Ok | QMessageBox.Cancel) return response == QMessageBox.Ok return True
def check_shortcuts(self): """Check shortcuts for conflicts.""" conflicts = [] for index, sh1 in enumerate(self.source_model.shortcuts): if index == len(self.source_model.shortcuts) - 1: break for sh2 in self.source_model.shortcuts[index + 1:]: if sh2 is sh1: continue if str(sh2.key) == str(sh1.key) \ and (sh1.context == sh2.context or sh1.context == '_' or sh2.context == '_'): conflicts.append((sh1, sh2)) if conflicts: self.parent().show_this_page.emit() cstr = "\n".join( ['%s <---> %s' % (sh1, sh2) for sh1, sh2 in conflicts]) QMessageBox.warning( self, _("Conflicts"), _("The following conflicts have been " "detected:") + "\n" + cstr, QMessageBox.Ok)
def __add_from_edges(self) -> None: """Add collection by input string.""" edges_str = "" while not edges_str: edges_str, ok = QInputDialog.getText( self, "Add by edges", "Please enter a connection expression:\n" "Example: [(0, 1), (1, 2), (2, 3), (3, 0)]" ) if not ok: return try: edges = eval(edges_str) if any(len(edge) != 2 for edge in edges): raise ValueError("wrong format") except (SyntaxError, ValueError) as error: QMessageBox.warning(self, str(error), f"Error: {error}") return else: self.add_collection(edges)
def combineRows(self): """ Combine selected rows, if the date and gear values are the same. """ selected = self.selectedItems() if len(selected) <= 1: return None idx = self.headerLabels.index('Date') dates = [item.text(idx) for item in selected] idx = self.headerLabels.index('Gear') gears = [item.text(idx) for item in selected] if len(set(dates)) > 1: QMessageBox.warning( self, "Cannot combine selected data", "Cannot combine selected data - dates do not match.") elif len(set(gears)) > 1: QMessageBox.warning( self, "Cannot combine selected data", "Cannot combine selected data - gears do not match.") else: self.data.combineRows(dates[0])
def set_value(self, name, value): """Set value for a variable.""" try: # We need to enclose values in a list to be able to send # them to the kernel in Python 2 svalue = [cloudpickle.dumps(value, protocol=PICKLE_PROTOCOL)] # Needed to prevent memory leaks. See issue 7158 if len(svalue) < MAX_SERIALIZED_LENGHT: self.shellwidget.set_value(name, svalue) else: QMessageBox.warning( self, _("Warning"), _("The object you are trying to modify is " "too big to be sent back to the kernel. " "Therefore, your modifications won't " "take place.")) except TypeError as e: QMessageBox.critical(self, _("Error"), "TypeError: %s" % to_text_string(e)) self.refresh_table()
def write(self, save_as=None): if save_as is not None: filename = save_as else: filename = self.editor.fileName() if not filename: filename = self.ask_for_filename() if not filename: return False self.editor.setFileName(filename) try: with open(filename, 'w') as f: f.write(self.editor.text()) self.editor.setModified(False) except IOError as exc: QMessageBox.warning(self.editor, "", "Error while saving '{}': {}".format(filename, str(exc))) return False else: return True
def slice(self): """ 切片操作。同时屏蔽可能出现的非法字符。 目前做不到对array数组进行索引。 :return: """ data = self.table_view.data text = self.slice_input.text().strip() for char in text: if not char in "[]:,.1234567890iloc": QMessageBox.warning(self, QCoreApplication.translate('PMGTableViewer','Invalid Input'), QCoreApplication.translate('PMGTableViewer',"invalid character \"%s\" in slicing statement.") % char) return try: data = eval('data' + text) except Exception as exeption: QMessageBox.warning(self, QCoreApplication.translate('PMGTableViewer','Invalid Input'), QCoreApplication.translate('PMGTableViewer',str(exeption))) self.table_view.show_data(data)
def _start_window(ert, args): _check_locale() help_center = HelpCenter("ERT") help_center.setHelpMessageLink("welcome_to_ert") splash = ErtSplash(version_string="Version {}".format(ert_gui.__version__)) splash.show() splash.repaint() splash_screen_start_time = time.time() configureErtNotifier(ert, args.config) window = _setup_main_window(ert, args) minimum_splash_screen_time = 2 sleep_time_left = minimum_splash_screen_time - (time.time() - splash_screen_start_time) if sleep_time_left > 0: time.sleep(sleep_time_left) window.show() splash.finish(window) window.activateWindow() window.raise_() ResLog.log( 3, "Versions: ecl:%s res:%s ert:%s" % (ecl.__version__, res.__version__, ert_gui.__version__), ) if not ert._real_enkf_main().have_observations(): QMessageBox.warning( window, "Warning!", "No observations loaded. Model update algorithms disabled!", ) return window
def load_and_translate(self, sbmlfile, pythonfile, editor, set_current=True): """ Read filename as combine archive, unzip, translate, reconstitute in Python, and create an editor instance and return it *Warning* This is loading file, creating editor but not executing the source code analysis -- the analysis must be done by the editor plugin (in case multiple editorstack instances are handled) """ widgeteditor = editor.editorstacks[0] sbmlfile = str(sbmlfile) widgeteditor.starting_long_process.emit(_("Loading %s...") % sbmlfile) text, enc = encoding.read(sbmlfile) sbmlstr = te.readFromFile(sbmlfile) text = "import tellurium as te\n\nr = te.loada('''\n" + str( te.sbmlToAntimony(sbmlstr)) + "''')" finfo = widgeteditor.create_new_editor(pythonfile, enc, text, set_current, new=True) index = widgeteditor.data.index(finfo) widgeteditor._refresh_outlineexplorer(index, update=True) widgeteditor.ending_long_process.emit("") if widgeteditor.isVisible() and widgeteditor.checkeolchars_enabled \ and sourcecode.has_mixed_eol_chars(text): name = os.path.basename(pythonfile) QMessageBox.warning( self, widgeteditor.title, _("<b>%s</b> contains mixed end-of-line " "characters.<br>Spyder will fix this " "automatically.") % name, QMessageBox.Ok) widgeteditor.set_os_eol_chars(index) widgeteditor.is_analysis_done = False finfo.editor.set_cursor_position('eof') finfo.editor.insert_text(os.linesep) return finfo, sbmlfile
def discrete_test(self): """Creates a discrete test thread.""" _comments = self.ui.le_comments.text() try: _test_pos = self.ui.le_points.text() _test_pos = _test_pos.replace(' ', '').split(',') _test_pos = _np.array(_test_pos, dtype=float) except Exception: _msg = 'Please select the test points properly.' _QMessageBox.warning(self, 'Warning', _msg, _QMessageBox.Ok) return if any([_test_pos.max() > 11, _test_pos.min() < -11]): _msg = ('Positions out of bounds. ' 'All the points must within +/- 11 mm.') _QMessageBox.warning(self, 'Warning', _msg, _QMessageBox.Ok) return if self.test_thd is not None: if self.test_thd.is_alive(): _msg = 'Please wait until the current test finishes.' _QMessageBox.warning(self, 'Warning', _msg, _QMessageBox.Ok) return self.test_thd = ThdTestAxis(test_pos=_test_pos, comments=_comments, mode=0) self.test_thd.start()
def set_umr_namelist(self): """Set UMR excluded modules name list""" arguments, valid = QInputDialog.getText(self, _('UMR'), _("Set the list of excluded modules as " "this: <i>numpy, scipy</i>"), QLineEdit.Normal, ", ".join(self.get_option('umr/namelist'))) if valid: arguments = to_text_string(arguments) if arguments: namelist = arguments.replace(' ', '').split(',') fixed_namelist = [] non_ascii_namelist = [] for module_name in namelist: if PY2: if all(ord(c) < 128 for c in module_name): if programs.is_module_installed(module_name): fixed_namelist.append(module_name) else: QMessageBox.warning(self, _('Warning'), _("You are working with Python 2, this means that " "you can not import a module that contains non-" "ascii characters."), QMessageBox.Ok) non_ascii_namelist.append(module_name) elif programs.is_module_installed(module_name): fixed_namelist.append(module_name) invalid = ", ".join(set(namelist)-set(fixed_namelist)- set(non_ascii_namelist)) if invalid: QMessageBox.warning(self, _('UMR'), _("The following modules are not " "installed on your machine:\n%s" ) % invalid, QMessageBox.Ok) QMessageBox.information(self, _('UMR'), _("Please note that these changes will " "be applied only to new Python/IPython " "consoles"), QMessageBox.Ok) else: fixed_namelist = [] self.set_option('umr/namelist', fixed_namelist)
def convert(self): #Always reset these values before conversion. self.Theta = None self.flightpath = None try: if self.ui.InputVal.text() == "": raise RuntimeError("Input value is required for conversion") if float(self.ui.InputVal.text()) <= 0: raise RuntimeError("Input value must be greater than 0 for conversion") inOption = self.ui.inputUnits.currentText() outOption = self.ui.outputUnits.currentText() if self.ui.totalFlightPathInput.text() !='': self.flightpath = float(self.ui.totalFlightPathInput.text()) else: self.flightpath = -1.0 if self.ui.scatteringAngleInput.text() !='': self.Theta = float(self.ui.scatteringAngleInput.text()) * math.pi / 360.0 self.output = TofConverter.convertUnits.doConversion(self.ui.InputVal.text(), inOption, outOption, self.Theta, self.flightpath) self.ui.convertedVal.clear() self.ui.convertedVal.insert(str(self.output)) except UnboundLocalError as ule: QMessageBox.warning(self, "TofConverter", str(ule)) return except ArithmeticError as ae: QMessageBox.warning(self, "TofConverter", str(ae)) return except RuntimeError as re: QMessageBox.warning(self, "TofConverter", str(re)) return
def run_script_in_current_shell(self, filename, wdir, args, debug, post_mortem): """Run script in current shell, if any""" norm = lambda text: remove_backslashes(to_text_string(text)) line = "%s('%s'" % ('debugfile' if debug else 'runfile', norm(filename)) if args: line += ", args='%s'" % norm(args) if wdir: line += ", wdir='%s'" % norm(wdir) if post_mortem: line += ', post_mortem=True' line += ")" if not self.execute_code(line, interpreter_only=True): QMessageBox.warning(self, _('Warning'), _("No Python console is currently selected to run <b>%s</b>." "<br><br>Please select or open a new Python console " "and try again." ) % osp.basename(norm(filename)), QMessageBox.Ok) else: self.visibility_changed(True) self.raise_()
def import_measurement_profiles(self): dial = PLoadDialog( "Measurement profile (*.json)", settings=self.settings, path="io.export_directory", caption="Import settings profiles", parent=self, ) if dial.exec_(): file_path = str(dial.selectedFiles()[0]) stat, err = self.settings.load_part(file_path) if err: QMessageBox.warning( self, "Import error", "error during importing, part of data were filtered.") measurement_dict = self.settings.measurement_profiles imp = ImportDialog(stat, measurement_dict, StringViewer) if not imp.exec_(): return for original_name, final_name in imp.get_import_list(): measurement_dict[final_name] = stat[original_name] self.settings.dump()
def import_pipeline(self): dial = PLoadDialog( "Segment pipeline (*.json)", settings=self._settings, path=IO_SAVE_DIRECTORY, caption="Import pipeline segment", ) if dial.exec_(): file_path = dial.selectedFiles()[0] profs, err = self._settings.load_part(file_path) if err: QMessageBox.warning( self, "Import error", "error during importing, part of data were filtered.") profiles_dict = self._settings.roi_pipelines imp = ImportDialog(profs, profiles_dict, ProfileDictViewer) if not imp.exec_(): return for original_name, final_name in imp.get_import_list(): profiles_dict[final_name] = profs[original_name] self._settings.dump() self.update_profile_list()
def reset_to_default(self): """Reset to default values of the shortcuts making a confirmation.""" reset = QMessageBox.warning( self, _("Shortcuts reset"), _("Do you want to reset " "to default values?"), QMessageBox.Yes | QMessageBox.No) if reset == QMessageBox.No: return reset_shortcuts() self.main.apply_shortcuts() self.table.load_shortcuts() self.load_from_conf() self.set_modified(False)
def load(self): """Loads configuration set.""" try: if not self.flag_updating_list: _filename = self.ui.cmb_file.currentText() + '.dat' if _filename != '.dat': with open(_filename, 'r') as _f: _comments = _f.readline().split('Comments: ')[1][:-1] _points = _f.readline().split( 'Test positions [mm]: ')[1][:-1] self.df = _pd.read_csv(_filename, sep='\t', skiprows=2, header=0) self.ui.le_comments.setText(_comments) self.ui.le_points.setText(_points) self.list_data() self.print_parameters() except Exception: _traceback.print_exc(file=_sys.stdout) _msg = 'Could not open the file.' _QMessageBox.warning(self, 'Failure', _msg, _QMessageBox.Ok)
def import_measurement_profiles(self): dial = QFileDialog(self, "Import settings profiles") dial.setDirectory(self.settings.get("io.export_directory", "")) dial.setFileMode(QFileDialog.ExistingFile) dial.setNameFilter("measurement profile (*.json)") if dial.exec_(): file_path = str(dial.selectedFiles()[0]) self.settings.set("io.export_directory", file_path) stat, err = self.settings.load_part(file_path) if err: QMessageBox.warning( self, "Import error", "error during importing, part of data were filtered.") measurement_dict = self.settings.measurement_profiles imp = ImportDialog(stat, measurement_dict, StringViewer) if not imp.exec_(): return for original_name, final_name in imp.get_import_list(): measurement_dict[final_name] = stat[original_name] self.profile_list.clear() self.profile_list.addItems(list(sorted(measurement_dict.keys()))) self.settings.dump()
def report_no_external_server(self, host, port, language): """ Report that connection couldn't be established with an external server. """ if os.name == 'nt': os_message = ( "<br><br>" "To fix this, please verify that your firewall or antivirus " "allows Python processes to open ports in your system, or the " "settings you introduced in our Preferences to connect to " "external LSP servers." ) else: os_message = ( "<br><br>" "To fix this, please verify the settings you introduced in " "our Preferences to connect to external LSP servers." ) warn_str = ( _("It appears there is no {language} language server listening " "at address:" "<br><br>" "<tt>{host}:{port}</tt>" "<br><br>" "Therefore, completion and linting for {language} will not " "work during this session.").format( host=host, port=port, language=language.capitalize()) + os_message ) QMessageBox.warning( self.main, _("Warning"), warn_str ) self.show_no_external_server_warning = False
def _process(self, rows, group=False): """ Submit the processing. Args: rows (set(int)): row indexes group (bool): if True, the group(s) of the selected samples will be processed entirely """ if not rows: return self.view.set_disabled(True) self.view.set_progress(0, 100) if group: result = self.model.processGroup(rows) else: result = self.model.process(rows) if not result: QMessageBox.warning( self.view, "Error", "Please check the " "parameters value before processing.") self.view.set_disabled(False)
def closeEvent(self, event): if self.is_working(): ret = QMessageBox.warning( self, "Batch work", "Batch work is not finished. " "Would you like to terminate it?", QMessageBox.No | QMessageBox.Yes, ) if ret == QMessageBox.Yes: self.terminate() else: event.ignore() self.settings.set_in_profile("batch_window_geometry", self.saveGeometry().toHex().data().decode("ascii"))
def warn_python_compatibility(self, pyexec): if not osp.isfile(pyexec): return spyder_version = sys.version_info[0] try: args = ["-c", "import sys; print(sys.version_info[0])"] proc = programs.run_program(pyexec, args) console_version = int(proc.communicate()[0]) except IOError: console_version = spyder_version except ValueError: return False if spyder_version != console_version: QMessageBox.warning(self, _('Warning'), _("You selected a <b>Python %d</b> interpreter for the console " "but Spyder is running on <b>Python %d</b>!.<br><br>" "Although this is possible, we recommend you to install and " "run Spyder directly with your selected interpreter, to avoid " "seeing false warnings and errors due to the incompatible " "syntax between these two Python versions." ) % (console_version, spyder_version), QMessageBox.Ok) return True
def add_save_to_project(self): save_class = self.save_translate_dict.get( self.save_choose.currentText(), None) if save_class is None: QMessageBox.warning(self, "Save problem", "Not found save class") dial = FormDialog([ AlgorithmProperty("suffix", "File suffix", ""), AlgorithmProperty("directory", "Sub directory", "") ] + save_class.get_fields()) if dial.exec(): values = dial.get_values() suffix = values["suffix"] directory = values["directory"] del values["suffix"] del values["directory"] save_elem = Save(suffix, directory, save_class.get_name(), save_class.get_short_name(), values) if self.update_element_chk.isChecked(): self.calculation_plan.replace_step(save_elem) else: self.calculation_plan.add_step(save_elem) self.plan.update_view()
def reset_window_layout(self): """Reset window layout to default.""" answer = QMessageBox.warning( self, _("Warning"), _("Window layout will be reset to default settings: " "this affects window position, size and dockwidgets.\n" "Do you want to continue?"), QMessageBox.Yes | QMessageBox.No, ) if answer == QMessageBox.Yes: self._plugin.setup_layout(default=True)
def restore_settings(self) -> None: """Restore Pyslvs settings.""" prefer = Preferences() for field in fields(prefer): # type: Field setting = self.settings.value(field.name, field.default) setattr(prefer, field.name, setting) # Specified solver setting kernel = ARGUMENTS.kernel if kernel: if kernel == "python_solvespace": prefer.planar_solver_option = 1 elif kernel == "sketch_solve": prefer.planar_solver_option = 2 elif kernel == "pyslvs": prefer.planar_solver_option = 0 else: QMessageBox.warning( self, "Kernel not found", f"No such kernel: {kernel}" ) self.apply_preferences(prefer, force=True)
def set_image(self, image: Image) -> bool: if image is None: return False if image.is_time: if image.is_stack: QMessageBox.warning(self, "Not supported", "Data that are time data are currently not supported") return False res = QMessageBox.question( self, "Not supported", "Time data are currently not supported. Maybe You would like to treat time as z-stack", QMessageBox.Yes | QMessageBox.No, QMessageBox.No, ) if res == QMessageBox.Yes: image = image.swap_time_and_stack() else: return False self.settings.image = image return True
def find_all(self): paths = glob(str(self.paths.text())) paths = sorted([ x for x in (set(paths) - self.files_to_proceed) if not os.path.isdir(x) ]) if len(paths) > 0: dialog = AcceptFiles(paths) if dialog.exec_(): new_paths = dialog.get_files() for path in new_paths: size = os.stat(path).st_size size = float(size) / (1024**2) lwi = QListWidgetItem("{:s} ({:.2f} MB)".format( path, size)) lwi.setTextAlignment(Qt.AlignRight) self.selected_files.addItem(lwi) self.files_to_proceed.update(new_paths) self.file_list_changed.emit(self.files_to_proceed) else: QMessageBox.warning(self, "No new files", "No new files found", QMessageBox.Ok)
def calculate(self): if self.settings.segmentation is None: QMessageBox.warning(self, "No segmentation", "need segmentation to work") return to_calculate = [] for i in range(2, self.measurement_layout.count()): # noinspection PyTypeChecker chk: QCheckBox = self.measurement_layout.itemAt(i).widget() if chk.isChecked(): leaf: Leaf = MEASUREMENT_DICT[chk.text()].get_starting_leaf() to_calculate.append(leaf.replace_(per_component=PerComponent.Yes, area=AreaType.ROI)) if not to_calculate: QMessageBox.warning(self, "No measurement", "Select at least one measurement") return profile = MeasurementProfile("", [MeasurementEntry(x.name, x) for x in to_calculate]) dial = ExecuteFunctionDialog( profile.calculate, kwargs={ "channel": self.settings.image.get_channel(self.channel_select.get_value()), "segmentation": self.settings.segmentation, "mask": None, "voxel_size": self.settings.image.spacing, "result_units": self.units_select.get_value(), }, ) dial.exec() result: MeasurementResult = dial.get_result() values = result.get_separated() labels = result.get_labels() self.result_view.clear() self.result_view.setColumnCount(len(values) + 1) self.result_view.setRowCount(len(labels)) for i, val in enumerate(labels): self.result_view.setItem(i, 0, QTableWidgetItem(val)) for j, values_list in enumerate(values): for i, val in enumerate(values_list): self.result_view.setItem(i, j + 1, QTableWidgetItem(str(val)))
def load(self): """ The event that is called when open project is clicked on the main window :return: None; if the user cancelled. """ file_name = self._load_file_dialog() if file_name is None: # Cancel close dialogs return # Sanity check _, file_ext = os.path.splitext(file_name) if file_ext != ".mtdproj": QMessageBox.warning(None, "Wrong file type!", "Please select a valid project file", QMessageBox.Ok) directory = os.path.dirname(file_name) project_loader = ProjectLoader(self.project_file_ext) project_loader.load_project(directory) self.last_project_location = directory self.__saved = True