Alpha VectorLabel is in alpha — docs and software are evolving. Report a problem →
User guide

The complete VectorLabel guide

Everything the software does, explained end to end — from installing the apps and the Vectorworks plug-ins to designing labels, binding data, and printing on Brady and Brother thermal printers.

Alpha · jump to any topic from the contents on the left.

Getting started

What VectorLabel is

VectorLabel is a macOS menu-bar app suite for printing wrap-around wire and cable labels. Its original and primary job is to take a list of circuits exported from Vectorworks ConnectCAD and print one label per wire on a Brady M610 or M611 label printer, but it also supports designing your own label templates and printing from your own data files (CSV/XLSX).

The app stays out of your way: by default it runs only in the menu bar (no Dock icon), watches a folder for new exports, and shows a print window automatically when one appears. You pick a template, choose which records to print, pick the printer, and print.

Because this is alpha software, expect rough edges. Some printers are fully validated on real hardware, while others are only partially hardware-verified — individual functions have been confirmed on real printers, but not every function or end-to-end path yet. See the gotchas for what is and isn't verified.

Tips

The menu-bar icon is your main entry point — click it to open the dropdown with printers, recent prints, and the Open Designer / Preferences / Quit actions.

If you only have a Brady M611 or M610, the core printing path is the most mature part of the app.

Heads up

Hardware verification is uneven in alpha. Per the project's own status notes: the Brady M611 is hardware-validated; the Brady M610's cut behavior is noted as still unverified; and all three Brother P-touch drivers (PT-E550W, PT-P750W, PT-E560BT) are implemented and partially hardware-verified — individual functions confirmed on real printers, but not yet every function end-to-end (docs/PTOUCH-DRIVER-STATUS.md).

The README's headline still describes the app narrowly as printing 'Brady M610/M611 wrap-around wire labels from Vectorworks ConnectCAD exports'; the suite has since grown to four apps and additional printers/designers.

The four apps and how they coordinate

The suite is built as four separate macOS applications, declared as four executables in Package.swift. Each is a self-contained .app with its own bundle identifier:

1) VectorLabel Engine (com.sai.vectorlabel.engine) — the headless print engine and the menu-bar hub. This is the ONLY app that talks to USB printers (it is the one that links the libusb library). It owns the printers, runs the print queue, and publishes live printer/cassette status that the other apps read (supply status refreshes automatically about every 30 seconds while printers are idle; nothing is polled while a job is printing). The menu-bar icon and Preferences window belong to this app. Only one Engine is allowed to run at a time — it takes an exclusive lock (engine.lock) so two engines can't fight over the USB printer.

2) VectorLabel Auto Print (com.sai.vectorlabel.autoprint) — a background helper with no Dock icon. It watches the Exports folder and, when a new CSV export appears (and you have auto-open enabled), it opens the print window. It does not print directly; it hands jobs to the Engine through the shared queue. It also hosts the print window's 'Edit' action, which opens the Template Designer in-process.

3) VectorLabel Template Designer (com.sai.vectorlabel.templatedesigner) — a normal Dock app for designing reusable label templates (.vltmp files, formerly .vlt.json). Launched from the Engine's menu or by double-clicking a template file.

4) VectorLabel Custom Designer (com.sai.vectorlabel.customdesigner) — a Dock app for free-form custom labels (.vlcus files) that can be bound to your own data file. It has a bottom Database pane for binding a CSV or Excel file (printing one label per row) and a print header with the printer picker, Copies, Cut and Print — see Custom Designer database mode.

How they coordinate: the Engine is the single source of truth for printing and printer status. The front-end apps never print themselves — they write job files into a shared queue folder and the Engine consumes them. The designers and Auto Print automatically start the Engine if it isn't running (ensureRunning), and they shut down when the Engine quits, so the whole suite comes up and goes down together. 'Reprint' from the menu bar is routed back to whichever app created the job (Auto Print or Custom Designer) so it can re-open the original window in its print-time state.

queue/       ready jobs
processing/  claimed by the Engine
done/        finished
failed/      errored
control/     cancel / detect-cassette requests
status/      printers.json (Engine-published status)
reprint/, reprint-custom/, cancelled/
Tips

You normally only launch the Engine and Auto Print; the two designers open on demand from the Engine menu (Open Template Designer / Open Custom Designer) or by opening a .vltmp / .vlcus document in Finder.

Because the Custom Designer intentionally avoids touching the Templates folder on launch, it won't trigger a macOS Documents-access prompt just by opening.

Heads up

Only ONE Engine can own the USB printer at a time. If a second Engine launches it won't double-run — it nudges the live Engine to re-show its menu-bar icon and then exits. When testing the suite, quit any legacy single VectorLabel.app so it doesn't contend for the device.

The inter-app launching (Open Template/Custom Designer) only works in the installed, packaged suite where all four apps carry their expected bundle ids. In a developer 'swift run' build the launch simply no-ops.

System requirements

VectorLabel requires macOS 14 (Sonoma) or later, on an Apple Silicon Mac (the released apps are arm64-only) — this is set as the minimum platform in Package.swift (.macOS(.v14)). The installer doesn't hard-block older systems: it warns that the apps may not run correctly and lets you continue at your own risk.

For end users, no extra software is required: the libusb USB library is bundled inside the Engine app (in Contents/Frameworks) and signed, so it runs on Macs that do not have Homebrew installed. The app uses the Hardened Runtime and is NOT sandboxed, because it needs raw USB access and access to your ~/Documents folder.

For USB printing (Brady M610, and the Brother P-touch models over USB) you connect the printer by USB cable. The Brady M611 can also be added as a network printer over TCP. For network printers you add them by host/IP in Preferences.

For developers building from source, you additionally need Xcode, and you must install libusb and pkg-config via Homebrew first (brew install libusb pkg-config). On Apple Silicon the build expects libusb at /opt/homebrew; on Intel Macs you edit the module map to /usr/local.

brew install libusb pkg-config   # developers only, before building in Xcode
Tips

Network (Wi-Fi) printing currently targets the M611 over raw TCP; USB is used for the M610 and the Brother PT models.

An Apple Developer account ($99/yr) is only needed if YOU want to sign/notarize your own builds — end users downloading official releases do not need one.

Heads up

The app is intentionally not sandboxed and needs raw USB plus ~/Documents access; this is expected for the kind of work it does, but it means the Engine app is the privileged piece of the suite.

Developer builds via plain 'swift run' do NOT enforce entitlements, and the inter-app launch features won't work because the four bundle ids aren't registered.

Installing and launching

For end users, official builds are distributed from the project's GitHub Releases page. Pushing a version tag runs a release workflow that signs (Developer ID), notarizes, staples, and attaches a guided .pkg installer plus a .zip and a .dmg to the Release. The recommended path is the guided .pkg installer, which walks you through welcome / license / readme / conclusion panes and installs all four apps.

After installation, launch VectorLabel Engine first — it places the menu-bar icon and brings the rest of the suite to life as needed. Auto Print also runs in the background. The two designers open on demand from the Engine menu or by double-clicking a template/custom-label document. You can also have the Engine start automatically when you log in: turn on the toggle in Preferences ▸ Advanced ▸ App Behaviour (macOS may ask you to approve it under System Settings ▸ General ▸ Login Items).

The sample (starter) templates now ship inside the app rather than being copied by the installer. On first launch the Engine offers them on the same setup screen that offers supply groups, where you choose which sample templates to install into your Templates folder. (Earlier builds placed the samples via the .pkg installer; the installer no longer copies them.)

The local install/build path (for developers or testers) is scripts/package-suite.sh to build the four .app bundles into dist/VectorLabel/, then scripts/install.sh to copy them into /Applications/VectorLabel/ and relaunch the always-on apps. A plain unsigned package runs on your own machine after a right-click → Open but is not distributable.

In Xcode, developers open Package.swift, select the VectorLabel scheme with destination My Mac, and build (⌘B). Info.plist and entitlements must be set manually in the Xcode target because Swift Package Manager can't bundle them.

scripts/package-suite.sh   # build the 4 .app bundles into dist/VectorLabel/
scripts/install.sh         # install into /Applications/VectorLabel/ and relaunch
  1. Download the latest release from the project's GitHub Releases page (.pkg installer recommended).
  2. Run the .pkg installer and follow its panes; it installs all four apps.
  3. Launch 'VectorLabel Engine' — the menu-bar icon appears.
  4. Open a designer from the menu bar (Open Template Designer / Open Custom Designer) or trigger a print by exporting from Vectorworks.
Tips

An unsigned .pkg (e.g. a local build) installs fine after a right-click → Open in Finder; official signed+notarized installers come from the release workflow.

You can verify a signed app on your Mac with: spctl --assess --type execute -vv on the app bundle — it should report 'accepted, source=Notarized Developer ID'.

The installer registers the designers with Launch Services so double-clicking a .vltmp or .vlcus file opens the correct designer.

Heads up

I could not find an end-user 'how to download' page bundled in the repo — the Releases page is the documented distribution channel, but the exact download URL is not in the source I read (put the real URL in only after confirming it).

