def show_keywords_need_review_message(sender, message=None): """Show a message keywords are not adequate to run an analysis. .. versionadded: 4.0 :param message: Additional message to display. :type message: str .. note:: The print button will be disabled if this method is called. """ LOGGER.debug('Showing incorrect keywords for v4 message') message = generate_input_error_message( tr('Layer Keywords Outdated:'), m.Paragraph( tr( 'Please update the keywords for your layers and then ' 'try to run the analysis again. Use the keyword wizard '), m.Image( 'file:///%s/img/icons/' 'show-keyword-wizard.svg' % resources_path(), **SMALL_ICON_STYLE), tr( ' icon in the toolbar to update your layer\'s keywords.'), message) ) send_static_message(sender, message)
def progress_callback(self, current_value, maximum_value, message=None): """GUI based callback implementation for showing progress. :param current_value: Current progress. :type current_value: int :param maximum_value: Maximum range (point at which task is complete. :type maximum_value: int :param message: Optional message dictionary to containing content we can display to the user. See safe.definitions.analysis_steps for an example of the expected format :type message: dict """ report = m.Message() report.add(LOGO_ELEMENT) report.add(m.Heading(tr('Analysis status'), **INFO_STYLE)) if message is not None: report.add(m.ImportantText(message['name'])) report.add(m.Paragraph(message['description'])) report.add(self.impact_function.performance_log_message()) send_static_message(self, report) self.progress_bar.setMaximum(maximum_value) self.progress_bar.setValue(current_value) QtGui.QApplication.processEvents()
def emit_pre_run_message(self): """Inform the user about parameters before starting the processing.""" title = tr('Processing started') details = tr( 'Please wait - processing may take a while depending on your ' 'hardware configuration and the analysis extents and data.') # trap for issue 706 try: exposure_name = self.exposure.name hazard_name = self.hazard.name # aggregation layer could be set to AOI so no check for that except AttributeError: title = tr('No valid layers') details = tr( 'Please ensure your hazard and exposure layers are set ' 'in the question area and then press run again.') message = m.Message(LOGO_ELEMENT, m.Heading(title, **WARNING_STYLE), m.Paragraph(details)) raise NoValidLayerError(message) text = m.Text( tr('This analysis will calculate the impact of'), m.EmphasizedText(hazard_name), tr('on'), m.EmphasizedText(exposure_name), ) if self.aggregation is not None: try: aggregation_name = self.aggregation.name # noinspection PyTypeChecker text.add( m.Text(tr('and bullet list the results'), m.ImportantText(tr('aggregated by')), m.EmphasizedText(aggregation_name))) except AttributeError: pass text.add('.') message = m.Message(LOGO_ELEMENT, m.Heading(title, **PROGRESS_UPDATE_STYLE), m.Paragraph(details), m.Paragraph(text)) try: # add which postprocessors will run when appropriated # noinspection PyTypeChecker post_processors_names = self.parameters['postprocessors'] post_processors = get_postprocessors(post_processors_names) message.add( m.Paragraph(tr('The following postprocessors will be used:'))) bullet_list = m.BulletedList() for name, post_processor in post_processors.iteritems(): bullet_list.add('%s: %s' % (get_postprocessor_human_name(name), post_processor.description())) message.add(bullet_list) except (TypeError, KeyError): # TypeError is for when function_parameters is none # KeyError is for when ['postprocessors'] is unavailable pass send_static_message(self, message)
def completed(self, zero_impact): """Slot activated when the process is done. :param zero_impact: Flag for zero impact. :type zero_impact: bool .. note:: Adapted from the dock """ # Try to run completion code # Show the result in the dock from layer if there is an impact. if not zero_impact: try: from datetime import datetime LOGGER.debug(datetime.now()) LOGGER.debug('get engine impact layer') LOGGER.debug(self.impact_function is None) # Load impact layer into QGIS qgis_impact_layer = read_impact_layer( self.impact_function.impact) report = self.show_results() except Exception, e: # pylint: disable=W0703 # FIXME (Ole): This branch is not covered by the tests self.analysis_error(e, self.tr('Error loading impact layer.')) else: # On success, display generated report impact_path = qgis_impact_layer.source() message = m.Message(report) # noinspection PyTypeChecker send_static_message(self, message) self.parent.step_fc_analysis.wvResults.impact_path = \ impact_path
def show_keywords_need_review_message(sender, message=None): """Show a message keywords are not adequate to run an analysis. .. versionadded: 4.0 :param sender: Sender of the message signal. Default to Any object. :type sender: object :param message: Additional message to display. :type message: str .. note:: The print button will be disabled if this method is called. """ LOGGER.debug('Showing incorrect keywords for v4 message') message = generate_input_error_message( tr('Layer Keywords Outdated:'), m.Paragraph( tr('Please update the keywords for your layers and then ' 'try to run the analysis again. Use the keyword wizard '), m.Image( 'file:///%s/img/icons/' 'show-keyword-wizard.svg' % resources_path(), **SMALL_ICON_STYLE), tr(' icon in the toolbar to update your layer\'s keywords.'), message)) send_static_message(sender, message)
def show_keyword_version_message(sender, keyword_version, inasafe_version): """Show a message indicating that the keywords version is mismatch .. versionadded: 3.2 :param keyword_version: The version of the layer's keywords :type keyword_version: str :param inasafe_version: The version of the InaSAFE :type inasafe_version: str .. note:: The print button will be disabled if this method is called. """ LOGGER.debug('Showing Mismatch Version Message') message = generate_input_error_message( tr('Layer Keyword\'s Version Mismatch:'), m.Paragraph( tr('Your layer\'s keyword\'s version ({layer_version}) does not ' 'match with your InaSAFE version ({inasafe_version}). If you ' 'wish to use it as an exposure, hazard, or aggregation layer ' 'in an analysis, please use the keyword wizard to update the ' 'keywords. You can open the wizard by clicking on ' 'the ').format(layer_version=keyword_version, inasafe_version=inasafe_version), m.Image( 'file:///%s/img/icons/' 'show-keyword-wizard.svg' % resources_path(), **SMALL_ICON_STYLE), tr(' icon in the toolbar.'))) send_static_message(sender, message)
def show_keyword_version_message(sender, keyword_version, inasafe_version): """Show a message indicating that the keywords version is mismatch .. versionadded: 3.2 :param keyword_version: The version of the layer's keywords :type keyword_version: str :param inasafe_version: The version of the InaSAFE :type inasafe_version: str .. note:: The print button will be disabled if this method is called. """ LOGGER.debug('Showing Mismatch Version Message') message = generate_input_error_message( tr('Layer Keyword\'s Version Mismatch:'), m.Paragraph( tr( 'Your layer\'s keyword\'s version ({layer_version}) does not ' 'match with your InaSAFE version ({inasafe_version}). If you ' 'wish to use it as an exposure, hazard, or aggregation layer ' 'in an analysis, please use the keyword wizard to update the ' 'keywords. You can open the wizard by clicking on ' 'the ').format( layer_version=keyword_version, inasafe_version=inasafe_version), m.Image( 'file:///%s/img/icons/' 'show-keyword-wizard.svg' % resources_path(), **SMALL_ICON_STYLE), tr( ' icon in the toolbar.')) ) send_static_message(sender, message)
def progress_callback(self, current_value, maximum_value, message=None): """GUI based callback implementation for showing progress. :param current_value: Current progress. :type current_value: int :param maximum_value: Maximum range (point at which task is complete. :type maximum_value: int :param message: Optional message dictionary to containing content we can display to the user. See safe.definitions.analysis_steps for an example of the expected format :type message: dict """ report = m.Message() report.add(LOGO_ELEMENT) report.add(m.Heading( tr('Analysis status'), **INFO_STYLE)) if message is not None: report.add(m.ImportantText(message['name'])) report.add(m.Paragraph(message['description'])) report.add(self.impact_function.performance_log_message()) send_static_message(self, report) self.progress_bar.setMaximum(maximum_value) self.progress_bar.setValue(current_value) QtGui.QApplication.processEvents()
def missing_keyword_message(sender, missing_keyword_exception): """Display an error when there is missing keyword. :param sender: The sender. :type sender: object :param missing_keyword_exception: A KeywordNotFoundError exception. :type missing_keyword_exception: KeywordNotFoundError """ warning_heading = m.Heading(tr('Missing Keyword'), **WARNING_STYLE) warning_message = tr( 'There is missing keyword that needed for this analysis.') detail_heading = m.Heading(tr('Detail'), **DETAILS_STYLE) suggestion_heading = m.Heading(tr('Suggestion'), **DETAILS_STYLE) detail = tr('The layer <b>%s</b> is missing the keyword <i>%s</i>.' % (missing_keyword_exception.layer_name, missing_keyword_exception.keyword)) suggestion = m.Paragraph( tr('Please use the keyword wizard to update the keywords. You ' 'can open the wizard by clicking on the '), m.Image( 'file:///%s/img/icons/' 'show-keyword-wizard.svg' % resources_path(), **SMALL_ICON_STYLE), tr(' icon in the toolbar.')) message = m.Message() message.add(warning_heading) message.add(warning_message) message.add(detail_heading) message.add(detail) message.add(suggestion_heading) message.add(suggestion) send_static_message(sender, message)
def show_options(self): """Show the options dialog.""" # import here only so that it is AFTER i18n set up from safe.gui.tools.options_dialog import OptionsDialog dialog = OptionsDialog(iface=self.iface, parent=self.iface.mainWindow()) if dialog.exec_(): # modal self.dock_widget.read_settings() from safe.gui.widgets.message import getting_started_message send_static_message(self.dock_widget, getting_started_message())
def print_map(self): """Open impact report dialog used to tune report when printing.""" # Check if selected layer is valid impact_layer = self.parent.iface.activeLayer() if impact_layer is None: # noinspection PyCallByClass,PyTypeChecker QtWidgets.QMessageBox.warning( self, 'InaSAFE', tr( 'Please select a valid impact layer before trying to ' 'print.')) return # Get output path from datastore # Fetch report for pdfs report report_path = os.path.dirname(impact_layer.source()) output_paths = [ os.path.join( report_path, 'output/impact-report-output.pdf'), os.path.join( report_path, 'output/inasafe-map-report-portrait.pdf'), os.path.join( report_path, 'output/inasafe-map-report-landscape.pdf'), ] # Make sure the file paths can wrap nicely: wrapped_output_paths = [ path.replace(os.sep, '<wbr>' + os.sep) for path in output_paths] # create message to user status = m.Message( m.Heading(tr('Map Creator'), **INFO_STYLE), m.Paragraph(tr( 'Your PDF was created....opening using the default PDF ' 'viewer on your system. The generated pdfs were saved ' 'as:'))) for path in wrapped_output_paths: status.add(m.Paragraph(path)) send_static_message(self, status) for path in output_paths: # noinspection PyCallByClass,PyTypeChecker,PyTypeChecker QtGui.QDesktopServices.openUrl( QtCore.QUrl.fromLocalFile(path))
def print_map(self): """Open impact report dialog used to tune report when printing.""" # Check if selected layer is valid impact_layer = self.parent.iface.activeLayer() if impact_layer is None: # noinspection PyCallByClass,PyTypeChecker QtGui.QMessageBox.warning( self, 'InaSAFE', tr( 'Please select a valid impact layer before trying to ' 'print.')) return # Get output path from datastore # Fetch report for pdfs report report_path = os.path.dirname(impact_layer.source()) output_paths = [ os.path.join( report_path, 'output/impact-report-output.pdf'), os.path.join( report_path, 'output/inasafe-map-report-portrait.pdf'), os.path.join( report_path, 'output/inasafe-map-report-landscape.pdf'), ] # Make sure the file paths can wrap nicely: wrapped_output_paths = [ path.replace(os.sep, '<wbr>' + os.sep) for path in output_paths] # create message to user status = m.Message( m.Heading(tr('Map Creator'), **INFO_STYLE), m.Paragraph(tr( 'Your PDF was created....opening using the default PDF ' 'viewer on your system. The generated pdfs were saved ' 'as:'))) for path in wrapped_output_paths: status.add(m.Paragraph(path)) send_static_message(self, status) for path in output_paths: # noinspection PyCallByClass,PyTypeChecker,PyTypeChecker QtGui.QDesktopServices.openUrl( QtCore.QUrl.fromLocalFile(path))
def show_options(self): """Show the options dialog.""" # import here only so that it is AFTER i18n set up from safe.gui.tools.options_dialog import OptionsDialog dialog = OptionsDialog(iface=self.iface, parent=self.iface.mainWindow()) dialog.show_option_dialog() if dialog.exec_(): # modal self.dock_widget.read_settings() from safe.gui.widgets.message import getting_started_message send_static_message(self.dock_widget, getting_started_message()) # Issue #4734, make sure to update the combobox after update the # InaSAFE option self.dock_widget.get_layers()
def open_as_pdf(self): """Print the selected report as a PDF product. .. versionadded: 4.3.0 """ # Get output path from datastore report_urls_dict = report_urls(self.impact_function) # get report urls for each product tag as list for key, value in list(report_urls_dict.items()): report_urls_dict[key] = list(value.values()) if self.dock: # create message to user status = m.Message( m.Heading(self.dock.tr('Map Creator'), **INFO_STYLE), m.Paragraph( self.dock. tr('Your PDF was created....opening using the default PDF ' 'viewer on your system.')), m.ImportantText( self.dock.tr('The generated pdfs were saved ' 'as:'))) for path in report_urls_dict.get(pdf_product_tag['key'], []): status.add(m.Paragraph(path)) status.add( m.Paragraph( m.ImportantText( self.dock.tr('The generated htmls were saved as:')))) for path in report_urls_dict.get(html_product_tag['key'], []): status.add(m.Paragraph(path)) status.add( m.Paragraph( m.ImportantText( self.dock.tr('The generated qpts were saved as:')))) for path in report_urls_dict.get(qpt_product_tag['key'], []): status.add(m.Paragraph(path)) send_static_message(self.dock, status) for path in report_urls_dict.get(pdf_product_tag['key'], []): # noinspection PyCallByClass,PyTypeChecker,PyTypeChecker QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(path))
def memory_error(): """Display an error when there is not enough memory.""" warning_heading = m.Heading(tr('Memory issue'), **WARNING_STYLE) warning_message = tr( 'There is not enough free memory to run this analysis.') suggestion_heading = m.Heading(tr('Suggestion'), **SUGGESTION_STYLE) suggestion = tr( 'Try zooming in to a smaller area or using a raster layer with a ' 'coarser resolution to speed up execution and reduce memory ' 'requirements. You could also try adding more RAM to your computer.') message = m.Message() message.add(warning_heading) message.add(warning_message) message.add(suggestion_heading) message.add(suggestion) send_static_message(dispatcher.Anonymous, message)
def open_as_pdf(self): """Print the selected report as a PDF product. .. versionadded: 4.3.0 """ # Get output path from datastore report_urls_dict = report_urls(self.impact_function) # get report urls for each product tag as list for key, value in list(report_urls_dict.items()): report_urls_dict[key] = list(value.values()) if self.dock: # create message to user status = m.Message( m.Heading(self.dock.tr('Map Creator'), **INFO_STYLE), m.Paragraph(self.dock.tr( 'Your PDF was created....opening using the default PDF ' 'viewer on your system.')), m.ImportantText(self.dock.tr( 'The generated pdfs were saved ' 'as:'))) for path in report_urls_dict.get(pdf_product_tag['key'], []): status.add(m.Paragraph(path)) status.add(m.Paragraph( m.ImportantText( self.dock.tr('The generated htmls were saved as:')))) for path in report_urls_dict.get(html_product_tag['key'], []): status.add(m.Paragraph(path)) status.add(m.Paragraph( m.ImportantText( self.dock.tr('The generated qpts were saved as:')))) for path in report_urls_dict.get(qpt_product_tag['key'], []): status.add(m.Paragraph(path)) send_static_message(self.dock, status) for path in report_urls_dict.get(pdf_product_tag['key'], []): # noinspection PyCallByClass,PyTypeChecker,PyTypeChecker QtGui.QDesktopServices.openUrl( QtCore.QUrl.fromLocalFile(path))
def memory_error(): """Display an error when there is not enough memory.""" warning_heading = m.Heading( tr('Memory issue'), **WARNING_STYLE) warning_message = tr( 'There is not enough free memory to run this analysis.') suggestion_heading = m.Heading( tr('Suggestion'), **SUGGESTION_STYLE) suggestion = tr( 'Try zooming in to a smaller area or using a raster layer with a ' 'coarser resolution to speed up execution and reduce memory ' 'requirements. You could also try adding more RAM to your computer.') message = m.Message() message.add(warning_heading) message.add(warning_message) message.add(suggestion_heading) message.add(suggestion) send_static_message(dispatcher.Anonymous, message)
def missing_keyword_message(sender, missing_keyword_exception): """Display an error when there is missing keyword. :param sender: The sender. :type sender: object :param missing_keyword_exception: A KeywordNotFoundError exception. :type missing_keyword_exception: KeywordNotFoundError """ warning_heading = m.Heading( tr('Missing Keyword'), **WARNING_STYLE) warning_message = tr( 'There is missing keyword that needed for this analysis.') detail_heading = m.Heading( tr('Detail'), **DETAILS_STYLE) suggestion_heading = m.Heading( tr('Suggestion'), **DETAILS_STYLE) detail = tr( 'The layer <b>%s</b> is missing the keyword <i>%s</i>.' % ( missing_keyword_exception.layer_name, missing_keyword_exception.keyword ) ) suggestion = m.Paragraph( tr('Please use the keyword wizard to update the keywords. You ' 'can open the wizard by clicking on the '), m.Image( 'file:///%s/img/icons/' 'show-keyword-wizard.svg' % resources_path(), **SMALL_ICON_STYLE), tr( ' icon in the toolbar.')) message = m.Message() message.add(warning_heading) message.add(warning_message) message.add(detail_heading) message.add(detail) message.add(suggestion_heading) message.add(suggestion) send_static_message(sender, message)
def show_no_keywords_message(sender): """Show a message indicating that no keywords are defined. .. note:: The print button will be disabled if this method is called. """ LOGGER.debug('Showing No Keywords Message') message = generate_input_error_message( tr('Layer keywords missing:'), m.Paragraph( tr('No keywords have been defined for this layer yet or there is ' 'an issue with the currently defined keywords and they need ' 'to be reviewed. If you wish to use this layer as an ' 'exposure, hazard, or aggregation layer in an analysis, ' 'please use the keyword wizard to update the keywords. You ' 'can open the wizard by clicking on the '), m.Image( 'file:///%s/img/icons/' 'show-keyword-wizard.svg' % resources_path(), **SMALL_ICON_STYLE), tr(' icon in the toolbar.'))) send_static_message(sender, message)
def show_no_keywords_message(sender): """Show a message indicating that no keywords are defined. .. note:: The print button will be disabled if this method is called. """ LOGGER.debug('Showing No Keywords Message') message = generate_input_error_message( tr('Layer keywords missing:'), m.Paragraph( tr( 'No keywords have been defined for this layer yet or there is ' 'an issue with the currently defined keywords and they need ' 'to be reviewed. If you wish to use this layer as an ' 'exposure, hazard, or aggregation layer in an analysis, ' 'please use the keyword wizard to update the keywords. You ' 'can open the wizard by clicking on the '), m.Image( 'file:///%s/img/icons/' 'show-keyword-wizard.svg' % resources_path(), **SMALL_ICON_STYLE), tr( ' icon in the toolbar.')) ) send_static_message(sender, message)
report = self.show_results( qgis_impact_layer, engine_impact_layer) except Exception, e: # pylint: disable=W0703 # FIXME (Ole): This branch is not covered by the tests self.analysis_error(e, self.tr('Error loading impact layer.')) else: # On success, display generated report impact_path = qgis_impact_layer.source() message = m.Message(report) # message.add(m.Heading(self.tr('View processing log as HTML'), # **INFO_STYLE)) # message.add(m.Link('file://%s' % self.parent.wvResults.log_path)) # noinspection PyTypeChecker send_static_message(self, message) self.parent.wvResults.impact_path = impact_path self.parent.pbProgress.hide() self.parent.lblAnalysisStatus.setText('Analysis done.') self.parent.pbnReportWeb.show() self.parent.pbnReportPDF.show() self.parent.pbnReportComposer.show() self.hide_busy() self.analysisDone.emit(True) def show_results(self, qgis_impact_layer, engine_impact_layer): """Helper function for slot activated when the process is done. .. note:: Adapted from the dock
def emit_pre_run_message(self): """Inform the user about parameters before starting the processing.""" title = tr('Processing started') details = tr( 'Please wait - processing may take a while depending on your ' 'hardware configuration and the analysis extents and data.') # trap for issue 706 try: exposure_name = self.exposure.name hazard_name = self.hazard.name # aggregation layer could be set to AOI so no check for that except AttributeError: title = tr('No valid layers') details = tr( 'Please ensure your hazard and exposure layers are set ' 'in the question area and then press run again.') message = m.Message( LOGO_ELEMENT, m.Heading(title, **WARNING_STYLE), m.Paragraph(details)) raise NoValidLayerError(message) text = m.Text( tr('This analysis will calculate the impact of'), m.EmphasizedText(hazard_name), tr('on'), m.EmphasizedText(exposure_name), ) if self.aggregation is not None: try: aggregation_name = self.aggregation.name # noinspection PyTypeChecker text.add(m.Text( tr('and bullet list the results'), m.ImportantText(tr('aggregated by')), m.EmphasizedText(aggregation_name))) except AttributeError: pass text.add('.') message = m.Message( LOGO_ELEMENT, m.Heading(title, **PROGRESS_UPDATE_STYLE), m.Paragraph(details), m.Paragraph(text)) try: # add which postprocessors will run when appropriated # noinspection PyTypeChecker post_processors_names = self.parameters['postprocessors'] post_processors = get_postprocessors(post_processors_names) message.add(m.Paragraph(tr( 'The following postprocessors will be used:'))) bullet_list = m.BulletedList() for name, post_processor in post_processors.iteritems(): bullet_list.add('%s: %s' % ( get_postprocessor_human_name(name), post_processor.description())) message.add(bullet_list) except (TypeError, KeyError): # TypeError is for when function_parameters is none # KeyError is for when ['postprocessors'] is unavailable pass send_static_message(self, message)
# Load impact layer into QGIS qgis_impact_layer = read_impact_layer(self.impact_function.impact) report = self.show_results() except Exception, e: # pylint: disable=W0703 # FIXME (Ole): This branch is not covered by the tests self.analysis_error(e, self.tr('Error loading impact layer.')) else: # On success, display generated report impact_path = qgis_impact_layer.source() message = m.Message(report) # message.add(m.Heading(self.tr('View processing log as HTML'), # **INFO_STYLE)) # message.add(m.Link('file://%s' % self.parent.wvResults.log_path)) # noinspection PyTypeChecker send_static_message(self, message) self.parent.step_fc_analysis.wvResults.impact_path = impact_path self.parent.step_fc_analysis.pbProgress.hide() self.parent.step_fc_analysis.lblAnalysisStatus.setText( 'Analysis done.') self.parent.step_fc_analysis.pbnReportWeb.show() self.parent.step_fc_analysis.pbnReportPDF.show() self.parent.step_fc_analysis.pbnReportComposer.show() self.hide_busy() self.analysisDone.emit(True) def show_impact_report(self, qgis_impact_layer): pass def show_results(self):