def build_post_processor_form(self, form_elements): """Build Post Processor Tab. :param form_elements: A Dictionary containing element of form. :type form_elements: dict """ scroll_layout = QVBoxLayout() scroll_widget = QWidget() scroll_widget.setLayout(scroll_layout) scroll = QScrollArea() scroll.setWidgetResizable(True) scroll.setWidget(scroll_widget) main_layout = QVBoxLayout() main_layout.addWidget(scroll) main_widget = QWidget() main_widget.setLayout(main_layout) self.tabWidget.addTab(main_widget, self.tr('Postprocessors')) self.tabWidget.tabBar().setVisible(True) # create elements for the tab values = OrderedDict() for label, parameters in form_elements.items(): parameter_container = ParameterContainer(parameters) parameter_container.setup_ui(must_scroll=False) scroll_layout.addWidget(parameter_container) input_values = parameter_container.get_parameters values[label] = input_values self.values['postprocessors'] = values scroll_layout.addStretch()
def main(): """Main function to run the example.""" app = QApplication([]) default_value_parameter = DefaultValueParameter() default_value_parameter.name = 'Value parameter' default_value_parameter.help_text = 'Help text' default_value_parameter.description = 'Description' default_value_parameter.labels = ['Setting', 'Do not use', 'Custom'] default_value_parameter.options = [0, 1, None] parameters = [default_value_parameter] extra_parameters = [(DefaultValueParameter, DefaultValueParameterWidget)] parameter_container = ParameterContainer(parameters, extra_parameters=extra_parameters) parameter_container.setup_ui() widget = QWidget() layout = QGridLayout() layout.addWidget(parameter_container) widget.setLayout(layout) widget.setGeometry(0, 0, 500, 500) widget.show() sys.exit(app.exec_())
def clear(self): """Clear current state.""" # Adapted from http://stackoverflow.com/a/13103617/1198772 for i in reversed(range(self.kwExtraKeywordsGridLayout.count())): self.kwExtraKeywordsGridLayout.itemAt(i).widget().setParent(None) self.parameters = [] self.parameter_container = ParameterContainer()
def main(): """Main function to run the example.""" app = QApplication([]) default_value_parameter = DefaultValueParameter() default_value_parameter.name = 'Value parameter' default_value_parameter.help_text = 'Help text' default_value_parameter.description = 'Description' default_value_parameter.labels = [ 'Setting', 'Do not use', 'Custom'] default_value_parameter.options = [0, 1, None] parameters = [ default_value_parameter ] extra_parameters = [ (DefaultValueParameter, DefaultValueParameterWidget) ] parameter_container = ParameterContainer( parameters, extra_parameters=extra_parameters) parameter_container.setup_ui() widget = QWidget() layout = QGridLayout() layout.addWidget(parameter_container) widget.setLayout(layout) widget.setGeometry(0, 0, 500, 500) widget.show() sys.exit(app.exec_())
def build_minimum_needs_form(self, parameters): """Build minimum needs tab. :param parameters: A list containing element of form :type parameters: list """ # create minimum needs tab scroll_layout = QVBoxLayout() scroll_widget = QWidget() scroll_widget.setLayout(scroll_layout) scroll = QScrollArea() scroll.setWidgetResizable(True) scroll.setWidget(scroll_widget) main_layout = QVBoxLayout() main_layout.addWidget(scroll) main_widget = QWidget() main_widget.setLayout(main_layout) extra_parameters = [(ResourceParameter, ResourceParameterWidget)] parameter_container = ParameterContainer( parameters=parameters, extra_parameters=extra_parameters) parameter_container.setup_ui() scroll_layout.addWidget(parameter_container) self.tabWidget.addTab(main_widget, self.tr('Minimum Needs')) self.tabWidget.tabBar().setVisible(True) self.values['minimum needs'] = parameter_container.get_parameters
def build_post_processor_form(self, form_elements): """Build Post Processor Tab. :param form_elements: A Dictionary containing element of form. :type form_elements: dict """ scroll_layout = QVBoxLayout() scroll_widget = QWidget() scroll_widget.setLayout(scroll_layout) scroll = QScrollArea() scroll.setWidgetResizable(True) scroll.setWidget(scroll_widget) main_layout = QVBoxLayout() main_layout.addWidget(scroll) main_widget = QWidget() main_widget.setLayout(main_layout) self.tabWidget.addTab(main_widget, self.tr('Postprocessors')) self.tabWidget.tabBar().setVisible(True) # create elements for the tab values = OrderedDict() for label, parameters in form_elements.items(): parameter_container = ParameterContainer(parameters) parameter_container.setup_ui(must_scroll=False) scroll_layout.addWidget(parameter_container) input_values = parameter_container.get_parameters values[label] = input_values self.values['postprocessors'] = values scroll_layout.addStretch()
def build_minimum_needs_form(self, parameters): """Build minimum needs tab. :param parameters: A list containing element of form :type parameters: list """ # create minimum needs tab scroll_layout = QVBoxLayout() scroll_widget = QWidget() scroll_widget.setLayout(scroll_layout) scroll = QScrollArea() scroll.setWidgetResizable(True) scroll.setWidget(scroll_widget) main_layout = QVBoxLayout() main_layout.addWidget(scroll) main_widget = QWidget() main_widget.setLayout(main_layout) extra_parameters = [(ResourceParameter, ResourceParameterWidget)] parameter_container = ParameterContainer( parameters=parameters, extra_parameters=extra_parameters) parameter_container.setup_ui() scroll_layout.addWidget(parameter_container) self.tabWidget.addTab(main_widget, self.tr('Minimum Needs')) self.tabWidget.tabBar().setVisible(True) self.values['minimum needs'] = parameter_container.get_parameters
def clear(self): """Clear current state.""" # Adapted from http://stackoverflow.com/a/13103617/1198772 for i in reversed(range(self.default_values_grid.count())): self.default_values_grid.itemAt(i).widget().setParent(None) self.parameters = [] self.parameter_container = ParameterContainer()
def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.parameters = [] self.parameter_container = ParameterContainer() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container)
def set_widgets(self): """Set widgets on the Extra Keywords tab.""" existing_inasafe_default_values = self.parent.get_existing_keyword( 'inasafe_default_values') # Remove old container and parameter if self.parameter_container: self.default_values_grid.removeWidget(self.parameter_container) if self.parameters: self.parameters = [] # Iterate through all inasafe fields # existing_inasafe_default_values for inasafe_field in self.inasafe_fields_for_the_layer(): # Create DefaultSelectParameter parameter = DefaultValueParameter() parameter.guid = inasafe_field['key'] parameter.name = inasafe_field['name'] parameter.is_required = False parameter.help_text = inasafe_field['default_value']['description'] # parameter.description = inasafe_field['default_value'] parameter.element_type = unicode parameter.labels = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[0] parameter.options = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[1] if existing_inasafe_default_values: existing_default_value = existing_inasafe_default_values.get( inasafe_field['key']) if existing_default_value: parameter.default = existing_default_value self.parameters.append(parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer( self.parameters, extra_parameters=self.extra_parameters) self.parameter_container.setup_ui() self.default_values_grid.addWidget(self.parameter_container) # Set default value to None for parameter_widget in self.parameter_container.\ get_parameter_widgets(): parameter_widget.widget().set_value(None) # Set default value from existing keywords if existing_inasafe_default_values: for guid, default in existing_inasafe_default_values.items(): parameter_widget = self.parameter_container.\ get_parameter_widget_by_guid(guid) if isinstance(parameter_widget, DefaultValueParameterWidget): parameter_widget.set_value(default)
def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.extra_parameters = [(DefaultValueParameter, DefaultValueParameterWidget)] self.parameters = [] self.parameter_container = ParameterContainer( extra_parameters=self.extra_parameters) self.default_values_grid.addWidget(self.parameter_container)
def clear(self): """Clear current state.""" # Adapted from http://stackoverflow.com/a/13103617/1198772 for i in reversed(range(self.default_values_grid.count())): self.default_values_grid.itemAt(i).widget().setParent(None) self.parameters = [] self.parameter_container = ParameterContainer()
def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.extra_parameters = [(DefaultSelectParameter, DefaultSelectParameterWidget)] self.parameters = [] self.parameter_container = ParameterContainer( extra_parameters=self.extra_parameters) self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) self.message_label = QLabel()
def clear(self): """Clear current state.""" # Adapted from http://stackoverflow.com/a/13103617/1198772 for i in reversed(range(self.kwExtraKeywordsGridLayout.count())): self.kwExtraKeywordsGridLayout.itemAt(i).widget().setParent(None) self.parameters = [] self.parameter_container = ParameterContainer()
def raster_changed(self, index): """Executed when raster is changed :param index: index of the selected raster :return: """ registry = QgsMapLayerRegistry.instance() layer_id = self.cbo_raster_input.itemData( index, QtCore.Qt.UserRole) layer = registry.mapLayer(layer_id) layer_purpose = self.keyword_io.read_keywords(layer, 'layer_purpose') if layer_purpose == 'hazard': impact_function = self.if_registry.filter_by_hazard( self.if_registry.impact_functions, self.keyword_io.read_keywords(layer) ) elif layer_purpose == 'exposure': impact_function = self.if_registry.filter_by_exposure( self.if_registry.impact_functions, self.keyword_io.read_keywords(layer) ) else: impact_function = [] if impact_function: parameters_dict = impact_function[0].parameters threshold_list = [] for param_key, param_value in parameters_dict.iteritems(): if 'threshold' in param_key: threshold_list.append(param_value) if threshold_list: param_container = ParameterContainer(threshold_list) param_container.setup_ui(must_scroll=False) self.threshold_editor.layout().addWidget(param_container) else: empty_threshold_label = QLabel( self.tr('No threshold configuration available ' 'for this layer')) self.threshold_editor.layout().addWidget( empty_threshold_label)
def build_widget(self, form_layout, name, parameter_value): """Create a new form element dynamically based from key_value type. The Parameter Container will be inserted to form_layout. :param form_layout: Mandatory a layout instance :type form_layout: QFormLayout :param name: Mandatory string referencing the key in the function configurable parameters dictionary. :type name: str :param parameter_value: Mandatory representing the value referenced by the key. :type parameter_value: object, list :returns: a function that return the value of widget :raises: None """ input_values = None if parameter_value is not None: # create and add widget to the dialog box # default tab's layout parameter_container = ParameterContainer(parameter_value) parameter_container.setup_ui(must_scroll=False) for w in [ w.widget() for w in parameter_container.get_parameter_widgets() ]: # Rizky : assign error handler for # InputListParameterWidget w.add_row_error_handler = self.explain_errors form_layout.addWidget(parameter_container) # bind parameter input_values = parameter_container.get_parameters self.values[name] = input_values else: LOGGER.debug('build_widget : parameter is None') LOGGER.debug(parameter_value) return input_values
def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.parameters = [] self.parameter_container = ParameterContainer() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container)
def set_widgets(self): """Set widgets on the Extra Keywords tab.""" existing_inasafe_default_values = self.parent.get_existing_keyword( 'inasafe_default_values') # Remove old container and parameter if self.parameter_container: self.default_values_grid.removeWidget( self.parameter_container) if self.parameters: self.parameters = [] # Iterate through all inasafe fields # existing_inasafe_default_values for inasafe_field in self.inasafe_fields_for_the_layer(): # Create DefaultSelectParameter parameter = DefaultValueParameter() parameter.guid = inasafe_field['key'] parameter.name = inasafe_field['name'] parameter.is_required = False parameter.help_text = inasafe_field['default_value']['description'] # parameter.description = inasafe_field['default_value'] parameter.element_type = unicode parameter.labels = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[0] parameter.options = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[1] if existing_inasafe_default_values: existing_default_value = existing_inasafe_default_values.get( inasafe_field['key']) if existing_default_value: parameter.default = existing_default_value self.parameters.append(parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer( self.parameters, extra_parameters=self.extra_parameters) self.parameter_container.setup_ui() self.default_values_grid.addWidget(self.parameter_container) # Set default value to None for parameter_widget in self.parameter_container.\ get_parameter_widgets(): parameter_widget.widget().set_value(None) # Set default value from existing keywords if existing_inasafe_default_values: for guid, default in existing_inasafe_default_values.items(): parameter_widget = self.parameter_container.\ get_parameter_widget_by_guid(guid) if isinstance(parameter_widget, DefaultValueParameterWidget): parameter_widget.set_value(default)
def build_widget(self, form_layout, name, parameter_value): """Create a new form element dynamically based from key_value type. The Parameter Container will be inserted to form_layout. :param form_layout: Mandatory a layout instance :type form_layout: QFormLayout :param name: Mandatory string referencing the key in the function configurable parameters dictionary. :type name: str :param parameter_value: Mandatory representing the value referenced by the key. :type parameter_value: object, list :returns: a function that return the value of widget :raises: None """ input_values = None if parameter_value is not None: # create and add widget to the dialog box # default tab's layout parameter_container = ParameterContainer(parameter_value) parameter_container.setup_ui(must_scroll=False) for w in [w.widget() for w in parameter_container.get_parameter_widgets()]: # Rizky : assign error handler for # InputListParameterWidget w.add_row_error_handler = self.explain_errors form_layout.addWidget(parameter_container) # bind parameter input_values = parameter_container.get_parameters self.values[name] = input_values else: LOGGER.debug('build_widget : parameter is None') LOGGER.debug(parameter_value) return input_values
def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.extra_parameters = [ (DefaultValueParameter, DefaultValueParameterWidget) ] self.parameters = [] self.parameter_container = ParameterContainer( extra_parameters=self.extra_parameters) self.default_values_grid.addWidget(self.parameter_container)
def build_minimum_needs_form(self, parameters): """Build minimum needs tab. :param parameters: A list containing element of form :type parameters: list """ # create minimum needs tab tab = QWidget() form_layout = QGridLayout(tab) form_layout.setContentsMargins(0, 0, 0, 0) parameter_container = ParameterContainer(parameters) form_layout.addWidget(parameter_container) self.tabWidget.addTab(tab, self.tr('Minimum Needs')) self.tabWidget.tabBar().setVisible(True) self.values['minimum needs'] = parameter_container.get_parameters
def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.extra_parameters = [ (DefaultSelectParameter, DefaultSelectParameterWidget) ] self.parameters = [] self.parameter_container = ParameterContainer( extra_parameters=self.extra_parameters) self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) self.message_label = QLabel()
class StepKwDefaultInaSAFEFields(WizardStep, FORM_CLASS): """Keyword Wizard Step: Default InaSAFE Fields""" def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.extra_parameters = [(DefaultSelectParameter, DefaultSelectParameterWidget)] self.parameters = [] self.parameter_container = ParameterContainer( extra_parameters=self.extra_parameters) self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) self.message_label = QLabel() def is_ready_to_next_step(self): """Check if the step is complete. If so, there is no reason to block the Next button. :returns: True if new step may be enabled. :rtype: bool """ return True def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to :rtype: WizardStep instance or None """ new_step = self.parent.step_kw_source return new_step def inasafe_fields_for_the_layer(self): """Return a list of inasafe fields the current layer. :returns: A list where each value represents inasafe field. :rtype: list """ if (self.parent.get_layer_geometry_key() == layer_geometry_raster['key']): return [] # Get hazard or exposure value layer_purpose_key = self.parent.step_kw_purpose.selected_purpose( )['key'] if layer_purpose_key != layer_purpose_aggregation['key']: subcategory_key = self.parent.step_kw_subcategory.\ selected_subcategory()['key'] else: subcategory_key = None # Get all fields with replace_null = True inasafe_fields = get_fields(layer_purpose_key, subcategory_key, replace_null=True, in_group=False) # remove compulsory field since it has been set in previous step try: inasafe_fields.remove( get_compulsory_fields(layer_purpose_key, subcategory_key)) except ValueError: pass return inasafe_fields # noinspection PyTypeChecker def set_widgets(self): """Set widgets on the Extra Keywords tab.""" self.clear() existing_inasafe_field = self.parent.get_existing_keyword( 'inasafe_fields') existing_inasafe_default_values = self.parent.get_existing_keyword( 'inasafe_default_values') # Remove old container and parameter if self.parameter_container: self.kwExtraKeywordsGridLayout.removeWidget( self.parameter_container) if self.parameters: self.parameters = [] layer_data_provider = self.parent.layer.dataProvider() # Iterate through all inasafe fields # existing_inasafe_default_values for inasafe_field in self.inasafe_fields_for_the_layer(): # Option for Not Available option_list = [no_field] for field in layer_data_provider.fields(): # Check the field type if isinstance(inasafe_field['type'], list): if field.type() in inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) else: if field.type() == inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) # Create DefaultSelectParameter parameter = DefaultSelectParameter() parameter.guid = inasafe_field['key'] parameter.name = inasafe_field['name'] parameter.is_required = False parameter.description = inasafe_field['description'] parameter.help_text = inasafe_field['help_text'] parameter.element_type = unicode parameter.options_list = option_list parameter.value = no_field parameter.default_labels = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[0] parameter.default_values = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[1] parameter.minimum = inasafe_field['default_value'].get('min_value') parameter.maximum = inasafe_field['default_value'].get('max_value') # Check if there is already value in the metadata. if existing_inasafe_field: existing_value = existing_inasafe_field.get( inasafe_field['key']) if existing_value: if existing_value in parameter.options_list: parameter.value = existing_value if existing_inasafe_default_values: existing_default_value = existing_inasafe_default_values.get( inasafe_field['key']) if existing_default_value: parameter.default = existing_default_value self.parameters.append(parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer( self.parameters, extra_parameters=self.extra_parameters) self.parameter_container.setup_ui() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) # Add Message label self.kwExtraKeywordsGridLayout.addWidget(self.message_label) # Set default value to None for parameter_widget in self.parameter_container.\ get_parameter_widgets(): parameter_widget.widget().set_default(None) # Set selected radio button to 'Do not use' parameter_widget.widget().set_selected_radio_button() # Set default value from existing keywords if existing_inasafe_default_values: for guid, default in existing_inasafe_default_values.items(): parameter_widget = self.parameter_container.\ get_parameter_widget_by_guid(guid) if isinstance(parameter_widget, DefaultSelectParameterWidget): parameter_widget.set_default(default) # Set selected radio button to 'Do not use' parameter_widget.set_selected_radio_button() def get_inasafe_fields(self): """Return inasafe fields from the current wizard state. :returns: Dictionary of key and value from InaSAFE Fields. :rtype: dict """ inasafe_fields = {} parameters = self.parameter_container.get_parameters(True) for parameter in parameters: if not parameter.value == no_field: inasafe_fields[parameter.guid] = parameter.value return inasafe_fields def get_inasafe_default_values(self): """Return inasafe default from the current wizard state. :returns: Dictionary of key and value from InaSAFE Default Values. :rtype: dict """ inasafe_default_values = {} parameters = self.parameter_container.get_parameters(True) for parameter in parameters: if parameter.default is not None: inasafe_default_values[parameter.guid] = parameter.default return inasafe_default_values def clear(self): """Clear current state.""" # Adapted from http://stackoverflow.com/a/13103617/1198772 for i in reversed(range(self.kwExtraKeywordsGridLayout.count())): self.kwExtraKeywordsGridLayout.itemAt(i).widget().setParent(None) self.parameters = [] self.parameter_container = ParameterContainer() def is_good_age_ratios(self): """Method to check the sum of age ratio is 1. :returns: True if the sum is 1 or the sum less than 1 but there is None. :rtype: bool """ default_values = self.get_inasafe_default_values() youth_ratio = default_values.get(youth_ratio_field['key']) adult_ratio = default_values.get(adult_ratio_field['key']) elderly_ratio = default_values.get(elderly_ratio_field['key']) ratios = [youth_ratio, adult_ratio, elderly_ratio] if None in ratios: # If there is None, just check to not exceeding 1 clean_ratios = [x for x in ratios if x is not None] ratios.remove(None) if sum(clean_ratios) > 1: return False else: if sum(ratios) != 1: return False return True def toggle_age_ratio_sum_message(self, flag): """Method to show error message about sum of age ratio. :param flag: Flag if the ratio is valid or not. :type flag: bool """ if not flag: self.message_label.setText( tr('The sum of your age ratios is not 1. Please fix it ' 'first before you can continue to the next step.')) self.message_label.setStyleSheet('color: red') else: self.message_label.setText(tr('You are good to go.')) self.message_label.setStyleSheet('color: green')
def set_widgets(self): """Set widgets on the Extra Keywords tab.""" existing_inasafe_field = self.parent.get_existing_keyword( 'inasafe_fields') # Remove old container and parameter if self.parameter_container: self.kwExtraKeywordsGridLayout.removeWidget( self.parameter_container) if self.parameters: self.parameters = [] layer_data_provider = self.parent.layer.dataProvider() # Iterate through all inasafe fields for inasafe_field in self.inasafe_fields_for_the_layer(): # Option for Not Available option_list = [no_field] for field in layer_data_provider.fields(): # Check the field type if isinstance(inasafe_field['type'], list): if field.type() in inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) else: if field.type() == inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) # If there is no option, pass if option_list == [no_field]: continue # Create SelectParameter select_parameter = SelectParameter() select_parameter.guid = inasafe_field['key'] select_parameter.name = inasafe_field['name'] select_parameter.is_required = False select_parameter.description = inasafe_field['description'] select_parameter.help_text = inasafe_field['help_text'] select_parameter.element_type = unicode select_parameter.options_list = option_list select_parameter.value = no_field # Check if there is already value in the metadata. if existing_inasafe_field: existing_value = existing_inasafe_field.get( inasafe_field['key']) if existing_value: if existing_value in select_parameter.options_list: select_parameter.value = existing_value self.parameters.append(select_parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer(self.parameters) self.parameter_container.setup_ui() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) if not self.parameters: no_field_message = tr( 'There is no available field that has match type for the ' 'InaSAFE fields. You can click next.') self.lblInaSAFEFields.setText(no_field_message)
def restore_default_values_page(self): """Setup UI for default values setting.""" # Clear parameters so it doesn't add parameters when # restore from changes. if self.default_value_parameters: self.default_value_parameters = [] if self.default_value_parameter_containers: self.default_value_parameter_containers = [] default_fields = all_default_fields() for field_group in all_field_groups: settable_fields = [] for field in field_group['fields']: if field not in default_fields: continue else: settable_fields.append(field) default_fields.remove(field) if not settable_fields: continue # Create group box for each field group group_box = QGroupBox(self) group_box.setTitle(field_group['name']) self.container_layout.addWidget(group_box) parameters = [] for settable_field in settable_fields: parameter = self.default_field_to_parameter(settable_field) if parameter: parameters.append(parameter) parameter_container = ParameterContainer( parameters, description_text=field_group['description'] ) parameter_container.setup_ui(must_scroll=False) group_box_inner_layout = QVBoxLayout() group_box_inner_layout.addWidget(parameter_container) group_box.setLayout(group_box_inner_layout) # Add to attribute self.default_value_parameter_containers.append(parameter_container) # Only show non-groups default fields if there is one if len(default_fields) > 0: for default_field in default_fields: parameter = self.default_field_to_parameter(default_field) if parameter: self.default_value_parameters.append(parameter) description_text = tr( 'In this options you can change the global default values for ' 'these variables.') parameter_container = ParameterContainer( self.default_value_parameters, description_text=description_text) parameter_container.setup_ui(must_scroll=False) self.other_group_box = QGroupBox(tr('Non-group fields')) other_group_inner_layout = QVBoxLayout() other_group_inner_layout.addWidget(parameter_container) self.other_group_box.setLayout(other_group_inner_layout) self.container_layout.addWidget(self.other_group_box) # Add to attribute self.default_value_parameter_containers.append(parameter_container)
def restore_default_values_page(self): """Setup UI for default values setting.""" # Clear parameters so it doesn't add parameters when # restore from changes. if self.default_value_parameters: self.default_value_parameters = [] if self.default_value_parameter_containers: self.default_value_parameter_containers = [] default_fields = all_default_fields() for field_group in all_field_groups: settable_fields = [] for field in field_group['fields']: if field not in default_fields: continue else: settable_fields.append(field) default_fields.remove(field) if not settable_fields: continue # Create group box for each field group group_box = QGroupBox(self) group_box.setTitle(field_group['name']) self.container_layout.addWidget(group_box) parameters = [] for settable_field in settable_fields: parameter = self.default_field_to_parameter(settable_field) if parameter: parameters.append(parameter) parameter_container = ParameterContainer( parameters, description_text=field_group['description']) parameter_container.setup_ui(must_scroll=False) group_box_inner_layout = QVBoxLayout() group_box_inner_layout.addWidget(parameter_container) group_box.setLayout(group_box_inner_layout) # Add to attribute self.default_value_parameter_containers.append(parameter_container) # Only show non-groups default fields if there is one if len(default_fields) > 0: for default_field in default_fields: parameter = self.default_field_to_parameter(default_field) if parameter: self.default_value_parameters.append(parameter) description_text = tr( 'In this options you can change the global default values for ' 'these variables.') parameter_container = ParameterContainer( self.default_value_parameters, description_text=description_text) parameter_container.setup_ui(must_scroll=False) self.other_group_box = QGroupBox(tr('Non-group fields')) other_group_inner_layout = QVBoxLayout() other_group_inner_layout.addWidget(parameter_container) self.other_group_box.setLayout(other_group_inner_layout) self.container_layout.addWidget(self.other_group_box) # Add to attribute self.default_value_parameter_containers.append(parameter_container)
class OptionsDialog(QtGui.QDialog, FORM_CLASS): """Options dialog for the InaSAFE plugin.""" def __init__(self, iface, dock=None, parent=None, qsetting=''): """Constructor for the dialog. :param iface: A Quantum GIS QGisAppInterface instance. :type iface: QGisAppInterface :param parent: Parent widget of this dialog :type parent: QWidget :param dock: Optional dock widget instance that we can notify of changes to the keywords. :type dock: Dock :param qsetting: String to specify the QSettings. By default, use empty string. :type qsetting: str """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr('InaSAFE %s Options' % get_version())) # Save reference to the QGIS interface and parent self.iface = iface self.parent = parent self.dock = dock if qsetting: self.settings = QtCore.QSettings(qsetting) else: self.settings = QtCore.QSettings() # InaSAFE default values self.default_value_parameters = [] self.default_value_parameter_container = None # Flag for restore default values self.is_restore_default = False # List of setting key and control self.boolean_settings = { 'visibleLayersOnlyFlag': self.cbxVisibleLayersOnly, 'set_layer_from_title_flag': self.cbxSetLayerNameFromTitle, 'setZoomToImpactFlag': self.cbxZoomToImpact, 'set_show_only_impact_on_report': self.cbx_show_only_impact, 'setHideExposureFlag': self.cbxHideExposure, 'useSelectedFeaturesOnly': self.cbxUseSelectedFeaturesOnly, 'useSentry': self.cbxUseSentry, 'template_warning_verbose': self.template_warning_checkbox, 'showOrganisationLogoInDockFlag': self.organisation_on_dock_checkbox, 'developer_mode': self.cbxDevMode, 'generate_report': self.checkbox_generate_reports, } self.text_settings = { 'keywordCachePath': self.leKeywordCachePath, 'ISO19115_ORGANIZATION': self.iso19115_organization_le, 'ISO19115_URL': self.iso19115_url_le, 'ISO19115_EMAIL': self.iso19115_email_le, 'ISO19115_TITLE': self.iso19115_title_le, 'ISO19115_LICENSE': self.iso19115_license_le, } # Set up things for context help self.help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Always set first tab to be open, 0-th index self.tabWidget.setCurrentIndex(0) # Hide not implemented group self.grpNotImplemented.hide() self.adjustSize() self.restore_state() # Hide checkbox if not developers if not self.cbxDevMode.isChecked(): self.checkbox_generate_reports.hide() # Set up listener for various UI self.custom_org_logo_checkbox.toggled.connect( self.set_organisation_logo) self.custom_north_arrow_checkbox.toggled.connect(self.set_north_arrow) self.custom_UseUserDirectory_checkbox.toggled.connect( self.set_user_dir) self.custom_templates_dir_checkbox.toggled.connect( self.set_templates_dir) self.custom_org_disclaimer_checkbox.toggled.connect( self.set_org_disclaimer) # Set up listener for restore defaults button self.restore_defaults = self.button_box_restore_defaults.button( QtGui.QDialogButtonBox.RestoreDefaults) self.restore_defaults.setCheckable(True) self.restore_defaults.clicked.connect( self.restore_defaults_ratio) # TODO: Hide this until behaviour is defined # hide template warning toggle self.template_warning_checkbox.hide() # hide custom template dir toggle self.custom_templates_dir_checkbox.hide() self.splitter_custom_report.hide() def save_boolean_setting(self, key, check_box): """Save boolean setting according to check_box state. :param key: Key to retrieve setting value. :type key: str :param check_box: Check box to show and set the setting. :type check_box: PyQt4.QtGui.QCheckBox.QCheckBox """ self.settings.setValue('inasafe/%s' % key, check_box.isChecked()) def restore_boolean_setting(self, key, check_box): """Set check_box according to setting of key. :param key: Key to retrieve setting value. :type key: str :param check_box: Check box to show and set the setting. :type check_box: PyQt4.QtGui.QCheckBox.QCheckBox """ flag = bool(self.settings.value( 'inasafe/%s' % key, inasafe_default_settings[key], type=bool)) check_box.setChecked(flag) def save_text_setting(self, key, line_edit): """Save text setting according to line_edit value. :param key: Key to retrieve setting value. :type key: str :param line_edit: Line edit for user to edit the setting :type line_edit: PyQt4.QtGui.QLineEdit.QLineEdit """ self.settings.setValue('inasafe/%s' % key, line_edit.text()) def restore_text_setting(self, key, line_edit): """Set line_edit text according to setting of key :param key: Key to retrieve setting value. :type key: str :param line_edit: Line edit for user to edit the setting :type line_edit: PyQt4.QtGui.QLineEdit.QLineEdit """ value = self.settings.value( 'inasafe/%s' % key, inasafe_default_settings[key], type=str) line_edit.setText(value) def restore_state(self): """Reinstate the options based on the user's stored session info.""" # Restore boolean setting as check box. for key, check_box in self.boolean_settings.items(): self.restore_boolean_setting(key, check_box) # Restore text setting as line edit. for key, line_edit in self.text_settings.items(): self.restore_text_setting(key, line_edit) # Restore Organisation Logo Path org_logo_path = self.settings.value( 'inasafe/organisation_logo_path', supporters_logo_path(), type=str) custom_org_logo_flag = ( org_logo_path != supporters_logo_path()) self.custom_org_logo_checkbox.setChecked(custom_org_logo_flag) self.leOrganisationLogoPath.setText(org_logo_path) # User Directory user_directory_path = self.settings.value( 'inasafe/defaultUserDirectory', temp_dir('impacts'), type=str) custom_user_directory_flag = ( user_directory_path != temp_dir('impacts')) self.custom_UseUserDirectory_checkbox.setChecked( custom_user_directory_flag) self.splitter_user_directory.setEnabled(custom_user_directory_flag) self.leUserDirectoryPath.setText(user_directory_path) # Earthquake function. # Populate the combobox first. for model in EARTHQUAKE_FUNCTIONS: self.earthquake_function.addItem(model['name'], model['key']) # Then make selected the default one. default_earthquake_function = setting('earthquake_function', str) keys = [model['key'] for model in EARTHQUAKE_FUNCTIONS] if default_earthquake_function not in keys: default_earthquake_function = EARTHQUAKE_FUNCTIONS[0]['key'] index = self.earthquake_function.findData(default_earthquake_function) self.earthquake_function.setCurrentIndex(index) # Restore North Arrow Image Path north_arrow_path = self.settings.value( 'inasafe/north_arrow_path', default_north_arrow_path(), type=str) custom_north_arrow_flag = ( north_arrow_path != default_north_arrow_path()) self.custom_north_arrow_checkbox.setChecked(custom_north_arrow_flag) self.leNorthArrowPath.setText(north_arrow_path) # Restore Report Template Directory Path report_template_dir = self.settings.value( 'inasafe/reportTemplatePath', '', type=str) custom_templates_dir_flag = (report_template_dir != '') self.custom_templates_dir_checkbox.setChecked( custom_templates_dir_flag) self.leReportTemplatePath.setText(report_template_dir) # Restore Disclaimer org_disclaimer = self.settings.value( 'inasafe/reportDisclaimer', disclaimer(), type=str) custom_org_disclaimer_flag = (org_disclaimer != disclaimer()) self.custom_org_disclaimer_checkbox.setChecked( custom_org_disclaimer_flag) self.txtDisclaimer.setPlainText(org_disclaimer) # Restore InaSAFE default values self.restore_default_values_page() def save_state(self): """Store the options into the user's stored session info.""" # Save boolean settings for key, check_box in self.boolean_settings.items(): self.save_boolean_setting(key, check_box) # Save text settings for key, line_edit in self.text_settings.items(): self.save_text_setting(key, line_edit) self.settings.setValue( 'inasafe/north_arrow_path', self.leNorthArrowPath.text()) self.settings.setValue( 'inasafe/organisation_logo_path', self.leOrganisationLogoPath.text()) self.settings.setValue( 'inasafe/reportTemplatePath', self.leReportTemplatePath.text()) self.settings.setValue( 'inasafe/reportDisclaimer', self.txtDisclaimer.toPlainText()) self.settings.setValue( 'inasafe/defaultUserDirectory', self.leUserDirectoryPath.text()) index = self.earthquake_function.currentIndex() value = self.earthquake_function.itemData(index) set_setting('earthquake_function', value) # Save InaSAFE default values self.save_default_values() def accept(self): """Method invoked when OK button is clicked.""" if not self.is_good_age_ratios(): display_warning_message_box( self, tr('Wrong Sum Age Ratio'), tr('You have set age ratio whose sum is not equal to 1. ' 'Please fix it in the <b>Global Default</b> tab before you ' 'can save it.')) return self.save_state() # FIXME: Option dialog should be independent from dock. if self.dock: self.dock.read_settings() self.close() # noinspection PyPep8Naming @pyqtSignature('') # prevents actions being handled twice def on_toolKeywordCachePath_clicked(self): """Auto-connect slot activated when cache file tool button is clicked. """ # noinspection PyCallByClass,PyTypeChecker file_name = QtGui.QFileDialog.getSaveFileName( self, self.tr('Set keyword cache file'), inasafe_default_settings['keywordCachePath'], self.tr('Sqlite DB File (*.db)')) self.leKeywordCachePath.setText(file_name) # noinspection PyPep8Naming @pyqtSignature('') # prevents actions being handled twice def on_toolUserDirectoryPath_clicked(self): """Auto-connect slot activated when user directory tool button is clicked. """ # noinspection PyCallByClass,PyTypeChecker dir_name = QtGui.QFileDialog.getExistingDirectory( self, self.tr('Results directory'), '', QtGui.QFileDialog.ShowDirsOnly) self.leUserDirectoryPath.setText(dir_name) # noinspection PyPep8Naming @pyqtSignature('') # prevents actions being handled twice def on_toolNorthArrowPath_clicked(self): """Auto-connect slot activated when north arrow tool button is clicked. """ # noinspection PyCallByClass,PyTypeChecker file_name = QtGui.QFileDialog.getOpenFileName( self, self.tr('Set north arrow image file'), '', self.tr( 'Portable Network Graphics files (*.png *.PNG);;' 'JPEG Images (*.jpg *.jpeg);;' 'GIF Images (*.gif *.GIF);;' 'SVG Images (*.svg *.SVG);;')) if file_name != '': self.leNorthArrowPath.setText(file_name) # noinspection PyPep8Naming @pyqtSignature('') # prevents actions being handled twice def on_toolOrganisationLogoPath_clicked(self): """Auto-connect slot activated when logo file tool button is clicked. """ # noinspection PyCallByClass,PyTypeChecker file_name = QtGui.QFileDialog.getOpenFileName( self, self.tr('Set organisation logo file'), '', self.tr( 'Portable Network Graphics files (*.png *.PNG);;' 'JPEG Images (*.jpg *.jpeg);;' 'GIF Images (*.gif *.GIF);;' 'SVG Images (*.svg *.SVG);;')) if file_name != '': self.leOrganisationLogoPath.setText(file_name) # noinspection PyPep8Naming @pyqtSignature('') # prevents actions being handled twice def on_toolReportTemplatePath_clicked(self): """Auto-connect slot activated when report file tool button is clicked. """ # noinspection PyCallByClass,PyTypeChecker dir_name = QtGui.QFileDialog.getExistingDirectory( self, self.tr('Templates directory'), '', QtGui.QFileDialog.ShowDirsOnly) self.leReportTemplatePath.setText(dir_name) def set_organisation_logo(self): """Auto-connect slot activated when org logo checkbox is toggled.""" is_checked = self.custom_org_logo_checkbox.isChecked() if is_checked: # Use previous org logo path path = self.settings.value( 'inasafe/organisation_logo_path', supporters_logo_path(), type=str) else: # Set organisation path line edit to default one path = supporters_logo_path() self.leOrganisationLogoPath.setText(path) self.splitter_org_logo.setEnabled(is_checked) def set_north_arrow(self): """Auto-connect slot activated when north arrow checkbox is toggled.""" is_checked = self.custom_north_arrow_checkbox.isChecked() if is_checked: # Show previous north arrow path path = self.settings.value( 'inasafe/north_arrow_path', default_north_arrow_path(), type=str) else: # Set the north arrow line edit to default one path = default_north_arrow_path() self.leNorthArrowPath.setText(path) self.splitter_north_arrow.setEnabled(is_checked) def set_user_dir(self): """Auto-connect slot activated when user dir checkbox is toggled. """ is_checked = self.custom_UseUserDirectory_checkbox.isChecked() if is_checked: # Show previous templates dir path = self.settings.value( 'inasafe/defaultUserDirectory', '', type=str) else: # Set the template report dir to '' path = temp_dir('impacts') self.leUserDirectoryPath.setText(path) self.splitter_user_directory.setEnabled(is_checked) def set_templates_dir(self): """Auto-connect slot activated when templates dir checkbox is toggled. """ is_checked = self.custom_templates_dir_checkbox.isChecked() if is_checked: # Show previous templates dir path = self.settings.value( 'inasafe/reportTemplatePath', '', type=str) else: # Set the template report dir to '' path = '' self.leReportTemplatePath.setText(path) self.splitter_custom_report.setEnabled(is_checked) def set_org_disclaimer(self): """Auto-connect slot activated when org disclaimer checkbox is toggled. """ is_checked = self.custom_org_disclaimer_checkbox.isChecked() if is_checked: # Show previous organisation disclaimer org_disclaimer = self.settings.value( 'inasafe/reportDisclaimer', disclaimer(), type=str) else: # Set the organisation disclaimer to the default one org_disclaimer = disclaimer() self.txtDisclaimer.setPlainText(org_disclaimer) self.txtDisclaimer.setEnabled(is_checked) @pyqtSlot() @pyqtSignature('bool') # prevents actions being handled twice def help_toggled(self, flag): """Show or hide the help tab in the stacked widget. .. versionadded: 3.2.1 :param flag: Flag indicating whether help should be shown or hidden. :type flag: bool """ if flag: self.help_button.setText(self.tr('Hide Help')) self.show_help() else: self.help_button.setText(self.tr('Show Help')) self.hide_help() def hide_help(self): """Hide the usage info from the user. .. versionadded: 3.2.1 """ self.main_stacked_widget.setCurrentIndex(1) def show_help(self): """Show usage info to the user.""" # Read the header and footer html snippets self.main_stacked_widget.setCurrentIndex(0) header = html_header() footer = html_footer() string = header message = options_help() string += message.to_html() string += footer self.help_web_view.setHtml(string) def restore_default_values_page(self): """Setup UI for default values setting.""" # Clear parameters so it doesn't add parameters when # restore from changes. if self.default_value_parameters: self.default_value_parameters = [] unordered_parameters = [] default_fields = all_default_fields() for default_field in default_fields: if default_field.get('type') == QVariant.Double: parameter = FloatParameter() elif default_field.get('type') in qvariant_whole_numbers: parameter = IntegerParameter() else: continue default_value = default_field.get('default_value') if not default_value: message = ( 'InaSAFE default field %s does not have default value' % default_field.get('name')) LOGGER.exception(message) continue parameter.guid = default_field.get('key') parameter.name = default_value.get('name') parameter.is_required = True parameter.precision = default_field.get('precision') parameter.minimum_allowed_value = default_value.get( 'min_value', 0) parameter.maximum_allowed_value = default_value.get( 'max_value', 100000000) parameter.help_text = default_value.get('help_text') parameter.description = default_value.get('description') # Check if user ask to restore to the most default value. if self.is_restore_default: parameter._value = default_value.get('default_value') else: # Current value qsetting_default_value = get_inasafe_default_value_qsetting( self.settings, GLOBAL, default_field['key']) # To avoid python error if qsetting_default_value > parameter.maximum_allowed_value: qsetting_default_value = parameter.maximum_allowed_value if qsetting_default_value < parameter.minimum_allowed_value: qsetting_default_value = parameter.minimum_allowed_value parameter.value = qsetting_default_value unordered_parameters.append(parameter) preferred_order = [ youth_ratio_field, adult_ratio_field, elderly_ratio_field ] for order in preferred_order: parameter_index = [ p.guid for p in unordered_parameters].index(order['key']) if parameter_index > -1: self.default_value_parameters.append( unordered_parameters[parameter_index]) unordered_parameters.pop(parameter_index) self.default_value_parameters.extend(unordered_parameters) description_text = tr( 'In this options you can change the global default values for ' 'these variables.') self.default_value_parameter_container = ParameterContainer( self.default_value_parameters, description_text=description_text) self.default_value_parameter_container.setup_ui() self.default_values_layout.addWidget( self.default_value_parameter_container) def age_ratios(self): """Helper to get list of age ratio from the options dialog. :returns: List of age ratio. :rtype: list """ parameter_container = self.default_value_parameter_container youth_ratio = parameter_container.get_parameter_by_guid( youth_ratio_field['key']).value adult_ratio = parameter_container.get_parameter_by_guid( adult_ratio_field['key']).value elderly_ratio = parameter_container.get_parameter_by_guid( elderly_ratio_field['key']).value ratios = [youth_ratio, adult_ratio, elderly_ratio] return ratios def is_good_age_ratios(self): """Method to check the sum of age ratio is 1. :returns: True if the sum is 1 or the sum less than 1 but there is None. :rtype: bool """ ratios = self.age_ratios() if None in ratios: # If there is None, just check to not exceeding 1 clean_ratios = [x for x in ratios if x is not None] ratios.remove(None) if sum(clean_ratios) > 1: return False else: if sum(ratios) != 1: return False return True def save_default_values(self): """Save InaSAFE default values.""" parameters = self.default_value_parameter_container.get_parameters() for parameter in parameters: set_inasafe_default_value_qsetting( self.settings, GLOBAL, parameter.guid, parameter.value ) def restore_defaults_ratio(self): """Restore InaSAFE default ratio.""" # Set the flag to true because user ask to. self.is_restore_default = True # remove current default ratio for i in reversed(range(self.default_values_layout.count())): widget = self.default_values_layout.itemAt(i).widget() if widget is not None: widget.setParent(None) # reload default ratio self.restore_default_values_page()
def set_up_resource_parameters(self): """Set up the resource parameter for the add/edit view. """ name_parameter = StringParameter('UUID-1') name_parameter.name = tr('Resource name') name_parameter.help_text = tr( 'Name of the resource that will be provided ' 'as part of minimum needs. ' 'e.g. Rice, Water etc.') name_parameter.description = tr( 'A <b>resource</b> is something that you provide to displaced ' 'persons in the event of a disaster. The resource will be made ' 'available at IDP camps and may need to be stockpiled by ' 'contingency planners in their preparations for a disaster.') name_parameter.is_required = True name_parameter.value = '' description_parameter = StringParameter('UUID-2') description_parameter.name = tr('Resource description') description_parameter.help_text = tr( 'Description of the resource that will be provided as part of ' 'minimum needs.') description_parameter.description = tr( 'This gives a detailed description of what the resource is and ') description_parameter.is_required = True description_parameter.value = '' unit_parameter = StringParameter('UUID-3') unit_parameter.name = tr('Unit') unit_parameter.help_text = tr( 'Single unit for the resources spelled out. e.g. litre, ' 'kilogram etc.') unit_parameter.description = tr( 'A <b>unit</b> is the basic measurement unit used for computing ' 'the allowance per individual. For example when planning water ' 'rations the unit would be single litre.') unit_parameter.is_required = True unit_parameter.value = '' units_parameter = StringParameter('UUID-4') units_parameter.name = tr('Units') units_parameter.help_text = tr( 'Multiple units for the resources spelled out. e.g. litres, ' 'kilogram etc.') units_parameter.description = tr( '<b>Units</b> are the basic measurement used for computing the ' 'allowance per individual. For example when planning water ' 'rations the units would be litres.') units_parameter.is_required = True units_parameter.value = '' unit_abbreviation_parameter = StringParameter('UUID-5') unit_abbreviation_parameter.name = tr('Unit abbreviation') unit_abbreviation_parameter.help_text = tr( 'Abbreviations of unit for the resources. e.g. l, kg etc.') unit_abbreviation_parameter.description = tr( "A <b>unti abbreviation</b> is the basic measurement unit's " "shortened. For example when planning water rations " "the units would be l.") unit_abbreviation_parameter.is_required = True unit_abbreviation_parameter.value = '' minimum_parameter = FloatParameter('UUID-6') minimum_parameter.name = tr('Minimum allowed') minimum_parameter.is_required = True minimum_parameter.precision = 2 minimum_parameter.minimum_allowed_value = -99999.0 minimum_parameter.maximum_allowed_value = 99999.0 minimum_parameter.help_text = tr( 'The minimum allowable quantity per person. ') minimum_parameter.description = tr( 'The <b>minimum</b> is the minimum allowed quantity of the ' 'resource per person. For example you may dictate that the water ' 'ration per person per day should never be allowed to be less ' 'than 0.5l. This is enforced when tweaking a minimum needs set ' 'before an impact evaluation') minimum_parameter.value = 0.00 maximum_parameter = FloatParameter('UUID-7') maximum_parameter.name = tr('Maximum allowed') maximum_parameter.is_required = True maximum_parameter.precision = 2 maximum_parameter.minimum_allowed_value = -99999.0 maximum_parameter.maximum_allowed_value = 99999.0 maximum_parameter.help_text = tr( 'The maximum allowable quantity per person. ') maximum_parameter.description = tr( 'The <b>maximum</b> is the maximum allowed quantity of the ' 'resource per person. For example you may dictate that the water ' 'ration per person per day should never be allowed to be more ' 'than 50l. This is enforced when tweaking a minimum needs set ' 'before an impact evaluation.') maximum_parameter.value = 100.0 default_parameter = FloatParameter('UUID-8') default_parameter.name = tr('Default') default_parameter.is_required = True default_parameter.precision = 2 default_parameter.minimum_allowed_value = -99999.0 default_parameter.maximum_allowed_value = 99999.0 default_parameter.help_text = tr( 'The default allowable quantity per person. ') default_parameter.description = tr( "The <b>default</b> is the default allowed quantity of the " "resource per person. For example you may indicate that the water " "ration per person weekly should be 67l.") default_parameter.value = 10.0 frequency_parameter = StringParameter('UUID-9') frequency_parameter.name = tr('Frequency') frequency_parameter.help_text = tr( "The frequency that this resource needs to be provided to a " "displaced person. e.g. weekly, daily, once etc.") frequency_parameter.description = tr( "The <b>frequency</b> informs the aid worker how regularly this " "resource needs to be provided to the displaced person.") frequency_parameter.is_required = True frequency_parameter.value = tr('weekly') sentence_parameter = TextParameter('UUID-10') sentence_parameter.name = tr('Readable sentence') sentence_parameter.help_text = tr( 'A readable presentation of the resource.') sentence_parameter.description = tr( "A <b>readable sentence</b> is a presentation of the resource " "that displays all pertinent information. If you are unsure then " "use the default. Properties should be included using double " "curly brackets '{{' '}}'. Including the resource name would be " "achieved by including e.g. {{ Resource name }}") sentence_parameter.is_required = True sentence_parameter.value = tr( "A displaced person should be provided with " "{{ Default }} {{ Unit }}/{{ Units }}/{{ Unit abbreviation }} of " "{{ Resource name }}. Though no less than {{ Minimum allowed }} " "and no more than {{ Maximum allowed }}. This should be provided " "{{ Frequency }}.") parameters = [ name_parameter, description_parameter, unit_parameter, units_parameter, unit_abbreviation_parameter, default_parameter, minimum_parameter, maximum_parameter, frequency_parameter, sentence_parameter ] parameter_container = ParameterContainer(parameters) parameter_container.setup_ui() layout = QGridLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(parameter_container) self.parameters_scrollarea.setLayout(layout)
class FieldMappingTab(QWidget, object): """Widget class for field mapping.""" def __init__(self, field_group=None, parent=None, iface=None): """Constructor.""" # Init from parent class QWidget.__init__(self, parent) # Attributes self.layer = None self.metadata = {} self.parent = parent self.iface = iface self.field_group = field_group self.setting = QSettings() # TODO(IS): Make dynamic # Main container self.main_layout = QVBoxLayout() # Inner layout self.header_layout = QHBoxLayout() self.content_layout = QHBoxLayout() self.footer_layout = QHBoxLayout() # Header self.header_label = QLabel() self.header_label.setWordWrap(True) # Content self.field_layout = QVBoxLayout() self.parameter_layout = QHBoxLayout() self.field_description = QLabel(tr('List of fields')) self.field_list = QListWidget() self.field_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.field_list.setDragDropMode(QAbstractItemView.DragDrop) self.field_list.setDefaultDropAction(Qt.MoveAction) self.field_list.setSizePolicy( QSizePolicy.Maximum, QSizePolicy.Expanding) # noinspection PyUnresolvedReferences self.field_list.itemSelectionChanged.connect(self.update_footer) # Footer self.footer_label = QLabel() # Parameters self.extra_parameters = [ (GroupSelectParameter, GroupSelectParameterWidget) ] self.parameters = [] self.parameter_container = None # Adding to layout self.header_layout.addWidget(self.header_label) self.field_layout.addWidget(self.field_description) self.field_layout.addWidget(self.field_list) self.field_layout.setSizeConstraint(QLayout.SetMaximumSize) self.content_layout.addLayout(self.field_layout) self.content_layout.addLayout(self.parameter_layout) self.footer_layout.addWidget(self.footer_label) self.main_layout.addLayout(self.header_layout) self.main_layout.addLayout(self.content_layout) self.main_layout.addLayout(self.footer_layout) self.setLayout(self.main_layout) def set_layer(self, layer, keywords=None): """Set layer and update UI accordingly. :param layer: A vector layer that has been already patched with metadata. :type layer: QgsVectorLayer :param keywords: Custom keyword for the layer. :type keywords: dict, None """ self.layer = layer if keywords is not None: self.metadata = keywords else: # Check if it has keywords if not hasattr(layer, 'keywords'): message = 'Layer {layer_name} does not have keywords.'.format( layer_name=layer.name()) raise KeywordNotFoundError(message) self.metadata = layer.keywords self.populate_parameter() def populate_field_list(self, excluded_fields=None): """Helper to add field of the layer to the list. :param excluded_fields: List of field that want to be excluded. :type excluded_fields: list """ # Populate fields list if excluded_fields is None: excluded_fields = [] self.field_list.clear() for field in self.layer.dataProvider().fields(): # Skip if it's excluded if field.name() in excluded_fields: continue # Skip if it's not number (float, int, etc) if field.type() not in qvariant_numbers: continue field_item = QListWidgetItem(self.field_list) field_item.setFlags( Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) field_item.setData(Qt.UserRole, field.name()) field_item.setText(field.name()) self.field_list.addItem(field_item) def populate_parameter(self): """Helper to setup the parameter widget.""" used_fields = [] self.parameters = [] for field in self.field_group.get('fields', []): selected_option = DO_NOT_USE options = OrderedDict([ (DO_NOT_USE, { 'label': tr('Do not use'), 'value': None, 'type': STATIC, 'constraint': {} }), ]) # Example: count if field['absolute']: # Used in field options field_label = tr('Count fields') else: # Example: ratio # Used in field options field_label = tr('Ratio fields') global_default_value = get_inasafe_default_value_qsetting( self.setting, GLOBAL, field['key']) options[GLOBAL_DEFAULT] = { 'label': tr('Global default'), 'value': global_default_value, 'type': STATIC, 'constraint': {} } default_custom_value = get_inasafe_default_value_qsetting( self.setting, RECENT, field['key']) custom_value = self.metadata.get( 'inasafe_default_values', {}).get( field['key'], default_custom_value) if field['key'] in self.metadata.get( 'inasafe_default_values', {}): if custom_value == global_default_value: selected_option = GLOBAL_DEFAULT else: selected_option = CUSTOM_VALUE min_value = field['default_value'].get('min_value', 0) max_value = field['default_value'].get('max_value', 100) default_step = (max_value - min_value) / 100.0 step = field['default_value'].get('increment', default_step) options[CUSTOM_VALUE] = { 'label': tr('Custom'), 'value': custom_value, 'type': SINGLE_DYNAMIC, 'constraint': { 'min': min_value, 'max': max_value, 'step': step } } custom_fields = self.metadata.get('inasafe_fields', {}).get( field['key'], []) if field['key'] in self.metadata.get('inasafe_fields', {}): selected_option = FIELDS if isinstance(custom_fields, basestring): custom_fields = [custom_fields] options[FIELDS] = { 'label': field_label, 'value': custom_fields, 'type': MULTIPLE_DYNAMIC, 'constraint': {} } used_fields.extend(custom_fields) parameter = GroupSelectParameter() parameter.guid = field['key'] parameter.name = field['name'] parameter.options = options parameter.selected = selected_option parameter.help_text = field['help_text'] parameter.description = field['description'] self.parameters.append(parameter) self.parameter_container = ParameterContainer( parameters=self.parameters, extra_parameters=self.extra_parameters, vertical=False ) self.parameter_container.setup_ui() constraints = self.field_group.get('constraints', {}) for key, value in constraints.items(): self.parameter_container.add_validator( validators[key], kwargs=value['kwargs'], validation_message=value['message']) self.parameter_layout.addWidget(self.parameter_container) # Set move or copy if self.field_group.get('exclusive', False): # If exclusive, do not add used field. self.populate_field_list(excluded_fields=used_fields) # Use move action since it's exclusive self.field_list.setDefaultDropAction(Qt.MoveAction) # Just make sure that the signal is disconnected try: # noinspection PyUnresolvedReferences self.field_list.itemChanged.disconnect(self.drop_remove) except TypeError: pass # Set header header_text = self.field_group['description'] header_text += '\n\n' + tr( 'You can only map one field to one concept.') else: # If not exclusive, add all field. self.populate_field_list() # Use copy action since it's not exclusive self.field_list.setDefaultDropAction(Qt.CopyAction) # noinspection PyUnresolvedReferences self.field_list.itemChanged.connect( partial(self.drop_remove, field_list=self.field_list)) self.connect_drop_remove_parameter() # Set header header_text = self.field_group['description'] header_text += '\n\n' + tr( 'You can map one field to more than one concepts.') self.header_label.setText(header_text) def get_parameter_value(self): """Get parameter of the tab. :returns: Dictionary of parameters by type in this format: {'fields': {}, 'values': {}}. :rtype: dict """ try: parameters = self.parameter_container.get_parameters(True) except InvalidValidationException as e: raise OriginalValidationException(e) field_parameters = {} value_parameters = {} for parameter in parameters: if parameter.selected_option_type() in [SINGLE_DYNAMIC, STATIC]: value_parameters[parameter.guid] = parameter.value elif parameter.selected_option_type() == MULTIPLE_DYNAMIC: field_parameters[parameter.guid] = parameter.value return { 'fields': field_parameters, 'values': value_parameters } def update_footer(self): """Update footer when the field list change.""" field_item = self.field_list.currentItem() if not field_item: self.footer_label.setText('') return field_name = field_item.data(Qt.UserRole) field = self.layer.fields().field(field_name) index = self.layer.fieldNameIndex(field_name) unique_values = self.layer.uniqueValues(index) pretty_unique_values = ', '.join([str(v) for v in unique_values[:10]]) footer_text = tr('Field type: {0}\n').format(field.typeName()) footer_text += tr('Unique values: {0}').format(pretty_unique_values) self.footer_label.setText(footer_text) def connect_drop_remove_parameter(self): parameter_widgets = self.parameter_container.get_parameter_widgets() for parameter_widget in parameter_widgets: field_list = parameter_widget.widget().list_widget field_list.itemChanged.connect( partial(self.drop_remove, field_list=field_list)) @staticmethod def drop_remove(*args, **kwargs): """Action when we need to remove dropped item. :param args: Position arguments. :type args: list :param kwargs: Keywords arguments. :type kwargs: dict """ dropped_item = args[0] field_list = kwargs['field_list'] num_duplicate = 0 for i in range(field_list.count()): if dropped_item.text() == field_list.item(i).text(): num_duplicate += 1 if num_duplicate > 1: # Notes(IS): For some reason, removeItemWidget is not working. field_list.takeItem(field_list.row(dropped_item))
def populate_parameter(self): """Helper to setup the parameter widget.""" used_fields = [] self.parameters = [] for field in self.field_group.get('fields', []): selected_option = DO_NOT_USE options = OrderedDict([ (DO_NOT_USE, { 'label': tr('Do not use'), 'value': None, 'type': STATIC, 'constraint': {} }), ]) # Example: count if field['absolute']: # Used in field options field_label = tr('Count fields') else: # Example: ratio # Used in field options field_label = tr('Ratio fields') global_default_value = get_inasafe_default_value_qsetting( self.setting, GLOBAL, field['key']) options[GLOBAL_DEFAULT] = { 'label': tr('Global default'), 'value': global_default_value, 'type': STATIC, 'constraint': {} } default_custom_value = get_inasafe_default_value_qsetting( self.setting, RECENT, field['key']) custom_value = self.metadata.get( 'inasafe_default_values', {}).get( field['key'], default_custom_value) if field['key'] in self.metadata.get( 'inasafe_default_values', {}): if custom_value == global_default_value: selected_option = GLOBAL_DEFAULT else: selected_option = CUSTOM_VALUE min_value = field['default_value'].get('min_value', 0) max_value = field['default_value'].get('max_value', 100) default_step = (max_value - min_value) / 100.0 step = field['default_value'].get('increment', default_step) options[CUSTOM_VALUE] = { 'label': tr('Custom'), 'value': custom_value, 'type': SINGLE_DYNAMIC, 'constraint': { 'min': min_value, 'max': max_value, 'step': step } } custom_fields = self.metadata.get('inasafe_fields', {}).get( field['key'], []) if field['key'] in self.metadata.get('inasafe_fields', {}): selected_option = FIELDS if isinstance(custom_fields, basestring): custom_fields = [custom_fields] options[FIELDS] = { 'label': field_label, 'value': custom_fields, 'type': MULTIPLE_DYNAMIC, 'constraint': {} } used_fields.extend(custom_fields) parameter = GroupSelectParameter() parameter.guid = field['key'] parameter.name = field['name'] parameter.options = options parameter.selected = selected_option parameter.help_text = field['help_text'] parameter.description = field['description'] self.parameters.append(parameter) self.parameter_container = ParameterContainer( parameters=self.parameters, extra_parameters=self.extra_parameters, vertical=False ) self.parameter_container.setup_ui() constraints = self.field_group.get('constraints', {}) for key, value in constraints.items(): self.parameter_container.add_validator( validators[key], kwargs=value['kwargs'], validation_message=value['message']) self.parameter_layout.addWidget(self.parameter_container) # Set move or copy if self.field_group.get('exclusive', False): # If exclusive, do not add used field. self.populate_field_list(excluded_fields=used_fields) # Use move action since it's exclusive self.field_list.setDefaultDropAction(Qt.MoveAction) # Just make sure that the signal is disconnected try: # noinspection PyUnresolvedReferences self.field_list.itemChanged.disconnect(self.drop_remove) except TypeError: pass # Set header header_text = self.field_group['description'] header_text += '\n\n' + tr( 'You can only map one field to one concept.') else: # If not exclusive, add all field. self.populate_field_list() # Use copy action since it's not exclusive self.field_list.setDefaultDropAction(Qt.CopyAction) # noinspection PyUnresolvedReferences self.field_list.itemChanged.connect( partial(self.drop_remove, field_list=self.field_list)) self.connect_drop_remove_parameter() # Set header header_text = self.field_group['description'] header_text += '\n\n' + tr( 'You can map one field to more than one concepts.') self.header_label.setText(header_text)
class StepKwInaSAFEFields(WizardStep, FORM_CLASS): """Keyword Wizard Step: InaSAFE Fields""" def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.parameters = [] self.parameter_container = ParameterContainer() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) def is_ready_to_next_step(self): """Check if the step is complete. If so, there is no reason to block the Next button. :returns: True if new step may be enabled. :rtype: bool """ return True def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to :rtype: WizardStep instance or None """ layer_purpose = self.parent.step_kw_purpose.selected_purpose() if layer_purpose['key'] != layer_purpose_aggregation['key']: subcategory = self.parent.step_kw_subcategory. \ selected_subcategory() else: subcategory = {'key': None} # Check if it can go to inasafe default field step default_inasafe_fields = get_fields( layer_purpose['key'], subcategory['key'], replace_null=True, in_group=False) if default_inasafe_fields: return self.parent.step_kw_default_inasafe_fields # Any other case return self.parent.step_kw_source def inasafe_fields_for_the_layer(self): """Return a list of inasafe fields the current layer. :returns: A list where each value represents inasafe field. :rtype: list """ if (self.parent.get_layer_geometry_key() == layer_geometry_raster['key']): return [] # Get hazard or exposure value layer_purpose_key = self.parent.step_kw_purpose.selected_purpose()[ 'key'] if layer_purpose_key != layer_purpose_aggregation['key']: subcategory_key = self.parent.step_kw_subcategory.\ selected_subcategory()['key'] else: subcategory_key = None # Get all fields with replace_null = False inasafe_fields = get_fields( layer_purpose_key, subcategory_key, replace_null=False, in_group=False) # remove compulsory field since it has been set in previous step try: inasafe_fields.remove(get_compulsory_fields( layer_purpose_key, subcategory_key)) except ValueError: pass return inasafe_fields # noinspection PyTypeChecker def set_widgets(self): """Set widgets on the Extra Keywords tab.""" existing_inasafe_field = self.parent.get_existing_keyword( 'inasafe_fields') # Remove old container and parameter if self.parameter_container: self.kwExtraKeywordsGridLayout.removeWidget( self.parameter_container) if self.parameters: self.parameters = [] layer_data_provider = self.parent.layer.dataProvider() # Iterate through all inasafe fields for inasafe_field in self.inasafe_fields_for_the_layer(): # Option for Not Available option_list = [no_field] for field in layer_data_provider.fields(): # Check the field type if isinstance(inasafe_field['type'], list): if field.type() in inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) else: if field.type() == inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) # If there is no option, pass if option_list == [no_field]: continue # Create SelectParameter select_parameter = SelectParameter() select_parameter.guid = inasafe_field['key'] select_parameter.name = inasafe_field['name'] select_parameter.is_required = False select_parameter.description = inasafe_field['description'] select_parameter.help_text = inasafe_field['help_text'] select_parameter.element_type = unicode select_parameter.options_list = option_list select_parameter.value = no_field # Check if there is already value in the metadata. if existing_inasafe_field: existing_value = existing_inasafe_field.get( inasafe_field['key']) if existing_value: if existing_value in select_parameter.options_list: select_parameter.value = existing_value self.parameters.append(select_parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer(self.parameters) self.parameter_container.setup_ui() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) if not self.parameters: no_field_message = tr( 'There is no available field that has match type for the ' 'InaSAFE fields. You can click next.') self.lblInaSAFEFields.setText(no_field_message) def get_inasafe_fields(self): """Return inasafe fields from the current wizard state. :returns: Dictionary of key and value from InaSAFE Fields. :rtype: dict """ inasafe_fields = {} parameters = self.parameter_container.get_parameters(True) for parameter in parameters: if not parameter.value == no_field: inasafe_fields[parameter.guid] = parameter.value return inasafe_fields def clear(self): """Clear current state.""" # Adapted from http://stackoverflow.com/a/13103617/1198772 for i in reversed(range(self.kwExtraKeywordsGridLayout.count())): self.kwExtraKeywordsGridLayout.itemAt(i).widget().setParent(None) self.parameters = [] self.parameter_container = ParameterContainer()
def set_widgets(self): """Set widgets on the Extra Keywords tab.""" self.clear() existing_inasafe_field = self.parent.get_existing_keyword( 'inasafe_fields') existing_inasafe_default_values = self.parent.get_existing_keyword( 'inasafe_default_values') # Remove old container and parameter if self.parameter_container: self.kwExtraKeywordsGridLayout.removeWidget( self.parameter_container) if self.parameters: self.parameters = [] layer_data_provider = self.parent.layer.dataProvider() # Iterate through all inasafe fields # existing_inasafe_default_values for inasafe_field in self.inasafe_fields_for_the_layer(): # Option for Not Available option_list = [no_field] for field in layer_data_provider.fields(): # Check the field type if isinstance(inasafe_field['type'], list): if field.type() in inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) else: if field.type() == inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) # Create DefaultSelectParameter parameter = DefaultSelectParameter() parameter.guid = inasafe_field['key'] parameter.name = inasafe_field['name'] parameter.is_required = False parameter.description = inasafe_field['description'] parameter.help_text = inasafe_field['help_text'] parameter.element_type = unicode parameter.options_list = option_list parameter.value = no_field parameter.default_labels = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[0] parameter.default_values = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[1] parameter.minimum = inasafe_field['default_value'].get( 'min_value') parameter.maximum = inasafe_field['default_value'].get( 'max_value') # Check if there is already value in the metadata. if existing_inasafe_field: existing_value = existing_inasafe_field.get( inasafe_field['key']) if existing_value: if existing_value in parameter.options_list: parameter.value = existing_value if existing_inasafe_default_values: existing_default_value = existing_inasafe_default_values.get( inasafe_field['key']) if existing_default_value: parameter.default = existing_default_value self.parameters.append(parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer( self.parameters, extra_parameters=self.extra_parameters) self.parameter_container.setup_ui() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) # Add Message label self.kwExtraKeywordsGridLayout.addWidget(self.message_label) # Set default value to None for parameter_widget in self.parameter_container.\ get_parameter_widgets(): parameter_widget.widget().set_default(None) # Set selected radio button to 'Do not use' parameter_widget.widget().set_selected_radio_button() # Set default value from existing keywords if existing_inasafe_default_values: for guid, default in existing_inasafe_default_values.items(): parameter_widget = self.parameter_container.\ get_parameter_widget_by_guid(guid) if isinstance(parameter_widget, DefaultSelectParameterWidget): parameter_widget.set_default(default) # Set selected radio button to 'Do not use' parameter_widget.set_selected_radio_button()
def set_widgets(self): """Set widgets on the Extra Keywords tab.""" existing_inasafe_field = self.parent.get_existing_keyword( 'inasafe_fields') # Remove old container and parameter if self.parameter_container: self.kwExtraKeywordsGridLayout.removeWidget( self.parameter_container) if self.parameters: self.parameters = [] layer_data_provider = self.parent.layer.dataProvider() # Iterate through all inasafe fields for inasafe_field in self.inasafe_fields_for_the_layer(): # Option for Not Available option_list = [no_field] for field in layer_data_provider.fields(): # Check the field type if isinstance(inasafe_field['type'], list): if field.type() in inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) else: if field.type() == inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) # If there is no option, pass if option_list == [no_field]: continue # Create SelectParameter select_parameter = SelectParameter() select_parameter.guid = inasafe_field['key'] select_parameter.name = inasafe_field['name'] select_parameter.is_required = False select_parameter.description = inasafe_field['description'] select_parameter.help_text = inasafe_field['help_text'] select_parameter.element_type = unicode select_parameter.options_list = option_list select_parameter.value = no_field # Check if there is already value in the metadata. if existing_inasafe_field: existing_value = existing_inasafe_field.get( inasafe_field['key']) if existing_value: if existing_value in select_parameter.options_list: select_parameter.value = existing_value self.parameters.append(select_parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer(self.parameters) self.parameter_container.setup_ui() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) if not self.parameters: no_field_message = tr( 'There is no available field that has match type for the ' 'InaSAFE fields. You can click next.') self.lblInaSAFEFields.setText(no_field_message)
class StepKwDefaultInaSAFEFields(WizardStep, FORM_CLASS): """Keyword Wizard Step: Default InaSAFE Fields""" def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.extra_parameters = [ (DefaultSelectParameter, DefaultSelectParameterWidget) ] self.parameters = [] self.parameter_container = ParameterContainer( extra_parameters=self.extra_parameters) self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) self.message_label = QLabel() def is_ready_to_next_step(self): """Check if the step is complete. If so, there is no reason to block the Next button. :returns: True if new step may be enabled. :rtype: bool """ return True def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to :rtype: WizardStep instance or None """ new_step = self.parent.step_kw_source return new_step def inasafe_fields_for_the_layer(self): """Return a list of inasafe fields the current layer. :returns: A list where each value represents inasafe field. :rtype: list """ if (self.parent.get_layer_geometry_key() == layer_geometry_raster['key']): return [] # Get hazard or exposure value layer_purpose_key = self.parent.step_kw_purpose.selected_purpose()[ 'key'] if layer_purpose_key != layer_purpose_aggregation['key']: subcategory_key = self.parent.step_kw_subcategory.\ selected_subcategory()['key'] else: subcategory_key = None # Get all fields with replace_null = True inasafe_fields = get_fields( layer_purpose_key, subcategory_key, replace_null=True, in_group=False) # remove compulsory field since it has been set in previous step try: inasafe_fields.remove(get_compulsory_fields( layer_purpose_key, subcategory_key)) except ValueError: pass return inasafe_fields # noinspection PyTypeChecker def set_widgets(self): """Set widgets on the Extra Keywords tab.""" self.clear() existing_inasafe_field = self.parent.get_existing_keyword( 'inasafe_fields') existing_inasafe_default_values = self.parent.get_existing_keyword( 'inasafe_default_values') # Remove old container and parameter if self.parameter_container: self.kwExtraKeywordsGridLayout.removeWidget( self.parameter_container) if self.parameters: self.parameters = [] layer_data_provider = self.parent.layer.dataProvider() # Iterate through all inasafe fields # existing_inasafe_default_values for inasafe_field in self.inasafe_fields_for_the_layer(): # Option for Not Available option_list = [no_field] for field in layer_data_provider.fields(): # Check the field type if isinstance(inasafe_field['type'], list): if field.type() in inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) else: if field.type() == inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) # Create DefaultSelectParameter parameter = DefaultSelectParameter() parameter.guid = inasafe_field['key'] parameter.name = inasafe_field['name'] parameter.is_required = False parameter.description = inasafe_field['description'] parameter.help_text = inasafe_field['help_text'] parameter.element_type = unicode parameter.options_list = option_list parameter.value = no_field parameter.default_labels = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[0] parameter.default_values = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[1] parameter.minimum = inasafe_field['default_value'].get( 'min_value') parameter.maximum = inasafe_field['default_value'].get( 'max_value') # Check if there is already value in the metadata. if existing_inasafe_field: existing_value = existing_inasafe_field.get( inasafe_field['key']) if existing_value: if existing_value in parameter.options_list: parameter.value = existing_value if existing_inasafe_default_values: existing_default_value = existing_inasafe_default_values.get( inasafe_field['key']) if existing_default_value: parameter.default = existing_default_value self.parameters.append(parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer( self.parameters, extra_parameters=self.extra_parameters) self.parameter_container.setup_ui() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) # Add Message label self.kwExtraKeywordsGridLayout.addWidget(self.message_label) # Set default value to None for parameter_widget in self.parameter_container.\ get_parameter_widgets(): parameter_widget.widget().set_default(None) # Set selected radio button to 'Do not use' parameter_widget.widget().set_selected_radio_button() # Set default value from existing keywords if existing_inasafe_default_values: for guid, default in existing_inasafe_default_values.items(): parameter_widget = self.parameter_container.\ get_parameter_widget_by_guid(guid) if isinstance(parameter_widget, DefaultSelectParameterWidget): parameter_widget.set_default(default) # Set selected radio button to 'Do not use' parameter_widget.set_selected_radio_button() def get_inasafe_fields(self): """Return inasafe fields from the current wizard state. :returns: Dictionary of key and value from InaSAFE Fields. :rtype: dict """ inasafe_fields = {} parameters = self.parameter_container.get_parameters(True) for parameter in parameters: if not parameter.value == no_field: inasafe_fields[parameter.guid] = parameter.value return inasafe_fields def get_inasafe_default_values(self): """Return inasafe default from the current wizard state. :returns: Dictionary of key and value from InaSAFE Default Values. :rtype: dict """ inasafe_default_values = {} parameters = self.parameter_container.get_parameters(True) for parameter in parameters: if parameter.default is not None: inasafe_default_values[parameter.guid] = parameter.default return inasafe_default_values def clear(self): """Clear current state.""" # Adapted from http://stackoverflow.com/a/13103617/1198772 for i in reversed(range(self.kwExtraKeywordsGridLayout.count())): self.kwExtraKeywordsGridLayout.itemAt(i).widget().setParent(None) self.parameters = [] self.parameter_container = ParameterContainer() def is_good_age_ratios(self): """Method to check the sum of age ratio is 1. :returns: True if the sum is 1 or the sum less than 1 but there is None. :rtype: bool """ default_values = self.get_inasafe_default_values() youth_ratio = default_values.get(youth_ratio_field['key']) adult_ratio = default_values.get(adult_ratio_field['key']) elderly_ratio = default_values.get(elderly_ratio_field['key']) ratios = [youth_ratio, adult_ratio, elderly_ratio] if None in ratios: # If there is None, just check to not exceeding 1 clean_ratios = [x for x in ratios if x is not None] ratios.remove(None) if sum(clean_ratios) > 1: return False else: if sum(ratios) != 1: return False return True def toggle_age_ratio_sum_message(self, flag): """Method to show error message about sum of age ratio. :param flag: Flag if the ratio is valid or not. :type flag: bool """ if not flag: self.message_label.setText( tr('The sum of your age ratios is not 1. Please fix it ' 'first before you can continue to the next step.')) self.message_label.setStyleSheet('color: red') else: self.message_label.setText(tr('You are good to go.')) self.message_label.setStyleSheet('color: green')
class StepKwInaSAFEFields(WizardStep, FORM_CLASS): """Keyword Wizard Step: InaSAFE Fields""" def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.parameters = [] self.parameter_container = ParameterContainer() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) def is_ready_to_next_step(self): """Check if the step is complete. If so, there is no reason to block the Next button. :returns: True if new step may be enabled. :rtype: bool """ return True def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to :rtype: WizardStep instance or None """ layer_purpose = self.parent.step_kw_purpose.selected_purpose() if layer_purpose['key'] != layer_purpose_aggregation['key']: subcategory = self.parent.step_kw_subcategory. \ selected_subcategory() else: subcategory = {'key': None} # Check if it can go to inasafe default field step default_inasafe_fields = get_fields(layer_purpose['key'], subcategory['key'], replace_null=True, in_group=False) if default_inasafe_fields: return self.parent.step_kw_default_inasafe_fields # Any other case return self.parent.step_kw_source def inasafe_fields_for_the_layer(self): """Return a list of inasafe fields the current layer. :returns: A list where each value represents inasafe field. :rtype: list """ if (self.parent.get_layer_geometry_key() == layer_geometry_raster['key']): return [] # Get hazard or exposure value layer_purpose_key = self.parent.step_kw_purpose.selected_purpose( )['key'] if layer_purpose_key != layer_purpose_aggregation['key']: subcategory_key = self.parent.step_kw_subcategory.\ selected_subcategory()['key'] else: subcategory_key = None # Get all fields with replace_null = False inasafe_fields = get_fields(layer_purpose_key, subcategory_key, replace_null=False, in_group=False) # remove compulsory field since it has been set in previous step try: inasafe_fields.remove( get_compulsory_fields(layer_purpose_key, subcategory_key)) except ValueError: pass return inasafe_fields # noinspection PyTypeChecker def set_widgets(self): """Set widgets on the Extra Keywords tab.""" existing_inasafe_field = self.parent.get_existing_keyword( 'inasafe_fields') # Remove old container and parameter if self.parameter_container: self.kwExtraKeywordsGridLayout.removeWidget( self.parameter_container) if self.parameters: self.parameters = [] layer_data_provider = self.parent.layer.dataProvider() # Iterate through all inasafe fields for inasafe_field in self.inasafe_fields_for_the_layer(): # Option for Not Available option_list = [no_field] for field in layer_data_provider.fields(): # Check the field type if isinstance(inasafe_field['type'], list): if field.type() in inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) else: if field.type() == inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) # If there is no option, pass if option_list == [no_field]: continue # Create SelectParameter select_parameter = SelectParameter() select_parameter.guid = inasafe_field['key'] select_parameter.name = inasafe_field['name'] select_parameter.is_required = False select_parameter.description = inasafe_field['description'] select_parameter.help_text = inasafe_field['help_text'] select_parameter.element_type = unicode select_parameter.options_list = option_list select_parameter.value = no_field # Check if there is already value in the metadata. if existing_inasafe_field: existing_value = existing_inasafe_field.get( inasafe_field['key']) if existing_value: if existing_value in select_parameter.options_list: select_parameter.value = existing_value self.parameters.append(select_parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer(self.parameters) self.parameter_container.setup_ui() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) if not self.parameters: no_field_message = tr( 'There is no available field that has match type for the ' 'InaSAFE fields. You can click next.') self.lblInaSAFEFields.setText(no_field_message) def get_inasafe_fields(self): """Return inasafe fields from the current wizard state. :returns: Dictionary of key and value from InaSAFE Fields. :rtype: dict """ inasafe_fields = {} parameters = self.parameter_container.get_parameters(True) for parameter in parameters: if not parameter.value == no_field: inasafe_fields[parameter.guid] = parameter.value return inasafe_fields def clear(self): """Clear current state.""" # Adapted from http://stackoverflow.com/a/13103617/1198772 for i in reversed(range(self.kwExtraKeywordsGridLayout.count())): self.kwExtraKeywordsGridLayout.itemAt(i).widget().setParent(None) self.parameters = [] self.parameter_container = ParameterContainer()
def set_widgets(self): """Set widgets on the Extra Keywords tab.""" self.clear() existing_inasafe_field = self.parent.get_existing_keyword( 'inasafe_fields') existing_inasafe_default_values = self.parent.get_existing_keyword( 'inasafe_default_values') # Remove old container and parameter if self.parameter_container: self.kwExtraKeywordsGridLayout.removeWidget( self.parameter_container) if self.parameters: self.parameters = [] layer_data_provider = self.parent.layer.dataProvider() # Iterate through all inasafe fields # existing_inasafe_default_values for inasafe_field in self.inasafe_fields_for_the_layer(): # Option for Not Available option_list = [no_field] for field in layer_data_provider.fields(): # Check the field type if isinstance(inasafe_field['type'], list): if field.type() in inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) else: if field.type() == inasafe_field['type']: field_name = field.name() option_list.append('%s' % field_name) # Create DefaultSelectParameter parameter = DefaultSelectParameter() parameter.guid = inasafe_field['key'] parameter.name = inasafe_field['name'] parameter.is_required = False parameter.description = inasafe_field['description'] parameter.help_text = inasafe_field['help_text'] parameter.element_type = unicode parameter.options_list = option_list parameter.value = no_field parameter.default_labels = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[0] parameter.default_values = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[1] parameter.minimum = inasafe_field['default_value'].get('min_value') parameter.maximum = inasafe_field['default_value'].get('max_value') # Check if there is already value in the metadata. if existing_inasafe_field: existing_value = existing_inasafe_field.get( inasafe_field['key']) if existing_value: if existing_value in parameter.options_list: parameter.value = existing_value if existing_inasafe_default_values: existing_default_value = existing_inasafe_default_values.get( inasafe_field['key']) if existing_default_value: parameter.default = existing_default_value self.parameters.append(parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer( self.parameters, extra_parameters=self.extra_parameters) self.parameter_container.setup_ui() self.kwExtraKeywordsGridLayout.addWidget(self.parameter_container) # Add Message label self.kwExtraKeywordsGridLayout.addWidget(self.message_label) # Set default value to None for parameter_widget in self.parameter_container.\ get_parameter_widgets(): parameter_widget.widget().set_default(None) # Set selected radio button to 'Do not use' parameter_widget.widget().set_selected_radio_button() # Set default value from existing keywords if existing_inasafe_default_values: for guid, default in existing_inasafe_default_values.items(): parameter_widget = self.parameter_container.\ get_parameter_widget_by_guid(guid) if isinstance(parameter_widget, DefaultSelectParameterWidget): parameter_widget.set_default(default) # Set selected radio button to 'Do not use' parameter_widget.set_selected_radio_button()
def set_up_resource_parameters(self): """Set up the resource parameter for the add/edit view. """ name_parameter = StringParameter('UUID-1') name_parameter.name = 'Resource name' name_parameter.help_text = ( 'Name of the resource that will be provided ' 'as part of minimum needs. ' 'e.g. Rice, Water etc.') name_parameter.description = ( 'A <b>resource</b> is something that you provide to displaced ' 'persons in the event of a disaster. The resource will be made ' 'available at IDP camps and may need to be stockpiled by ' 'contingency planners in their preparations for a disaster.') name_parameter.is_required = True name_parameter.value = '' description_parameter = StringParameter('UUID-2') description_parameter.name = 'Resource description' description_parameter.help_text = ( 'Description of the resource that will be provided as part of ' 'minimum needs.') description_parameter.description = ( 'This gives a detailed description of what the resource is and ') description_parameter.is_required = True description_parameter.value = '' unit_parameter = StringParameter('UUID-3') unit_parameter.name = 'Unit' unit_parameter.help_text = ( 'Single unit for the resources spelled out. e.g. litre, ' 'kilogram etc.') unit_parameter.description = ( 'A <b>unit</b> is the basic measurement unit used for computing ' 'the allowance per individual. For example when planning water ' 'rations the unit would be single litre.') unit_parameter.is_required = True unit_parameter.value = '' units_parameter = StringParameter('UUID-4') units_parameter.name = 'Units' units_parameter.help_text = ( 'Multiple units for the resources spelled out. e.g. litres, ' 'kilogram etc.') units_parameter.description = ( '<b>Units</b> are the basic measurement used for computing the ' 'allowance per individual. For example when planning water ' 'rations the units would be litres.') units_parameter.is_required = True units_parameter.value = '' unit_abbreviation_parameter = StringParameter('UUID-5') unit_abbreviation_parameter.name = 'Unit abbreviation' unit_abbreviation_parameter.help_text = ( 'Abbreviations of unit for the resources. e.g. l, kg etc.') unit_abbreviation_parameter.description = ( "A <b>unti abbreviation</b> is the basic measurement unit's " "shortened. For example when planning water rations " "the units would be l.") unit_abbreviation_parameter.is_required = True unit_abbreviation_parameter.value = '' minimum_parameter = FloatParameter('UUID-6') minimum_parameter.name = 'Minimum allowed' minimum_parameter.is_required = True minimum_parameter.precision = 2 minimum_parameter.minimum_allowed_value = -99999.0 minimum_parameter.maximum_allowed_value = 99999.0 minimum_parameter.help_text = ( 'The minimum allowable quantity per person. ') minimum_parameter.description = ( 'The <b>minimum</b> is the minimum allowed quantity of the ' 'resource per person. For example you may dictate that the water ' 'ration per person per day should never be allowed to be less ' 'than 0.5l. This is enforced when tweaking a minimum needs set ' 'before an impact evaluation') minimum_parameter.value = 0.00 maximum_parameter = FloatParameter('UUID-7') maximum_parameter.name = 'Maximum allowed' maximum_parameter.is_required = True maximum_parameter.precision = 2 maximum_parameter.minimum_allowed_value = -99999.0 maximum_parameter.maximum_allowed_value = 99999.0 maximum_parameter.help_text = ( 'The maximum allowable quantity per person. ') maximum_parameter.description = ( 'The <b>maximum</b> is the maximum allowed quantity of the ' 'resource per person. For example you may dictate that the water ' 'ration per person per day should never be allowed to be more ' 'than 50l. This is enforced when tweaking a minimum needs set ' 'before an impact evaluation.') maximum_parameter.value = 100.0 default_parameter = FloatParameter('UUID-8') default_parameter.name = 'Default' default_parameter.is_required = True default_parameter.precision = 2 default_parameter.minimum_allowed_value = -99999.0 default_parameter.maximum_allowed_value = 99999.0 default_parameter.help_text = ( 'The default allowable quantity per person. ') default_parameter.description = ( "The <b>default</b> is the default allowed quantity of the " "resource per person. For example you may indicate that the water " "ration per person weekly should be 67l.") default_parameter.value = 10.0 frequency_parameter = StringParameter('UUID-9') frequency_parameter.name = 'Frequency' frequency_parameter.help_text = ( "The frequency that this resource needs to be provided to a " "displaced person. e.g. weekly, daily, once etc.") frequency_parameter.description = ( "The <b>frequency</b> informs the aid worker how regularly this " "resource needs to be provided to the displaced person.") frequency_parameter.is_required = True frequency_parameter.value = 'weekly' sentence_parameter = StringParameter('UUID-10') sentence_parameter.name = 'Readable sentence' sentence_parameter.help_text = ( 'A readable presentation of the resource.') sentence_parameter.description = ( "A <b>readable sentence</b> is a presentation of the resource " "that displays all pertinent information. If you are unsure then " "use the default. Properties should be included using double " "curly brackets '{{' '}}'. Including the resource name would be " "achieved by including e.g. {{ Resource name }}") sentence_parameter.is_required = True sentence_parameter.value = ( "A displaced person should be provided with " "{{ Default }} {{ Unit }}/{{ Units }}/{{ Unit abbreviation }} of " "{{ Resource name }}. Though no less than {{ Minimum allowed }} " "and no more than {{ Maximum allowed }}. This should be provided " "{{ Frequency }}.") parameters = [ name_parameter, description_parameter, unit_parameter, units_parameter, unit_abbreviation_parameter, default_parameter, minimum_parameter, maximum_parameter, frequency_parameter, sentence_parameter ] parameter_container = ParameterContainer(parameters) layout = QGridLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(parameter_container) self.resource_widget.setLayout(layout)
def restore_default_values_page(self): """Setup UI for default values setting.""" # Clear parameters so it doesn't add parameters when # restore from changes. if self.default_value_parameters: self.default_value_parameters = [] unordered_parameters = [] default_fields = all_default_fields() for default_field in default_fields: if default_field.get('type') == QVariant.Double: parameter = FloatParameter() elif default_field.get('type') in qvariant_whole_numbers: parameter = IntegerParameter() else: continue default_value = default_field.get('default_value') if not default_value: message = ( 'InaSAFE default field %s does not have default value' % default_field.get('name')) LOGGER.exception(message) continue parameter.guid = default_field.get('key') parameter.name = default_value.get('name') parameter.is_required = True parameter.precision = default_field.get('precision') parameter.minimum_allowed_value = default_value.get( 'min_value', 0) parameter.maximum_allowed_value = default_value.get( 'max_value', 100000000) parameter.help_text = default_value.get('help_text') parameter.description = default_value.get('description') # Check if user ask to restore to the most default value. if self.is_restore_default: parameter._value = default_value.get('default_value') else: # Current value qsetting_default_value = get_inasafe_default_value_qsetting( self.settings, GLOBAL, default_field['key']) # To avoid python error if qsetting_default_value > parameter.maximum_allowed_value: qsetting_default_value = parameter.maximum_allowed_value if qsetting_default_value < parameter.minimum_allowed_value: qsetting_default_value = parameter.minimum_allowed_value parameter.value = qsetting_default_value unordered_parameters.append(parameter) preferred_order = [ youth_ratio_field, adult_ratio_field, elderly_ratio_field ] for order in preferred_order: parameter_index = [ p.guid for p in unordered_parameters].index(order['key']) if parameter_index > -1: self.default_value_parameters.append( unordered_parameters[parameter_index]) unordered_parameters.pop(parameter_index) self.default_value_parameters.extend(unordered_parameters) description_text = tr( 'In this options you can change the global default values for ' 'these variables.') self.default_value_parameter_container = ParameterContainer( self.default_value_parameters, description_text=description_text) self.default_value_parameter_container.setup_ui() self.default_values_layout.addWidget( self.default_value_parameter_container)
class StepKwInaSAFERasterDefaultValues(WizardStep, FORM_CLASS): """Keyword Wizard Step: InaSAFE Raster Default Values.""" def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.extra_parameters = [ (DefaultValueParameter, DefaultValueParameterWidget) ] self.parameters = [] self.parameter_container = ParameterContainer( extra_parameters=self.extra_parameters) self.default_values_grid.addWidget(self.parameter_container) def is_ready_to_next_step(self): """Check if the step is complete. If so, there is no reason to block the Next button. :returns: True if new step may be enabled. :rtype: bool """ return True def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to :rtype: WizardStep instance or None """ new_step = self.parent.step_kw_source return new_step def inasafe_fields_for_the_layer(self): """Return a list of inasafe fields the current layer. :returns: A list where each value represents inasafe field. :rtype: list """ # Get hazard or exposure value layer_purpose_key = self.parent.step_kw_purpose.selected_purpose()[ 'key'] if layer_purpose_key != layer_purpose_aggregation['key']: subcategory_key = self.parent.step_kw_subcategory.\ selected_subcategory()['key'] else: subcategory_key = None # Get all fields with replace_null = True inasafe_fields = get_fields( layer_purpose_key, subcategory_key, replace_null=True, in_group=False) # remove compulsory field since it has been set in previous step try: inasafe_fields.remove(get_compulsory_fields( layer_purpose_key, subcategory_key)) except ValueError: pass return inasafe_fields # noinspection PyTypeChecker def set_widgets(self): """Set widgets on the Extra Keywords tab.""" existing_inasafe_default_values = self.parent.get_existing_keyword( 'inasafe_default_values') # Remove old container and parameter if self.parameter_container: self.default_values_grid.removeWidget( self.parameter_container) if self.parameters: self.parameters = [] # Iterate through all inasafe fields # existing_inasafe_default_values for inasafe_field in self.inasafe_fields_for_the_layer(): # Create DefaultSelectParameter parameter = DefaultValueParameter() parameter.guid = inasafe_field['key'] parameter.name = inasafe_field['name'] parameter.is_required = False parameter.help_text = inasafe_field['default_value']['description'] # parameter.description = inasafe_field['default_value'] parameter.element_type = unicode parameter.labels = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[0] parameter.options = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[1] if existing_inasafe_default_values: existing_default_value = existing_inasafe_default_values.get( inasafe_field['key']) if existing_default_value: parameter.default = existing_default_value self.parameters.append(parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer( self.parameters, extra_parameters=self.extra_parameters) self.parameter_container.setup_ui() self.default_values_grid.addWidget(self.parameter_container) # Set default value to None for parameter_widget in self.parameter_container.\ get_parameter_widgets(): parameter_widget.widget().set_value(None) # Set default value from existing keywords if existing_inasafe_default_values: for guid, default in existing_inasafe_default_values.items(): parameter_widget = self.parameter_container.\ get_parameter_widget_by_guid(guid) if isinstance(parameter_widget, DefaultValueParameterWidget): parameter_widget.set_value(default) def get_inasafe_default_values(self): """Return inasafe default from the current wizard state. :returns: Dictionary of key and value from InaSAFE Default Values. :rtype: dict """ inasafe_default_values = {} parameters = self.parameter_container.get_parameters(True) for parameter in parameters: if parameter.value is not None: inasafe_default_values[parameter.guid] = parameter.value return inasafe_default_values def clear(self): """Clear current state.""" # Adapted from http://stackoverflow.com/a/13103617/1198772 for i in reversed(range(self.default_values_grid.count())): self.default_values_grid.itemAt(i).widget().setParent(None) self.parameters = [] self.parameter_container = ParameterContainer()
def main(): """Main function to run the example.""" app = QApplication([]) options = OrderedDict([ (DO_NOT_USE, { 'label': 'Do not use', 'value': None, 'type': STATIC, 'constraint': {} }), (GLOBAL_DEFAULT, { 'label': 'Global default', 'value': 0.5, 'type': STATIC, 'constraint': {} }), ( CUSTOM_VALUE, { 'label': 'Custom', 'value': 0.7, # Taken from keywords / recent value 'type': SINGLE_DYNAMIC, 'constraint': { 'min': 0, 'max': 1 } }), ( FIELDS, { 'label': 'Ratio fields', 'value': ['field A', 'field B', 'field C'], # Taken from keywords 'type': MULTIPLE_DYNAMIC, 'constraint': {} }) ]) default_value_parameter = GroupSelectParameter() default_value_parameter.name = 'Group Select parameter' default_value_parameter.help_text = 'Help text' default_value_parameter.description = 'Description' default_value_parameter.options = options default_value_parameter.selected = 'ratio fields' parameters = [default_value_parameter] extra_parameters = [(GroupSelectParameter, GroupSelectParameterWidget)] parameter_container = ParameterContainer(parameters, extra_parameters=extra_parameters) parameter_container.setup_ui() widget = QWidget() layout = QGridLayout() layout.addWidget(parameter_container) widget.setLayout(layout) widget.setGeometry(0, 0, 500, 500) widget.show() sys.exit(app.exec_())
class StepKwInaSAFERasterDefaultValues(WizardStep, FORM_CLASS): """Keyword Wizard Step: InaSAFE Raster Default Values.""" def __init__(self, parent=None): """Constructor for the tab. :param parent: parent - widget to use as parent (Wizard Dialog). :type parent: QWidget """ WizardStep.__init__(self, parent) self.extra_parameters = [(DefaultValueParameter, DefaultValueParameterWidget)] self.parameters = [] self.parameter_container = ParameterContainer( extra_parameters=self.extra_parameters) self.default_values_grid.addWidget(self.parameter_container) def is_ready_to_next_step(self): """Check if the step is complete. If so, there is no reason to block the Next button. :returns: True if new step may be enabled. :rtype: bool """ return True def get_next_step(self): """Find the proper step when user clicks the Next button. :returns: The step to be switched to :rtype: WizardStep instance or None """ new_step = self.parent.step_kw_source return new_step def inasafe_fields_for_the_layer(self): """Return a list of inasafe fields the current layer. :returns: A list where each value represents inasafe field. :rtype: list """ # Get hazard or exposure value layer_purpose_key = self.parent.step_kw_purpose.selected_purpose( )['key'] if layer_purpose_key != layer_purpose_aggregation['key']: subcategory_key = self.parent.step_kw_subcategory.\ selected_subcategory()['key'] else: subcategory_key = None # Get all fields with replace_null = True inasafe_fields = get_fields(layer_purpose_key, subcategory_key, replace_null=True) # remove compulsory field since it has been set in previous step try: inasafe_fields.remove( get_compulsory_fields(layer_purpose_key, subcategory_key)) except ValueError: pass return inasafe_fields # noinspection PyTypeChecker def set_widgets(self): """Set widgets on the Extra Keywords tab.""" existing_inasafe_default_values = self.parent.get_existing_keyword( 'inasafe_default_values') # Remove old container and parameter if self.parameter_container: self.default_values_grid.removeWidget(self.parameter_container) if self.parameters: self.parameters = [] # Iterate through all inasafe fields # existing_inasafe_default_values for inasafe_field in self.inasafe_fields_for_the_layer(): # Create DefaultSelectParameter parameter = DefaultValueParameter() parameter.guid = inasafe_field['key'] parameter.name = inasafe_field['name'] parameter.is_required = False parameter.help_text = inasafe_field['default_value']['description'] # parameter.description = inasafe_field['default_value'] parameter.element_type = unicode parameter.labels = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[0] parameter.options = get_inasafe_default_value_fields( self.parent.setting, inasafe_field['key'])[1] if existing_inasafe_default_values: existing_default_value = existing_inasafe_default_values.get( inasafe_field['key']) if existing_default_value: parameter.default = existing_default_value self.parameters.append(parameter) # Create the parameter container and add to the wizard. self.parameter_container = ParameterContainer( self.parameters, extra_parameters=self.extra_parameters) self.parameter_container.setup_ui() self.default_values_grid.addWidget(self.parameter_container) # Set default value to None for parameter_widget in self.parameter_container.\ get_parameter_widgets(): parameter_widget.widget().set_value(None) # Set default value from existing keywords if existing_inasafe_default_values: for guid, default in existing_inasafe_default_values.items(): parameter_widget = self.parameter_container.\ get_parameter_widget_by_guid(guid) if isinstance(parameter_widget, DefaultValueParameterWidget): parameter_widget.set_value(default) def get_inasafe_default_values(self): """Return inasafe default from the current wizard state. :returns: Dictionary of key and value from InaSAFE Default Values. :rtype: dict """ inasafe_default_values = {} parameters = self.parameter_container.get_parameters(True) for parameter in parameters: if parameter.value is not None: inasafe_default_values[parameter.guid] = parameter.value return inasafe_default_values def clear(self): """Clear current state.""" # Adapted from http://stackoverflow.com/a/13103617/1198772 for i in reversed(range(self.default_values_grid.count())): self.default_values_grid.itemAt(i).widget().setParent(None) self.parameters = [] self.parameter_container = ParameterContainer()