This commit is contained in:
2026-09-09 17:35:23 +08:00
parent 2a98ae7556
commit 161af68fe3
1271 changed files with 58251 additions and 98639 deletions
@@ -0,0 +1,273 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>NcFileCommand Panel (Program File) | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="NcFileCommand Panel (Program File) | HiAPI-C# 2025 ">
<link rel="icon" href="../../../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../../../public/docfx.min.css">
<link rel="stylesheet" href="../../../public/main.css">
<meta name="docfx:navrel" content="../../../toc.html">
<meta name="docfx:tocrel" content="toc.html">
<meta name="docfx:rel" content="../../../">
<meta name="loc:inThisArticle" content="In this article">
<meta name="loc:searchResultsCount" content="{count} results for &quot;{query}&quot;">
<meta name="loc:searchNoResults" content="No results for &quot;{query}&quot;">
<meta name="loc:tocFilter" content="Filter by title">
<meta name="loc:nextArticle" content="Next">
<meta name="loc:prevArticle" content="Previous">
<meta name="loc:themeLight" content="Light">
<meta name="loc:themeDark" content="Dark">
<meta name="loc:themeAuto" content="Auto">
<meta name="loc:changeTheme" content="Change theme">
<meta name="loc:copy" content="Copy">
<meta name="loc:downloadPdf" content="Download PDF">
<script type="module" src="./../../../public/docfx.min.js"></script>
<script>
const theme = localStorage.getItem('theme') || 'auto'
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
</script>
</head>
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
<header class="bg-body border-bottom">
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
<div class="container-xxl flex-nowrap">
<a class="navbar-brand" href="../../../index.html">
<img id="logo" class="svg" src="../../../img/HiAPI.logo.png" alt="">
</a>
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
<i class="bi bi-three-dots"></i>
</button>
<div class="collapse navbar-collapse" id="navpanel">
<div id="navbar">
<form class="search" role="search" id="search">
<i class="bi bi-search"></i>
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
</form>
</div>
</div>
</div>
</nav>
</header>
<main class="container-xxl">
<div class="toc-offcanvas">
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<nav class="toc" id="toc"></nav>
</div>
</div>
</div>
<div class="content">
<div class="actionbar">
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
<i class="bi bi-list"></i>
</button>
<nav id="breadcrumb"></nav>
</div>
<article data-uid="Anatomy-NcFileCommandPanel">
<h1 id="ncfilecommand-panel-program-file">NcFileCommand Panel (Program File)</h1>
<p>The key model is <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html">NcFileCommand</a>.</p>
<p>The command carries exactly two values: <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html#Hi_SessionCommands_NcFileCommand_NcFile">NcFile</a>, the path of
the program to play, and <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html#Hi_SessionCommands_NcFileCommand_NcKind">NcKind</a>, the runner that plays it.
The program text stays a file on disk — the project stores the path and nothing else, which is what
separates this command from <a class="xref" href="NcCodeCommand-panel.html">NC Code</a>, whose text is serialized
into the project itself.</p>
<p><code>NcFile</code> is normally a path relative to the project folder — that is what the browse dialog yields —
and an absolute path on the server is accepted just as well. No base directory is stored with the
command: at play time <a class="xref" href="../../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_RunNcFile_">RunNcFile</a> hands the stored path
together with the project's own base directory to the local project service, and that is where a
relative path acquires its root. The WPF panel's <code>BaseDirectory</code> is the code-behind assistant
property the <a class="xref" href="../../conventions/gui-file-path-assignment.html">Load Pattern</a> asks a file-assigning GUI to carry,
assigned to the panel by its parent — a panel member, not a model member.</p>
<p>The panel renders on the command's own node in the Mission branch of the Execution page's Control
Tree, below the move / duplicate / delete control bar. This command has no title of its own, so the
row and tree label read <code>Program File [path]</code>, the path being the detail the label brackets.</p>
<div class="NOTE">
<h5>Note</h5>
<p>The GUI labels this command &ldquo;Program File&rdquo;: it plays NC, CL (CLSF) and CSV files — the runner is
picked by <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html#Hi_SessionCommands_NcFileCommand_NcKind">NcKind</a>, and
<a class="xref" href="../../../api/Hi.MachiningProcs.NcKind.html#Hi_MachiningProcs_NcKind_Auto">Auto</a> reads it off the extension
(<a class="xref" href="../../../api/Hi.MachiningProcs.NcKindUtil.html#Hi_MachiningProcs_NcKindUtil_DetectByPath_">DetectByPath</a>: <code>.cl</code>, <code>.cls</code> and <code>.clsf</code> play as CL, <code>.csv</code>
as CSV, and every other extension as brand NC).</p>
</div>
<h2 id="layout">Layout</h2>
<ul>
<li>NcFileCommand Panel
<ul>
<li>Head Line
<ul>
<li>Program File Path Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html#Hi_SessionCommands_NcFileCommand_NcFile">NcFile</a>.</li>
<li>Its hint names both accepted forms: an absolute path on the server, or a path relative to
the project folder.</li>
<li>Every keystroke saves the path. Leaving the field or pressing Enter additionally refreshes
the file-info banner.</li>
<li>The web field flexes to fill the row beside the Browse button at any panel width; the WPF
field is a fixed 200 px column carrying its own label.</li>
</ul>
</li>
<li>Browse Button
<ul>
<li>Opens the shared file-explorer dialog — see <a href="#browsing-for-a-program">Browsing for a Program</a>.</li>
</ul>
</li>
</ul>
</li>
<li>Play As Select
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html#Hi_SessionCommands_NcFileCommand_NcKind">NcKind</a>.</li>
<li>Four choices: Auto (by extension), Brand NC, CL (CLSF) and CSV. The hint restates what Auto
detects, so the runner can be pinned when the extension would route the file elsewhere.</li>
<li>This control is the web client's. The WPF panel ships no kind control, so a project edited
there keeps the kind it already holds — Auto until something else sets it.</li>
</ul>
</li>
<li>File Info Banner
<ul>
<li>Appears once the path field is non-empty. Every fact in it is read on the server.</li>
<li>Found: a green banner stating the file size, its modified stamp and its line count, with a
Preview button in the banner's action slot.</li>
<li>Missing: an orange banner saying the file is not found on the server, and no Preview button.</li>
</ul>
</li>
<li>Preview Dialog
<ul>
<li>Read-only. The server returns the file's first 100 lines and the dialog shows them in a
monospace block that scrolls within 60% of the viewport height, inside a card capped at 80%.
An empty file previews as &quot;(empty)&quot;.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="browsing-for-a-program">Browsing for a Program</h2>
<p>Browse opens the shared server-side file explorer dialog. File reads happen on the server; the
browser never uploads file bytes.</p>
<p>The <a class="xref" href="../../conventions/gui-file-path-assignment.html">Load Pattern</a>'s general web convention offers the Admin,
Project and Resource roots. This picker narrows to one: it opens on the project directory and allows
no other root, so a pick always yields a project-relative path. A file outside the project is
reached by typing its absolute path into the path field, which the server accepts.</p>
<p>The dialog carries four filter groups rather than one catch-all:</p>
<ul>
<li><strong>NC Files</strong> — <code>.nc</code>, <code>.anc</code>, <code>.tap</code>, <code>.eia</code>, <code>.mpf</code>, <code>.spf</code>, <code>.cnc</code>, <code>.ptp</code>, <code>.h</code>. The open set:
brand controller extensions, of which these are the common ones rather than all of them.</li>
<li><strong>CL Files</strong> — <code>.cl</code>, <code>.cls</code>, <code>.clsf</code>.</li>
<li><strong>CSV Files</strong> — <code>.csv</code>.</li>
<li><strong>All Files</strong> — an empty extension list, which is the empty filter the Load Pattern asks every
browser to preserve. It is the backstop for a brand extension the NC group does not name.</li>
</ul>
<p>CL and CSV are split out because they are closed extension sets: those are exactly the extensions
Auto routes to the CL and CSV runners, and everything else falls through to brand NC.</p>
<p>The WPF Browse button opens an <code>OpenFileDialog</code> with the panel's file-filter resource, starting at
the project directory or at the current file's own directory. A pick under the project directory is
stored as a relative path, and a pick outside it as an absolute one.</p>
<h2 id="multi-pick-fan-out">Multi-Pick Fan-Out</h2>
<p>The dialog is multi-select, and this is the one command editor that grows the mission. The first
picked file lands on this command. Each further pick becomes a <strong>new</strong> Program File command, added
to the list this command sits in and moved into place directly after it, in pick order — the same
list, so a command inside a nested list fans out inside that nested list. The panel then reports a
structure change, which rebuilds the owning list's branch around the new rows and leaves the
selection on this command.</p>
<h2 id="where-the-program-text-is-edited">Where the Program Text Is Edited</h2>
<p>The two clients part company here, and the command is the same either way: it stores a path.</p>
<ul>
<li><strong>Web</strong> — the panel does not edit the file. It assigns the path, picks the runner, reports what
the server knows about the file, and previews its first 100 lines read-only. Nothing in the
browser writes NC bytes back; the two file endpoints this panel calls are both reads.</li>
<li><strong>WPF</strong> — the panel opens the file. A non-text file, or one the panel cannot find, disables the
editor and states why in the Head Message Place above it. A text file within 20000 lines opens for
editing, with its line count in the group-box header; a longer one shows its first 20000 lines
read-only and warns in the Head Message Place. Two seconds after the last keystroke the editor
writes the file back, and reports the save in that same message place. The editor is AvalonEdit
with line numbers where that assembly resolves, and a plain Consolas text box otherwise.</li>
</ul>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p>
<h3 id="web-application">Web Application</h3>
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
<ul>
<li><code>wwwroot-src/src/components/mission/NcFileCommandPanel.vue</code> — this panel: the path field and
Browse, the &ldquo;Play As&rdquo; kind select, the file-info banner and its Preview button, the read-only
preview dialog, the four filter groups, and the multi-pick fan-out.</li>
<li><code>wwwroot-src/src/components/widgets/FileExplorerDialog.vue</code> — the shared server-side browser
Browse opens: the pickable / multi / filters / initial-root / allowed-roots props, and the pick
event whose emitted strings pair a root name with a relative path — that relative half is what the
command stores.</li>
<li><code>wwwroot-src/src/components/widgets/fileFilter.ts</code> — the filter shape the four groups are built
from; an empty extension list means all files.</li>
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — maps the <code>ncfile</code> kind to this
panel. A kind absent from that map is served by the generic field editor instead.</li>
<li><code>wwwroot-src/src/api/mission.ts</code> — <code>loadNcFile</code>, <code>setNcFilePath</code>, <code>setNcFileNcKind</code>,
<code>getNcFileInfo</code> and <code>previewNcFile</code>, plus the kind union and the file-info shape.</li>
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: the path hint, the Play As hint, the
four filter labels, the banner's found and not-found lines, and the preview titles.</li>
<li><code>Missions/MissionController.cs</code> — four endpoints serve this command: a PUT for the path, a PUT for
the NC kind, and the two server-side reads behind the banner and the preview (both POSTs, both
resolving a relative path against the project folder). The command-snapshot builder emits the file
path and the NC kind for this kind of command.</li>
</ul>
<h3 id="hiapi-engine">HiAPI Engine</h3>
<ul>
<li><code>HiNc/SessionCommands/NcFileCommand.cs</code> — the model: <code>NcFile</code>, <code>NcKind</code> defaulting to Auto, the
&ldquo;Program File&rdquo; display name and its Program-category catalog registration, the XML round-trip that
writes the path verbatim, the <code>Program File [path]</code> row label, and <code>Run</code> handing path and kind to
the session shell.</li>
<li><code>HiMech/MachiningProcs/NcKind.cs</code> — the kind enum (Auto / BrandNc / Cl / Csv) and the
detect-by-path helper, the authority for what Auto does.</li>
<li><code>HiNc/MachiningProcs/SessionShell.cs</code> — <code>RunNcFile</code> passes the stored path together with the
project's base directory to the local project service.</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="NcCodeCommand-panel.html">NcCodeCommand Panel</a> — the other Program command: NC text stored in the project instead of a path to a file</li>
<li><a href="../../../manual/run/playing-a-program.html">Playing a Program</a> — the task these two commands serve</li>
<li><a href="index.html">Mission</a> — the rest of the command panels</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></div>
</div>
<div class="affix">
<nav id="affix"></nav>
</div>
</main>
<div class="container-xxl search-results" id="search-results"></div>
<footer class="border-top text-secondary">
<div class="container-xxl">
<div class="flex-fill">
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
</div>
</div>
</footer>
</body>
</html>