* chore: rename workbench to FreecadRobustMCPBridge * fix: stdio cleanup and bug fix for JSON RPC * fix: update FreeCAD MCP bridge and tests * test: Fix GUI Integration tests and other issues * fix: unit tests in CI and a few other things * docs: generate GitHub pages site and link to it. * fix: General code improvements and DRY refactoring * chore: General cleanup * chore: small fixes * docs: cleanup * docs: fixes * docs: small corrections * docs: fix * test: release check * bump: workbench v0.6.0 * chore: bump macros to 0.6.0 * docs: Release improvements * refactor: improve DRYness of code
151 lines
3.9 KiB
Python
151 lines
3.9 KiB
Python
"""Preferences management for the Robust MCP Bridge workbench.
|
|
|
|
SPDX-License-Identifier: MIT
|
|
Copyright (c) 2025 Sean P. Kane (GitHub: spkane)
|
|
|
|
This module handles reading and writing workbench preferences using
|
|
FreeCAD's parameter system.
|
|
|
|
NOTE: Using os.path instead of pathlib throughout this module due to
|
|
FreeCAD's module loading behavior which can have issues with some
|
|
Python features at load time.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TypedDict
|
|
|
|
import FreeCAD
|
|
|
|
|
|
class PreferencesDict(TypedDict):
|
|
"""Type definition for the preferences dictionary."""
|
|
|
|
auto_start: bool
|
|
status_bar_enabled: bool
|
|
xmlrpc_port: int
|
|
socket_port: int
|
|
|
|
|
|
# Parameter path for our workbench preferences
|
|
PARAM_PATH = "User parameter:BaseApp/Preferences/Mod/RobustMCPBridge"
|
|
|
|
# Default values
|
|
DEFAULT_AUTO_START = False
|
|
DEFAULT_STATUS_BAR_ENABLED = True
|
|
DEFAULT_XMLRPC_PORT = 9875
|
|
DEFAULT_SOCKET_PORT = 9876
|
|
|
|
|
|
def get_param() -> FreeCAD.ParameterGrp:
|
|
"""Get the parameter group for our preferences."""
|
|
return FreeCAD.ParamGet(PARAM_PATH)
|
|
|
|
|
|
def get_auto_start() -> bool:
|
|
"""Get whether the bridge should auto-start when FreeCAD launches.
|
|
|
|
Returns:
|
|
True if bridge should auto-start, False otherwise.
|
|
Default: False
|
|
"""
|
|
return get_param().GetBool("AutoStart", DEFAULT_AUTO_START)
|
|
|
|
|
|
def set_auto_start(enabled: bool) -> None:
|
|
"""Set whether the bridge should auto-start when FreeCAD launches.
|
|
|
|
Args:
|
|
enabled: True to enable auto-start, False to disable.
|
|
"""
|
|
get_param().SetBool("AutoStart", enabled)
|
|
|
|
|
|
def get_status_bar_enabled() -> bool:
|
|
"""Get whether the status bar indicator is enabled.
|
|
|
|
Returns:
|
|
True if status bar indicator should be shown, False otherwise.
|
|
Default: True
|
|
"""
|
|
return get_param().GetBool("StatusBarEnabled", DEFAULT_STATUS_BAR_ENABLED)
|
|
|
|
|
|
def set_status_bar_enabled(enabled: bool) -> None:
|
|
"""Set whether the status bar indicator is enabled.
|
|
|
|
Args:
|
|
enabled: True to show status bar indicator, False to hide.
|
|
"""
|
|
get_param().SetBool("StatusBarEnabled", enabled)
|
|
|
|
|
|
def get_xmlrpc_port() -> int:
|
|
"""Get the XML-RPC port number.
|
|
|
|
Returns:
|
|
Port number for XML-RPC server.
|
|
Default: 9875
|
|
"""
|
|
return get_param().GetInt("XMLRPCPort", DEFAULT_XMLRPC_PORT)
|
|
|
|
|
|
def set_xmlrpc_port(port: int) -> None:
|
|
"""Set the XML-RPC port number.
|
|
|
|
Args:
|
|
port: Port number for XML-RPC server (1024-65535).
|
|
|
|
Raises:
|
|
ValueError: If port is out of valid range.
|
|
"""
|
|
if not 1024 <= port <= 65535:
|
|
raise ValueError(f"Port must be between 1024 and 65535, got {port}")
|
|
get_param().SetInt("XMLRPCPort", port)
|
|
|
|
|
|
def get_socket_port() -> int:
|
|
"""Get the JSON-RPC socket port number.
|
|
|
|
Returns:
|
|
Port number for JSON-RPC socket server.
|
|
Default: 9876
|
|
"""
|
|
return get_param().GetInt("SocketPort", DEFAULT_SOCKET_PORT)
|
|
|
|
|
|
def set_socket_port(port: int) -> None:
|
|
"""Set the JSON-RPC socket port number.
|
|
|
|
Args:
|
|
port: Port number for JSON-RPC socket server (1024-65535).
|
|
|
|
Raises:
|
|
ValueError: If port is out of valid range.
|
|
"""
|
|
if not 1024 <= port <= 65535:
|
|
raise ValueError(f"Port must be between 1024 and 65535, got {port}")
|
|
get_param().SetInt("SocketPort", port)
|
|
|
|
|
|
def get_all_preferences() -> PreferencesDict:
|
|
"""Get all preferences as a dictionary.
|
|
|
|
Returns:
|
|
Dictionary with all preference values.
|
|
"""
|
|
return {
|
|
"auto_start": get_auto_start(),
|
|
"status_bar_enabled": get_status_bar_enabled(),
|
|
"xmlrpc_port": get_xmlrpc_port(),
|
|
"socket_port": get_socket_port(),
|
|
}
|
|
|
|
|
|
def reset_to_defaults() -> None:
|
|
"""Reset all preferences to their default values."""
|
|
set_auto_start(DEFAULT_AUTO_START)
|
|
set_status_bar_enabled(DEFAULT_STATUS_BAR_ENABLED)
|
|
set_xmlrpc_port(DEFAULT_XMLRPC_PORT)
|
|
set_socket_port(DEFAULT_SOCKET_PORT)
|