"""Preferences page for FreeCAD Preferences dialog integration. SPDX-License-Identifier: MIT Copyright (c) 2025 Sean P. Kane (GitHub: spkane) This module provides a QWidget-based preferences page that integrates with FreeCAD's main Preferences dialog (Edit → Preferences). NOTE: This is separate from the preferences.py module which handles the actual preference storage. This module only handles the UI. """ from __future__ import annotations from PySide import QtCore, QtWidgets # type: ignore[import-not-found] class MCPBridgePreferencesPage(QtWidgets.QWidget): """Preferences page for FreeCAD's Preferences dialog. This widget appears in the FreeCAD Preferences dialog sidebar when registered via FreeCADGui.addPreferencePage(). Required methods: - loadSettings(): Load preferences into widgets - saveSettings(): Save widget values to preferences """ def __init__(self, parent: QtWidgets.QWidget | None = None) -> None: """Initialize the preferences page widget.""" super().__init__(parent) # Set window title - this appears in the preferences tree under the category self.setWindowTitle("General") self._setup_ui() def _setup_ui(self) -> None: """Set up the user interface.""" layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(10, 10, 10, 10) # Title title = QtWidgets.QLabel("
{var_name}")
var_label.setTextFormat(QtCore.Qt.RichText)
desc_label = QtWidgets.QLabel(description)
env_layout.addRow(var_label, desc_label)
server_layout.addLayout(env_layout)
server_layout.addSpacing(5)
server_note = QtWidgets.QLabel(
"Ensure these match the ports configured above."
)
server_note.setTextFormat(QtCore.Qt.RichText)
server_layout.addWidget(server_note)
layout.addWidget(server_group)
# Add stretch to push everything to the top
layout.addStretch()
def loadSettings(self) -> None:
"""Load settings from FreeCAD preferences into widgets.
This method is called by FreeCAD when the Preferences dialog opens.
"""
# Import here to avoid circular imports and ensure module is available
from preferences import (
get_auto_start,
get_socket_port,
get_status_bar_enabled,
get_xmlrpc_port,
)
self.auto_start_cb.setChecked(get_auto_start())
self.status_bar_cb.setChecked(get_status_bar_enabled())
self.xmlrpc_spin.setValue(get_xmlrpc_port())
self.socket_spin.setValue(get_socket_port())
def saveSettings(self) -> None:
"""Save settings from widgets to FreeCAD preferences.
This method is called by FreeCAD when OK or Apply is clicked.
"""
from preferences import (
get_socket_port,
get_xmlrpc_port,
set_auto_start,
set_socket_port,
set_status_bar_enabled,
set_xmlrpc_port,
)
# Track if ports changed for potential restart
old_xmlrpc = get_xmlrpc_port()
old_socket = get_socket_port()
# Save all preferences
set_auto_start(self.auto_start_cb.isChecked())
set_status_bar_enabled(self.status_bar_cb.isChecked())
set_xmlrpc_port(self.xmlrpc_spin.value())
set_socket_port(self.socket_spin.value())
# Check if ports changed and notify about restart if needed
new_xmlrpc = self.xmlrpc_spin.value()
new_socket = self.socket_spin.value()
if old_xmlrpc != new_xmlrpc or old_socket != new_socket:
# Import FreeCAD here to avoid issues at module load time
import FreeCAD
FreeCAD.Console.PrintMessage(
"MCP Bridge ports changed. "
"If the bridge is running, restart it for changes to take effect.\n"
)