Source code for sec_interp.gui.main_dialog_tools

from __future__ import annotations

"""Map tool management module for SecInterp main dialog.

This module handles the initialization and orchestration of map tools
(pan, measure) used in the preview canvas.
"""

from typing import TYPE_CHECKING, Any

from qgis.gui import QgsMapTool, QgsMapToolPan

from .tools.interpretation_tool import ProfileInterpretationTool
from .tools.measure_tool import ProfileMeasureTool

if TYPE_CHECKING:
    from .main_dialog import SecInterpDialog


[docs] class DialogToolManager: """Manages map tools and related event handling for the preview canvas."""
[docs] def __init__( self, dialog: SecInterpDialog, pan_tool: Optional[QgsMapTool] = None, measure_tool: Optional[ProfileMeasureTool] = None, interpretation_tool: Optional[ProfileInterpretationTool] = None, ): """Initialize tool manager with reference to parent dialog. Args: dialog: The :class:`sec_interp.gui.main_dialog.SecInterpDialog` instance pan_tool: Optional pan tool for injection measure_tool: Optional measure tool for injection interpretation_tool: Optional interpretation tool for injection """ self.dialog = dialog self.pan_tool = pan_tool self.measure_tool = measure_tool self.interpretation_tool = interpretation_tool
[docs] def initialize_tools(self) -> None: """Create and configure map tools if not already provided.""" if not self.pan_tool: self.pan_tool = QgsMapToolPan(self.dialog.preview_widget.canvas) if not self.measure_tool: self.measure_tool = ProfileMeasureTool(self.dialog.preview_widget.canvas) if not self.interpretation_tool: self.interpretation_tool = ProfileInterpretationTool(self.dialog.preview_widget.canvas) # Connect polygonFinished signal to dialog handler self.interpretation_tool.polygonFinished.connect(self.dialog.on_interpretation_finished) self.dialog.preview_widget.canvas.setMapTool(self.pan_tool)
[docs] def toggle_measure_tool(self, checked: bool) -> None: """Toggle between measurement and pan tools. Args: checked: True to activate measure tool, False for pan tool. """ if checked: # Reset any previous measurement when starting new one self.measure_tool.reset() self.dialog.preview_widget.canvas.setMapTool(self.measure_tool) self.measure_tool.activate() # Show finalize button when measurement tool is active self.dialog.preview_widget.btn_finalize.setVisible(True) else: self.dialog.preview_widget.canvas.setMapTool(self.pan_tool) self.pan_tool.activate() # Hide finalize button when measurement tool is inactive self.dialog.preview_widget.btn_finalize.setVisible(False)
[docs] def activate_default_tool(self) -> None: """Set the default (pan) tool.""" self.dialog.preview_widget.canvas.setMapTool(self.pan_tool) self.pan_tool.activate()
[docs] def toggle_interpretation_tool(self, checked: bool) -> None: """Toggle between interpretation and pan tools. Args: checked: True to activate interpretation tool, False for pan tool. """ if checked: # Deactivate measure tool if active self.dialog.preview_widget.btn_measure.setChecked(False) # Reset and activate interpretation tool self.interpretation_tool.reset() self.dialog.preview_widget.canvas.setMapTool(self.interpretation_tool) self.interpretation_tool.activate() else: self.dialog.preview_widget.canvas.setMapTool(self.pan_tool) self.pan_tool.activate()
[docs] def update_measurement_display(self, metrics: dict[str, Any]) -> None: """Display measurement results from multi-point tool. Args: metrics: Dictionary containing measurement data. """ if not metrics or metrics.get("point_count", 0) < 2: return total_dist = metrics.get("total_distance", 0) horiz_dist = metrics.get("horizontal_distance", 0) elev_change = metrics.get("elevation_change", 0) avg_slope = metrics.get("avg_slope", 0) seg_count = metrics.get("segment_count", 0) point_count = metrics.get("point_count", 0) # Format result text with HTML for better presentation msg = ( f"<b>{self.dialog.tr('Multi-Point Measurement')}</b><br>" f"<b>{self.dialog.tr('Points')}:</b> {point_count} | <b>{self.dialog.tr('Segments')}:</b> {seg_count}<br>" f"<b>{self.dialog.tr('Total Distance')}:</b> {total_dist:.2f} m<br>" f"<b>{self.dialog.tr('Horizontal Distance')}:</b> {horiz_dist:.2f} m<br>" f"<b>{self.dialog.tr('Elevation Change')}:</b> {elev_change:+.2f} m<br>" f"<b>{self.dialog.tr('Average Slope')}:</b> {avg_slope:.1f}°" ) self.dialog.preview_widget.results_text.setHtml(msg) # Ensure results group is expanded self.dialog.preview_widget.results_group.setCollapsed(False)