Xrefs panel
Xref Manager
Reload, unload, detach or bind several xrefs at once, picked from a list that shows each one's status and saved path.
PYXREFMANAGERXMWhat it does#
Lists every top-level xref in the drawing, sorted by name, with its status and the path saved in the drawing. You tick the ones to work on, pick one action, and the tool applies it to each xref in turn. One xref that fails does not stop the others: they are all tried, and the ones that did not work are listed at the end with the reason.
Each line of the list reads like this:
Site [loaded] ..\Xref\site.dwg
Grid [not found, overlay] P:\Jobs\1234\Xref\grid.dwg
Logo [unloaded] .\logo.dwg
The word in brackets is the xref's status: loaded,
unloaded, not found (the file is not at the saved path or
on any search path), unresolved or unreferenced (attached
but with no reference left in the drawing). An xref attached as an overlay also says
overlay. An xref with no saved path shows (no path).
How to use it#
- Click Xref Manager, or type
PYXREFMANAGER. If the drawing has no xrefs a toast says so and nothing opens. - Tick the xrefs to work on. The search box narrows a long list. Click OK.
- Pick what should happen to them: Reload, Unload, Detach or Bind.
- For Bind, pick how. Bind keeps each xref's layers and
styles apart, renamed in the
Site$0$Wallspattern. Insert merges them into the drawing's own layers and styles, the way the INSERT command does. - Detach and Bind ask once more before they start, because both take the xref out of its file's control.
- The tool works through the list. When every xref worked, a toast says so (for example "Reloaded 3 xrefs"). When some failed, the toast says how many of how many, and a window lists each failure with its reason. That window shows the first 15; its Copy button puts all of them on the clipboard.
Limitations#
- Nested xrefs are not listed. Reload, unload or bind the xref that holds them.
- Only a loaded xref can be bound. An unloaded or missing one is reported as not done, with its status as the reason; reload it (or fix its path with Xref Repath) first.
- AutoCAD reloads an xref whose file it cannot find without raising an error. The tool
reads every xref's status again after a Reload, so one that is still not loaded is
reported as failed, for example
not found at ..\Xref\site.dwg, rather than counted as done. - One action per run. To reload some xrefs and unload others, run the tool twice.
- The tool does not attach or overlay new xrefs. Use XATTACH for that. Images, PDF underlays and other attachments are not listed: only DWG xrefs.
Good to know#
A ribbon click sends the PYXREFMANAGER command to the drawing, so the whole
run is one command and a single U takes it back, Detach and Bind included.
Undo is the only way back from either.
The list is a quick status report in its own right: open it, read it, and press Cancel. Nothing changes until you pick an action.
Other uses#
- Unload the heavy backgrounds before you work on your own layers, and reload them all in one pass before you plot.
- Reload every xref after a consultant issues new backgrounds, and see at once which ones did not come back.
- Bind the xrefs into a copy of the drawing for an archive or a transmittal that must open without its reference files.
Source#
The tool's own files, word for word as shipped in Xrefs.panel/Xref_Manager.pushbutton. Every pyACAD tool is an ordinary bundle: copy these into your own extension and change what you like.
script.py Runs on a click. View on GitHub# -*- coding: utf-8 -*-
"""Reload, unload, detach or bind several of the drawing's xrefs at once.
Lists every top-level xref with its status and saved path, asks what to do
with the ones picked, and does it to each in turn, so one that fails does not
stop the rest. Detach and bind ask first: both take the xref out of the
drawing's control and only Undo brings it back. Nested xrefs are not listed,
since they follow the xref that holds them.
"""
from pyacad import doc, forms, script, toast, xrefs
__title__ = 'Xref Manager'
TITLE = 'Xref Manager'
ACTIONS = ['Reload', 'Unload', 'Detach', 'Bind']
DONE = {'Reload': 'Reloaded', 'Unload': 'Unloaded', 'Detach': 'Detached', 'Bind': 'Bound'}
LIMIT = 15 # failures shown in the alert; Copy carries them all
def run():
if script.get_document_path() is None:
toast.warning('Open a drawing first')
return
rows = sorted([x for x in xrefs.list() if not x['nested']],
key=lambda x: x['name'].lower())
if not rows:
toast.info('This drawing has no xrefs')
return
labels = xrefs.describe(rows)
picked = forms.select_from_list(
[(label, row['name']) for label, row in zip(labels, rows)],
title=TITLE, multiselect=True, prompt='Pick the xrefs to work on')
if not picked:
return
action = forms.ask_options('What should happen to %s?' % _what(picked),
ACTIONS, title=TITLE)
if action is None:
return
insert = False
if action == 'Bind':
how = forms.ask_options(
"Bind keeps each xref's layers and styles apart, renamed like "
"Site$0$Walls. Insert merges them into the drawing's own, as INSERT does.",
['Bind', 'Insert'], title=TITLE)
if how is None:
return
insert = how == 'Insert'
if action in ('Detach', 'Bind') and not forms.confirm(_warning(action, insert, picked), TITLE):
return
status = dict((row['name'], row['status']) for row in rows)
with doc.lock():
results = [_apply(action, name, insert, status.get(name)) for name in picked]
if action == 'Reload':
# AutoCAD reloads a missing file without complaint; the status says.
results = xrefs.check_loaded(results, xrefs.list())
_report(results, DONE[action])
def _apply(action, name, insert, status):
"""(name, error) for one xref; error is None when it worked."""
if action == 'Bind' and status != 'loaded':
return name, '%s; only a loaded xref can be bound' % xrefs.status_label(status)
try:
if action == 'Reload':
xrefs.reload([name])
elif action == 'Unload':
xrefs.unload([name])
elif action == 'Detach':
xrefs.detach(name)
else:
xrefs.bind([name], insert=insert)
except Exception as error:
return name, str(error) or error.__class__.__name__
return name, None
def _report(results, verb):
head = xrefs.headline(results, verb)
failed = len([1 for name, error in results if error])
if not failed:
toast.success(head)
return
if failed == len(results):
toast.error(head)
else:
toast.warning(head, '%d not done' % failed)
forms.alert(xrefs.summarize(results, verb, limit=LIMIT), TITLE,
copy=xrefs.summarize(results, verb))
def _warning(action, insert, picked):
if action == 'Detach':
return ('Detach %s? It leaves the drawing with every reference to it.'
if len(picked) == 1 else
'Detach %s? They leave the drawing with every reference to them.') % _what(picked)
how = ' as inserted blocks' if insert else ''
return ('Bind %s into the drawing%s? It stops following its file.'
if len(picked) == 1 else
'Bind %s into the drawing%s? They stop following their files.') % (_what(picked), how)
def _what(names):
"""'Site' for one xref, '3 xrefs' for more."""
return names[0] if len(names) == 1 else '%d xrefs' % len(names)
if '__commandpath__' in globals():
run()bundle.yaml The bundle contract: the keys pyACAD reads for this tool. View on GitHubtitle: Xref Manager
tooltip: Reload, unload, detach or bind several xrefs at once. Pick them from a list that shows each one's status and saved path.
context: doc
keytip: XM
alias: XM