diff --git a/freecad/InitGui.py b/freecad/InitGui.py index 0a6d1b9..662e559 100644 --- a/freecad/InitGui.py +++ b/freecad/InitGui.py @@ -44,14 +44,23 @@ class SiloWorkbench(FreeCADGui.Workbench): "Silo_Commit", "Silo_Pull", "Silo_Push", + ] + + # Menu has management/admin commands (file commands are in File menu + # via the Create module's SiloMenuManipulator) + self.menu_commands = [ "Silo_Info", "Silo_BOM", + "Silo_TagProjects", + "Silo_SetStatus", + "Silo_Rollback", + "Separator", "Silo_Settings", "Silo_Auth", ] self.appendToolbar("Silo", self.toolbar_commands) - self.appendMenu("Silo", self.toolbar_commands) + self.appendMenu("Silo", self.menu_commands) def Activated(self): """Called when workbench is activated.""" @@ -67,7 +76,9 @@ class SiloWorkbench(FreeCADGui.Workbench): def _show_shortcut_recommendations(self): """Show keyboard shortcut recommendations dialog on first activation.""" try: - param_group = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/KindredSilo") + param_group = FreeCAD.ParamGet( + "User parameter:BaseApp/Preferences/Mod/KindredSilo" + ) if param_group.GetBool("ShortcutsShown", False): return param_group.SetBool("ShortcutsShown", True) diff --git a/freecad/silo_commands.py b/freecad/silo_commands.py index 01ba57f..b162c87 100644 --- a/freecad/silo_commands.py +++ b/freecad/silo_commands.py @@ -106,6 +106,10 @@ def _get_auth_source() -> str: return param.GetString("AuthSource", "") +def _get_auth_token() -> str: + return _fc_settings.get_api_token() + + # Thin wrappers so command classes can call these without refactoring. # They delegate to the settings adapter or the shared client. @@ -848,9 +852,6 @@ class Silo_Save: # Check if document has unsaved changes gui_doc = FreeCADGui.getDocument(doc.Name) is_modified = gui_doc.Modified if gui_doc else True - FreeCAD.Console.PrintMessage( - f"[DEBUG] Modified={is_modified}, FileName={doc.FileName}\n" - ) if gui_doc and not is_modified and doc.FileName: FreeCAD.Console.PrintMessage("No changes to save.\n") @@ -858,17 +859,9 @@ class Silo_Save: # Collect properties BEFORE saving to avoid dirtying the document # (accessing Shape properties can trigger recompute) - FreeCAD.Console.PrintMessage("[DEBUG] Collecting properties...\n") properties = collect_document_properties(doc) - # Check modified state after collecting properties - is_modified_after_props = gui_doc.Modified if gui_doc else True - FreeCAD.Console.PrintMessage( - f"[DEBUG] After collect_properties: Modified={is_modified_after_props}\n" - ) - # Save locally - FreeCAD.Console.PrintMessage("[DEBUG] Saving to canonical path...\n") file_path = _sync.save_to_canonical_path(doc, force_rename=True) if not file_path: # Fallback to regular save if canonical path fails @@ -879,24 +872,12 @@ class Silo_Save: FreeCAD.Console.PrintError("Could not determine save path\n") return - # Check modified state after save - is_modified_after_save = gui_doc.Modified if gui_doc else True - FreeCAD.Console.PrintMessage( - f"[DEBUG] After save: Modified={is_modified_after_save}\n" - ) - # Force clear modified flag if save succeeded (needed for assemblies) - if is_modified_after_save and gui_doc: - FreeCAD.Console.PrintMessage( - "[DEBUG] Attempting to clear Modified flag...\n" - ) + if gui_doc and gui_doc.Modified: try: gui_doc.Modified = False - FreeCAD.Console.PrintMessage( - f"[DEBUG] After force clear: Modified={gui_doc.Modified}\n" - ) - except Exception as e: - FreeCAD.Console.PrintMessage(f"[DEBUG] Could not clear Modified: {e}\n") + except Exception: + pass FreeCAD.Console.PrintMessage(f"Saved: {file_path}\n") @@ -909,12 +890,6 @@ class Silo_Save: new_rev = result["revision_number"] FreeCAD.Console.PrintMessage(f"Uploaded as revision {new_rev}\n") - # Check modified state after upload - is_modified_after_upload = gui_doc.Modified if gui_doc else True - FreeCAD.Console.PrintMessage( - f"[DEBUG] After upload: Modified={is_modified_after_upload}\n" - ) - except Exception as e: FreeCAD.Console.PrintWarning(f"Upload failed: {e}\n") FreeCAD.Console.PrintMessage("File saved locally but not uploaded.\n") @@ -2675,9 +2650,9 @@ class SiloAuthDockWidget: self._url_label.setText(_get_api_url()) has_token = _client.is_authenticated() - username = _client.auth_username() - role = _client.auth_role() - source = _client.auth_source() + username = _get_auth_username() + role = _get_auth_role() + source = _get_auth_source() # Check server connectivity try: diff --git a/freecad/silo_origin.py b/freecad/silo_origin.py index d78600c..fd186e5 100644 --- a/freecad/silo_origin.py +++ b/freecad/silo_origin.py @@ -15,10 +15,10 @@ import FreeCADGui from .silo_commands import ( _client, _sync, + collect_document_properties, + find_file_by_part_number, get_tracked_object, set_silo_properties, - find_file_by_part_number, - collect_document_properties, ) @@ -126,19 +126,35 @@ class SiloOrigin: def connect(self) -> bool: """Trigger authentication if needed. - Shows the Silo authentication dialog if not already authenticated. + Shows the Silo login dialog if not already authenticated. Returns: True if authenticated after this call """ if _client.is_authenticated(): - return True + try: + ok, _ = _client.check_connection() + if ok: + return True + except Exception: + pass - # Show auth dialog via existing Silo_Auth command + # Show login dialog directly try: - cmd = FreeCADGui.Command.get("Silo_Auth") - if cmd: - cmd.Activated() + from PySide import QtWidgets + + mw = FreeCADGui.getMainWindow() + if mw is None: + return False + + # Find or create the auth dock widget and trigger its login dialog + panel = mw.findChild(QtWidgets.QDockWidget, "SiloDatabaseAuth") + if panel and hasattr(panel, "_auth"): + panel._auth._show_login_dialog() + else: + # Fallback: run the Settings command so the user can configure + FreeCADGui.runCommand("Silo_Settings") + return _client.is_authenticated() except Exception as e: FreeCAD.Console.PrintError(f"Silo connect failed: {e}\n") @@ -379,7 +395,9 @@ class SiloOrigin: # Upload to Silo properties = collect_document_properties(doc) - _client._upload_file(obj.SiloPartNumber, str(file_path), properties, comment="") + _client._upload_file( + obj.SiloPartNumber, str(file_path), properties, comment="" + ) # Clear modified flag doc.Modified = False