Skip to content

Commit

Permalink
Merge pull request #647 from kartoza/timlinux/issue620
Browse files Browse the repository at this point in the history
  • Loading branch information
timlinux authored Nov 29, 2024
2 parents 31fad99 + 1f7bda1 commit 92d77f0
Show file tree
Hide file tree
Showing 16 changed files with 130 additions and 114 deletions.
27 changes: 16 additions & 11 deletions geest/core/json_tree_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,9 @@ def getStatus(self):
return ""

data = self.attributes()
# log_message(f"Data: {data}")
analysis_mode = data.get("analysis_mode", "")
qgis_layer_source_key = analysis_mode.replace("use_", "") + "layer_spource"
qgis_layer_shapefile_key = analysis_mode.replace("use_", "") + "shapefile"
status = ""

# First check if the item weighting is 0, or its parent factor is zero
Expand Down Expand Up @@ -301,27 +303,30 @@ def getStatus(self):
if "Failed" in data.get("result", ""):
return "Workflow failed"
# Item required and not configured
if "Do Not Use" in data.get("analysis_mode", "") and data.get(
"indicator_required", False
):
if "Do Not Use" in analysis_mode and data.get("factor_weighting", 0.0) > 0:
return "Required and not configured"
# Item not required but not configured
if "Do Not Use" in data.get("analysis_mode", "") and not data.get(
"indicator_required", False
):
if "Do Not Use" in analysis_mode:
return "Not configured (optional)"
# Item required and not configured
if (
self.isIndicator()
and (data.get("analysis_mode", "") == "")
and data.get("indicator_required", False)
and (analysis_mode == "")
and (data.get("factor_weighting", 0.0) > 0)
):
return "Required and not configured"
# Item not required but not configured
if (
self.isIndicator()
and (data.get("analysis_mode", "") == "")
and not data.get("indicator_required", False)
and (analysis_mode == "")
and (data.get("factor_weighting", 0.0) == 0.0)
):
return "Not configured (optional)"
if (
self.isIndicator()
and analysis_mode != "use_default_index_score"
and not data.get(qgis_layer_source_key, False)
and not data.get(qgis_layer_shapefile_key, False)
):
return "Not configured (optional)"
if "Not Run" in data.get("result", "") and not data.get("result_file", ""):
Expand Down
5 changes: 3 additions & 2 deletions geest/gui/dialogs/factor_aggregation_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,15 @@ def switch_page(self):
current_index = self.stacked_widget.currentIndex()
self.stacked_widget.setCurrentIndex(1 - current_index) # Toggle between 0 and 1

def refresh_configuration(self):
def refresh_configuration(self, attributes: dict):
"""Refresh the configuration widget and table.
We call this when any data source widget changes to ensure the data source
and the configuration are conistent with each other.
"""
self.configuration_widget.refresh_radio_buttons()
log_message("data_changed signal received, refreshing configuration")
self.configuration_widget.refresh_radio_buttons(attributes)

def create_checkbox_widget(self, row: int, weighting_value: float) -> QWidget:
checkbox = QCheckBox()
Expand Down
8 changes: 6 additions & 2 deletions geest/gui/factor_configuration_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,16 @@ def create_radio_buttons(self, attributes: dict) -> None:
default_radio = self.button_group.buttons()[0]
default_radio.setChecked(True)

def refresh_radio_buttons(self) -> None:
def refresh_radio_buttons(self, attributes: dict) -> None:
"""
Refreshes the radio buttons.
"""
log_message("Refreshing radio buttons")
for key, value in attributes.items():
log_message(f"Key: {key}, Value: {value}")
for key, widget in self.widgets.items():
widget.update_widgets()
log_message(f"Updating widget for key: {key}")
widget.update_widgets(attributes)

def on_selection_changed(self, button) -> None:
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def set_internal_widgets_enabled(self, enabled: bool) -> None:
level=Qgis.Critical,
)

def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def get_data(self) -> dict:
raise NotImplementedError("Subclasses must implement get_data.")

@abstractmethod
def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
To be implemented by subclasses.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def set_internal_widgets_enabled(self, enabled: bool) -> None:
level=Qgis.Critical,
)

