app
Adom Desktop - Fusion 360 Bridge
Public Made by Adomby adom
Drive Autodesk Fusion 360 from the cloud via Adom Desktop: component libraries, IPC package generation, board layout, exports (STEP/Gerbers/BOM/CPL), fast APS cloud search, and parametric modeling.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
"""Close document command — close a Fusion 360 document without the save dialog."""
import adsk.core
def handle_close_document(app: adsk.core.Application, args: dict) -> dict:
"""Close a document in Fusion 360 without triggering the save dialog.
Args (all optional):
name: Name of the document to close. If omitted, closes the active document.
save: If True, save before closing. Default False (discard changes, no dialog).
This is essential for automation — a normal close triggers a modal save dialog
that blocks the Fusion main thread and hangs the add-in until the user clicks.
"""
target_name = args.get("name")
save_changes = args.get("save", False)
try:
if target_name:
# Find the document by name
doc = None
for i in range(app.documents.count):
d = app.documents.item(i)
if d.name == target_name:
doc = d
break
if doc is None:
# List available docs for a helpful error
available = [app.documents.item(i).name for i in range(app.documents.count)]
return {
"success": False,
"error": f"Document '{target_name}' not found. Open documents: {available}",
"_hint": "Call fusion_document_info to list open documents, or use fusion_close_document with no name to close the active document.",
}
else:
# Close the active document
doc = app.activeDocument
if doc is None:
return {
"success": False,
"error": "No active document to close.",
"_hint": "Call fusion_document_info to check open documents — nothing is currently active.",
}
doc_name = doc.name
# Check if document has unsaved changes (for reporting)
is_saved = True
try:
is_saved = doc.isSaved
except Exception:
pass
# Close the document. Passing False skips the save dialog entirely.
doc.close(save_changes)
remaining = app.documents.count
new_active = None
try:
if app.activeDocument:
new_active = app.activeDocument.name
except Exception:
pass
return {
"success": True,
"output": f"Closed '{doc_name}' (save={save_changes}, had_unsaved={'yes' if not is_saved else 'no'}). {remaining} document(s) remaining.",
"data": {
"closedDocument": doc_name,
"savedBeforeClose": save_changes,
"hadUnsavedChanges": not is_saved,
"remainingDocuments": remaining,
"activeDocument": new_active,
},
"_hint": f"{remaining} document(s) still open."
+ (f" Active: '{new_active}'. " if new_active else " No active document. ")
+ "Use fusion_get_app_state to check workspace, or fusion_open_cloud_file to open another document.",
}
except Exception as e:
return {
"success": False,
"error": f"Failed to close document: {e}",
"_hint": "Retry with {\"save\": false} to discard changes, or call fusion_screenshot_fusion to check for a blocking Save dialog and dismiss it with fusion_send_key.",
}
def handle_close_all_documents(app: adsk.core.Application, args: dict) -> dict:
"""Close ALL open documents without save dialogs.
Closes every open document/tab in Fusion without triggering any save
dialogs. Essential before restarting Fusion to avoid the 'Recovered
Documents' modal on next launch.
Args (all optional):
save: If True, save each document before closing. Default False.
"""
save_changes = args.get("save", False)
closed = []
errors = []
skipped = []
# Snapshot the current document list ONCE. Do NOT loop on app.documents.count,
# because Fusion may auto-create an Untitled blank doc whenever all docs close,
# which turns `while count > 0` into an infinite loop and times out the bridge.
try:
snapshot = []
for i in range(app.documents.count):
d = app.documents.item(i)
snapshot.append(d)
except Exception as e:
return {
"success": False,
"error": f"Failed to enumerate documents: {e}",
"_hint": "Retry with {\"save\": false} to discard changes, or call fusion_screenshot_fusion to check for a blocking Save dialog and dismiss it with fusion_send_key.",
}
for doc in snapshot:
try:
doc_name = doc.name
except Exception:
doc_name = "<unknown>"
try:
# Skip Untitled blank docs — Fusion recreates them, closing is pointless
has_data_file = False
try:
has_data_file = doc.dataFile is not None
except Exception:
has_data_file = False
if not has_data_file and doc_name.lower().startswith("untitled"):
skipped.append(doc_name)
continue
doc.close(save_changes)
closed.append(doc_name)
except Exception as e:
errors.append(f"{doc_name}: {e}")
# Keep going — don't abort the whole batch on one failure
return {
"success": len(errors) == 0,
"output": f"Closed {len(closed)} document(s)"
+ (f", skipped {len(skipped)} Untitled" if skipped else "")
+ (f", {len(errors)} error(s)" if errors else ""),
"data": {
"closed": closed,
"skipped": skipped if skipped else None,
"errors": errors if errors else None,
"remainingDocuments": app.documents.count,
},
}