Skip to content

Commit

Permalink
Merge pull request #767 from kartoza/timlinux/issue714
Browse files Browse the repository at this point in the history
Fix datasource widget interactions
  • Loading branch information
timlinux authored Jan 15, 2025
2 parents 9f6be29 + f4692f6 commit b4d3a45
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 17 deletions.
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"author": "Kartoza",
"email": "[email protected]",
"description": "Gender Enabling Environments Spatial Tool",
"version": "0.4.6",
"version": "0.4.7",
"changelog": "",
"server": false
}
Expand Down
4 changes: 2 additions & 2 deletions geest/gui/dialogs/analysis_aggregation_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -634,8 +634,8 @@ def load_combo_from_model(
if layer:
combo.setLayer(layer)
if item.attribute(f"{prefix}_shapefile", False):
lineedit.setText(self.attributes[f"{prefix}_shapefile"])
lineedit.setText(self.item.attribute[f"{prefix}_shapefile"])
lineedit.setVisible(True)
if item.attribute(f"{prefix}_raster", False):
lineedit.setText(self.attributes[f"{prefix}_raster"])
lineedit.setText(self.item.attribute[f"{prefix}_raster"])
lineedit.setVisible(True)
17 changes: 16 additions & 1 deletion geest/gui/panels/tree_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,10 @@ def show_attributes(self, item):
dialog = QDialog()
dialog.setWindowState(Qt.WindowMaximized)
dialog.setWindowTitle("Attributes")
dialog.resize(600, 400)
dialog.resize(
int(QApplication.desktop().screenGeometry().width() * 0.9),
int(QApplication.desktop().screenGeometry().height() * 0.9),
)

layout = QVBoxLayout()
dialog.setLayout(layout)
Expand Down Expand Up @@ -1077,6 +1080,10 @@ def add_to_map(
def edit_analysis_aggregation(self, analysis_item):
"""Open the AnalysisAggregationDialog for editing the weightings of factors in the analysis."""
dialog = AnalysisAggregationDialog(analysis_item, parent=self)
dialog.resize(
int(QApplication.desktop().screenGeometry().width() * 0.9),
int(QApplication.desktop().screenGeometry().height() * 0.9),
)
if dialog.exec_(): # If OK was clicked
dialog.saveWeightingsToModel()
self.save_json_to_working_directory() # Save changes to the JSON if necessary
Expand All @@ -1090,6 +1097,10 @@ def edit_dimension_aggregation(self, dimension_item):
dialog = DimensionAggregationDialog(
dimension_name, dimension_data, dimension_item, parent=self
)
dialog.resize(
int(QApplication.desktop().screenGeometry().width() * 0.9),
int(QApplication.desktop().screenGeometry().height() * 0.9),
)
if dialog.exec_(): # If OK was clicked
dialog.saveWeightingsToModel()
self.save_json_to_working_directory() # Save changes to the JSON if necessary
Expand All @@ -1103,6 +1114,10 @@ def edit_factor_aggregation(self, factor_item):
dialog = FactorAggregationDialog(
factor_name, factor_data, factor_item, parent=self
)
dialog.resize(
int(QApplication.desktop().screenGeometry().width() * 0.9),
int(QApplication.desktop().screenGeometry().height() * 0.9),
)
if dialog.exec_(): # If OK was clicked
dialog.save_weightings_to_model()
self.save_json_to_working_directory() # Save changes to the JSON if necessary
Expand Down
20 changes: 11 additions & 9 deletions geest/gui/toggle_switch.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from qgis.PyQt.QtWidgets import QWidget
from qgis.PyQt.QtCore import Qt, pyqtSignal, QSize
from qgis.PyQt.QtCore import Qt, pyqtSignal, QSize, QRect
from qgis.PyQt.QtGui import QColor, QPainter


Expand All @@ -10,7 +10,7 @@ class ToggleSwitch(QWidget):

def __init__(self, initial_value=False, parent=None):
super().__init__(parent)
self.setFixedSize(QSize(40, 20)) # Size of the toggle switch
self.setFixedSize(QSize(60, 26)) # Size of the toggle switch
self.checked = initial_value

def paintEvent(self, event):
Expand All @@ -21,20 +21,22 @@ def paintEvent(self, event):
# Background color based on state
if self.checked:
painter.setBrush(
QColor("#002244")
QColor("#fffdcf")
) # Active state color (blue) from WB Style Guide
else:
painter.setBrush(QColor("#ADB5BD")) # Inactive state color (gray)
painter.setBrush(QColor("#fffdcf")) # Inactive state color (gray)

# Draw the rounded rectangle as the background
painter.setRenderHint(QPainter.Antialiasing)
painter.drawRoundedRect(rect, rect.height() // 2, rect.height() // 2)
painter.drawRoundedRect(rect, rect.height() // 4, rect.height() // 4)

# Draw the circle (slider knob)
knob_radius = rect.height() - 6
knob_x = rect.x() + 3 if not self.checked else rect.right() - knob_radius - 3
painter.setBrush(QColor("#009CA7")) # From WB Style Guide
painter.drawEllipse(knob_x, rect.y() + 3, knob_radius, knob_radius)
knob_radius = rect.height() // 4
knob_x = rect.x() if not self.checked else rect.right() - 30
knob_rect = QRect(knob_x, rect.y(), 30, 26)
# knob_rect.setWidth(30)
painter.setBrush(QColor("#6FB7B5")) # From WB Style Guide
painter.drawRoundedRect(knob_rect, knob_radius, knob_radius)

def mousePressEvent(self, event):
"""Toggle the switch on mouse click."""
Expand Down
67 changes: 63 additions & 4 deletions geest/gui/widgets/datasource_widgets/vector_datasource_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
QToolButton,
QFileDialog,
)
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtCore import QSettings, QEvent, Qt
from qgis.gui import QgsMapLayerComboBox
from .base_datasource_widget import BaseDataSourceWidget
from qgis.core import QgsMapLayerProxyModel, QgsProject, QgsVectorLayer
from qgis.PyQt.QtCore import QSettings
from geest.utilities import log_message
from qgis.core import QgsMapLayerProxyModel, QgsProject, Qgis
from geest.utilities import log_message, resources_path


class VectorDataSourceWidget(BaseDataSourceWidget):
Expand Down Expand Up @@ -69,6 +70,21 @@ def add_internal_widgets(self) -> None:
self.shapefile_line_edit = QLineEdit()
self.shapefile_line_edit.setVisible(False) # Hide initially

# Add clear button inside the line edit
self.clear_button = QToolButton(self.shapefile_line_edit)
clear_icon = QIcon(resources_path("resources", "icons", "clear.svg"))
self.clear_button.setIcon(clear_icon)
self.clear_button.setToolTip("Clear")
self.clear_button.setCursor(Qt.ArrowCursor)
self.clear_button.setStyleSheet("border: 0px; padding: 0px;")
self.clear_button.clicked.connect(self.clear_shapefile)
self.clear_button.setVisible(False)

self.shapefile_line_edit.textChanged.connect(
lambda text: self.clear_button.setVisible(bool(text))
)
self.shapefile_line_edit.textChanged.connect(self.resize_clear_button)
# Add a button to select a shapefile
self.shapefile_button = QToolButton()
self.shapefile_button.setText("...")
self.shapefile_button.clicked.connect(self.select_shapefile)
Expand All @@ -77,7 +93,11 @@ def add_internal_widgets(self) -> None:
self.attributes[f"{self.widget_key}_shapefile"]
)
self.shapefile_line_edit.setVisible(True)
self.layer_combo.setVisible(False)
else:
self.layer_combo.setVisible(True)
self.layout.addWidget(self.shapefile_line_edit)
self.resize_clear_button()
self.layout.addWidget(self.shapefile_button)

# Emit the data_changed signal when any widget is changed
Expand All @@ -90,6 +110,31 @@ def add_internal_widgets(self) -> None:

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

def resizeEvent(self, event):
"""
Handle resize events for the parent container.
Args:
event: The resize event.
"""
super().resizeEvent(event)
self.resize_clear_button()

def resize_clear_button(self):
"""Reposition the clear button when the line edit is resized."""
log_message("Resizing clear button")
# Position the clear button inside the line edit
frame_width = self.shapefile_line_edit.style().pixelMetric(
self.shapefile_line_edit.style().PM_DefaultFrameWidth
)
self.shapefile_line_edit.setStyleSheet(
f"QLineEdit {{ padding-right: {self.clear_button.sizeHint().width() + frame_width}px; }}"
)
sz = self.clear_button.sizeHint()
self.clear_button.move(
self.shapefile_line_edit.width() - sz.width() - frame_width - 5, 6
)

def select_shapefile(self):
"""
Opens a file dialog to select a shapefile and stores the last directory in QSettings.
Expand All @@ -105,14 +150,28 @@ def select_shapefile(self):

if file_path:
# Update the line edit with the selected file path
self.shapefile_line_edit.setText(file_path)
# ⚠️ Be careful about changing the order of the following lines
# It could cause the clear button to render in the incorrect place
self.layer_combo.setVisible(False)
self.shapefile_line_edit.setVisible(True)
self.shapefile_line_edit.setText(file_path)
# Trigger resize event explicitly
self.resizeEvent(None)
# Save the directory of the selected file to QSettings
settings.setValue("Geest/lastShapefileDir", os.path.dirname(file_path))

except Exception as e:
log_message(f"Error selecting shapefile: {e}", level=Qgis.Critical)

def clear_shapefile(self):
"""
Clears the shapefile line edit and hides it along with the clear button.
"""
self.shapefile_line_edit.clear()
self.shapefile_line_edit.setVisible(False)
self.layer_combo.setVisible(True)
self.update_attributes()

def update_attributes(self):
"""
Updates the attributes dict to match the current state of the widget.
Expand Down
47 changes: 47 additions & 0 deletions geest/resources/icons/clear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added geest/resources/images/clear.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit b4d3a45

Please sign in to comment.