def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def set_internal_widgets_enabled(self, enabled: bool) -> None:
"""
pass

def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def set_internal_widgets_enabled(self, enabled: bool) -> None:
level=Qgis.Critical,
)

def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def set_internal_widgets_enabled(self, enabled: bool) -> None:
level=Qgis.Critical,
)

def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ def set_internal_widgets_enabled(self, enabled: bool) -> None:
level=Qgis.Critical,
)

def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def set_internal_widgets_enabled(self, enabled: bool) -> None:
level=Qgis.Critical,
)

def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,62 +44,13 @@ def add_internal_widgets(self) -> None:
self.table_widget.setEditTriggers(QTableWidget.NoEditTriggers)
self.internal_layout.addWidget(self.table_widget)
self.table_widget.setColumnCount(2)
self.table_widget.setHorizontalHeaderLabels(["Name", "Value 0-100"])
self.table_widget.setColumnWidth(1, 80)
self.table_widget.horizontalHeader().setStretchLastSection(False)
self.table_widget.horizontalHeader().setSectionResizeMode(
0, self.table_widget.horizontalHeader().Stretch
)

safety_classes = self.attributes.get(
f"classify_safety_polygon_into_classes_unique_values", {}
)
if not isinstance(safety_classes, dict):
safety_classes = {}
# remove any item from the safety_classes where the key is not a string
safety_classes = {
k: v for k, v in safety_classes.items() if isinstance(k, str)
}
self.table_widget.setRowCount(len(safety_classes))

def validate_value(value):
return 0 <= value <= 100

log_message(f"Classes: {safety_classes}")
# iterate over the dict and populate the table
for row, (class_name, value) in enumerate(safety_classes.items()):
if row >= self.table_widget.rowCount():
continue

if not isinstance(class_name, str):
continue

if not isinstance(value, (int, float)) or not 0 <= value <= 100:
value = 0

name_item = QTableWidgetItem(class_name)
value_item = QSpinBox()
self.table_widget.setItem(row, 0, name_item)
value_item.setRange(0, 100) # Set spinner range
value_item.setValue(value) # Default value
self.table_widget.setCellWidget(row, 1, value_item)

def on_value_changed(value):
# Color handling for current cell
if value is None or not (0 <= value <= 100):
value_item.setStyleSheet("color: red;")
value_item.setValue(0)
else:
value_item.setStyleSheet("color: black;")
self.update_cell_colors()
self.update_data()

value_item.valueChanged.connect(on_value_changed)

# Call update_cell_colors after all rows are created
self.update_cell_colors()

value_item.valueChanged.connect(on_value_changed)
return self.populate_table()
self.internal_layout.addWidget(self.table_widget)

except Exception as e:
Expand All @@ -108,6 +59,55 @@ def on_value_changed(value):

log_message(traceback.format_exc(), level=Qgis.Critical)

def populate_table(self):

self.table_widget.setHorizontalHeaderLabels(["Name", "Value 0-100"])
safety_classes = self.attributes.get(
f"classify_safety_polygon_into_classes_unique_values", {}
)
if not isinstance(safety_classes, dict):
safety_classes = {}
# remove any item from the safety_classes where the key is not a string
safety_classes = {k: v for k, v in safety_classes.items() if isinstance(k, str)}
self.table_widget.setRowCount(len(safety_classes))

def validate_value(value):
return 0 <= value <= 100

log_message(f"Classes: {safety_classes}")
# iterate over the dict and populate the table
for row, (class_name, value) in enumerate(safety_classes.items()):
if row >= self.table_widget.rowCount():
continue

if not isinstance(class_name, str):
continue

if not isinstance(value, (int, float)) or not 0 <= value <= 100:
value = 0

name_item = QTableWidgetItem(class_name)
value_item = QSpinBox()
self.table_widget.setItem(row, 0, name_item)
value_item.setRange(0, 100) # Set spinner range
value_item.setValue(value) # Default value
self.table_widget.setCellWidget(row, 1, value_item)

def on_value_changed(value):
# Color handling for current cell
if value is None or not (0 <= value <= 100):
value_item.setStyleSheet("color: red;")
value_item.setValue(0)
else:
value_item.setStyleSheet("color: black;")
self.update_cell_colors()
self.update_data()

value_item.valueChanged.connect(on_value_changed)

# Call update_cell_colors after all rows are created
self.update_cell_colors()

def update_cell_colors(self):
# Check if all values are zero
all_zeros = True
Expand Down Expand Up @@ -178,11 +178,14 @@ def set_internal_widgets_enabled(self, enabled: bool) -> None:
level=Qgis.Critical,
)

def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
Only needed in cases where a) there are internal widgets and b)
the attributes may change externally e.g. in the datasource widget.
"""
pass
log_message("Updating widgets for SafetyPolygonConfigurationWidget")
self.attributes = attributes
self.table_widget.clear()
self.populate_table()
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def set_internal_widgets_enabled(self, enabled: bool) -> None:
level=Qgis.Critical,
)

def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def set_internal_widgets_enabled(self, enabled: bool) -> None:
level=Qgis.Critical,
)

def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def set_internal_widgets_enabled(self, enabled: bool) -> None:
level=Qgis.Critical,
)

def update_widgets(self) -> None:
def update_widgets(self, attributes: dict) -> None:
"""
Updates the internal widgets with the current attributes.
Expand Down
Loading

0 comments on commit 92d77f0

Please sign in to comment.