Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #2132 - traceback on parsing custom minimum needs file #2133

Closed
wants to merge 9 commits into from
7 changes: 5 additions & 2 deletions metadata.txt
Expand Up @@ -9,11 +9,12 @@


[general]
name=InaSAFE-Dev
name=InaSAFE
qgisMinimumVersion=2.0
qgisMaximumVersion=2.99
description=InaSAFE is free software that allows disaster managers to study realistic natural hazard impact scenarios for better planning, preparedness and response activities.
version=3.1.0
about=Developed for the Indonesian Government - BNPB, Australian Government - AIFDR and World Bank - GFDRR
version=3.1.1
# alpha, beta, rc or final
status=final

Expand All @@ -23,6 +24,8 @@ status=final
# Optional items:

changelog=
3.1.1
* Fixes issues with resizing of some dialogs e.g. minimum needs dialog
3.1.0
New features:
* Reorganised impact functions
Expand Down
20 changes: 12 additions & 8 deletions safe/gui/tools/minimum_needs/needs_manager_dialog.py
Expand Up @@ -44,6 +44,7 @@
InvalidMaximumError,
InvalidMinimumError)
from safe_extras.parameters.string_parameter import StringParameter
from safe_extras.parameters.text_parameter import TextParameter
from safe.utilities.help import show_context_help
from safe.utilities.resources import resources_path, get_ui_class
from safe.messaging import styles
Expand Down Expand Up @@ -194,6 +195,9 @@ def __init__(self, parent=None, dock=None):
self.profile_combo.activated.connect(self.select_profile)
# noinspection PyUnresolvedReferences
self.stacked_widget.currentChanged.connect(self.page_changed)
# initial sync profile_combo and resource list
self.clear_resource_list()
self.populate_resource_list()

def reject(self):
"""Overload the base dialog reject event so we can handle state change.
Expand Down Expand Up @@ -293,8 +297,8 @@ def add_new_resource(self):
"""Handle add new resource requests.
"""
parameters_widget = [
self.resource_widget.layout().itemAt(i) for i in
range(self.resource_widget.layout().count())][0].widget()
self.parameters_scrollarea.layout().itemAt(i) for i in
range(self.parameters_scrollarea.layout().count())][0].widget()
parameter_widgets = [
parameters_widget.vertical_layout.itemAt(i).widget() for i in
range(parameters_widget.vertical_layout.count())]
Expand Down Expand Up @@ -326,8 +330,8 @@ def edit_resource(self):
if not resource:
return
parameters_widget = [
self.resource_widget.layout().itemAt(i) for i in
range(self.resource_widget.layout().count())][0].widget()
self.parameters_scrollarea.layout().itemAt(i) for i in
range(self.parameters_scrollarea.layout().count())][0].widget()
parameter_widgets = [
parameters_widget.vertical_layout.itemAt(i).widget() for i in
range(parameters_widget.vertical_layout.count())]
Expand Down Expand Up @@ -462,7 +466,7 @@ def set_up_resource_parameters(self):
frequency_parameter.is_required = True
frequency_parameter.value = 'weekly'

sentence_parameter = StringParameter('UUID-10')
sentence_parameter = TextParameter('UUID-10')
sentence_parameter.name = 'Readable sentence'
sentence_parameter.help_text = (
'A readable presentation of the resource.')
Expand Down Expand Up @@ -498,7 +502,7 @@ def set_up_resource_parameters(self):
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
layout.addWidget(parameter_container)
self.resource_widget.setLayout(layout)
self.parameters_scrollarea.setLayout(layout)

def remove_resource(self):
"""Remove the currently selected resource.
Expand All @@ -520,8 +524,8 @@ def save_resource(self):
# Hackorama to get this working outside the method that the
# parameters where defined in.
parameters_widget = [
self.resource_widget.layout().itemAt(i) for i in
range(self.resource_widget.layout().count())][0]
self.parameters_scrollarea.layout().itemAt(i) for i in
range(self.parameters_scrollarea.layout().count())][0]
parameters = parameters_widget.widget().get_parameters()

resource = {}
Expand Down
5 changes: 3 additions & 2 deletions safe/gui/tools/minimum_needs/needs_profile.py
Expand Up @@ -208,8 +208,9 @@ def get_needs_parameters(self):
precision_influence = [
'Maximum allowed', 'Minimum allowed', 'Default']
for element in precision_influence:
if resource[element] is not None and '.' in resource[element]:
precisions.append(self.precision_of(resource[element]))
resource_element = str(resource[element])
if resource[element] is not None and '.' in resource_element:
precisions.append(self.precision_of(resource_element))

