Skip to content

Commit

Permalink
Merge pull request #273 from kartoza/tim
Browse files Browse the repository at this point in the history
Fix unwanted deps
  • Loading branch information
timlinux authored Sep 16, 2024
2 parents e02c701 + aeaee94 commit 65f19bc
Show file tree
Hide file tree
Showing 16 changed files with 1,208 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,4 @@ nix-result/
data
core
app.py
/geest.zip
946 changes: 946 additions & 0 deletions export.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion geest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

#from .geest import Geest
#from .core import RenderQueue, setting
from .core import setting, JSONValidator
from .core import setting #, JSONValidator
from .utilities import resources_path
from .gui import GeestOptionsFactory, GeestDock

Expand Down
9 changes: 1 addition & 8 deletions geest/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,5 @@
from .constants import APPLICATION_NAME
from .settings import setting, set_setting

#from .animation_controller import (
# MapMode,
# AnimationController,
# InvalidAnimationParametersException,
#)
from .default_settings import default_settings
from .json_validator import JSONValidator
#from .movie_creator import MovieFormat, MovieCommandGenerator, MovieCreationTask
#from .render_queue import RenderJob, RenderQueue
#from .json_validator import JSONValidator
2 changes: 2 additions & 0 deletions geest/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
from .geest_dock import GeestDock
from .geest_treeview import JsonTreeItem, JsonTreeModel, CustomTreeView
from .setup_panel import SetupPanel
from .tree_panel import TreePanel
from .layer_detail_dialog import LayerDetailDialog
5 changes: 5 additions & 0 deletions geest/gui/dialogs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .base_dialog import BaseDialog
from .osm_downloader_dialog import OSMDownloaderDialog
from .index_score_dialog import IndexScoreDialog

__all__ = ['BaseDialog', 'OSMDownloaderDialog', 'IndexScoreDialog']
88 changes: 88 additions & 0 deletions geest/gui/dialogs/base_dialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
from abc import ABC, abstractmethod
from qgis.PyQt.QtWidgets import QDialog, QVBoxLayout, QLabel, QHBoxLayout, QPushButton
from qgis.PyQt.QtCore import Qt

from GEEST2.geest.gui.widgets.widget_factory import WidgetFactory


class BaseDialog(QDialog, ABC):
def __init__(self, input_specs: dict, on_accept_callback, parent=None):
"""
Initialize the base dialog.
:param input_specs: Dictionary containing dialog specifications.
:param on_accept_callback: Callback function to handle inputs upon acceptance.
:param parent: Parent widget.
"""
super().__init__(parent)
self.input_specs = input_specs
self.widgets = {}
self.on_accept_callback = on_accept_callback
self.init_ui()

def init_ui(self):
# Set dialog properties
self.setWindowTitle(self.input_specs.get('title', 'Dialog'))
self.layout = QVBoxLayout()
self.setLayout(self.layout)

# Iterate over input specifications to create widgets
for element in self.input_specs.get('elements', []):
widget_type = element.get('type')
label_text = element.get('label', '')
widget = self.create_widget(widget_type, element)

if label_text:
label = QLabel(label_text)
label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
self.layout.addWidget(label)

if widget:
self.layout.addWidget(widget)
self.widgets[element.get('name')] = widget

# Add dialog buttons
self.add_buttons()

def add_buttons(self):
button_layout = QHBoxLayout()
self.ok_button = QPushButton("OK")
self.cancel_button = QPushButton("Cancel")
self.ok_button.clicked.connect(self.handle_accept)
self.cancel_button.clicked.connect(self.reject)
button_layout.addStretch()
button_layout.addWidget(self.ok_button)
button_layout.addWidget(self.cancel_button)
self.layout.addLayout(button_layout)

def create_widget(self, widget_type, spec):
return WidgetFactory.create_widget(widget_type, spec, self)

def get_inputs(self):
inputs = {}
for name, widget in self.widgets.items():
spec = next((elem for elem in self.input_specs['elements'] if elem['name'] == name), None)
if spec:
inputs[name] = WidgetFactory.get_widget_value(widget, spec)
return inputs

def handle_accept(self):
if self.validate_inputs():
inputs = self.get_inputs()
self.on_accept_callback(inputs)
self.accept()
else:
# handle validation failure
pass

@staticmethod
def validate_inputs():
# input validation happens here
return True

@abstractmethod
def process_inputs(self, inputs: dict):
"""
This must be implemented by derived classes!
"""
pass
28 changes: 28 additions & 0 deletions geest/gui/dialogs/index_score_dialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from .base_dialog import BaseDialog

class IndexScoreDialog(BaseDialog):
def __init__(self, on_accept_callback, parent=None):
input_specs = {
'title': 'Index Score Configuration',
'elements': [
{
'type': 'doublespinbox',
'label': 'Default Value',
'name': 'default_value',
'min': 0.0,
'max': 100.0,
'decimals': 2,
'default': 50.0
},
{
'type': 'spinbox',
'label': 'Allowed Range',
'name': 'allowed_range',
'min': 1,
'max': 10,
'default': 5
},
# other widgettes go here
]
}
super().__init__(input_specs, on_accept_callback, parent)
26 changes: 26 additions & 0 deletions geest/gui/dialogs/osm_downloader_dialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from .base_dialog import BaseDialog