scripts/install.sh installs into /Applications/VectorLabel/ (or ~/Applications if /Applications isn't writable) and deliberately leaves any legacy /Applications/VectorLabel.app untouched; quit that legacy app while testing the suite so they don't both grab the USB printer.

On-disk layout: where your files and settings live

VectorLabel keeps your documents under your home Documents folder and keeps its internal coordination files under Application Support.

Your documents live in ~/Documents/VectorLabel/. Inside it: Templates/ holds your label template files from the designer, and Exports/ holds one subfolder per Vectorworks project, each containing the exported CSV files. The CSVs are named with a date-time code (…_export_YYYYMMDD_HHMMSS.csv), and the app keeps at most 15 exports per project by default (older ones are pruned).

The watch folder root and the Templates folder are both configurable in Preferences, so these paths can be moved.

The apps coordinate through a hidden inter-process folder under ~/Library/Application Support/VectorLabel/ipc/ (the name becomes 'VectorLabel Beta' for beta builds). This holds the print queue and status: queue/, processing/, done/, failed/, control/, status/ (with printers.json), plus reprint/, reprint-custom/, and cancelled/. You normally never touch this folder.

Your preferences are stored in the standard macOS UserDefaults (not a visible file you edit). They include the watch-folder path, Templates-folder path, max exports per project (default 15), default print range, appearance, per-printer calibration offsets keyed by serial number, and shared print-table column layout. Recent-print history and a small crash log (~/Library/Logs/VectorLabel-crash.log) are also kept.

~/Documents/VectorLabel/
  Templates/         label templates (.vltmp / legacy .vlt.json)
  Exports/
    <VWFileName>/    <VWFileName>_export_YYYYMMDD_HHMMSS.csv  (max 15)

~/Library/Application Support/VectorLabel/ipc/   internal queue + status
Tips

Use the menu-bar 'Open Export Folder' command (⌘E) to jump straight to ~/Documents/VectorLabel/Exports/ in Finder.

Calibration offsets are saved per physical printer (by serial number), so they survive unplugging/reconnecting and relaunching.

Heads up

The README still shows the older template extension '.vlt.json'; the packaged designers now use '.vltmp' (templates) and '.vlcus' (custom labels), with .vlt.json supported as a legacy name.

A factory 'Reset Defaults' (Advanced tab) also clears per-printer alignment/calibration offsets.

Beta builds use a separate 'VectorLabel Beta' Application Support folder, so a beta and a production build keep independent IPC/status state.

First run and granting USB / printer access

On first run, launch the Engine; it adds the menu-bar icon and begins scanning for connected printers. For a USB printer (Brady M610, Brother PT models), plug it in by USB and the Engine's scan should detect it. You can also force a scan with the 'Scan USB' button in Preferences → Printers.

Granting access to the printer: the Engine talks to USB printers via libusb and automatically detaches the macOS kernel/CUPS driver when it claims the device, so you generally don't need to remove the printer from System Settings first. If a printer is detected but can't be opened, the app reports 'Could not open printer (permissions?)' — this usually means another process (such as the system print driver or a second Engine) is holding the device.

Documents access: because the app reads and writes ~/Documents/VectorLabel, macOS may show a one-time prompt to allow access to your Documents folder the first time the app reads it. The Custom Designer is deliberately written to avoid touching the Templates folder on launch so it doesn't trigger that prompt just by opening.

Notifications: the Engine asks for permission to post local notifications (used for messages like a failed reprint). Granting this is optional — if you decline, those notifications are silently skipped.

For a network M611, you don't have to know its IP: Preferences → Printers → Scan → 'Scan network (subnet)' auto-discovers it on your local network. You can also add it directly by entering its host/IP and choosing the model, then click 'Add' — useful when subnet discovery can't reach it, or for a Wi-Fi Brother model (guessed as PT-E550W, since it can't be positively identified over the network).

  1. Launch VectorLabel Engine and look for the menu-bar icon.
  2. Plug in your USB printer (or prepare to add a network printer by IP).
  3. Open the menu bar → Preferences… → Printers tab.
  4. For USB: click Scan → 'Scan USB' if the printer isn't already listed. For network: click Scan → 'Scan network (subnet)' to auto-discover, or type the host/IP, pick the model, and click 'Add'.
  5. If macOS prompts to allow Documents access or notifications, allow them.
Tips

Brady USB ids: M610 is VID 0x0E2E / PID 0x010B (confirmed). The M611 is detected as its composite USB device (VID 0x0E2E / PID 0x13), hardware-confirmed on a real unit — if an M611 still isn't found over USB, suspect the cable or port, or add it as a network printer instead.

If the menu-bar icon ever disappears (macOS can drop it after long uptime or sleep), simply re-launching the Engine nudges the live one to re-show the icon and opens Preferences as a reliable on-screen entry point.

Heads up

The Brother USB transport detaches the macOS AppleUSBPrinter kext and does not reattach it; after using a Brother printer with VectorLabel you may need to unplug/replug for the system print driver to take it back.

'Could not open printer (permissions?)' almost always means the device is busy (claimed by another app or a second Engine), not a macOS privacy setting.

Units (inches or millimetres) and typing math into fields

VectorLabel can display and accept dimensions in either inches or millimetres, and the choice is suite-wide. Set it in Engine ▸ Preferences ▸ Advanced ▸ "Units" (Inches / Millimetres). The setting applies live to every app at once: the designer rulers, every dimension field in the designers (object position/size, table row/column sizes, label length), the print previews, and the printer/supply readouts all switch together. Because labels are always stored the same way internally, switching units is purely a display-and-entry change — it never alters a saved template or custom label, and a file made by someone working in inches opens identically for someone working in millimetres.

The Template and Custom Designer rulers also have a small in/mm toggle in the top-left ruler corner, so you can flip units right on the canvas without opening Preferences.

Every physical-dimension field also understands fractions, the other unit, and basic arithmetic — type it and it converts to the field's current unit. Examples: 1/8", 1 1/4, or 3mm auto-convert; arithmetic works too, so .25"-1/8" becomes 0.125" and, in millimetres, 10+5 becomes 15 mm. A comma decimal like 12,7 is accepted. This works across the designers' object, position, size and table fields and in the supply editor. Fields that are not physical label measurements are left as-is: font size (points), line/stroke weights, percentages, degrees, and counts are entered plainly.

1/8"      → 0.125 in
1 1/4     → 1.25 in
3mm       → converts to the field's unit
.25"-1/8" → 0.125 in
10+5      → 15 mm   (in millimetre mode)
12,7      → 12.7    (comma decimal)
Tips

You don't have to switch the whole app to millimetres to enter one metric value — just type 3mm (or 12,7) into an inch field and it converts.

Use arithmetic to nudge a value without doing the maths yourself — just type an expression like 1.5-0.1 straight into a size field (no leading = needed; these aren't formulas).

Heads up

Units are display + entry only — the stored file is unchanged. If a saved label "looks the same size" after switching units, that's expected; the numbers just read in the other unit.

Font size stays in points, and weights/percent/degrees/counts stay unitless — the fraction/other-unit/math parsing applies only to physical label dimensions.

Software updates

The Engine checks GitHub for new VectorLabel releases. On first launch it asks how often to check — on every launch, every N days (the pre-selected default, every 7 days), or manually only — and you can change that choice any time in Preferences → Updates. When a newer version is found, a popup lists the changes between your installed version and the new one — every version in between, pulled from the project changelog — with three choices: "Update Now" (downloads the installer to ~/Downloads and opens it), "Remind Me Tomorrow" (asks again in 24 hours), and "Don't Update" (skips that version only — a later release will prompt again). Preferences → Updates also has a "Check for Updates Now" button with the last-checked time, and when a version is available its Updates card shows the same what's-changed list with its own Update Now button (even if you previously skipped or snoozed). The menu-bar dropdown has a "Check for Updates…" row as well.

Vectorworks integration

What the integration does

ConnectCAD is the cabling/signal-flow design add-on inside Vectorworks. Every cable run you draw is a 'circuit' object that carries data about both of its ends: which device, which socket, which connector, the room, the rack, the signal type, the cable type and length, and so on.

VectorLabel ships two Python command plug-ins for Vectorworks. When you run one, it reads those circuit objects and writes a CSV file (a plain spreadsheet) into ~/Documents/VectorLabel/Exports/. The VectorLabel AutoPrint app watches that folder and automatically opens the print window when a new file lands. Nothing is sent over a network and no copy/paste is needed.

Each circuit produces TWO label rows in the CSV — one for the Source end and one for the Destination end — because a wire wrap label is usually applied near each end of the cable.

~/Documents/VectorLabel/Exports/<VWFileName>/<VWFileName>_export_YYYYMMDD_HHMMSS.csv
Tip

You never open the CSV yourself. AutoPrint reads it for you. The CSV is just the hand-off format between Vectorworks and VectorLabel.

Heads up

This integration is specifically for ConnectCAD circuits. Other Vectorworks objects in your selection or on your layer are silently skipped (they are counted as 'non-circuit object(s) skipped').

Installing the two command plug-ins in Vectorworks

There are TWO separate menu commands, one per Python file. Vectorworks shows one menu command per registered command plug-in, so you create two New Command plug-ins and paste a different script into each.

The two script files live in the VectorworksPlugin folder of the VectorLabel project: export_selected.py and export_all.py. You paste the ENTIRE contents of each file — each script is self-contained, so there is no separate shared file to import.

VectorworksPlugin/export_selected.py
VectorworksPlugin/export_all.py
  1. In Vectorworks, go to Tools menu, then Plug-ins, then Plug-in Manager.
  2. Click New Command. Set Language to Python.
  3. Name the command exactly: Export Selected Circuits to VectorLabel.
  4. Open export_selected.py in a text editor, copy the whole file, and paste it into the command's script body. Save/close the Plug-in Manager.
  5. Click New Command again (Language: Python). Name it exactly: Export All Circuits to VectorLabel.
  6. Paste the entire contents of export_all.py into this second command.
  7. Add the commands to your workspace: Tools menu, then Workspaces, then Edit Current Workspace. Drag both commands into a menu of your choice, then save the workspace.
  8. The two commands now appear in the menu you chose and are ready to run.
Tips

The command names matter for your own clarity but the script does the work; just keep the two scripts in separate commands so both menu items exist.

On Windows the path the scripts write to is the user's Documents/VectorLabel folder as well (the script uses the home folder); the documentation here describes the Mac path because the rest of VectorLabel is a Mac app.

Heads up

If you paste both scripts into a single command, you will only get one menu item and lose one of the two export modes. Create two distinct New Command plug-ins.

If a command does not appear in your menu after pasting, you most likely forgot the Edit Current Workspace step — installing in the Plug-in Manager alone does not place it in a menu.

The two commands: Selected vs All

'Export Selected Circuits to VectorLabel' exports only what you currently have selected. Internally it collects every object matching the selection criteria. If nothing is selected, it shows an alert: 'No objects selected. Select one or more ConnectCAD circuits.' If your selection contains objects but none are circuits, it shows 'No ConnectCAD circuits found in selection.' with a count of skipped objects.

'Export All Circuits to VectorLabel' ignores your selection entirely and walks the ACTIVE DESIGN LAYER, exporting every ConnectCAD circuit found on it. If there are none, it shows 'No ConnectCAD circuits found on the active layer.' with a skipped count.

Tips

Use 'Export Selected' to print labels for just a few cables you fixed up. Use 'Export All' to relabel an entire design layer at once.

'Export All' is layer-scoped: it only sees the layer that is active in Vectorworks at the moment you run it. Switch to the layer you want before running.

Heads up

'Export All' uses the ACTIVE design layer only — circuits on other layers are not included.

An object counts as a 'circuit' only if it has a source device name, a destination device name, a Signal value, or a CircuitType value. A circuit missing all of these would be skipped.

What ConnectCAD data is exported (every column)

For each circuit the script writes two rows — a 'Source' row and a 'Destination' row — marked by a column named _Side. Each row carries shared circuit-level fields plus the fields specific to that end of the cable, plus a few 'Other end' fields so a label can reference where the cable goes.

Shared circuit-level columns (same value on both the Source and Destination rows): Number (the circuit/cable number), Cable, Signal, Circuits, CableLength, CableCalculatedLength, Number Display, Cable Type, Cable Outside Diameter, and CircuitType.

End-specific columns take their value from the Source end on the Source row and from the Destination end on the Destination row: Device_Name, Device_Tag, Socket_Name, Socket_Tag, Socket_Signal, Connector, Socket_Circs, Room, Rack, and RackU.

Cross-reference columns describe the OTHER end of the same cable: Other_Device, Other_Socket, and Other_Connector. On a Source row these point at the destination; on a Destination row they point back at the source.

_Side, Number, Cable, Signal, Circuits, CableLength, CableCalculatedLength, Number Display, Cable Type, Cable Outside Diameter, CircuitType, Device_Name, Device_Tag, Socket_Name, Socket_Tag, Socket_Signal, Connector, Socket_Circs, Room, Rack, RackU, Other_Device, Other_Socket, Other_Connector
Tips

These exact column names are the field names you reference when you build a label template in the VectorLabel designer (for example Device_Name, Room, Rack, RackU, Connector, Number).

The 'Other_...' columns are useful for a 'TO:' line on a label — e.g. show this end's device and the other end's device on the same wrap.

Heads up

Field names come directly from ConnectCAD's parametric record. If your version of ConnectCAD names a field differently, that column may come through blank. Any field the script asks for that doesn't exist is written as an empty value, not an error.

Number Display, Cable Type, and Cable Outside Diameter contain spaces in their column names — match them exactly in templates.

Source-end fields are read from Src_* record fields and destination-end from Dst_* fields (e.g. Src_Dev_Name, Dst_Skt_Conn). These internal names are not the CSV column names; the CSV uses the friendlier names listed above.

Output file: format, location, and naming

The export is a UTF-8 CSV file with a header row of column names followed by one row per label (two rows per circuit, Source and Destination).

It is written to ~/Documents/VectorLabel/Exports/<VWFileName>/, where <VWFileName> is your Vectorworks document's name without its extension. Each Vectorworks project gets its own subfolder so exports from different drawings never mix.

The filename embeds a date-and-time stamp: <VWFileName>_export_YYYYMMDD_HHMMSS.csv — for example ESM_Kodak_Hall_Master_export_20260614_172508.csv. The timestamp makes every export unique and lets VectorLabel sort them chronologically just from the name.

~/Documents/VectorLabel/Exports/ESM_Kodak_Hall_Master/ESM_Kodak_Hall_Master_export_20260614_172508.csv
Tip

Because the folder is named after the Vectorworks file, renaming your .vwx file means the next export goes into a new subfolder.

Heads up

If your Vectorworks file has never been saved (no filename), the project-folder name is derived from an empty filename, which can produce an oddly named or empty-named folder. Save your Vectorworks document first.

How many exports are kept (datecode pruning)

Each project subfolder keeps a maximum of 15 exports. After each export the script deletes the oldest files beyond that limit so the folder doesn't grow forever.

Pruning is based on the YYYYMMDD_HHMMSS datecode IN THE FILENAME, not on the file's modification date. This keeps it correct even after copying files, cloud sync, or Time Machine restores, which can scramble file-system timestamps.

Files that don't match the VectorLabel export naming pattern are never touched, so anything else you keep in the folder is safe.

MAX_EXPORTS_PER_PROJECT = 15   # in export_selected.py and export_all.py
Tips

The VectorLabel AutoPrint app also prunes the same folder to the same limit after it reads a new export, so the count stays at 15 from both sides.

The keep-count is adjustable on the VectorLabel side under Preferences with the label 'Exports to keep per project' (default 15).

Heads up

The Python scripts hard-code the limit at 15 (MAX_EXPORTS_PER_PROJECT). Changing the Preferences value in the Mac app changes the app's pruning, but the script will still prune to 15 when it runs — keep them in mind together if you raise the app's limit.

Export is silent

A successful export shows NO confirmation dialog in Vectorworks. The command runs, writes the file, prunes old ones, and returns quietly — by design, so it stays out of your way.

Vectorworks only shows an alert when something is wrong: nothing selected, no circuits found in the selection or on the layer. Those alerts include a count of non-circuit objects that were skipped.

Tip

The 'confirmation' you should look for is the VectorLabel print window appearing on your Mac, not a dialog in Vectorworks.

Heads up

Because success is silent, if you don't see the print window appear, check the troubleshooting points: AutoPrint must be running, auto-open must be on, and the file must have actually contained circuits.

How VectorLabel detects the export and opens the print window

VectorLabel AutoPrint is a background menu-bar front end with no Dock icon. On launch it starts watching ~/Documents/VectorLabel/Exports/ using macOS FSEvents in recursive mode, so a new CSV dropped into ANY project subfolder is noticed immediately.

When a new file appears, AutoPrint checks the filename matches the export pattern (_export_YYYYMMDD_HHMMSS.csv) and that it sits one level below the Exports root (inside a project subfolder). It waits a brief moment for the file to finish writing, parses it into label records, prunes the folder to the keep-limit, and then — if 'Auto-open print window when export is detected' is enabled — opens the print window with those records and brings the app to the front.

If you happen to run an export TWICE for the same file path in one session, AutoPrint remembers it already handled that path and won't open the window twice. If a file isn't readable yet (still writing or cloud-syncing), AutoPrint releases its claim and retries when the file changes again.

AppSettings.shared.exportsFolderURL  →  ~/Documents/VectorLabel/Exports/
Tips

The auto-open toggle is in VectorLabel's Engine Preferences under Export: 'Auto-open print window when export is detected' (on by default).

AutoPrint intentionally does NOT scan existing files at launch — it only reacts to a NEW export written while it is running. If you exported before opening the app, re-run the export.

Heads up

If AutoPrint is not running when you export, nothing pops up. The window only opens for exports created while the watcher is live. Since 1.15.0 this state is rare and self-healing: the Engine relaunches AutoPrint within about 20 seconds whenever it isn't running (so with the Engine set to launch at login, AutoPrint follows it up automatically) — but an export made during that brief gap is still not picked up retroactively; re-export it.

If the print window doesn't appear, confirm the auto-open preference is enabled — with it off, the export is still saved and parsed but no window opens automatically.

Detection has a built-in latency (about half a second to coalesce Vectorworks' write burst, plus a short settle delay), so the window appears a moment after the export, not instantly.

Step-by-step: export from Vectorworks and print

This is the full round trip from a finished ConnectCAD design to printed wrap labels.

  1. Make sure VectorLabel (the AutoPrint front end / menu-bar app) is running on your Mac, and that 'Auto-open print window when export is detected' is enabled in its Preferences.
  2. In Vectorworks, open and SAVE your project file (so it has a filename — that name becomes the export subfolder).
  3. Decide your scope: to label specific cables, select those ConnectCAD circuits. To label a whole layer, switch to that design layer (no selection needed).
  4. Run the matching menu command: 'Export Selected Circuits to VectorLabel' for your selection, or 'Export All Circuits to VectorLabel' for the active layer.
  5. Nothing happens visibly in Vectorworks on success (silent export). The CSV is written to ~/Documents/VectorLabel/Exports/<VWFile>/.
  6. Switch to your Mac: within a moment the VectorLabel print window opens automatically, populated with one row per cable end (Source and Destination).
  7. In the print window pick your label template and printer/supply, review/filter the records, and print. (Template editing and printer setup are covered in the print-window and designer docs.)
Tips

If you change circuits in Vectorworks, just re-run the export — a fresh timestamped CSV is created and the print window reopens with the new data.

Old exports auto-clean to the 15 most recent per project, so you can re-export freely without housekeeping.

Heads up

If you get a Vectorworks alert instead of a print window, read it: 'No objects selected' means select circuits first; 'No ConnectCAD circuits found...' means your selection/layer had no recognizable circuits.

If no window appears and no alert showed, AutoPrint may not be running or auto-open may be off.

Designing labels

Template Designer vs Custom Designer

VectorLabel ships two designer windows that look almost identical but are aimed at different jobs. The window title bar reads "VectorLabel — Template Designer" or "VectorLabel — Custom Designer", and the top-left subtitle under the VectorLabel logo says either "Template Designer" or "Custom Designer".

Template Designer makes REUSABLE templates. A template is a layout with data-bound fields (for example a text box set to the "Cable Name" column). You save it as a .vltmp file, and the Print window later loads it, fills the fields from each row of your wire-export data, and prints one label per record. Its file-toolbar buttons are "Open…", "Save as…" and "Save" — a new blank template is created with the + on the tab bar (see Working in tabs). New documents start named "Untitled Template" until you save them; the tab shows the template's name. When launched on its own it opens an Open Template picker so you choose a template rather than landing on a blank one. It can load a CSV purely as a PREVIEW so you can see how fields will look — the "Load CSV…" button is in the Records panel at the bottom of the window (not the top toolbar) — and it does not print.

Custom Designer makes ONE-OFF labels and can also print them itself. Its file-toolbar buttons are "Open…", "Save Label" and "Save as…" (a new blank design is the + on the tab bar), and new documents start named "Untitled Custom Design". "Save Label" saves straight back to the open .vlcus file with no dialog; "Save as…" writes a copy to a new file. It has an extra print header (printer picker — which shows each printer's loaded supply beside its name — Copies, Cut, Feed to clear, Print) and a bottom "Database" pane. You can bind a CSV or Excel (.xlsx) file as print data and the Custom Designer will print one label per row; with no data bound it just prints the single label you designed. Saved files are .vlcus and embed both the design and a copy of the bound data so a Reprint reopens the exact label. Saving and the start-up recents dialog are covered under Saving and opening.

VectorLabel — Template Designer

The real designer canvas — a true-to-size label with objects you drag, rotate and bind to data; tabs let you keep several open. Shown with the 1_5x4 V1 template on Brady M6-33-427.

Tips

If you just want to print a handful of labels right now, use the Custom Designer. If you are building a layout to be reused across many print jobs from your wire data, use the Template Designer.

Both designers can also open Brady (.BWT) and Brother P-touch (.lbx) templates and convert them — see the Importing section.

Heads up

The two windows share the same underlying HTML canvas, so the editing controls are the same. The differences are the toolbar buttons, the default document name, and the Custom Designer's print header + Database pane.

Working in tabs

Both designers and the Print window are tabbed, so you can keep several labels open at once. A bar of tabs runs across the top of the window; each tab is one open document (or, in the Print window, one exported job) and keeps its own full state — canvas, selection, zoom, undo history, bound data and (in the Custom Designer and Print window) its own printer selection.

  • New tab / new document — click the + at the end of the tab bar (in the two designers). In the Custom Designer the new tab shows a start dialog with your 5 most recent labels, "Browse…", and "New blank label"; in the Template Designer it opens the template picker.
  • Opening a file opens a new tab. Using "Open…", double-clicking a .vltmp/.vlcus in the Finder, or importing a Brady .BWT / Brother .lbx all open in their own new tab — whatever you were working on is left untouched. You can select several files at once and each opens in its own tab. If a file is already open, you don't get a second copy — the window simply switches to its existing tab (a same-named copy elsewhere on disk is a different file and still opens separately). New "Untitled…" documents are never treated as duplicates. In the Custom Designer, choosing a label from the start dialog reuses the current blank tab rather than leaving a leftover "Untitled" tab behind.
  • The tab shows the document name (the file name, or "Untitled…" until you save). A dot (•) in front of the name means that tab has unsaved changes.
  • Too many tabs to fit? The strip scrolls, and ‹ › arrows appear at the ends so you can page through them.
  • Closing. Click a tab's to close just that document — you'll be asked to save if it has unsaved changes. Closing the whole window (its title-bar ✕) closes every tab; a designer prompts for each unsaved document, and the Print window asks once before clearing all tabs.

In the Print window, each export from Vectorworks arrives as a new tab and the window jumps to the most recent one; printing or cancelling closes just that tab when others are open, or the whole window when it's the last one. A re-export or Reprint of a data file that's already showing doesn't add a duplicate — it lands on the open tab and refreshes it.

Choosing a label supply (die-cut vs continuous)

Before you design, pick the label supply you will print on. Click the "Supply" button in the top bar (it shows the current size and a ▾ arrow) to open the "Choose a label supply" picker. Supplies are grouped by category with columns: Supply, Type, Label size, Printable, and Buy. Click a row to select it; the picker closes and the canvas resizes to match.

There are two kinds of supply. Die-cut supplies are pre-cut to a FIXED size (for example 1" × 1.5"); both their overall size and printable area are fixed, shown as width × height. Continuous (tape) supplies have a fixed width but NO fixed length — you choose how long each label is. Continuous rows show their size as width × "definable".

When a continuous supply is selected, a "Length" field (in inches) and a "⤢ Fit" button appear in the top bar. Type a length, or click Fit to set the length automatically to the farthest edge of your content (plus a small trailing margin). Die-cut supplies ignore length.

If a printer is connected and reports a loaded cassette, the picker shows a "Use currently installed" button that jumps to the matching defined supply, and the matching row is tagged "● installed". If nothing is loaded it shows "No cassette detected". When more than one supply group exists, a "Supply group" dropdown lets you switch groups.

VectorLabel — Template Designer

The real "Choose a label supply" picker — supplies grouped by category with Type, Label size, Printable and Buy columns; ● marks the supply the open design uses.

  1. Click the "Supply" button in the top bar.
  2. In the "Choose a label supply" window, find your part in the grouped list (use the "Supply group" dropdown if shown).
  3. Click the row to select it — the canvas resizes to that supply.
  4. For a continuous tape, set the "Length" (inches) in the top bar, or click "⤢ Fit" to fit it to your content.
  5. Click "Close" if you opened the picker but didn't change anything.
Tips

The supply list is editable and shared from the app's supply catalog; it updates live (about every 2 seconds) if you edit the catalog elsewhere while a designer is open.

If a continuous category note reads "any material of the listed width matches", any tape of that width will fit that entry.

Heads up

If a supply you previously used was removed from the catalog, the designer keeps the saved canvas size as a "ghost" (it shows "(supply unavailable)") so your layout doesn't suddenly resize — pick a new supply to fix it.

Changing supplies recenters the canvas and resets the continuous Length to that supply's default, so a length you set for one tape won't carry to another.

Canvas behavior, zoom, and 90° rotation

The canvas shows your label at the printable size, centered in a scrollable area, with rulers along the top and left edges. The rulers read in your chosen unit (inches or millimetres), and a small in/mm toggle in the top-left ruler corner flips them right there — the same choice as Engine ▸ Preferences ▸ Advanced ▸ Units (see Units and typing math into fields). The top bar has zoom controls: a − / percentage / + group, a "Reset" button (back to 100%), and a "⌖ Center" button to recenter the label in the view. A "Show wrap"/"Hide wrap" toggle shows or hides the soft-wrap preview guides for text.

The "⟳ 90°" button rotates the label canvas 90 degrees so you can design in the other orientation. For continuous tape this switches between the default landscape and a portrait override. For die-cut it shows the canvas in portrait while the renderer keeps the physical label dimensions and rotates your design onto them. The button highlights when rotation is on. The rotation is saved with the template/label. On Brady printers you rarely need it to fix a sideways die-cut label any more — at print time the design is fitted automatically to the printable area the loaded cassette reports (see Automatic orientation on Brady printers); ⟳ 90° remains the manual override.

Snapping is controlled in the second toolbar (the "Snap" row): "⊞ Grid" snaps objects to a grid, "⊡ Objects" snaps to other objects' edges, and a "Grid size" dropdown chooses the spacing (options shown in both millimeters and inches). These settings are remembered between sessions.

Tips

Arrow keys nudge the selected object; hold Shift for a finer nudge. When grid snapping is on, arrow keys move by one grid step.

The properties panel on the right is resizable — drag its left edge. Its numeric inputs have larger stepper buttons, and with an input focused the ↑/↓ arrow keys step and apply the value just like the buttons.

Heads up

Rotation is editor-only geometry for die-cut: the actual printed label keeps its physical size and the design is rotated onto it. On Brady printers the print-time orientation is decided against the loaded cassette's reported printable area; only a genuinely ambiguous case (square printable area, square design) keeps the printer's reported orientation, where ⟳ 90° is your override. Always confirm the printed result on the physical label in this alpha.

Printable-area margins (the hatched overlay)

Thermal printers can't print all the way to the edge of the label — a narrow Brother tape only exposes a centered band of the print head, and a Brady die-cut label's printable area is smaller than the physical label. Both designers show this per printer: the canvas (the white area you design on) is still exactly the printable area, and the unprintable margins are drawn as hatched strips outside it, with a dashed outline marking the physical edge of the label or tape. Hovering a hatched strip names the printer it comes from ("Unprintable margin — <model>"). The overlay lives in the designers only — the Print window's preview shows just the printable area (its "Printable area" row notes when the dimensions come from the loaded cassette).

Which printer's margins are shown depends on the designer. The Custom Designer follows the printer currently selected in its printer dropdown. The Template Designer has no live printer, so it gains a "⎙ Printer" dropdown next to the Supply button: pick the model you intend to print on, or "None" for no overlay. The choice is saved with the template, and it also becomes the default for new templates.

Where the numbers come from: for Brother P-touch models, the across-tape band comes from the per-tape print-head table (each tape width exposes a fixed set of head pins — for example, 12 mm tape prints a centered band of about 0.39"/9.9 mm, while 24 mm tape uses the full head). For Brady printers, the printable area comes from the supply catalog — die-cut: the printable size centered in the physical label; continuous: the printable band centered across the tape. When a connected printer reports its loaded cassette's printable area (M611 telemetry), that live reading overrides the static tables.

A "▧ Margins" toggle sits in the designers' Snap toolbar next to the grid controls; it hides or shows the overlay and is remembered between sessions.

VectorLabel — Template Designer

The real designer with the overlay on: the 1_5x4 V1 wrap template targeted at an M611 (the "⎙ Printer" dropdown in the top bar). The white canvas is the printable 1.5″ × 1.5″ panel; the hatched strips are the unprintable rest of the physical 1.5″ × 4″ label, with a dashed outline at its edge.

  1. Template Designer: pick your target model in the "⎙ Printer" dropdown next to the Supply button ("None" = no overlay).
  2. Custom Designer: just select the printer — the overlay follows it (and its loaded cassette, when reported).
  3. Keep your content inside the white canvas; anything under the hatching is off the printable area.
  4. Use the "▧ Margins" button next to the grid controls to hide or show the overlay.
Tips

The overlay is visual only — it never moves your objects or changes what is sent to the printer. The canvas has always been the printable area; the hatching just shows what surrounds it on the physical label.

The "⎙ Printer" dropdown lists the models from the printer registry, so it works with no printer connected at all.

Heads up

The static Brady margins are only as accurate as the supply catalog entry — if you've edited a supply's printable size, the overlay follows your edit. A live cassette readout (M611) is authoritative when present.

Brother P-touch support overall is alpha and only partially hardware-verified — treat the exact band placement as approximate until you've test-printed on your unit.

Adding objects (text, barcode, table, image, symbol, line, shapes, arrow)

The left sidebar has an "Add" section with buttons for every object type: "Text", "Line", "Rect", "Arrow", "Circle", "Oval", "Triangle", "Polygon", "Image", "Symbol", "Barcode", and "Table". Clicking one drops a new object onto the canvas and selects it. Below the buttons is an "Objects (N)" list of everything on the canvas; clicking a row selects that object, and a "Delete selected" button appears when something is selected.

Text starts as a small box reading "Text". Barcode starts as a QR Code containing "12345". Lines and arrows start as a 1-inch horizontal stroke. Rect, Circle, Oval, Triangle and Polygon are shapes — outlined by default, with an optional solid fill (see shape properties). Rect can also take a corner radius to become a rounded rectangle, and a Polygon can have 3–12 sides. All of them move, resize and rotate like the other objects. Image opens a file picker (PNG, JPG, JPEG, or SVG) followed by a monochrome-conversion dialog. Symbol opens the "Insert symbol" library. Table asks for the number of rows and columns (1–20 each), then drops a grid onto the canvas.

Tables. Every cell behaves like its own text box: click a cell to select it (a single click selects it even if the table itself wasn't selected yet), then use the properties panel to set its content — Static text, a data Field, a Formula, or Date/Time (see Date/Time source) — plus the full text formatting (font, size, bold/italic/underline, alignment, wrap, auto-scale, tracking, stretch). You can also drag a column header from the records pane straight onto a cell to bind it, exactly like a text box. Shift-click selects a rectangular range of cells and ⌘-click toggles individual cells; formatting and sizing changes apply to every selected cell, and ⌘C / ⌘V copies and pastes cells within or between tables. Drag the grid lines to resize rows and columns (with "Lock table size" on, dragging redistributes space inside the table instead of growing it); right-click a cell for row/column commands, including "Set row height…" and "Set column width…" to type exact sizes. The table's settings offer "Equal columns" / "Equal rows" locks with a numeric size input, a grid line width, and overall width/height (also adjustable with the corner grab handles, or lockable). Clicking a cell that's already selected starts editing it, so a double-click — at any speed — types straight into a cell, and the editor matches the cell's type: a Static cell opens for typing in place, a Formula cell opens the formula editor, and a Field cell jumps to the column picker in the panel. You can also merge cells, Excel-style: select several and right-click → "Merge cells" to merge the selection's bounding rectangle into one cell, or right-click a merged cell and choose "Split cell" to break it apart — the text stays in the top-left cell, and every cell comes out with the merged cell's formatting. Merged cells print identically in the Designer preview, the print preview, and on the label. The right-click menu also offers "Clear text" (content only, formatting kept) and "Clear text & formatting" (a full reset), applied to a single cell or the whole selection. The first time a value lands in a cell (typed, or bound to a column) its font is auto-sized once so about 10 characters fit the cell; after that the size is yours — deleting the value and entering another never re-sizes it.

The symbol library (the "Symbol" button) offers monochrome safety/handling icons: Caution, High voltage, Laser, Flammable, Hot surface, No entry, No smoking, Eye protection, Ear protection, Head protection, Earth / ground, Fragile, This way up, and Mandatory. These are original recreations, not the official copyrighted artwork. Pick one to insert it; it is rasterized to a monochrome image and prints through the image path.

Images are converted to pure black-and-white when added. The "Add image — convert to monochrome" dialog (or "Adjust image" when re-editing) has Brightness, Contrast, and Threshold sliders with a live preview; click "Add to label" / "Apply" or "Cancel". You can re-open it later from the image's properties via "Adjust monochrome…", and "Replace image…" swaps the picture.

  1. Click an object type in the left "Add" sidebar (e.g. "Text" or "Barcode").
  2. The new object appears selected on the canvas; edit it in the right-hand properties panel.
  3. For "Image", choose a file, adjust Brightness/Contrast/Threshold, then click "Add to label".
  4. For "Symbol", click an icon in the "Insert symbol" window.
Tips

You can duplicate the selected object with Cmd-D, copy/paste with Cmd-C / Cmd-V, and delete with the Delete or Backspace key (or the Delete button).

The transparent parts of a PNG or SVG stay transparent through the monochrome conversion.

Heads up

Symbols are simplified vector recreations for visual reference, not certified standards-compliant safety marks.

Barcode-only or image-only content imported from some third-party files may not be supported — see the Importing section.

Text box properties and data binding

Select a text box to edit it in the right panel. The top "Text source" row has three mode buttons: "Static", "Field", and "Formula". Static is plain typed text (type in the box, or double-click the text on the canvas to type directly). Field binds the text to one data column — pick it from the "— choose column —" dropdown, or drag a column header from the Records panel (Template Designer) / Database pane (Custom Designer) onto the text box. Formula lets you write a spreadsheet-style expression starting with "=".

Formulas support text joining with & and the functions IF, LEFT, RIGHT, LEN, UPPER, LOWER, TRIM, and MID, plus = and <> comparisons; column names resolve to the current record's values. A "Fields ▾" button lists insertable field buttons, and "Editor ⤢" opens a larger formula editor with a live preview. Example placeholder: =IF(Number<>"",Number,"").

Under "Text formatting" you have: a font picker (curated fonts plus your installed system fonts), "Size (pt)" (when Auto-scale is on it is labeled "Size (pt) — max"), a "Style" row with Bold (B), Italic (I) and Underline (U) toggles, "Horizontal align" (left, center, right, justify), "Vertical align" (top, middle, bottom), a "Wrap text" checkbox, an "Auto-scale to fit (max size)" checkbox (shrinks text to fit the box; it never grows past the Size — with "Wrap text" also on, the text wraps and shrinks to the largest size where every wrapped line fits the box), "Tracking (px)" (space between characters), and "Width stretch (%)" (10–300%, horizontally stretches the glyphs). The "Position & size" block at the bottom sets X, Y, width and height in your chosen unit (inches or millimetres), and — like every dimension field — accepts fractions, the other unit, and simple math (see Units and typing math into fields). Font size stays in points, and Tracking/Width stretch stay unitless.

=IF(Number<>"",Number,"")
  1. Click the text box on the canvas (or in the Objects list).
  2. Choose "Static", "Field", or "Formula" under "Text source".
  3. For Static, type your text. For Field, pick a column. For Formula, type an expression beginning with "=".
  4. Set font, "Size (pt)", Style (B/I/U), alignment, and any wrap / auto-scale / tracking / stretch options.
Tips

Turn on "Auto-scale to fit (max size)" for variable data so long values shrink to fit instead of overflowing the box.

You can drop a column header onto an empty spot on the canvas to instantly create a new field-bound text box.

Heads up

In the Template Designer the field list is the fixed wire-export columns; in the Custom Designer, once a CSV/Excel file is bound, the field list comes from that file's columns.

Field and Formula text only resolve when there is record data; with no data they preview blank.

Barcode and 2-D code properties

Select a barcode to edit it. The "Barcode" section has a "Type" dropdown with: QR Code, Data Matrix, Aztec Code, PDF417, Micro QR, Code 128, GS1-128, Code 39, Code 93, EAN-13, EAN-8, UPC-A, UPC-E, Interleaved 2 of 5, and Codabar. For symbologies that support it, an "Error correction" dropdown appears (QR/Micro QR show L/M/Q/H with their recovery percentages; PDF417 shows numbered levels).

Under "Data source" the same modes as text apply: "Static" (type the barcode value), "Field" (bind to a column), "Formula", or "Date/Time" (encode the current date/time — see Date/Time source). You can also drag a column header onto the barcode to bind it. The "Position & size" block sets X, Y, width and height in your chosen unit.

Square 2-D codes (QR, Data Matrix, Aztec, Micro QR) keep a square shape so they stay scannable; linear codes and PDF417 can be stretched freely. The Custom Designer's Database pane flags any record whose barcode can't encode (it would print blank).

  1. Add a Barcode and select it.
  2. Pick the "Type" (symbology) from the dropdown.
  3. Set "Error correction" if offered.
  4. Under "Data source" choose Static / Field / Formula and enter or bind the value.
Tips

For variable data, set the barcode to Field mode and bind the column carrying the code value.

Use higher QR error correction (Q or H) when labels may get scuffed or partly covered.

Heads up

If a record's value can't be encoded by the chosen symbology, that label's barcode prints blank — the Custom Designer Database pane warns about such rows.

Stretching a square 2-D code is prevented on purpose; only its overall (uniform) size changes.

Line, rectangle, oval, circle, triangle, polygon, and arrow properties

Line: a "Weight (px)" field (1–10) plus X, Y and Width. Lines are horizontal strokes you position and size.

Rectangle and Oval: a "Border (px)" field (1–10) plus the Position & size block. The Rectangle also has a "Corner radius" field — set it above zero to round the corners (a rounded rectangle).

Circle: a "Border (px)" field, plus "Diameter (in)" and "Radius (in)" fields (changing one updates the other), with position controls. Symbols also expose a single "Size (in)" because they stay square.

Triangle and Polygon: two new shape types that behave like the rectangle/oval — a "Border (px)" field plus the Position & size block. The Polygon adds a "Sides" field (3–12) to choose how many sides it has (triangle, pentagon, hexagon, and so on). Both move, resize and rotate like the other objects.

Solid fill: the rectangle, oval, circle, triangle and polygon each have a fill option — leave it off for an outline shape, or turn it on to draw the shape filled solid. (Since printing is monochrome, "solid" means a solid black fill.)

Arrow: "Thickness (px)" (1–20), "Arrowhead size (px)" (4–60), and a "Heads" row with "◄ Start" and "End ►" toggles to put an arrowhead at either or both ends, plus X, Y and Length.

Tips

Use the dedicated Diameter/Radius fields on a Circle for precise sizing instead of dragging.

Type the corner radius (and any size field) with fractions, the other unit, or a bit of math — e.g. 1/16" or 2mm — see Units and typing math into fields.

Heads up

A solid-filled shape prints as solid black, which uses a lot of ribbon and can bleed on some supplies — test on your stock before a long run.

Selecting, moving, and multi-select

Click an object on the canvas to select it; drag it to move it. Double-click a Static text box to type directly into it on the canvas. Clicking empty canvas deselects everything. The properties panel shows "Click an object on the canvas to edit it. Shift-click to select several at once." when nothing is selected.

Marquee (rubber-band) selection: press on an empty part of the canvas and drag a box; every object the box touches is selected. Holding Shift, Cmd, or Ctrl while marquee-ing ADDS to the current selection instead of replacing it.

In the Objects list, standard macOS modifiers apply: Shift-click selects the range between the anchor and the clicked item; Cmd/Ctrl-click toggles a single item in or out of the selection; a plain click selects just that one. When several objects are selected, shared properties can be edited together and the Delete button reads "Delete N selected".

  1. Click an object to select and drag to move it.
  2. To select several: drag a box around them on the canvas, or Shift/Cmd-click them in the Objects list.
  3. Shift/Cmd/Ctrl while dragging a marquee adds to the existing selection.
  4. Press Delete (or click the delete button) to remove the selection.
Tips

Arrow keys nudge the whole multi-selection at once.

Cmd-Z undoes the last change in the canvas; ⌘S saves the document and ⌘⇧S is Save As (in both designers).

Heads up

A plain single click on empty canvas clears the selection — if you meant to add to a selection, hold Shift/Cmd while marquee-ing.

Saving and opening templates and custom labels

Template Designer: "Save" / "Save as…" save a .vltmp template. "Save" (⌘S) writes back to the open template; "Save as…" (⌘⇧S) saves a copy. The "Save Template" dialog asks for a Template name and shows the label size and object count; templates live in ~/Documents/VectorLabel/Templates/. "Open…" shows an Open Template picker listing saved templates (with size and object count) and a "Browse file…" option. "New" / "New…" opens "New Template" where you set a name and label size and click "Create".

The Template Designer's Open file picker also accepts legacy ".json"/".vlt.json" templates, plus Brady ".BWT" and Brother P-touch ".lbx" files (auto-converted).

Custom Designer: "Save Label" (⌘S) saves straight back to the open .vlcus file — no dialog — and "Save as…" (⌘⇧S) writes a copy to a new file. A brand-new label, or one you opened from a Brady .BWT / Brother .lbx import, is still prompted for a location the first time you save, so an imported original is never overwritten. "Open…" accepts .vlcus, plus Brady .BWT and Brother .lbx (auto-converted). "New" opens "New Custom Design" (name + label size + "Create").

The Custom Designer start dialog. When the Custom Designer opens — and on each new "+" tab — a start dialog offers your 5 most recent labels to reopen, plus "Browse…" and "New blank label". Opening a label from here reuses the current blank tab instead of leaving a stray "Untitled" tab behind, and reopening a label that's already open just switches to its tab rather than making a second copy.

Both designers warn before replacing the canvas (importing, opening, or starting new) if you have unsaved changes, with Save / Don't Save / Cancel choices. Finder double-clicking a .vltmp opens it in the Template Designer; a .vlcus opens in the Custom Designer.

Files kept "online-only" by Dropbox, iCloud Drive, or OneDrive are downloaded automatically before opening: a small "Downloading…" popup with a Cancel button appears, and once the file is local the open continues on its own. This applies everywhere a file can be chosen — data sources, templates, imports, images, and Finder double-clicks. Cancelling the download simply returns you to where you were.

~/Documents/VectorLabel/Templates/
  1. Template Designer: click "Save" (⌘S) — or "Save as…" (⌘⇧S) — enter a Template name, then save into ~/Documents/VectorLabel/Templates/.
  2. Template Designer: click "Open…" and pick a template card, or "Browse file…" for any folder.
  3. Custom Designer: click "Save Label" (⌘S) to write straight back to the open .vlcus, "Save as…" (⌘⇧S) to save a copy, or "Open…" to reopen one.
  4. Use "New" / "New…" (or the start dialog's "New blank label") to start a blank document.
Tips

⌘S saves, ⌘⇧S saves-as, in both designers.

A .vlcus stores its own copy of the bound data, so reopening it (or reprinting) recreates the exact label even if the original spreadsheet moved.

Heads up

"Save Label" (⌘S) writes silently to the open file, so it overwrites your last saved version — use "Save as…" if you want to keep a separate copy. A new or imported label still shows a save dialog the first time.

When a save dialog does appear, navigate to the folder it names — the app cannot silently write the file for you.

Deleting a template from the Open picker permanently removes the file from the Templates folder and cannot be undone.

Importing Brady .BWT and Brother P-touch .lbx

Both designers can open third-party templates from their "Open…" dialog: Brady Workstation .BWT and Brother P-touch Editor .lbx. The app converts them into a VectorLabel design as a new, unsaved document, and warns first if you have unsaved changes (Replace / Cancel).

Brady .BWT imports recover the label geometry (size and orientation) and text/prompt objects, turning each prompt into a data-bound text field so binding a data file whose columns match the prompt names fills them in. Object types not yet decoded (barcodes, images, shapes) are listed as import notes rather than dropped silently — so a partial import is never mistaken for a complete one. A Brady import fails if no readable text fields are found (for example a barcode-only or image-only template).

Brother .lbx imports recover the tape geometry and map text:text to static text, barcode objects to barcodes (with QR error-correction level), and shapes to their VectorLabel equivalents — lines, rectangles, rounded rectangles, ellipses and polygons now come across instead of being dropped. Images, groups, and unsupported barcode types are still reported as warnings. Brother imports auto-select the closest matching P-touch tape width.

After an import with anything that needs attention, an "Import note" dialog lists the items that couldn't be fully converted.

The supply is matched automatically. When you import a Brady .BWT or Brother .lbx template, VectorLabel picks the matching catalog supply for you so the converted label opens at the right size and orientation — a Brady label is matched to the "Brady M6" supply group (by part number first, then by size), and a Brother label to the "Brother P-touch" tape group (by tape width). If it can't confidently match one, the supply picker opens showing the imported label's dimensions and asks you to choose which supply it should print on, rather than guessing.

  1. In either designer click "Open…".
  2. Choose a .BWT or .lbx file (these may not show a file-type icon; the picker still accepts them).
  3. Review any "Import note" listing items that need attention.
  4. Adjust the converted design and save it as a .vltmp or .vlcus.
Tip

For Brady files, name your bound data columns to match the original prompt names so the recovered fields fill automatically.

Heads up

Importers are reverse-engineered and validated against sample files; they decode a subset of object types. Barcodes/images/shapes from Brady files, and images/groups/unsupported barcodes from Brother files, are reported as warnings, not imported. (Brother rectangles, rounded rectangles, ellipses, polygons and lines now do import.)

A Brady barcode-only or image-only template will not import (it reports no readable text fields).

Custom Designer database mode (bind, browse, edit records)

Only the Custom Designer has the bottom "Database" pane. Click "Choose data file…" to bind a CSV or Excel (.xlsx) file as print data — the designer prints one label per row. Once a file is bound, its name becomes a menu button in the toolbar: the name shows the current file, and a dropdown ▾ next to it offers Replace… (bind a different file), Export… (write the current data out), and Clear (unbind, back to a single label), along with the auto-sync controls described below. The pane header shows the file name, row and column counts, and how many rows are selected. On a narrow window the database toolbar wraps its controls neatly onto a second row rather than clipping.

Multi-sheet Excel workbooks. If the .xlsx you bind has more than one worksheet (tab), a picker asks which sheet holds your print data instead of silently taking the first one. To change it later, open the file-name button's ▾ menu and choose "Redefine tab…" — it reopens the same picker. Your chosen sheet is saved in the .vlcus document, so reopening the file and "Refresh from source" both re-read that same worksheet. Single-sheet workbooks and CSV files behave exactly as before — no picker appears.

Once bound, the pane is a record browser much like the Print window: a search box ("Search all fields…"), a "⧩ Filter & sort" button, a "Columns ▾" show/hide-and-reorder menu, per-row checkboxes for selecting which rows print, and inline cell editing. Hover a cell and click the ✎ button to edit its value in place (Enter saves, Escape cancels).

Header row by number. The "first row is headers" control (CSV and Excel) is now a tick plus a row number (default 1). With the tick on, that row supplies the column names and everything above it is hidden — so if your spreadsheet has a title and notes at the top, set the number to, say, 10 to treat row 10 as the header and ignore rows 1–9. With the tick off, columns are named Column 1, 2, 3….

Building and editing data on the fly. You don't need a file to start: the Custom Designer can build a data set from scratch and edit it as you go (it lives inside the .vlcus — your original import is never modified). The Database pane toolbar adds:

  • + Row — add a blank row. On an empty document the first row automatically creates five columns (Column 1…Column 5).
  • + Column — add a new column (Custom Designer only).
  • Editable column headers — click the ✎ on a header to rename it (Enter saves, Escape cancels). Renames automatically update everywhere the column is used: field bindings, formulas, filter & sort rules, saved presets, and the column menu.
  • Free edit — a spreadsheet-style mode (the button flashes while it's on). Cells edit directly on click with no ✎/✓ buttons; select multiple cells by dragging or Shift-clicking; copy/paste ranges (⌘C / ⌘V, Excel-compatible); and drag the small corner handle of a cell to fill down — it auto-increments when the value ends in a number (hold Option to repeat the same value instead) and ripples the same value otherwise. Headers are freely editable in this mode too.
  • Ripple — auto-enumerate a value down many rows. In standard editing it's a "Ripple…" button next to a cell's ✓/✗; in Free edit it's a right-click on a cell. The dialog takes a prefix (pre-filled from the cell), a start (number or letter, e.g. A→B→C), an increment (1 → 1,2,3 · 2 → 1,3,5), a postfix, and a record count.
  • Export… — write the current data set out as a CSV or Excel (.xlsx) file (you can overwrite your original import if you want).

Auto-sync a bound data file. If your data lives in a file you keep editing elsewhere, turn on Auto-sync and VectorLabel reloads the bound data automatically whenever that source file changes on disk — no manual refresh. While Auto-sync is on, in-app editing is hidden (the file is the single source of truth) so your edits can't be overwritten mid-sync; the data toolbar shows an "Auto-sync enabled · editing disabled — click to disable" button. Auto-sync and "Refresh from source" both live in the bound file-name button's dropdown menu (the same ▾ that holds Replace / Export / Clear). "Refresh from source" re-reads the file once on demand (and re-prompts if it moved); Auto-sync keeps doing that automatically.

The print header's "Print" range control appears when data is bound and a field on the canvas actually uses it: "All", "Selected" (the checked rows), or "Range" (from–to). Filters, sorts, and saved presets are shared with the Print window, so a preset saved in either place shows up in both. The pane can be resized by dragging its top edge.

VectorLabel — Custom Designer

The real Database pane with a sample CSV bound — the header shows the file, row/column counts and selection; row checkboxes choose what prints; the toolbar carries "+ Row" / "+ Column", "Free edit", "Export…" and the shared search / filter / columns controls.

  1. In the Custom Designer, click "Choose data file…" in the Database pane and pick a CSV or .xlsx.
  2. Bind a canvas field to a column (Field mode, or drag a column header onto a text/barcode object).
  3. Use the checkboxes, "Search all fields…", or "⧩ Filter & sort" to choose which rows print.
  4. In the print header set the "Print" range (All / Selected / Range), Copies, and Cut, then Print.
  5. Use ✎ on a cell to fix a value inline; or open the file-name ▾ menu and use "Refresh from source" (once) or turn on "Auto-sync" (keeps reloading) after editing the file externally.
Tips

Edit small data fixes inline with the ✎ cell editor rather than reopening the spreadsheet.

Turn on Auto-sync when a colleague or another program keeps updating the source file — the labels track it automatically (in-app editing is hidden while it's on).

Use the file-name ▾ menu's "Clear" to return to designing/printing a single label.

Heads up

The Custom Designer prints one label per row, so a large bound file can be a big job — a confirmation appears for jobs over 10 labels.

Print/preview against sample data is for the on-canvas view; with no data bound, the actual printed label uses an empty record (static text prints, field/formula text is blank).

Data, formulas & barcodes

The three content sources: Static, Field, Formula

When you select a text box (or a barcode), the properties panel shows three buttons to choose where its content comes from. The buttons are labelled Static, Field, and Formula.

Static: you type a fixed value that is the same on every label. For a text box this is a multi-line text area with the placeholder "Type label text…". For a barcode the static input has the placeholder "Barcode data…". Use this for things that never change, like a fixed prefix, a company name, or a single test barcode value.

Field: the object is bound to one column of your data. The panel shows a drop-down of available columns; pick one and the object displays that column's value for the current record, changing automatically label-to-label. The panel also tells you that you can drag a column header straight onto the box: "…or drag a column header from the Records panel onto the text box, or onto an empty spot to create a new field." (In the Custom designer the wording refers to the Database pane instead of the Records panel.) Dropping a column header on an existing text box switches it to Field mode bound to that column; dropping on an empty spot creates a new field-bound text box there.

Formula: the object's content is computed by an Excel-style expression that must begin with an equals sign (=). This lets you combine several columns, add separators, change case, trim, take part of a string, and branch with IF. The formula bar is a monospace input with the example placeholder =IF(Number<>"",Number,""). Next to it are a "Fields ▾" button (drops down clickable buttons that insert a column name into the formula) and an "Editor ⤢" button that opens the full Formula editor with a live preview.

Under the hood each object stores a mode of "static", "field", or "formula". Older designs that predate the mode flag still work: a legacy object with only a formula is treated as a formula, one with only a bound column as a field, and one with only plain text as static.

There is also a fourth content source, "Date/Time", for printing the current date and/or time — chosen the same way as a data field. It's covered in Date/Time source below.

  1. Click the text box or barcode you want to set up.
  2. In the properties panel, click Static, Field, or Formula.
  3. For Static, type the fixed value.
  4. For Field, choose a column from the drop-down (or drag a column header onto the box).
  5. For Formula, type an expression starting with = , or click Editor ⤢ to build it with a live preview, then Apply.
Tips

Dragging a data column header onto an empty area of the label instantly creates a new field-bound text box — the fastest way to lay out data.

Switching an object to Formula when it had no formula yet starts you with ="" (an empty string) so the box is blank until you write the expression.

Heads up

A formula MUST start with =. If it doesn't, the whole thing is treated as plain static text and printed literally.

Field mode binds to the column's internal key (e.g. Cable, Device_Name), but the drop-down and formula buttons show the friendlier display name (e.g. "Cable Name", "Device Name").

Date/Time source (printing today's date and time)

A text object, a barcode, or a table cell can print the current date and/or time. In the object's content source, pick "Date/Time" (it sits alongside Static, Field and Formula, chosen the same way you'd pick a data field), then choose a format from the presets. The value isn't baked in when you design — it renders the current date and/or time at print time, so a batch printed today shows today's date.

The format presets include separator-less numeric forms as well as the usual punctuated ones and time formats:

YYYYMMDD      20260704
MMDDYYYY      07042026
DDMMYYYY      04072026
MM/DD/YYYY    07/04/2026
YYYY-MM-DD    2026-07-04
Mon DD, YYYY  Jul 04, 2026
… plus time formats (e.g. HH:MM, hh:MM am/pm)
Tips

The separator-less forms (YYYYMMDD, MMDDYYYY, DDMMYYYY) are handy inside a barcode, where slashes and dashes aren't wanted.

Because Date/Time renders at print time, reprinting an old job later prints the date it's reprinted, not the original print date.

Heads up

Date/Time uses your Mac's current clock at the moment of printing — there's no way to set a fixed past/future date through this source (type a Static value for that).

The built-in data columns (cable/connector data)

When you are working from the built-in cable schedule data, these are the standard columns. The left side is the friendly display name you see in menus and formula buttons; the right side in parentheses is the underlying column key. A formula can refer to a column by either name (matching is case-insensitive).

Number (Number), Cable Name (Cable), Signal (Signal), Connector (Connector), Device Name (Device_Name), Device Tag (Device_Tag), Socket Name (Socket_Name), Socket Tag (Socket_Tag), Other Device (Other_Device), Other Socket (Other_Socket), Other Connector (Other_Connector), Rack (Rack), Room (Room), Rack U (RackU), Side (_Side), Cable Type (Cable_Type), Cable Length (CableLength).

In the Custom designer, when you bind your own spreadsheet/database, the column list comes from your imported data instead, and the display name and key are simply the column's own name.

Number, Cable Name (Cable), Signal, Connector, Device Name (Device_Name), Device Tag (Device_Tag), Socket Name (Socket_Name), Socket Tag (Socket_Tag), Other Device (Other_Device), Other Socket (Other_Socket), Other Connector (Other_Connector), Rack, Room, Rack U (RackU), Side (_Side), Cable Type (Cable_Type), Cable Length (CableLength)
Tips

In a formula you can write either the friendly name or the raw key — =Cable Name and =Cable resolve to the same value.

If you type a column name that does not exist, the formula prints the name itself (not a blank), which makes typos easy to spot in the preview.

Heads up

Column keys with no spaces (like Device_Name) use underscores; the friendly names (like "Device Name") use spaces. Both work in formulas, but be consistent so your formulas stay readable.

The formula language: functions and operators

Formulas are Excel-style and always begin with =. They work on text. The complete set of built-in functions is small and fixed (these are the only functions supported):

IF(condition, value_if_true, value_if_false) — returns the second argument when the condition is "true", otherwise the third. A condition is true when it is a non-empty value: any non-empty text counts as true (including the text "0" and "false"), and an empty string counts as false. Comparisons like Cable<>"" produce a true/false the IF can test.

LEFT(text, n) — the first n characters. If you omit n it defaults to 1; n of 0 gives an empty string.

RIGHT(text, n) — the last n characters (n defaults to 1).

MID(text, start, length) — length characters starting at position start, where the first character is position 1.

LEN(text) — the number of characters in text.

UPPER(text) — converts to UPPER CASE.

LOWER(text) — converts to lower case.

TRIM(text) — removes leading and trailing spaces.

Operators: & joins (concatenates) two values into one string. = tests whether a field equals a value, and <> tests whether it is not equal (these are string comparisons). Parentheses ( ) group sub-expressions. Numbers and quoted "text literals" can be used directly. An integer-valued number prints without a decimal point (2, not 2.0).

Important comparison rule: a comparison (= or <>) only fires immediately after a bare column name, with a single value on the right — for example Number<>"" or Side="Source". This matches how the live preview evaluates, so the preview and the printed label always agree.

Functions: IF  LEFT  RIGHT  MID  LEN  UPPER  LOWER  TRIM
Operators: &  (concatenate)   =  (equals)   <>  (not equal)   ( )  (grouping)
Literals: "quoted text"   123 (numbers)
Tips

Use & to stitch pieces together with separators, e.g. Number&" - "&Cable produces "N044 - RIO 1 PRI".

Wrap optional pieces in IF so empty columns don't leave stray separators or dashes on the label.

The Formula editor (Editor ⤢ button) shows a Live preview with ‹ › arrows to step through your real records, so you can confirm the formula on several rows before applying.

Heads up

These eight functions (IF, LEFT, RIGHT, MID, LEN, UPPER, LOWER, TRIM) are the ENTIRE function set. There is no CONCATENATE, no FIND/SEARCH, no SUBSTITUTE, no arithmetic (+, -, *, /), and no number formatting — only text operations, &, =, <>, and comparison-against-a-single-value.

If a formula has a syntax error it prints as a blank string rather than an error message, so check the live preview if a box comes up empty.

Comparison only works right after a column name (e.g. Cable<>""). You cannot compare two arbitrary expressions or chain comparisons.

Truthiness follows JavaScript: the text "0" is considered true in an IF because it is a non-empty string. Test with explicit comparisons (e.g. =IF(Field<>"",…)) when you mean "is this column filled in".

Common formula recipes (copy-paste)

These are real, working examples. The first four are the formulas actually used in the built-in label template, so they are known to be correct.

Cable number with cable name, but drop the " - " separator when there is no cable name, and fall back to just the cable name when there is no number:

Show a connector only when present:

Show a rack only when present (right-aligned field on the template):

Show the far end as "@ Device : Socket", omitting the socket part when blank, and printing nothing at all when there is no other device:

Build them up from simple pieces with the recipes below.

=IF(Number<>"",Number&IF(Cable<>""," - "&Cable,""),IF(Cable<>"",Cable,""))
=IF(Connector<>"",Connector,"")
=IF(Rack<>"",Rack,"")
=IF(Other_Device<>"","@ "&Other_Device&IF(Other_Socket<>""," : "&Other_Socket,""),"")
=UPPER(Cable)
="CBL-"&Number
=LEFT(Number,3)
=TRIM(Device_Name)
Tips

UPPERCASE everything for high-visibility labels: =UPPER(Cable)

Join two columns with a slash, only adding the slash when both exist: =IF(Device_Name<>"",Device_Name&IF(Socket_Name<>""," / "&Socket_Name,""),"")

Prefix every value: ="CBL-"&Number

First three characters of a code: =LEFT(Number,3)

Last four characters: =RIGHT(Cable,4)

Tidy stray spaces from imported data: =TRIM(Device_Name)

Heads up

When concatenating, guard every optional piece with IF(col<>"", …, "") so you never print a lone dash, slash, or "@" with nothing after it.

Barcodes and 2-D codes: supported symbologies

A barcode object is added as its own object type and gets its data from the same three sources (Static / Field / Formula) as text — so you can bind a barcode to a data column or build its value with a formula, and it changes per label. New barcodes default to a QR Code with error correction M and the sample value 12345.

The complete list of supported symbologies, with the exact menu labels:

2-D / matrix codes: QR Code (qrcode), Data Matrix (datamatrix), Aztec Code (azteccode), Micro QR (microqrcode).

Stacked: PDF417 (pdf417).

1-D / linear codes: Code 128 (code128), GS1-128 (gs1-128), Code 39 (code39), Code 93 (code93), EAN-13 (ean13), EAN-8 (ean8), UPC-A (upca), UPC-E (upce), Interleaved 2 of 5 (interleaved2of5), Codabar (codabar).

All symbologies are produced by the same vendored bwip-js engine in both the on-screen preview and the print path, so the preview matches the printed code.

QR Code, Data Matrix, Aztec Code, Micro QR, PDF417, Code 128, GS1-128, Code 39, Code 93, EAN-13, EAN-8, UPC-A, UPC-E, Interleaved 2 of 5, Codabar
VectorLabel — Print

A live example running the real app: this QR is bound to the record’s Number field and re-encodes for every row — the same bwip-js engine that renders it here prints it.

  1. Add a barcode object.
  2. Pick the symbology from the Symbology drop-down.
  3. Choose the content source (Static / Field / Formula) and set the value.
  4. If the symbology supports error correction, pick a level from the Error correction drop-down.
  5. Size the box on the canvas.
Tips

For data that changes per label (serial numbers, asset IDs, cable numbers), bind the barcode to a Field or write a Formula — the code regenerates for every record at print time.

Drag a data column header onto a barcode to bind it to that column in one step.

Heads up

EAN/UPC and the other numeric/fixed-format symbologies will fail to encode if the value doesn't fit their rules (e.g. letters in an EAN-13, or the wrong digit count). When a value can't be encoded — or is empty — the label is printed BLANK for that code rather than printing a garbage barcode.

Which symbologies are hardware-scan-verified on which printers is not established in this area's source; treat scannability as something to test on your own scanner during alpha.

Square vs stretchable codes, and error correction

Square (fixed aspect) codes: QR Code, Data Matrix, Aztec Code, and Micro QR are always drawn square and centered in their box, regardless of the box shape. Making the box wider than it is tall just adds empty margin — the code stays square so it scans reliably.

Stretchable codes: the linear 1-D codes (Code 128, GS1-128, Code 39, Code 93, EAN-13, EAN-8, UPC-A, UPC-E, Interleaved 2 of 5, Codabar) AND the stacked PDF417 stretch freely to fill the box on both width and height. You size their width and height independently.

Error correction is offered only for the symbologies that support it, via an "Error correction" drop-down:

QR Code and Micro QR: levels with friendly labels — QR offers "L — 7%", "M — 15%", "Q — 25%", "H — 30%"; Micro QR offers L, M, Q. Higher levels survive more damage/smudging but pack less data into the same size.

PDF417: levels labelled "Level 0" through "Level 8".

Data Matrix, Aztec, and all the 1-D codes have no user-selectable error-correction setting (Data Matrix and Aztec manage it automatically).

A quiet zone (clear margin) is automatically included around every code so it scans even when placed next to other label content.

Error correction — QR / Micro QR: L (7%), M (15%), Q (25%), H (30%, QR only)
Error correction — PDF417: Level 0 … Level 8
Square (centered): QR, Data Matrix, Aztec, Micro QR
Stretch to fill box: Code 128, GS1-128, Code 39, Code 93, EAN-13/8, UPC-A/E, Interleaved 2 of 5, Codabar, PDF417
Tips

For labels that may get scuffed, scratched, or partly covered (cable wraps, dusty racks), choose a higher QR error-correction level (Q or H).

If a 2-D code looks merged into a solid block at small sizes, give it a slightly larger box — the renderer needs room to keep module edges crisp.

Heads up

If you change a barcode's symbology, its error-correction level is automatically clamped to a value the new symbology allows (or removed if the new type has none), so don't be surprised if the level resets when you switch types.

Making a square 2-D code's box very small can leave no room for even one whole module, in which case nothing is drawn (the code prints blank). Increase the box size if a code disappears.

How content is rebuilt for every label at print time

Nothing on a label is a fixed picture of one record. When you print, each label is generated from its own data row: Field objects pull that row's column value, Formula objects are re-evaluated against that row, and barcodes are encoded fresh from that row's value.

Barcodes specifically are regenerated per record at full print resolution — they are not stored as a fixed-resolution image, so a field-bound barcode is sharp at any printer DPI and correct for each individual label.

Because the preview and the print path use the same formula engine and the same barcode engine, the on-screen preview of any given record is an accurate proxy for what that label will print.

Tip

Use the record-stepping arrows in the Formula editor's Live preview to spot-check formulas and bound barcodes across several real rows before committing to a full print run.

Heads up

If a Field or Formula resolves to empty for a given row, that text box simply prints nothing for that label — there is no placeholder. Verify with the live preview that rows you expect to be filled actually are.

A barcode whose value is empty or unencodable for a particular row prints blank on that label only; other rows still print normally.

Printing & printers

The Labels list: search, sort, filter, columns, inline editing, selection

The Labels list shows every record (label) from your export. The header shows either the total count or "X of Y shown" when a filter or search is active. Click a row to preview that label on the right. The list is built to stay fast even with thousands of rows.

Search: the "Search all fields…" box matches across every field. Space-separated terms must all appear in a row (e.g. "amp lan" finds rows containing both). A ✕ button clears the search.

Filter & sort: the "⧩ Filter & sort" button opens a dialog where you build conditions. Each condition is a Field, an operator (Contains, Does not contain, Is exactly, Is not, =, ≠, >, ≥, <, ≤, Is empty, Is not empty), and a value (typed Text or another column's value via Field). Conditions combine with AND/OR inside a group, and you can add multiple groups combined with AND/OR. A "Show Source and Destination when only Source or Destination matches" checkbox keeps pairs together. Sort supports multiple levels (A→Z / Z→A) plus a pair mode: "Sort sources & destinations (breaks pairs)", "Sort by source — destinations stay with sources", or "Sort by destination — sources stay with destinations".

Columns: "Columns ▾" toggles which columns show. Drag a column header to reorder; drag its right edge to resize; right-click a header for "Hide column" / "Show all hidden columns". This column layout is shared with the designer.

Inline editing: hover a cell and click the ✎ pencil (or use the inline editor) to change a value. Enter saves, Escape cancels. Edits update the previewed/printed label and are written back to the source CSV file (so a later reprint uses the corrected value).

Editing on the fly: a "+ Row" button adds a blank row (saved back to the CSV), and a "Free edit" mode (the button flashes while active) turns the list into a spreadsheet-style grid — click any cell to edit directly, drag or Shift-click to multi-select, copy/paste ranges (⌘C / ⌘V), and drag a cell's corner handle to fill down (auto-increments when the value ends in a number; hold Option to repeat instead). A "Ripple" action (a button by the cell editor, or right-click in Free edit) auto-enumerates a value down many rows via a prefix / start / increment / postfix / count dialog. The Print window can add rows but not columns — the columns come from the export. (These on-the-fly editing tools are in the Print window and Custom Designer only; the Template Designer is for building reusable templates and has no record editing.)

Selection / which labels print: each row has a print checkbox and a pair checkbox (the ⇅ icon toggles a Source+Destination pair together). The header checkbox selects/deselects all visible rows. Shift+click a checkbox extends the selection across all visible rows in between. "Sources" and "Destinations" buttons in the Print bar select one side at a time.

VectorLabel — Print

The real Labels list — print and pair (⇅) checkboxes, Source/Destination sides, and the "Search all fields…" / "⧩ Filter & sort" / "Columns ▾" / "+ Row" / "Free edit" toolbar above the records.

  1. Use the search box or "⧩ Filter & sort" to narrow the list.
  2. Tick the rows (or pairs) you want, or use Select all / Sources / Destinations.
  3. In the Print bar choose Selected, All, or Range.
  4. Click a row to confirm the preview looks right, then Print.
Tips

Range in the Print bar counts by visible position, so it respects the active filter/sort — not raw record order.

A ⚠ next to a row number means a barcode on that label can't encode that record's value and would print blank.

Heads up

If you inline-edit a row and it then gets filtered or searched out of view, the edit is abandoned (the editor is torn down).

Inline edits are written back to the source CSV; if that write fails the on-disk file can differ from what printed.

Filter/sort presets

You can save a filter+sort combination as a named preset. In the Filter & sort dialog, "Save as preset…" prompts for a name. Saved presets appear as buttons in the Labels header; click one to apply it. The active preset is highlighted.

Right-click a preset button for: Apply (activate), Edit…, Rename…, Update preset with current, and Delete. Presets are stored in app settings and shared between the Print window and the designer.

  1. Open "⧩ Filter & sort" and build your filter and/or sort.
  2. Click "Save as preset…" and give it a name.
  3. Later, click the preset button in the header to apply it.
Tip

"Update preset with current" overwrites a preset with whatever filter/sort is active right now.

Live preview, the required-supply check, and expanded preview

The right-hand preview shows the selected label rendered with real data, scaled to fill the sidebar (drag the sidebar's left edge to resize; the width is remembered). It shows the label in the same orientation as the template — including continuous labels and 90°-rotated die-cut labels — so the preview matches what actually prints and what the designer shows. Arrows (‹ ›) step through visible labels, and ⊞ opens the expanded preview. The preview shows just the printable area — the hatched physical-label overlay lives in the designers, not here (see Printable-area margins in the designers chapter). The "Printable area" row under the preview notes "(from loaded cassette)" when its dimensions come from the cassette the printer reports rather than the static supply catalog.

Under the preview, a "Required supply" panel shows the supply the template needs (displayed as "BM/M6-<core>" so the bulk box and the small roll are treated as the same), the Label size and Printable area, and "Buy" buttons for each part number. A green ✓ means the loaded cassette matches; "⚠ mismatch" means the loaded label size/part doesn't match and the print may be misaligned or cropped.

The expanded preview (⊞ or the "Print preview" modal) shows every visible label in a grid. You can zoom (40%–300%, remembered), toggle "Show enabled only", and tick Print / Pair on each tile.

"Inherit rack": when you sort by Rack with the inherit option on, a blank-Rack side of a pair borrows its partner's rack and shows it in parentheses, e.g. "(RIO RACK)", both in the preview and on the printed label.

Tip

The matched/mismatch check is based on the real loaded label size and part number reported by the printer, not just the part number text.

Heads up

A network Brother printer can't report its loaded tape, so it shows no loaded-cassette readout and won't show a match/mismatch.

Choosing the printer and confirming the supply

The printer dropdown in the Print bar lists every connected printer (name plus serial), and each entry also shows that printer's loaded supply beside its name — the part number when the cassette reports one, otherwise the loaded label size — so you can see what's in each printer before picking one. A colored dot and a word show status: green/Ready, yellow/Busy, red/Offline. The list is populated from VectorLabel's live USB and network scan.

You often don't need to pick at all. In both the Print window and the Custom Designer, every tab remembers its own printer selection, and when you open a label (or pick a template) VectorLabel auto-selects a printer whose loaded supply matches it — falling back to the printer you used most recently. A printer you pick by hand always wins; auto-select never overrides a manual choice.

The supply line under the printer shows the loaded part number (click it to re-detect), live telemetry if the printer supports it, and any pre-flight error. If nothing is detected you'll see a "Detect supply" button. Supply status refreshes automatically about every 30 seconds while printers are idle and immediately when the print window opens; nothing is polled while a job is printing.

Telemetry (M611 only): when available it shows Battery %, Labels %, and Ribbon %. A ⚠ appears when the job may need more labels or ribbon than remain.

Pre-flight: printer-reported problems (printhead open, invalid supply, invalid ribbon) are shown in red and block printing until fixed; a "Re-detect" button re-reads the supply.

  1. Pick the printer in the dropdown.
  2. Check the status dot says Ready.
  3. Confirm the loaded supply matches (green ✓) or press Detect supply / Re-detect.
  4. If a pre-flight error shows, fix it on the printer and press Re-detect.
Tip

You can switch printers at any time; the supply readout and cut options update for the selected printer.

Heads up

The Print button is disabled unless a template is chosen, at least one label is selected, the printer status is Ready, and there is no pre-flight error.

Cut modes and "Feed to clear"

The "Cut" dropdown sets when the printer cuts. The options come from the selected printer's driver; the standard Brady set is "Every Label", "End of Job", and "None" (internally eachLabel / afterJobLast / never). If you don't change it, a sensible default is used per supply: continuous tape cuts after every label; die-cut stock cuts once at end of job.

"Feed to clear" (a checkbox labelled "Feed to clear") feeds a blank lead label before the job to advance/clear the supply — for die-cut, one label (cut per your setting); for continuous, 1 inch, always cut. The checkbox only appears when the selected printer's driver supports it — the Brady M610 and M611 do; Brother P-touch does not. The choice is remembered per printer, so each printer keeps its own setting.

On the M611 the built-in cutter actuates automatically. On a printer with no auto-cutter set to "Every Label", the app prints one label at a time and pauses for a manual cut between labels (this manual-cut pause path exists for the M610 in code).

  1. Pick when to cut from the Cut dropdown.
  2. Optionally tick "Feed to clear" to advance a blank lead label first (Brady printers only; remembered per printer).
Tip

Both the M610 and M611 cutters are full-cut only; a "half-cut" mode degrades to a single full cut at end of job.

Heads up

The Brother drivers are only partially hardware-verified, and cut suppression ("None"/never) on the Brother classic dialect is one of the paths not yet confirmed — the terminator may still feed and cut. Treat "None" on Brother as untested.

The M610's cut byte behavior overall is noted as not fully hardware-verified in the project's own memory.

Send modes: one-at-a-time vs full job

Send mode is a per-printer setting under Preferences ▸ Printers ▸ "Per-Printer Settings…". The choices are "One at a time" and "Full job".

One at a time: each label is its own print job — per-label progress, and you can cancel mid-run (the in-flight labels finish, the rest are dropped). Full job: the whole job is sent in one shot — fastest, but it can't be interrupted once it starts, so no Cancel button is offered for it and progress shows only what the printer itself reports. Both run at full speed. On the M611 a full-job print now starts immediately — the end-of-job signal is sent right after the job data, so the printer doesn't sit waiting before the first label.

Some drivers report live progress on their own and always stream as one job; for those the Send mode picker is greyed out with the note "This printer reports live print progress on its own, so it always streams as one job." The M610 defaults to single-label (it has a SmartCell label counter, so it reports accurate per-label progress in both modes); the M611 defaults to Full job.

  1. Open Preferences ▸ Printers ▸ Per-Printer Settings…
  2. Find the printer card and set Send mode to "One at a time" or "Full job".
  3. Apply (or Apply & Close).
Tip

Choose "One at a time" if you want to be able to cancel partway through and see per-label progress.

Heads up

With the M611 in "Full job", you cannot cancel once printing starts — the job shows no Cancel button — and the status tracks only what the printer reports (a literal "unknown" if it stops reporting; see Live progress).

Live progress, mid-run cancel, and job completion

When you print, a "Printing…" dialog shows a progress bar and "Printing label X of Y…" as labels are sent (driven by the printer for drivers that report a counter or live telemetry). On completion a "Print complete" dialog confirms the count sent.

After the job starts the Print window closes, returns you to your previous app, and the menu-bar popover opens so you can keep watching status there. Live job outcome (complete / cancelled / failed) is tracked by the Engine's menu bar after the window closes.

The status never lies. The job status in the menu bar (and in the Custom Designer's print header) only advances when the printer actually reports progress. If an M611 stops reporting mid-job — a dropped connection, say — the status shows a literal "unknown" rather than a made-up advancing count; a job that stays silent shows "unknown" for about its estimated print time and is then marked printed. Progress is never faked.

"Printer paused" vs "unknown". If you pause the printer on the device mid-print (M611), the status shows "Printer paused" in orange. The job is held open: live tracking resumes when you press resume on the printer, the job completes only when the printer sends its real job-complete signal, and you can still cancel it while paused. The two states mean different things — "Printer paused" means you paused it on the device; "unknown" means the printer stopped reporting. In both cases the Engine waits for real information instead of inventing progress. (Pause detection is hardware-verified in one-label-at-a-time mode; it is implemented for full-job mode too but not yet separately verified there.)

Cancelling: the Cancel button appears only for jobs that can actually be cancelled. In "One at a time" mode you can cancel mid-run — the in-flight labels finish and the remaining labels are dropped. The M610 then reports the count the hardware actually printed (from its SmartCell counter). The M611 has no firmware-level cancel; in single-label mode at most about two labels are in flight, so cancel stops within a label or two. A full-job batch is sent in one shot and can't be interrupted, so no Cancel is shown for it.

If nothing renders (e.g. every selected record fails to render) or the job can't be queued, the spinner is dismissed and an alert explains why ("Nothing to print" or "Couldn't start the print").

Heads up

The M611 waits/blocks until the printer reports the job actually finished before closing the port, so the spinner may persist briefly after the last label.

Recent Prints and reprint

Every print (and every configured-but-cancelled job) is recorded to Recent Prints, shown scrollable in the menu bar with buttons to jump to top/bottom and clear it. Pressing Reprint reopens the Print window with the same source file, selection, range, and filter/sort.

If the source CSV is gone (exports get pruned), reprint offers "Reprint Without Editing" (re-send the original rendered labels) or Cancel. A job that was cancelled before any labels rendered cannot be reprinted that way and says so.

Reprinting a Custom Designer job. Reprinting a job that came from the Custom Designer reopens that label in the Custom Designer with the full setup it was printed with: the print range (All / Current / Selected / Range) and its bounds, which rows were ticked, the record that was being previewed, the database filter, sort and search, and the printer that was chosen — while loading the current version of the label file, so edits you've saved since printing are included. If the label auto-syncs its data from a source file, a data refresh no longer resets the restored print selection. This applies to prints made in v1.9.0 or later.

Clearing history is in Preferences ▸ Recent ▸ "Clear History" (with a confirmation).

  1. Open the menu bar, find the job, and press Reprint.
  2. Adjust the selection/template if needed, then Print again.
Heads up

Exports are pruned per project (Preferences ▸ Export ▸ "Exports to keep per project"); recent-print records are kept even when their source file is gone.

Printer setup: scanning, network printers, and supported models

Printers are managed in Preferences ▸ Printers. The "Scan" menu offers "Scan USB" and "Scan network (subnet)". A status-refresh interval (Preferences ▸ Printers ▸ "Refresh interval", 1–600 s) controls how often the app rescans and re-reads live status; it is paused while a job prints.

Add a network printer with "Add network printer": type the IP/hostname (e.g. 192.168.1.50) and pick the model from the dropdown; the model decides which driver drives it (raw TCP). Network printers can be removed with a "Remove" button.

Brady M610: USB only, 300 DPI, reads its loaded cassette via Brady SmartCell, supports self-laminating wire/cable wraps. No live telemetry (no battery/ribbon %).

Brady M611: USB and network (raw TCP port 9100, telemetry on 9102), 300 DPI, built-in auto-cutter, live telemetry. Network discovery scans the subnet for the Brady control port 9102. Per the project's notes the M611 is the most hardware-validated printer.

Brother P-touch: 180 DPI TZe tapes. PT-E550W and PT-P750W are Wi-Fi "W" models (USB plus raw TCP 9100); PT-E560BT is Bluetooth/USB hardware but prints over USB only (no Wi-Fi/9100). Add a network Brother by entering its IP and choosing PT-E550W as the model.

  1. Open Preferences ▸ Printers.
  2. For USB: connect the printer and choose Scan ▸ Scan USB.
  3. For network: choose Scan ▸ Scan network, or use "Add network printer" with the IP and model.
  4. Confirm the printer appears with a green Ready dot.
Tip

Each printer's USB vendor/product IDs and which connection methods (USB, Network, Bluetooth) are enabled are editable per model in "Per-Printer Settings…".

Heads up

All three Brother drivers pass offline (golden-vector) tests and are partially hardware-verified — individual functions have been confirmed on real printers, but orientation, cut behavior, media auto-detect, and the cut-suppression bit are not yet all confirmed on every model (see docs/PTOUCH-DRIVER-STATUS.md). Test one model at a time.

Do not connect a PT-E560BT expecting the classic Brother dialect — it uses a different dialect; routing is by USB product ID to avoid a one-job hang.

A network Brother is print-only: it can't auto-detect the loaded tape, so the die-cut→continuous re-map won't trigger — use a continuous template or USB for that.

Loaded media auto-detection

Brady printers read the loaded cassette automatically: the M610/M611 use Brady SmartCell, which reports the real part number, label width/height, printable area, die-cut vs continuous, and supply level. This drives the green ✓ / ⚠ mismatch indicator and the cut default.

Brother printers read the loaded tape over USB using the ESC i S status command (tape width, errors). This is implemented but not yet individually confirmed on real hardware (the Brother drivers are only partially hardware-verified).

You rarely need to ask for a re-read: supply status refreshes automatically about every 30 seconds while printers are idle and immediately when the print window opens; nothing is polled while a job is printing, so a refresh can never interfere with an active print. You can still force a re-read at any time: click the loaded part number or the "Detect supply" button in the Print window, the ↻ button on the printer's row in the Engine's menu-bar dropdown (a spinner shows while it runs; the button is hidden for offline printers and declines politely while that printer is mid-print), or "Detect cassette" on the printer's row in Preferences.

  1. Load the supply in the printer.
  2. In the Print window click "Detect supply" (or the part number) to re-read it.
  3. Confirm the Required supply panel shows a green ✓.
Tip

Matching is by part number first, then by physical label size, so a bulk box and its cartridge both count as a match.

Heads up

Media auto-detect over the network is not available (it reads the USB IN endpoint), so network printers derive the tape from the rendered raster instead.

Brother media auto-detect (ESC i S) is implemented but not yet confirmed on hardware.

Automatic orientation on Brady printers

You don't have to think about which way a die-cut label feeds. When a job goes to a Brady printer (M610 or M611), every die-cut design is fitted against the printable-area rectangle that the loaded cassette itself reports, so the design always lands on the label the right way around — wire wraps, raised panels, any supply, including custom supplies you've added to the catalog yourself.

The orientation decision never consults the supply catalog — only what the cassette reports — so editing the supply library can't change how anything prints.

If the fit is genuinely ambiguous (a square printable area and a square design), the printer's reported orientation is kept, and the designer's "⟳ 90°" button remains the manual override (see Canvas behavior, zoom, and 90° rotation). Continuous tape is unchanged and works as it always has.

Tip

Because the fit uses the cassette's own printable rectangle, a supply you defined by hand in Edit Supplies orients just as correctly as a factory one — the catalog entry is only used for designing, never for orienting the print.

Heads up

This applies to the Brady M610 and M611 only. Brother P-touch orientation is a separate, still not fully hardware-verified area — see Which printers actually work today.

Per-printer calibration (alignment)

If a printed label lands slightly off-center, you can nudge it per printer. In Preferences ▸ Printers, each printer's row has calibration controls: "Print calibration grid" (enabled only when the printer is Ready) prints a reference grid, then you enter a Horizontal and Vertical offset in pixels until the grid lands square on the label. A "Reset" button zeroes them.

The controls show the reference scale (e.g. "300 px = 1 inch (300 DPI)"). Offsets are stored per printer serial, so they follow that physical printer, and are applied to every print from it.

Calibration (and other printer settings) is shared across the whole suite: you set it once in the Engine's Preferences and it applies to every print — from the print window and from both designers, not just the Engine — and it works for network and Brother printers, not only USB Brady.

A factory reset (Advanced ▸ Reset Defaults) also clears all per-printer alignment offsets.

  1. Open Preferences ▸ Printers and find the printer.
  2. Click "Print calibration grid".
  3. Compare the printed grid to the label edges.
  4. Enter Horizontal and Vertical offsets (in px) and reprint the grid until it's centered.
  5. Use "Reset" to return to zero if needed.
Tip

Offsets are entered in the calibration reference DPI shown next to the button, not the internal master render DPI.

Heads up

"Print calibration grid" is disabled unless the printer is Ready.

The editable Supply Catalog

The list of label supplies is fully editable. Open it from Preferences ▸ Printers ▸ Label Supplies ▸ "Edit Supplies…". The structure is: Supply group → Category → Supply → Part number.

A Supply group is assigned to one or more printer models (e.g. the "Brady M6" group serves M610 and M611; the "Brother P-touch" group serves PT-E550W/PT-P750W/PT-E560BT). You can add, duplicate, delete, import, and export groups, set the Group name and which Printers it serves, and "Restore defaults…".

The "Set up supply groups" wizard. To add the bundled factory groups without hand-building them, use the wizard. It opens on its own the first time an install finishes — both a fresh install and an in-place upgrade of the running Engine — and you can reopen it any time from Preferences ▸ Printers ▸ "Set Up Supply Groups…". It lists the bundled ("available") groups and your ("existing") groups side by side. For each available group you choose Don't install, Install New, or Install & Replace: it defaults to Replace when a group of the same name already exists, otherwise Install New. Picking Install New over a name you already have adds a numbered copy (e.g. "Brady M6 2") rather than overwriting. Each existing group also has a Delete tick, and an "Install all & clear existing" preset wipes your groups and installs a clean factory set.

Inside a group you add Categories (named, reorderable) and drag supplies between them. Each Supply has a Name; a Type of Die-cut or Continuous; size fields (die-cut: Label W × H; continuous: Width × Default length, since the length is set at print time as "width × definable"); Printable W × H; a Self-laminating toggle (die-cut only); and a Material family (e.g. B-427).

Both units at once. Every supply size shows an inch field and a millimetre field side by side — type into either and both update, so you can enter whatever unit a supplier lists without converting by hand. Roll length shows feet and metres together the same way. (This is independent of the app-wide Units setting; the supply editor always shows both.)

Each Supply has one or more Part numbers (the orderable SKUs). For die-cut you set a quantity per roll and a "Rotate 90°" checkbox (Brady feeds some labels rotated on the roll). For continuous you set a Material label (e.g. Vinyl) and a roll length (feet and metres shown together). Each part also has its own "Buy link" field. Brady (M6) parts come pre-filled with that part number's Brady search URL, so nothing changes for them — but you can edit it or paste your own supplier's page instead. Leave a part's Buy link blank and it simply shows no Buy button (Brother P-touch tapes ship blank for now, so they have no button until you add a link). These become the "Buy" buttons in the Print window (e.g. "PN/250" for die-cut, "Vinyl PN/50'" for continuous).

The catalog is saved, versioned, and migrated, so the app can add new default sizes for existing users without wiping their customizations. Edits sync live into open Print/Designer windows.

A "Buy" button opens that part's stored Buy link in your browser; only http/https links are honored, and a part with no link shows no button.

Preferences ▸ Printers ▸ Label Supplies ▸ Edit Supplies…
  1. Open Preferences ▸ Printers ▸ Label Supplies ▸ "Edit Supplies…".
  2. Pick or add a Supply group and confirm the Printers it serves.
  3. Add/rename Categories and drag supplies between them.
  4. Select a supply and set its Name, Type, sizes, and Material family.
  5. Under Part numbers, click "Add part" and fill in the part number, quantity or roll length, Rotate 90° (die-cut), and an optional Buy link (blank = no Buy button).
  6. Click Apply or Apply & Close.
Tips

Use "Duplicate" on a group to base a custom group on an existing one, then rename it.

Type a size in whichever unit your supplier prints — the inch and mm fields (and the feet/metres roll length) stay in step, and each field also accepts fractions and math like the designer fields (see Units and typing math).

Editing the defaults alone only affects fresh installs; the app's migration adds new default sizes to existing users additively by part number.

Heads up

"Restore defaults…" replaces every group, category, supply and part number with the built-in Brady defaults and warns that your customizations will be lost.

Deleting a group, category, supply, or part can't be undone (you get a confirmation first).

Some seeded Brother TZe part numbers are placeholders/best-effort and should be verified before ordering.

Fixing common problems

How the four apps fit together (read this first)

VectorLabel is not one app — it's a suite of four pieces that work together. The Engine is the background piece that does the real work: it lives in the macOS menu bar (top-right of your screen), watches for new exports, talks to the printers over USB/network, and sends the actual print jobs. If the Engine isn't running, nothing prints — its menu-bar icon must be present.

The Template Designer and Custom Designer are separate windowed apps for building label layouts. Auto Print is the print window that pops up when a Vectorworks export arrives. The two designers and the print window can't reach a printer on their own — they hand the job to the Engine, which owns the USB connection.

Most 'nothing happens' problems trace back to the Engine: it isn't running, or it's running but its menu-bar icon got pushed off-screen by a crowded menu bar.

The Vectorworks plug-in scripts are a fifth, separate piece that runs inside Vectorworks itself and drops CSV files into the watch folder.

  1. Look at your menu bar (top-right). If you don't see the VectorLabel icon, the Engine isn't running — launch VectorLabel.
  2. If you launched it and still see no icon (a crowded menu bar can hide it), launch it again; the second launch is designed to surface the Preferences window so you have a way in.
  3. Use the menu-bar icon to reach Preferences, the designers, and the export folder.
Tips

The build number and short commit hash are shown in the menu-bar footer — quote them when reporting a bug.

Quitting the Engine (Quit VectorLabel, ⌘Q) stops all printing and watching until you relaunch.

Heads up

The designers and print window only know how to *launch* their siblings when you've installed the packaged suite (the .pkg/.dmg). If you're running a one-off dev build, the 'Open … Designer' menu items may do nothing.

The app won't open ('unidentified developer' / Gatekeeper)

macOS blocks apps it can't verify. Releases of VectorLabel from the project's GitHub Releases page are signed with a Developer ID and notarized by Apple, so they should open normally. But if you have an unsigned or ad-hoc build (for example one you built yourself, or an unsigned .pkg installer), macOS will refuse to open it on a double-click and show a warning about an unidentified developer.

The standard workaround for an app or installer macOS won't open directly is to right-click it and choose Open — that gives you a one-time override that a plain double-click doesn't.

spctl --assess --type execute -vv /Applications/VectorLabel.app
  1. In Finder, right-click (or Control-click) the app or the .pkg installer.
  2. Choose Open from the menu.
  3. In the dialog that appears, confirm Open again.
  4. If macOS still refuses, open System Settings → Privacy & Security, scroll down, and click the 'Open Anyway' button that appears after a blocked launch attempt.
Tip

A properly notarized release verifies with: spctl --assess --type execute -vv /Applications/VectorLabel.app — it should report 'accepted, source=Notarized Developer ID'.

Heads up

Right-click → Open is only needed for unsigned/ad-hoc builds. If a *notarized* release is being blocked, something else is wrong (re-download it; a partial download can break the signature).

My Brady printer isn't detected over USB

The Engine finds USB printers by scanning for them. Both the Brady M610 and M611 are identified by hardware-confirmed USB IDs (the M611's was validated on a real unit), so a printer that isn't found usually points to power, cabling, or another app holding the device — not an ID mismatch.

Detection also requires that the Engine actually be running and able to claim the USB device. The app talks to printers at the raw-USB level (it is intentionally not sandboxed so it can do this), so a power, cable, or 'another app grabbed the printer' problem will stop detection cold.

  1. Confirm the Engine is running (menu-bar icon present).
  2. Open Preferences and go to the Printers tab. The top row reads 'No printers detected' or 'N printer(s) connected'.
  3. Use the Scan menu → Scan USB to force a re-scan.
  4. Power-cycle the printer and reseat the USB cable; try a different cable/port (some cables are charge-only).
  5. If an M611 still won't appear over USB, you can also add it over the network instead (see the network section).
Tips

Each connected printer shows a colored status dot in the Printers tab: green = ready, yellow = busy, dim = offline.

The status refresh interval (and thus how quickly a newly plugged printer appears) is set in Preferences → Printers → Status Refresh.

Heads up

Scanning is paused while a job is printing, and the app deliberately avoids scanning during an active job — finish or cancel the job before expecting a freshly plugged printer to show up.

M611 USB detection is hardware-confirmed — if an M611 isn't found, the cause is almost always the cable, power, or another app holding the device.

Adding a network (Wi-Fi/Ethernet) printer

Some printers can be reached over the network instead of USB. There are two ways: let the Engine scan your subnet, or type the printer's IP address in by hand.

The Brady M611 can be discovered automatically because it answers on a Brady-specific control port. A Brother P-touch 'W' model (PT-E550W / PT-P750W) only answers on the generic raw-print port, so the scanner can find that it's *a* raw printer but can't positively confirm it's a Brother — when added by scan it's guessed as a PT-E550W, which you can correct or remove.

  1. Open Preferences → Printers.
  2. To auto-discover: Scan menu → 'Scan network (subnet)'. New printers found are added automatically.
  3. To add by hand: in the 'Add network printer' row, type the IP (e.g. 192.168.1.50) in the address field, pick the correct model from the dropdown, and click Add. Picking the model is what tells the Engine which driver to use.
  4. Remove a wrongly-guessed or stale network printer with its Remove button.
Tip

For a Brother Wi-Fi model, add it by IP and pick PT-E550W as the model so it routes to the Brother driver.

Heads up

A network-added printer is print-only: it can't auto-read the loaded tape/cassette over the network. So the automatic die-cut→continuous remap won't trigger, and there's no live loaded-supply readout — use a continuous template, or connect over USB, when you need that.

The PT-E560BT is a Bluetooth unit with no Wi-Fi; it can't be added over the network — it prints over USB only.

Brother P-touch drivers are all alpha and only partially hardware-verified — see the Brother section.

Nothing happens after I export from Vectorworks

When you run the Vectorworks command, it writes a CSV file into ~/Documents/VectorLabel/Exports/<YourVWFileName>/ and the Engine is supposed to notice it and open the print window. The export is *silent on success* — there's deliberately no 'done' dialog — so 'nothing happened' is often actually a success you didn't see, plus the print window failing to open.

For the print window to pop up automatically, the Engine must be running and 'Auto-open print window when export is detected' must be on. If the Engine is closed, the CSV is still written and will be picked up the next time the Engine starts.

~/Documents/VectorLabel/Exports/<VWFileName>/<VWFileName>_export_YYYYMMDD_HHMMSS.csv
  1. Check ~/Documents/VectorLabel/Exports/<YourVWFileName>/ for a new CSV named like <name>_export_YYYYMMDD_HHMMSS.csv. If it's there, the export worked.
  2. Make sure the Engine is running (menu-bar icon).
  3. Open Preferences → Export and confirm 'Auto-open print window when export is detected' is turned on.
  4. Confirm the Watch Folder in Preferences → Export points at the same place Vectorworks is writing to (default ~/Documents/VectorLabel).
  5. From the menu bar, you can also use 'Open Export Folder' (⌘E) to jump straight to the folder.
Tip

The plug-in only alerts on *errors*. If you saw no error dialog in Vectorworks, the export almost certainly succeeded.

Heads up

If you moved/changed the Watch Folder in Preferences but the Vectorworks scripts still write to the default ~/Documents/VectorLabel/Exports/, the Engine won't see the files. Keep them aligned.

Old exports are pruned (default keep-15 per project) by the date code in the filename — a missing older CSV may simply have been pruned.

My export is empty / 'No ConnectCAD circuits' in Vectorworks

There are two Vectorworks commands. 'Export Selected Circuits to VectorLabel' exports whatever you currently have selected; 'Export All Circuits to VectorLabel' exports every ConnectCAD circuit on the active design layer, ignoring selection.

The scripts only export objects they recognize as ConnectCAD circuits. Other objects (equipment, symbols, text) are skipped, and if nothing qualifies you get an alert instead of a file.

  1. If you used the Selected command and nothing was selected, you'll see 'No objects selected. Select one or more ConnectCAD circuits.' — select your circuits first.
  2. If your selection had objects but none were circuits: 'No ConnectCAD circuits found in selection. (N non-circuit object(s) skipped)' — you selected the wrong kind of object.
  3. Make sure you're on the right *design layer* when using the All command — it only looks at the active layer.
  4. Try the 'Export All Circuits' command to rule out a selection problem.
Tip

The number of skipped non-circuit objects is shown in the alert — a high skip count usually means you grabbed the wrong objects.

Heads up

'All' is strictly the *active* design layer. Circuits on other layers won't be included.

Both scripts must be installed as two *separate* Vectorworks command plug-ins (one per .py file) and added to your workspace, per the README.

Labels print misaligned, shifted, or off-center

If printed labels are consistently shifted in one direction, use the per-printer calibration controls. VectorLabel can print a calibration grid and then let you nudge the horizontal and vertical offset (in printer pixels) until the grid lands square on the label.

A different cause of 'misaligned or cropped' is a supply mismatch: the loaded cassette/tape doesn't match the supply the template was designed for. The print window shows a green ✓ when they match and a red ⚠ warning when they don't — printing anyway risks cropping.

A label printing sideways is a different problem again — and on Brady printers it shouldn't happen: every die-cut design is fitted automatically to the printable area the loaded cassette reports (see Automatic orientation on Brady printers). If a Brady die-cut label still comes out sideways, please report it. (Brother orientation is a separate, not fully hardware-verified area.)

  1. Open Preferences → Printers and find your printer.
  2. Use the calibration control to print the calibration grid.
  3. Adjust the Horizontal and Vertical offset fields (values are in printer pixels; the panel shows how many px = 1 inch for that printer's DPI).
  4. Reprint the grid and repeat until it's square; there's a reset-to-zero option if you overshoot.
  5. Separately, check the supply indicator in the print window: if it's a red ⚠, load the matching supply (or pick a template/supply that matches what's loaded) and click Re-detect.
Tip

Calibration offsets are stored per printer serial number, so each unit keeps its own alignment.

Heads up

Calibration won't fix a *supply* mismatch — a label designed for a wider/narrower supply than what's loaded will still crop. Fix the supply first.

Network-added printers can't auto-detect the loaded supply, so the match indicator may not be meaningful for them.

The job status says "Printer paused" or "unknown"

Neither of these is the app misbehaving — they are the Engine being honest about what the printer is telling it. The job status (in the menu bar and the Custom Designer's print header) only ever shows what the printer really reports; it never invents an advancing count (see Live progress).

"Printer paused" (orange) means you paused the printer on the device itself mid-print (M611). The job is held open, not abandoned: press resume on the printer and live tracking picks up again, the job completes only when the printer sends its real job-complete signal, and you can still cancel the job while it's paused.

"unknown" means the printer stopped reporting — a dropped connection, for example. Rather than showing a made-up count, the status reads "unknown"; if the job stays silent it shows "unknown" for about its estimated print time and is then marked printed.

  1. "Printer paused": press resume on the printer — the status returns to live tracking on its own. Or cancel the job from the menu bar if you've changed your mind.
  2. "unknown": check the connection (USB cable, or network reachability for a network M611) and watch the printer itself — it may still be printing normally even though it stopped reporting.
  3. If a silent job was marked printed but the labels never appeared, reprint it from Recent Prints once the printer is back.
Tip

The quick read: orange "Printer paused" = the printer is waiting for you; "unknown" = the app is waiting for the printer. In both cases the Engine waits for real information instead of guessing.

Heads up

Pause detection is hardware-verified in one-label-at-a-time mode; it's implemented for full-job mode too but not yet separately verified there (alpha).

A 2-D barcode (QR / Data Matrix) prints as a solid black block

This is a known alpha gotcha. The app renders everything at a high-resolution master and then downscales to the printer's native resolution. For 2-D codes (QR, Data Matrix, Aztec, Micro QR), the size of each tiny module must line up exactly with that downscale step. If it doesn't, the modules blur together when downscaled and the whole code prints as one solid black rectangle that no scanner can read.

Practically: make the 2-D code bigger on the label, or adjust its size so the modules are large enough to survive the downscale. Linear barcodes (Code 128, Code 39, etc.) and PDF417 stretch freely and don't have this exact-size requirement.

  1. In the designer, select the 2-D barcode and increase its size noticeably.
  2. Re-check the preview — if it still looks like a solid block at print size, make it larger again.
  3. Prefer a linear barcode (e.g. Code 128) if you only need a small mark and a square 2-D code keeps merging.
Tip

Square 2-D codes (QR / Data Matrix / Aztec / Micro QR) are kept square by the app; linear codes and PDF417 are allowed to stretch.

Heads up

This is an alignment-to-downscale issue (the master resolution divides down to native by a fixed factor — roughly ×3 for Brady, ×5 for Brother). It is not a data error: the code is being drawn, it's just too fine to survive scaling.

If a barcode genuinely can't encode the record's value, that's a *different* problem — the app warns and the barcode prints blank (see the next section).

A barcode prints blank / 'this record can't be encoded'

This is separate from the solid-black problem. Each barcode symbology (UPC-A, EAN-13, Code 39, etc.) only accepts certain characters or lengths. If a record's value can't be encoded by the chosen symbology — for example letters in a numeric-only barcode — the barcode can't be generated and that label prints blank where the code would be.

The app warns you ahead of time. In the print window, a row carrying an un-encodable barcode is flagged ('A barcode on this label can't encode this record — it will print blank'), and the preview shows the message 'This record can't be encoded as <type>'.

  1. Look for the barcode-warning marker on the flagged rows in the print window.
  2. Either change the barcode symbology to one that accepts your data (Code 128 is the most permissive for mixed text), or fix the source data so it fits the symbology's rules.
  3. If you see 'Barcode engine unavailable', the barcode renderer didn't load — relaunch the window/app.
Tip

Code 128 accepts the widest range of characters; the EAN/UPC family is strict about digit count and check digits.

Heads up

A blank barcode is the app correctly refusing to print an invalid code, not a printer fault.

Don't confuse this with the solid-black 2-D issue — blank = can't encode; solid black = too small to downscale.

Text is too big, too small, or cut off

Text objects can auto-scale to fit their box. With auto-scale on (and wrap off), the app shrinks the font so the single line fits the box — the whole value is always shown and is never truncated with a "…". With wrap and auto-scale both on, the text wraps onto multiple lines and shrinks to the largest size where every wrapped line fits the box — and the designer canvas, the print preview, and the printed label all agree. If auto-scale is off, long values can overflow and get clipped at the edge of the box.

For continuous tape, you can also grow the label length to fit the content instead of shrinking the text, using the designer's fit-length action.

  1. In the designer, select the text object and enable its auto-scale option so long values shrink to fit.
  2. If you'd rather keep the font size, make the text box wider, or turn on word-wrap so it flows onto multiple lines.
  3. On continuous supply, use the designer's 'fit label length to content' action to lengthen the label instead of shrinking text (you'll see 'Length fit to content').
  4. Verify in the print preview before sending — the preview reflects the real rendered size.
Tip

Wrap and auto-scale work together: with both on, long values wrap onto several lines and shrink just enough for every line to fit.

Heads up

With auto-scale off and wrap off, overflowing text is clipped at the box edge (no "…"), not resized.

'Fit length to content' only applies to continuous supplies; die-cut stock has a fixed printable height from the catalog.

A template opens at the wrong size

A template's on-canvas size comes from the *supply* it's assigned to in the catalog (the supply's printable width/height). If a template opens too big, too small, or the wrong shape, it's almost always pointing at a different supply than you expect — or at a supply whose dimensions were edited.

Continuous supplies use the template's chosen printed length; die-cut supplies use the fixed printable height defined for that part number in the catalog. So switching a template between a continuous and a die-cut supply changes how its length is determined.

  1. Open the template and check which supply/part number it's assigned to.
  2. Open Preferences → Printers → Edit Supplies… and confirm that part number's printable dimensions are what you expect.
  3. Reassign the template to the correct supply if it's pointing at the wrong one.
  4. For continuous supplies, set the intended printed length on the template.
Tip

The print window's supply indicator (green ✓ / red ⚠) tells you whether the template's supply matches what's physically loaded.

Heads up

If a previous user edited the supply catalog dimensions, every template on that supply changes size with it.

Die-cut height is fixed by the catalog and ignores any custom length you set.

I can't find my label supply or part number

The label-supply catalog (categories, sizes, part numbers, roll lengths/quantities, 90° feed rotation, and buy links) is fully editable in the app — you don't need to touch any code to add a size or SKU. It's grouped per printer model (e.g. a Brady 'M6 / M7' group, a 'Brother P-touch' group).

The catalog is versioned and migrated, so existing installs get new *default* sizes added automatically when the app updates. Anything you add yourself is preserved across updates.

  1. Open Preferences → Printers.
  2. Under 'Label Supplies', click 'Edit Supplies…'.
  3. Find the right printer group, then add or edit a supply: set its category, size, part number, roll length/quantity, 90° rotation, and each part's Buy link if you want.
  4. Save — the new supply is now selectable on templates and in the print window.
Tips

Each part number has its own "Buy link". Brady parts arrive pre-filled with the Brady part-number search; you can replace it with any supplier's page. The print window's "Buy" button opens that stored link — and a part with a blank link (including Brother tapes for now) shows no button.

The README points to the same place: Engine ▸ Preferences ▸ Printers ▸ Edit Supplies…

Heads up

Brother TZe part numbers seeded by default (especially the 3.5 mm one) are best-effort placeholders and may need correcting in Edit Supplies — they're not all hardware-confirmed.

Adding a new *default* size for everyone requires a code-side catalog version bump; editing the catalog in-app only affects your install.

Cutting and feed options (and what's still being verified)

The print window lets you choose when the supply is cut for a job ('Cut' dropdown), and whether to feed a blank lead label first to clear/advance the supply. By default, continuous tape is cut after every label (so each printed length separates) and die-cut stock is cut once at the end of the job. You can override this per job.

Be aware that on Brady M610, the exact cut byte sequences are not yet hardware-verified (alpha). On the Brother classic models — whose drivers are only partially hardware-verified — suppressing the cut entirely ('never') is a path not yet confirmed, so the job terminator may still feed and cut. Treat M610 and Brother cut behavior as experimental until you've tested it on your unit.

  1. In the print window, set the 'Cut' dropdown to the behavior you want (cut every label / cut at end / don't cut, depending on the supply).
  2. On a Brady printer, turn on the lead-label/feed-to-clear option if the first label is coming out mis-fed — for die-cut it feeds one label, for continuous it feeds about 1 inch and always cuts it off. (The checkbox only shows for printers that support it; Brother P-touch doesn't.)
  3. Test on a small batch before committing a long run.
Tip

The cut default adapts to the loaded supply when the printer reports it (continuous vs die-cut).

Heads up

M610 cut bytes are UNVERIFIED on hardware — if cutting misbehaves on an M610, that's a known unverified area.

Brother 'never cut' is not yet hardware-confirmed — the strip may still be cut even when you ask for no cut.

Where are my files (templates, exports, history)?

Everything VectorLabel writes lives under ~/Documents/VectorLabel/ by default. Templates from the designer go in Templates/; CSV exports from Vectorworks land in Exports/<VWFileName>/, one folder per project file.

Recent print history is kept separately so you can reprint, and old exports are pruned automatically (default: keep the newest 15 per project), using the date code in the filename rather than file metadata so it stays correct under cloud sync.

~/Documents/VectorLabel/\n  Templates/\n  Exports/<VWFileName>/
  1. Templates: ~/Documents/VectorLabel/Templates/
  2. Exports: ~/Documents/VectorLabel/Exports/<VWFileName>/
  3. Jump to the export folder quickly from the menu bar: 'Open Export Folder' (⌘E).
  4. Change the watch/templates folders in Preferences → Export and Preferences → Templates if you keep them elsewhere.
Tip

Reprint past jobs from the menu bar's Recent Prints section, or clear that history from Preferences → Recent.

Heads up

If you reprint an export whose CSV was pruned or moved, you'll get a 'Source file not found' alert — you can reprint the original labels but can't re-edit them.

Pruning is by the filename's date code; renaming exports can confuse pruning.

Which printers actually work today (alpha honesty)

The app's primary target is Brady M610/M611 wrap-around wire labels over USB. Both models' USB IDs are hardware-confirmed, and the M611's cut/orientation behavior is more validated than the M610's — M610 cut bytes specifically remain unverified.

Brother P-touch support (PT-E550W, PT-P750W classic dialect; PT-E560BT D460BT dialect) is implemented, passes offline 'golden vector' tests, and is partially hardware-verified — individual functions have been confirmed on real printers (for example, text now prints at the weight the preview shows — hardware-verified), but no Brother model has been verified end-to-end yet. Orientation, cut behavior, USB claim, and media auto-detect are not yet all confirmed on every model. Verify on your own unit before a production run.

  1. Brady M610/M611: the main supported path (USB; M611 also network).
  2. Brother PT-E550W / PT-P750W: implemented, network-capable, PARTIALLY hardware-verified (not yet end-to-end).
  3. Brother PT-E560BT: implemented (USB only — its Bluetooth isn't supported), PARTIALLY hardware-verified (not yet end-to-end).
  4. If you test on real Brother hardware and something's mirrored or upside-down, that's an expected not-yet-fully-verified area (orientation flips exist in code but aren't confirmed on every model).
Tip

The authoritative, up-to-date status is in docs/PTOUCH-DRIVER-STATUS.md — it tracks per-model what's verified vs implemented-only.

Heads up

Never feed a PT-E560BT (USB 04F9:2203) the classic Brother dialect — wrong routing makes it print one job then hang until power-cycled. The app routes by USB product ID to prevent this, but it's the known failure mode to watch for.

Adding more printer types is supported via docs/WRITING-A-PRINTER-DRIVER.md, but new cut/feed bytes ship disabled until hardware-verified.

Does it run on Windows? Requirements

No. VectorLabel is a macOS-only suite — it's built as native macOS apps and talks to printers through macOS USB facilities. There is no Windows or Linux build.

To run the released app you just need a Mac and a release from the project's GitHub Releases page. Building it yourself additionally needs Xcode plus libusb and pkg-config from Homebrew, but end users installing the signed release do not need Homebrew — libusb is bundled inside the app.

brew install libusb pkg-config
  1. End users: download a signed/notarized release (.dmg or .pkg installer) and install on macOS.
  2. Developers building from source: brew install libusb pkg-config, then open Package.swift in Xcode (see README).
  3. Vectorworks side: install the two Python command plug-ins into your Vectorworks workspace (README has the steps).
Tip

The app is not sandboxed by design (it needs raw USB and ~/Documents access); that's expected and is why it's distributed notarized rather than via the App Store.

Heads up

A self-built unsigned/ad-hoc app runs only on your machine and isn't distributable; only the notarized release is shareable.

Reporting problems (in the app or on the web)

The easiest way to report a problem is from inside the apps. Every error alert in all four apps has a "Report…" button next to OK — click it and a "Report a Problem" popup opens, pre-filled with the error, where you describe what you were doing and click "Send Report". To report something that didn't show an alert, use the Engine menu bar's "Report a Problem…" row (below "Check for Updates…") — there the description is required. And if an app crashed, the next launch offers to send a report for it, pre-filled with the crash details it captured.

The first report asks for your name and email (phone optional) so the developer can follow up; they're stored on your Mac and attached to later reports automatically (the popup then shows "Reporting as <name> · <email>" with an Edit button). Reports are sent privately to the developer — they're filed in a private repository, not posted publicly. Along with your description, a report includes the app name, version and build, your macOS version and Mac model, the current printer status (including the loaded cassette), and the tail of the app's recent log — each app keeps a rolling log file in ~/Library/Logs/VectorLabel/.

If you're not in the app — or you'd rather not send logs — use the feedback form on this site. No GitHub account is needed; it goes to the same place. Whichever route you use, it helps to include the build number and short commit hash shown in the menu-bar footer, your printer model and connection type (USB vs network), the loaded supply part number, and the exact text of any alert you saw.

  1. On any error alert, click "Report…" — or use the menu bar's "Report a Problem…" any time.
  2. Describe what you were doing. The first time, fill in your name and email (phone optional) — they're remembered.
  3. Click "Send Report" — it goes privately to the developer with the diagnostic info above.
  4. Not in the app? Use the feedback form — no GitHub account needed — and include the build number + commit hash from the menu-bar footer.
Tip

If sending fails (you're offline, or the build has reporting unconfigured), the popup offers "Copy Report" instead — it puts the full report on the clipboard so you can paste it into the website feedback form or an email.

Heads up

Because this is alpha, some areas (M610 cutting, the Brother models) are only partially verified or still unverified — mention if your issue is in one of those areas so it's triaged correctly.

A report carries your contact info and the app's recent log so the developer can diagnose and follow up — don't put anything in the description you wouldn't email.