parameter.precision = max(precisions)
parameters.append(parameter)
Expand Down
30 changes: 25 additions & 5 deletions safe/gui/ui/needs_manager_dialog_base.ui
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>751</width>
<height>669</height>
<width>737</width>
<height>538</height>
</rect>
</property>
<property name="contextMenuPolicy">
Expand Down Expand Up @@ -263,6 +263,28 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="parameters_scrollarea">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>717</width>
<height>430</height>
</rect>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
Expand Down Expand Up @@ -291,9 +313,7 @@
</item>
</layout>
</widget>
<resources>
<include location="../resources/resources.qrc"/>
</resources>
<resources/>
<connections>
<connection>
<sender>button_box</sender>
Expand Down
Expand Up @@ -21,7 +21,7 @@ def target_field():
field.name = 'Target Field'
field.is_required = True
field.help_text = (
'This field of impact layer marks inundated roads by \'1\' value')
'This field of impact layer marks inundated buildings by \'1\' value')
field.description = (
'This field of impact layer marks inundated roads by \'1\' value. '
'This is the longer description of this parameter.')
Expand Down
2 changes: 2 additions & 0 deletions safe_extras/parameters/qt_widgets/qt4_parameter_factory.py
Expand Up @@ -11,6 +11,7 @@
from qt_widgets.float_parameter_widget import FloatParameterWidget
from qt_widgets.integer_parameter_widget import IntegerParameterWidget
from qt_widgets.string_parameter_widget import StringParameterWidget
from qt_widgets.text_parameter_widget import TextParameterWidget
from qt_widgets.generic_parameter_widget import GenericParameterWidget


Expand All @@ -24,6 +25,7 @@ def __init__(self):
'FloatParameter': FloatParameterWidget,
'IntegerParameter': IntegerParameterWidget,
'StringParameter': StringParameterWidget,
'TextParameter': TextParameterWidget
}

def register_widget(self, parameter, parameter_widget):
Expand Down
55 changes: 55 additions & 0 deletions safe_extras/parameters/qt_widgets/text_parameter_widget.py
@@ -0,0 +1,55 @@
# coding=utf-8
"""Docstring for this file."""
__author__ = 'ismailsunni'
__project_name = 'parameters'
__filename = 'string_parameter_widget'
__date__ = '8/28/14'
__copyright__ = 'ismail@kartoza.com'
__doc__ = ''


from PyQt4.QtGui import QTextEdit, QSizePolicy

from qt_widgets.generic_parameter_widget import GenericParameterWidget


class TextParameterWidget(GenericParameterWidget):
"""Widget class for string parameter."""
def __init__(self, parameter, parent=None):
"""Constructor

.. versionadded:: 2.2

:param parameter: A StringParameter object.
:type parameter: StringParameter

"""
super(TextParameterWidget, self).__init__(parameter, parent)

self._line_edit_input = QTextEdit()
self._line_edit_input.setSizePolicy(
QSizePolicy.Minimum, QSizePolicy.Minimum)
# Tooltips
self.setToolTip('Write the value for %s here ' % self._parameter.name)
self._line_edit_input.setText(self._parameter.value)

self._inner_input_layout.addWidget(self._line_edit_input)

def get_parameter(self):
"""Obtain string parameter object from the current widget state.

:returns: A StringParameter from the current state of widget
"""
value = self._line_edit_input.toPlainText()
if value.__class__.__name__ == 'QString':
value = str(value)
self._parameter.value = value
return self._parameter

def set_text(self, text):
"""Update the text of the widget

:param text: The new text
:type text: str
"""
self._line_edit_input.setText(text)
22 changes: 22 additions & 0 deletions safe_extras/parameters/text_parameter.py
@@ -0,0 +1,22 @@
# coding=utf-8
"""String Parameter."""

from generic_parameter import GenericParameter


class TextParameter(GenericParameter):
"""A subclass of generic parameter that accepts text only.

.. versionadded:: 3.2
"""

def __init__(self, guid=None):
"""Constructor.

:param guid: Optional unique identifier for this parameter. If none
is specified one will be generated using python hash. This guid
will be used when storing parameters in the registry.
:type guid: str, None
"""
super(TextParameter, self).__init__(guid)
self.expected_type = [str, unicode]