class OSMDownloaderDialog(BaseDialog):
def __init__(self, on_accept_callback, parent=None):
input_specs = {
'title': 'OSM Downloader',
'elements': [
{
'type': 'radiobutton',
'label': 'Data Source',
'name': 'data_source',
'options': [
{'label': 'Manual Input', 'id': 'manual', 'checked': True},
{'label': 'Download from OSM', 'id': 'osm'}
]
},
{
'type': 'lineedit',
'label': 'OSM Query',
'name': 'osm_query',
'default': 'highway=primary'
},
# more weedjits here
]
}
super().__init__(input_specs, on_accept_callback, parent)
2 changes: 1 addition & 1 deletion geest/gui/geest_dock.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from .setup_panel import SetupPanel
from .tree_panel import TreePanel
from .layer_detail_dialog import LayerDetailDialog
from ..utilities import resources_path
from geest.utilities import resources_path


class GeestDock(QDockWidget):
Expand Down
15 changes: 11 additions & 4 deletions geest/gui/geest_treeview.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,19 @@ def setData(self, index, value, role=Qt.EditRole):

def flags(self, index):
"""Allow editing of the name and weighting columns."""

#Override the flags method to allow specific columns to be editable.

if not index.isValid():
return Qt.NoItemFlags

item = index.internalPointer()
if index.column() == 0 or index.column() == 2:
# Allow editing for the first column (name) and third column (weighting)
return Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled
return Qt.ItemIsSelectable | Qt.ItemIsEnabled
# For example, only allow editing for the first and second columns
if index.column() == 0 or index.column() == 1:
return Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsEnabled

return Qt.ItemIsSelectable | Qt.ItemIsEnabled

def update_font_color(self, item, color):
"""Update the font color of an item."""
item.font_color = color
Expand Down
2 changes: 1 addition & 1 deletion geest/gui/setup_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
)
from qgis.PyQt.QtCore import QFileInfo, QSettings, QVariant
from qgis.PyQt.QtGui import QPixmap
from ..utilities import resources_path
from geest.utilities import resources_path


class SetupPanel(QWidget):
Expand Down
18 changes: 17 additions & 1 deletion geest/gui/tree_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from .geest_treeview import CustomTreeView, JsonTreeModel
from .setup_panel import SetupPanel
from .layer_detail_dialog import LayerDetailDialog
from ..utilities import resources_path
from geest.utilities import resources_path
from geest.core import set_setting, setting

class TreePanel(QWidget):
Expand Down Expand Up @@ -115,6 +115,22 @@ def __init__(self, parent=None, json_file=None):
button_bar.addWidget(self.edit_toggle) # Add the edit toggle
layout.addLayout(button_bar)
self.setLayout(layout)

def edit(self, index, trigger, event):
"""
Override the edit method to enable editing only on the column that was clicked.
"""
# Get the column that was clicked
column = index.column()

# Only allow editing on specific columns (e.g., column 0, 1, etc.)
if column == 0: # Only make the first column editable
return super().edit(index, trigger, event)
elif column == 2: # And the third column editable
return super().edit(index, trigger, event)

# Return False if the column shouldn't be editable
return False

def load_json(self):
"""Load the JSON data from the file."""
Expand Down
3 changes: 3 additions & 0 deletions geest/gui/widgets/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .widget_factory import WidgetFactory

__all__ = ['WidgetFactory']
77 changes: 77 additions & 0 deletions geest/gui/widgets/widget_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from qgis.PyQt.QtWidgets import (
QDoubleSpinBox, QSpinBox, QLineEdit, QComboBox, QRadioButton, QButtonGroup,
QFileDialog, QWidget, QHBoxLayout
)
from qgis.gui import QgsLayerComboBox
from qgis.core import QgsMapLayer

class WidgetFactory:
@staticmethod
def create_widget(widget_type, spec, parent):
if widget_type == 'doublespinbox':
widget = QDoubleSpinBox(parent)
widget.setRange(spec.get('min', -1e10), spec.get('max', 1e10))
widget.setDecimals(spec.get('decimals', 2))
widget.setValue(spec.get('default', 0.0))
return widget
elif widget_type == 'spinbox':
widget = QSpinBox(parent)
widget.setRange(spec.get('min', -1e9), spec.get('max', 1e9))
widget.setValue(spec.get('default', 0))
return widget
elif widget_type == 'lineedit':
widget = QLineEdit(parent)
widget.setText(spec.get('default', ''))
return widget
elif widget_type == 'dropdown':
widget = QComboBox(parent)
options = spec.get('options', [])
widget.addItems(options)
default = spec.get('default')
if default in options:
widget.setCurrentText(default)
elif options:
widget.setCurrentText(options[0])
return widget
elif widget_type == 'radiobutton':
button_group = QButtonGroup(parent)
layout = QHBoxLayout()
container = QWidget(parent)
container.setLayout(layout)
for option in spec.get('options', []):
rb = QRadioButton(option['label'])
rb.setChecked(option.get('checked', False))
button_group.addButton(rb, id=option.get('id'))
layout.addWidget(rb)
container.button_group = button_group # Attach the button group for retrieval
return container
elif widget_type == 'layerselector':
widget = QgsLayerComboBox(parent)
layer_type = spec.get('layer_type', 'vector') # can be vector or raster
if layer_type == 'vector':
widget.setFilters(QgsMapLayer.VectorLayer)
elif layer_type == 'raster':
widget.setFilters(QgsMapLayer.RasterLayer)
widget.setCurrentLayer(spec.get('default_layer', None))
return widget
# more widgets go here
else:
return None

@staticmethod
def get_widget_value(widget, spec):
widget_type = spec.get('type')
if widget_type in ['doublespinbox', 'spinbox']:
return widget.value()
elif widget_type == 'lineedit':
return widget.text()
elif widget_type == 'dropdown':
return widget.currentText()
elif widget_type == 'radiobutton':
checked_button = widget.button_group.checkedButton()
return checked_button.text() if checked_button else None
elif widget_type == 'layerselector':
layer = widget.currentLayer()
return layer.name() if layer else None
else:
return None
File renamed without changes.

0 comments on commit 65f19bc

Please sign in to comment.