init
This commit is contained in:
216
enriched-qwen3-coder-next/DataPRO/CanFDApiProxy.md
Normal file
216
enriched-qwen3-coder-next/DataPRO/CanFDApiProxy.md
Normal file
@@ -0,0 +1,216 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/CanFDApiProxy/Protocol.cs
|
||||
- DataPRO/CanFDApiProxy/CanApiException.cs
|
||||
- DataPRO/CanFDApiProxy/HttpClientFactory.cs
|
||||
- DataPRO/CanFDApiProxy/CommandName.cs
|
||||
- DataPRO/CanFDApiProxy/RESTWrapper.cs
|
||||
- DataPRO/CanFDApiProxy/CANFD.cs
|
||||
generated_at: "2026-04-16T03:47:56.020895+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "39cf8ff3a187bfe6"
|
||||
---
|
||||
|
||||
# CANFDApiProxy Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a C# client-side API proxy for interacting with a remote CAN FD device’s RESTful HTTP/HTTPS API. It encapsulates low-level HTTP communication, request/response serialization, and error handling to expose a strongly-typed, asynchronous interface for retrieving and setting device configuration, status, and diagnostic data (e.g., CAN bus state, LEDs, serial number, file operations). It serves as the primary integration point for applications needing programmatic access to the device’s REST endpoints, abstracting away the underlying JSON/HTTP mechanics and enforcing consistent error handling via `CanApiException`.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `CANFD` (Singleton Class)
|
||||
|
||||
The main public entry point. Exposes asynchronous methods for GET and POST operations against device endpoints.
|
||||
|
||||
#### Public Methods
|
||||
|
||||
- **`public static CANFD API { get; }`**
|
||||
Gets the singleton instance of the `CANFD` class.
|
||||
|
||||
- **`public async Task<UsbTreeMessage> GetUsbTree(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves USB tree topology from the device via `GET /usb-tree`.
|
||||
|
||||
- **`public async Task<BatteryMessage> GetBattery(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves battery status via `GET /battery`.
|
||||
|
||||
- **`public async Task<DiagnosticMessageRow[]> GetBIST(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves Built-In Self-Test (BIST) results via `POST /diagnostics` with `{"format":"csv"}`; parses CSV response into `DiagnosticMessageRow[]`.
|
||||
|
||||
- **`public async Task<CalibrationMessage> GetCalibrationDate(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves calibration date via `GET /calibration-date`.
|
||||
|
||||
- **`public async Task<SerialMessage> GetSerial(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves device serial number via `GET /serial`.
|
||||
|
||||
- **`public async Task<LEDsMessage> GetLEDs(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves LED status (color, state) for CAN1–CAN4 and device-level status flags (`Status`, `Battery`, `Pwr`, `Sts`) via `GET /leds`. Internally deserializes `CANInfoInternal` and constructs `LEDsMessage`.
|
||||
|
||||
- **`public async Task<CANInfoMessage> GetCANInfo(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves CAN interface info (e.g., mode, bitrate) for CAN1–CAN4 via `GET /can-info`.
|
||||
|
||||
- **`public async Task<CANStateMessage> GetCANState(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves CAN interface state (e.g., active, error-active) and last update timestamp for CAN1–CAN4 via `GET /can-state`.
|
||||
|
||||
- **`public async Task<CANStatsMessage> GetCANStats(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves CAN interface statistics (STD/EXT frames, errors, overruns, bus load) for CAN1–CAN4 via `GET /can-stats`.
|
||||
|
||||
- **`public async Task<CANConfigMessage> GetCANConfig(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves CAN interface configuration (bitrates, SJW, FD flags, included status) for CAN1–CAN4 and `Pipe` via `GET /can-config`.
|
||||
|
||||
- **`public async Task<DeviceInfoMessage> GetDeviceInfo(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves device hardware/software info via `GET /device-info`.
|
||||
|
||||
- **`public async Task<NtpMessage> GetNtp(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves NTP configuration/status via `GET /ntp`.
|
||||
|
||||
- **`public async Task<PowerMessage> GetPower(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves power state via `GET /power`.
|
||||
|
||||
- **`public async Task<ServicesMessage> GetServices(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves enabled services via `GET /services`.
|
||||
|
||||
- **`public async Task<NetworkMessage> GetNetwork(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves network configuration via `GET /network`.
|
||||
|
||||
- **`public async Task<ClocksMessage> GetClocks(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves clock/time info via `GET /clocks`.
|
||||
|
||||
- **`public async Task<EventPinMessage> GetEventPin(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves event pin configuration/status via `GET /event-pin`.
|
||||
|
||||
- **`public async Task<RecordingMessage> GetRecording(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves recording status via `GET /recording`.
|
||||
|
||||
- **`public async Task<UsbStatsMessage> GetUsbStats(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Retrieves USB statistics via `GET /usb-stats`.
|
||||
|
||||
- **`public async Task<SerialMessage> SetSerial(string deviceHost, SerialRequest serialRequest, CancellationToken cancellationToken)`**
|
||||
Sets device serial number via `POST /serial`.
|
||||
|
||||
- **`public async Task<PowerMessage> SetPowerOff(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Powers off device via `POST /power` with `{"cmd":"off"}`.
|
||||
|
||||
- **`public async Task<PowerMessage> SetPowerReboot(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Reboots device via `POST /power` with `{"cmd":"reboot"}`.
|
||||
|
||||
- **`public async Task<CANConfigMessage> SetCANConfig(string deviceHost, CANConfigRequest canConfigRequest, CancellationToken cancellationToken)`**
|
||||
Configures CAN interface(s) via `POST /can-config`.
|
||||
|
||||
- **`public async Task<LEDsPostMessage> SetLEDs(string deviceHost, LedName led, LedCmd cmd, LedColor color, CancellationToken cancellationToken)`**
|
||||
Controls LED via `POST /leds` with `{"led":"...", "cmd":"...", "color":"..."}`.
|
||||
|
||||
- **`public async Task<ClocksMessage> SetClocks(string deviceHost, DateTime dateTime, CancellationToken cancellationToken)`**
|
||||
Sets device clock via `POST /clocks` with `{"cmd":"set", "time":"yyyy-MM-dd HH:mm:ss"}`.
|
||||
|
||||
- **`public async Task<ClocksMessage> SyncClocks(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Syncs device clock via `POST /clocks` with `{"cmd":"sync"}`.
|
||||
|
||||
- **`public async Task<RecordingMessage> SetRecordingStart(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Starts recording via `POST /recording` with `{"cmd":"start"}`.
|
||||
|
||||
- **`public async Task<RecordingMessage> SetRecordingTriggerCheck_Quick(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Performs quick trigger check via `POST /recording` with `{"cmd":"triggercheck_quick"}`.
|
||||
|
||||
- **`public async Task<RecordingMessage> SetRecordingStop(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Stops recording via `POST /recording` with `{"cmd":"stop"}`.
|
||||
|
||||
- **`public async Task<NetworkMessage> SetNetwork(string deviceHost, NetworkRequest networkRequest, CancellationToken cancellationToken)`**
|
||||
Sets network configuration via `POST /network`.
|
||||
|
||||
- **`public async Task<EventPinMessage> SetEventPinArm(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Arms event pin via `POST /event-pin` with `{"cmd":"arm"}`.
|
||||
|
||||
- **`public async Task<EventPinMessage> SetEventPinDisarm(string deviceHost, CancellationToken cancellationToken)`**
|
||||
Disarms event pin via `POST /event-pin` with `{"cmd":"disarm"}`.
|
||||
|
||||
- **`public async Task<StatusMessage> Delete(string deviceHost, string usbPath, CancellationToken cancellationToken)`**
|
||||
Deletes file/directory on device via `POST /file` with `{"cmd":"delete", "path":"..."}`. Validates `usbPath` is non-null/empty.
|
||||
|
||||
- **`public async Task Download(string deviceHost, string usbPath, string destinationDirectory, TimeSpan timeOut, CancellationToken cancellationToken)`**
|
||||
Downloads file/directory (as `.zip` if directory) from device to local path. Validates `usbPath`, `destinationDirectory`, and that `destinationDirectory` exists. Uses `POST /file` with `{"cmd":"download", "path":"..."}` and reads response as stream.
|
||||
|
||||
- **`public async Task<StatusMessage> Upload(string deviceHost, string uploadUsbPath, string sourcefile, TimeSpan timeOut, CancellationToken cancellationToken)`**
|
||||
Uploads local file to device via `POST /file` with multipart form data (`cmd=upload`, `path=uploadUsbPath`, `file=<bytes>`). Validates `uploadUsbPath`, `sourcefile`, and that `sourcefile` exists.
|
||||
|
||||
### Supporting Types (Internal)
|
||||
|
||||
- **`RESTWrapper` (internal static class)**
|
||||
Encapsulates HTTP communication logic.
|
||||
|
||||
- `public static int Port { get; set; } = 5000`
|
||||
Default port for API calls.
|
||||
- `public static Protocol Protocol { get; set; } = Protocol.http`
|
||||
Protocol used (`http` or `https`).
|
||||
- `public static TimeSpan Timeout { get; set; } = 30s`
|
||||
Default HTTP timeout.
|
||||
- `public static async Task<string> GetResourceAsync(...)`
|
||||
Performs GET request; throws `CanApiException` on non-2xx status (including deserialized error message).
|
||||
- `public static async Task<string> PostResourceAsync<T>(...)`
|
||||
Performs JSON POST request; throws `CanApiException` on non-2xx status.
|
||||
- `public static async Task<Stream> SendResourceReadAsStreamAsync<T>(...)`
|
||||
Performs POST request and returns response as `Stream` (for large downloads).
|
||||
- `public static async Task<string> PostResourceReadAsStringAsync(...)`
|
||||
Performs multipart form POST and returns response as `string`.
|
||||
- `public static async Task WriteStreamToFileAsync(Stream inputStream, string filePath)`
|
||||
Writes stream to file.
|
||||
|
||||
- **`HttpClientFactory` (internal static class)**
|
||||
Creates configured `HttpClient` instances.
|
||||
|
||||
- `public static HttpClient CreateHttpClient()`
|
||||
Returns a new `HttpClient` with `Accept: application/json` header and cleared default headers.
|
||||
|
||||
- **`CanApiException` (public class)**
|
||||
Custom exception for API errors.
|
||||
|
||||
- `public int? StatusCode { get; set; }`
|
||||
HTTP status code if available.
|
||||
- Constructors: `(string, Exception)`, `(string, int)`.
|
||||
|
||||
- **`Protocol` (public enum)**
|
||||
`http`, `https`.
|
||||
|
||||
- **`CommandName` (internal enum)**
|
||||
Maps logical command names to REST endpoint paths (via `DescriptionAttribute`):
|
||||
- `Serial`, `LEDs`, `Battery`, `CalibrationDate`, `CANInfo`, `CANState`, `CANStats`, `CANConfig`, `DeviceInfo`, `Ntp`, `Power`, `Services`, `Network`, `Clocks`, `EventPin`, `Recording`, `UsbStats`, `UsbTree`, `File`, `Diagnostics`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Host Validation**: All public methods in `CANFD` and `RESTWrapper` require `deviceHost` to be non-null/non-empty; otherwise, `ArgumentNullException` is thrown.
|
||||
- **Path Validation**: `Delete`, `Download`, and `Upload` methods require `usbPath`/`sourcefile`/`destinationDirectory` to be non-null/non-empty and, where applicable, exist on the filesystem.
|
||||
- **Timeout Isolation**: `Download` and `Upload` temporarily override `RESTWrapper.Timeout` and restore it in a `finally` block.
|
||||
- **Error Handling**: Non-2xx HTTP responses trigger `CanApiException` with status code and deserialized error message (if available). Specific handling for `400`, `403`, `404`, `500`, `503`.
|
||||
- **JSON Content-Type**: All POST requests use `application/json` or `multipart/form-data` as appropriate.
|
||||
- **Protocol Consistency**: All endpoints use the same `Protocol` and `Port` (configurable at class level).
|
||||
- **CancellationToken Propagation**: All async methods accept and propagate `CancellationToken`; cancellation results in `CanApiException` with message `"An API call was cancelled or timedout"`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Dependencies
|
||||
- **`Microsoft.Extensions.Http`**: Used via `IHttpClientFactory` in `HttpClientFactory`.
|
||||
- **`Newtonsoft.Json`**: Used for JSON serialization/deserialization (`JsonConvert.DeserializeObject<T>`, `PostAsJsonAsync`).
|
||||
- **`CsvHelper`**: Used in `GetBIST` to parse CSV responses.
|
||||
- **`System.Net.Http`**: Core HTTP client functionality.
|
||||
- **`System.IO`**: File/stream operations (`FileStream`, `File.ReadAllBytes`, `CopyToAsync`).
|
||||
|
||||
### Internal Dependencies
|
||||
- **`CANFDApiProxy.Messages`**: Contains response message types (e.g., `UsbTreeMessage`, `BatteryMessage`, `StatusMessage`, `LEDsPostMessage`, `CANConfigMessage`, etc.).
|
||||
- **`CANFDApiProxy.Requests`**: Contains request types (e.g., `SerialRequest`, `CANConfigRequest`, `LEDsRequest`, `FileRequest`, `NetworkRequest`, `ClocksRequest`, `CanPostRequest`).
|
||||
- **`CANFDApiProxy.Interfaces`**: `ICANFDApi` interface implemented by `CANFD`.
|
||||
|
||||
### Inferred Consumers
|
||||
- Any application or library requiring programmatic access to the CAN FD device’s REST API (e.g., test harnesses, UI clients, logging services).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`RESTWrapper.Timeout` is global state**: Changing `RESTWrapper.Timeout` affects all subsequent calls until changed again. `Download`/`Upload` temporarily override it, but concurrent calls may interfere.
|
||||
- **`CANInfoInternal` is an internal implementation detail**: `GetLEDs`, `GetCANInfo`, `GetCANState`, `GetCANStats`, and `GetCANConfig` all deserialize the same internal type (`CANInfoInternal`) and manually construct the public message types. Changes to the device’s `/leds`, `/can-info`, etc., response structure may break these methods.
|
||||
- **`IsDirectory` heuristic is flawed**: `CANFD.IsDirectory` uses `Path.GetExtension(fileOrDirectory)` to infer directory vs. file. This is unreliable (e.g., directories without extensions, files with no extension). The `BuildFilePath` logic assumes directories end with `/` or lack an extension, but this may not match the device’s behavior.
|
||||
- **`GetBIST` CSV parsing is fragile**: Uses `CsvHelper` with `PrepareHeaderForMatch` to lowercase headers. Assumes device CSV headers match `DiagnosticMessageRow` property names case-insensitively; any mismatch will cause silent failures or exceptions.
|
||||
- **`PostAsJsonAsync` uses `PostAsJsonAsync` extension**: Relies on `System.Net.Http.Json` extension (not shown in source), which may not be available in all environments.
|
||||
- **`WriteStreamToFileAsync` resets stream position**: Only resets if `inputStream.CanSeek`; otherwise, it may start from current position.
|
||||
- **No retry logic**: Transient network errors or server overload are not retried; callers must implement retry policies.
|
||||
- **`Protocol` enum is lowercase**: `Protocol.http` → `"http"` (via `ToString()`), but HTTP/HTTPS schemes are case-insensitive per RFC. This is consistent but non-standard (typically `"HTTP"`/`"HTTPS"`).
|
||||
- **`CommandName.DescriptionAttr` is internal**: Only used internally; external consumers cannot leverage this enum mapping directly.
|
||||
113
enriched-qwen3-coder-next/DataPRO/CanFDApiProxy/Interfaces.md
Normal file
113
enriched-qwen3-coder-next/DataPRO/CanFDApiProxy/Interfaces.md
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/CanFDApiProxy/Interfaces/ICANFDApi.cs
|
||||
generated_at: "2026-04-16T04:03:01.127013+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "b35bfae408176fa6"
|
||||
---
|
||||
|
||||
# Interfaces
|
||||
|
||||
## Documentation Page: `ICANFDApi` Interface
|
||||
|
||||
---
|
||||
|
||||
### **1. Purpose**
|
||||
|
||||
The `ICANFDApi` interface defines the contract for a proxy layer that abstracts communication with a remote CANFD device (e.g., a hardware diagnostic or data acquisition unit). It provides a standardized set of asynchronous methods to *retrieve* (GET) and *modify* (SET) device state and configuration across multiple subsystems—including USB, serial, LEDs, clocks, CAN bus, power, battery, network, recording, and event pins—while also supporting file operations (download, upload, delete) over USB. This interface decouples client code from transport-specific implementation details (e.g., HTTP, serial, or custom protocol), enabling testability and modularity in the broader system.
|
||||
|
||||
---
|
||||
|
||||
### **2. Public Interface**
|
||||
|
||||
All methods are `async` and return `Task<T>` where `T` is a specific message type defined in `CANFDApiProxy.Messages`. Each method accepts a `deviceHost` (string, likely an IP or hostname) and a `CancellationToken`.
|
||||
|
||||
#### **GET Methods (Read-Only Queries)**
|
||||
|
||||
| Method | Return Type | Description |
|
||||
|--------|-------------|-------------|
|
||||
| `GetUsbTree(string deviceHost, CancellationToken ct)` | `Task<UsbTreeMessage>` | Retrieves the USB device tree (e.g., connected USB devices and their hierarchy). |
|
||||
| `GetUsbStats(string deviceHost, CancellationToken ct)` | `Task<UsbStatsMessage>` | Retrieves USB statistics (e.g., throughput, errors). |
|
||||
| `GetSerial(string deviceHost, CancellationToken ct)` | `Task<SerialMessage>` | Retrieves current serial port configuration/settings. |
|
||||
| `GetLEDs(string deviceHost, CancellationToken ct)` | `Task<LEDsMessage>` | Retrieves current LED states (e.g., on/off, color). |
|
||||
| `GetClocks(string deviceHost, CancellationToken ct)` | `Task<ClocksMessage>` | Retrieves current clock/time settings. |
|
||||
| `GetEventPin(string deviceHost, CancellationToken ct)` | `Task<EventPinMessage>` | Retrieves current configuration/state of the event pin (e.g., armed/disarmed, trigger mode). |
|
||||
| `GetCANConfig(string deviceHost, CancellationToken ct)` | `Task<CANConfigMessage>` | Retrieves current CAN bus configuration (e.g., bitrate, mode). |
|
||||
| `GetCANInfo(string deviceHost, CancellationToken ct)` | `Task<CANInfoMessage>` | Retrieves static CAN hardware info (e.g., controller type, supported modes). |
|
||||
| `GetCANState(string deviceHost, CancellationToken ct)` | `Task<CANStateMessage>` | Retrieves dynamic CAN bus state (e.g., error states, active/inactive). |
|
||||
| `GetCANStats(string deviceHost, CancellationToken ct)` | `Task<CANStatsMessage>` | Retrieves CAN bus statistics (e.g., frames sent/received, errors). |
|
||||
| `GetBattery(string deviceHost, CancellationToken ct)` | `Task<BatteryMessage>` | Retrieves battery status (e.g., voltage, charge level, health). |
|
||||
| `GetServices(string deviceHost, CancellationToken ct)` | `Task<ServicesMessage>` | Retrieves list of running/available services on the device. |
|
||||
| `GetNtp(string deviceHost, CancellationToken ct)` | `Task<NtpMessage>` | Retrieves NTP (network time protocol) configuration/status. |
|
||||
| `GetPower(string deviceHost, CancellationToken ct)` | `Task<PowerMessage>` | Retrieves current power state (e.g., AC/battery, power mode). |
|
||||
| `GetDeviceInfo(string deviceHost, CancellationToken ct)` | `Task<DeviceInfoMessage>` | Retrieves device identification and firmware info (e.g., model, serial, version). |
|
||||
| `GetRecording(string deviceHost, CancellationToken ct)` | `Task<RecordingMessage>` | Retrieves recording status (e.g., running/stopped, file path, duration). |
|
||||
| `GetNetwork(string deviceHost, CancellationToken ct)` | `Task<NetworkMessage>` | Retrieves network interface configuration (e.g., IP, gateway, DNS). |
|
||||
|
||||
#### **SET Methods (State Modifications)**
|
||||
|
||||
| Method | Return Type | Parameters | Description |
|
||||
|--------|-------------|------------|-------------|
|
||||
| `SetSerial(string deviceHost, SerialRequest request, CancellationToken ct)` | `Task<SerialMessage>` | `SerialRequest` | Updates serial port configuration and returns the new state. |
|
||||
| `SetLEDs(string deviceHost, LedName led, LedCmd cmd, LedColor color, CancellationToken ct)` | `Task<LEDsPostMessage>` | `LedName`, `LedCmd`, `LedColor` | Sets a specific LED (`led`) to a command (`cmd`, e.g., ON/OFF/BLINK) and color (`color`). Returns updated LED state. |
|
||||
| `SetClocks(string deviceHost, DateTime dateTime, CancellationToken ct)` | `Task<ClocksMessage>` | `DateTime` | Sets the device clock to `dateTime` and returns updated clock state. |
|
||||
| `SetEventPinArm(string deviceHost, CancellationToken ct)` | `Task<EventPinMessage>` | — | Arms the event pin (e.g., enables triggering on external events). |
|
||||
| `SetEventPinDisarm(string deviceHost, CancellationToken ct)` | `Task<EventPinMessage>` | — | Disarms the event pin (e.g., disables triggering). |
|
||||
| `SyncClocks(string deviceHost, CancellationToken ct)` | `Task<ClocksMessage>` | — | Triggers clock synchronization (e.g., via NTP or PTP) and returns updated clock state. |
|
||||
| `SetCANConfig(string deviceHost, CANConfigRequest request, CancellationToken ct)` | `Task<CANConfigMessage>` | `CANConfigRequest` | Updates CAN bus configuration and returns the new state. |
|
||||
| `SetPowerOff(string deviceHost, CancellationToken ct)` | `Task<PowerMessage>` | — | Initiates device power-off sequence. Returns final power state. |
|
||||
| `SetPowerReboot(string deviceHost, CancellationToken ct)` | `Task<PowerMessage>` | — | Initiates device reboot. Returns final power state. |
|
||||
| `SetRecordingStart(string deviceHost, CancellationToken ct)` | `Task<RecordingMessage>` | — | Starts data recording and returns updated recording status. |
|
||||
| `SetRecordingStop(string deviceHost, CancellationToken ct)` | `Task<RecordingMessage>` | — | Stops data recording and returns updated recording status. |
|
||||
| `SetNetwork(string deviceHost, NetworkRequest request, CancellationToken ct)` | `Task<NetworkMessage>` | `NetworkRequest` | Updates network configuration and returns the new state. |
|
||||
|
||||
#### **File Operations**
|
||||
|
||||
| Method | Return Type | Parameters | Description |
|
||||
|--------|-------------|------------|-------------|
|
||||
| `Download(string deviceHost, string usbPath, string destinationDirectory, TimeSpan timeOut, CancellationToken ct)` | `Task` | `usbPath`, `destinationDirectory`, `timeOut` | Downloads a file from the device’s USB storage (`usbPath`) to the host’s `destinationDirectory`. Throws on timeout (`timeOut`). |
|
||||
| `Upload(string deviceHost, string uploadUsbPath, string sourcefile, TimeSpan timeOut, CancellationToken ct)` | `Task<StatusMessage>` | `uploadUsbPath`, `sourcefile`, `timeOut` | Uploads `sourcefile` to the device’s USB storage at `uploadUsbPath`. Returns a `StatusMessage` indicating success/failure. |
|
||||
| `Delete(string deviceHost, string usbPath, CancellationToken ct)` | `Task<StatusMessage>` | `usbPath` | Deletes the file at `usbPath` on the device’s USB storage. Returns a `StatusMessage`. |
|
||||
|
||||
> **Note**: `LedName`, `LedCmd`, and `LedColor` are enums (defined elsewhere) specifying LED identifiers, commands (e.g., `On`, `Off`, `Toggle`), and colors (e.g., `Red`, `Green`, `Blue`). `SerialRequest`, `CANConfigRequest`, and `NetworkRequest` are request DTOs (defined in `CANFDApiProxy.Requests`) containing structured configuration data.
|
||||
|
||||
---
|
||||
|
||||
### **3. Invariants**
|
||||
|
||||
- **Consistent `deviceHost` usage**: All methods require a `deviceHost` string identifying the target device; this must be a valid address (e.g., IP or hostname) resolvable by the underlying transport.
|
||||
- **Cancellation propagation**: All methods accept a `CancellationToken`; implementations must respect cancellation and propagate it to underlying I/O operations.
|
||||
- **Timeout handling for file ops**: `Download`, `Upload`, and `Delete` accept a `TimeSpan timeOut`; operations exceeding this duration must fail (e.g., via `OperationCanceledException` or `TimeoutException`).
|
||||
- **Idempotency not guaranteed**: SET methods may have side effects (e.g., reboot, start/stop recording); repeated calls may not be idempotent (e.g., calling `SetPowerOff` twice may not be safe).
|
||||
- **State consistency**: GET methods return the *current* device state at the time of the call; SET methods return the *new* state after applying the change.
|
||||
|
||||
---
|
||||
|
||||
### **4. Dependencies**
|
||||
|
||||
#### **Internal Dependencies**
|
||||
- **Namespaces**:
|
||||
- `CANFDApiProxy.Messages` — Defines response message types (e.g., `UsbTreeMessage`, `StatusMessage`, `LEDsMessage`).
|
||||
- `CANFDApiProxy.Requests` — Defines request DTOs (e.g., `SerialRequest`, `CANConfigRequest`, `NetworkRequest`).
|
||||
- **System namespaces**: `System`, `System.Threading`, `System.Threading.Tasks` — Standard .NET async/await and cancellation support.
|
||||
|
||||
#### **External Dependencies (Inferred)**
|
||||
- **Transport layer**: Not specified in the interface, but implementations (e.g., `CANFDApi` class) likely depend on HTTP clients, serial ports, or custom socket protocols.
|
||||
- **Serialization**: JSON or binary serialization may be used for requests/responses (not visible here, but implied by DTO usage).
|
||||
- **Consumers**: Any module requiring device control (e.g., UI, automation scripts, logging services) would depend on this interface (via DI or direct reference).
|
||||
|
||||
---
|
||||
|
||||
### **5. Gotchas**
|
||||
|
||||
- **No validation on `usbPath`/`destinationDirectory`**: The interface accepts arbitrary strings for file paths; implementations must handle path traversal, permissions, or invalid paths (e.g., `../secret.bin`).
|
||||
- **`SetLEDs` uses discrete parameters**: Unlike other SET methods that take a request DTO, `SetLEDs` uses primitive parameters (`LedName`, `LedCmd`, `LedColor`). This may indicate legacy design or a simple, fixed API surface for LEDs.
|
||||
- **`SyncClocks` vs `SetClocks`**: Two distinct clock-setting methods exist:
|
||||
- `SetClocks` sets an *explicit* `DateTime`.
|
||||
- `SyncClocks` triggers *automatic* sync (e.g., via NTP). Confusing usage may lead to unintended time overrides.
|
||||
- **No error details in return types**: Most methods return *state* messages (e.g., `PowerMessage`, `RecordingMessage`) but not explicit error payloads. Failures likely manifest as exceptions (e.g., `HttpRequestException`, `TimeoutException`), not `StatusMessage` with error codes.
|
||||
- **`Download` returns `void`**: Unlike `Upload`/`Delete`, `Download` returns `Task` (no `StatusMessage`). Clients must infer success/failure via exception handling only.
|
||||
- **No batch operations**: Each GET/SET call is atomic; no support for bulk updates (e.g., setting multiple LEDs in one call).
|
||||
|
||||
> **None identified from source alone** for other categories (e.g., thread-safety, ordering guarantees).
|
||||
129
enriched-qwen3-coder-next/DataPRO/CanFDApiProxy/Messages.md
Normal file
129
enriched-qwen3-coder-next/DataPRO/CanFDApiProxy/Messages.md
Normal file
@@ -0,0 +1,129 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/CanFDApiProxy/Messages/StatusMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/ErrorMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/NtpMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/LEDsPostMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/DiagnosticsMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/ClocksMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/DeviceInfoMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/SerialMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/ServicesMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/NetworkMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/CalibrationMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/CANInfoMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/UsbTreeMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/BatteryMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/RecordingMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/PowerMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/EventPinMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/CANStateMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/LEDsMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/CANStatsMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/CANConfigMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/UsbStatsMessage.cs
|
||||
- DataPRO/CanFDApiProxy/Messages/CANInfoInternal.cs
|
||||
generated_at: "2026-04-16T04:02:31.640911+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "7eb2e08a0b1b3deb"
|
||||
---
|
||||
|
||||
# CANFDApiProxy.Messages Module Documentation
|
||||
|
||||
---
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module defines a set of data transfer objects (DTOs) used for serializing and deserializing JSON payloads exchanged with the CANFD API proxy service. These message classes represent structured responses and requests for device status, configuration, diagnostics, hardware state (e.g., LEDs, power, battery, clocks), network settings, CAN bus statistics, USB device tree, and calibration data. They serve as the contract between the API proxy layer and higher-level components (e.g., UI, logging, control logic), enabling type-safe handling of RESTful or IPC-based communication endpoints.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes reside in the `CANFDApiProxy.Messages` namespace and are `public`. No classes are `internal` in the public interface (though `CANInfoInternal` is declared `internal`, it is not part of the public API surface).
|
||||
|
||||
### Message Classes
|
||||
|
||||
| Class | Properties | Description |
|
||||
|-------|------------|-------------|
|
||||
| `StatusMessage` | `string status` | Generic status response. |
|
||||
| `ErrorMessage` | `string Error` | Error response payload. |
|
||||
| `NtpMessage` | `string Ntp`, `string Fallback` | NTP synchronization status and fallback address. |
|
||||
| `LEDsPostMessage` | `string status`, `string reply` | Response to an LED control POST request. |
|
||||
| `DiagnosticsMessageRequest` | `string format` | Request to retrieve diagnostics in a specified format (e.g., `"json"`, `"text"`). Includes custom `ToString()` override. |
|
||||
| `DeviceInfoMessage` | `string Kernel_version`, `string Os_release`, `string Serial_number`, `string Version_number` | Device firmware and OS metadata. |
|
||||
| `SerialMessage` | `string Serial`, `string Status` | Serial port status and current value. Includes custom `ToString()` override. |
|
||||
| `ServicesMessage` | `Service[] services` | List of managed services with `Enabled`, `Name`, `Status`. |
|
||||
| `NetworkMessage` | `string Current_address`, `bool Dhcp`, `string Interface`, `string Mac_address`, `string Set_address`, `string Ok` | Network interface configuration and status. |
|
||||
| `CalibrationMessage` | `int Calibration_date`, `string Calibration_date_string` | Calibration timestamp (numeric and human-readable). Includes custom `ToString()` override. |
|
||||
| `CANInfoMessage` | `List<CANInfo> CANInfoList` | List of CAN interface info objects (`Name`, `Info`). |
|
||||
| `UsbTreeMessage` | `Child[] children`, `string name`, `string path`, `string type` | Hierarchical USB device tree node. `Child` has same fields and recursive `children`. |
|
||||
| `BatteryMessage` | `decimal LoadV`, `decimal Current`, `decimal Power`, `decimal Percent`, `bool Enable` | Battery telemetry. Includes custom `ToString()` override. |
|
||||
| `RecordingMessage` | `string Recording`, `bool Autoarm`, `string Recording_dir`, `string Ok`, `string Reply` | Recording state and configuration. Includes custom `ToString()` override. |
|
||||
| `PowerMessage` | `bool Battery_enable`, `bool Nvin_pin`, `bool On_pin`, `bool Power_fault`, `string Status` | Power subsystem state. Includes custom `ToString()` override. |
|
||||
| `EventPinMessage` | `bool? Armed`, `bool? Event`, `bool? Event_pin`, `string File_name`, `string Ok`, `string Reply` | Event pin trigger state and file context. Includes custom `ToString()` override. |
|
||||
| `CANStateMessage` | `List<CANState> CANStateList` | List of CAN interface states (`Name`, `string State`, `float Last_updated`). |
|
||||
| `LEDsMessage` | `List<LED> LEDs`, `Battery Battery`, `Pwr Pwr`, `Status Status`, `Sts Sts` | LED states (color per LED), plus global LED groups. `LED` has `Name`, `Red`, `Green`, `Blue`. |
|
||||
| `CANStatsMessage` | `List<CANStats> CANStatsList` | List of CAN interface statistics (`Name`, `Last_updated`, `Std_data`, `Std_remote`, `Ext_data`, `Ext_remote`, `Err_frame`, `Bus_load`, `Overruns`). |
|
||||
| `CANConfigMessage` | `List<CANConfig> CANConfigList`, `Pipe Pipe`, `string Status` | CAN bus configuration for up to 4 interfaces (`CANConfig`), plus pipe path and status. Includes `CreateCanConfigRequest()` factory method (see below). |
|
||||
| `UsbStatsMessage` | `Filesystem Filesystem`, `Swissbit Swissbit`, `Traffic Traffic` | USB storage health and throughput stats. Nested types: `Filesystem`, `Swissbit`, `Lifetime_Info`, `Spare_Block_Info`, `Erase_Info`, `Average_Erase_Count`, `Max_Erase_Count`, `Rated_Erase_Count`, `Traffic`. |
|
||||
|
||||
### Factory Method
|
||||
|
||||
| Method | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `CANConfigMessage.CreateCanConfigRequest` | `static CANConfigRequest CreateCanConfigRequest(CANConfigMessage canConfigMessage)` | Converts a `CANConfigMessage` into a `CANConfigRequest` (from `CANFDApiProxy.Requests`). Maps the first four `CANConfig` entries to `can1`–`can4` fields. Returns a `CANConfigRequest` with `Status` set to exception message on failure. |
|
||||
|
||||
### Helper Classes (Public)
|
||||
|
||||
| Class | Properties | Description |
|
||||
|-------|------------|-------------|
|
||||
| `Service` | `bool Enabled`, `string Name`, `string Status` | Represents a service in `ServicesMessage`. |
|
||||
| `LED` | `string Name`, `bool Red`, `bool Green`, `bool Blue` | Represents a single LED in `LEDsMessage`. |
|
||||
| `CANInfo` | `string Name`, `string Info` | Represents CAN interface info in `CANInfoMessage`. Constructor enforces non-null `name`/`info`. |
|
||||
| `CANState` | `string Name`, `string State`, `float Last_updated` | Represents CAN interface state in `CANStateMessage`. Constructor enforces non-null `name`/`state`. |
|
||||
| `CANStats` | `string Name`, `float Last_updated`, `int Std_data`, `int Std_remote`, `int Ext_data`, `int Ext_remote`, `int Err_frame`, `float Bus_load`, `int Overruns` | Represents CAN interface stats in `CANStatsMessage`. Constructor enforces non-null `name`. |
|
||||
| `CANConfig` | `string Name`, `int Base_or_arb_bitrate`, `int Base_or_arb_sjw`, `int Data_bitrate`, `int Data_sjw`, `string Filetype`, `bool Included`, `bool Is_fd` | Represents CAN interface configuration in `CANConfigMessage`. Constructor enforces non-null `name`/`filetype`. |
|
||||
|
||||
> **Note**: `CANConfigRequest` is imported from `CANFDApiProxy.Requests` and is not defined here. Its structure is inferred from usage in `CreateCanConfigRequest`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Non-null `Name` fields**: In `CANInfo`, `CANState`, `CANStats`, and `CANConfig`, the `Name` property is set via constructor and is read-only (`get;` only), implying it must be non-null at construction and never changed afterward.
|
||||
- **Fixed CAN interface count**: `CANConfigMessage.CreateCanConfigRequest` assumes exactly 4 CAN interfaces (`can1`–`can4`) and accesses `CANConfigArray[0]` through `[3]`. Index out-of-range exceptions will occur if the list has fewer than 4 items.
|
||||
- **Nullable booleans**: Fields like `Armed`, `Event`, `Event_pin`, `Rtc_present`, `Rtc_setup` are declared as `bool?`, indicating they may be absent or unknown.
|
||||
- **Numeric precision**: Battery metrics (`LoadV`, `Current`, `Power`, `Percent`) use `decimal` for precision; CAN stats use `int` for counters and `float` for time/load metrics.
|
||||
- **String formatting**: `Calibration_date` is an `int` (likely Unix epoch), while `Calibration_date_string` provides human-readable form—both must be consistent.
|
||||
- **LED color state**: In `LEDsMessage.LED`, each LED’s color (`Red`, `Green`, `Blue`) is a `bool`, implying binary on/off per channel.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports/References
|
||||
- `System.Collections.Generic` (used in `CANInfoMessage`, `CANStateMessage`, `CANStatsMessage`, `LEDsMessage`)
|
||||
- `System.Text` (used in `CANConfigMessage.ToString()` via `StringBuilder`)
|
||||
- `CANFDApiProxy.Requests` (used in `CANConfigMessage.CreateCanConfigRequest()` to construct `CANConfigRequest`)
|
||||
|
||||
### Inferred Usage
|
||||
- **Serialization**: All classes are simple POCOs with public setters, designed for JSON deserialization (e.g., via `System.Text.Json` or `Newtonsoft.Json`).
|
||||
- **API layer**: These messages are likely consumed/produced by HTTP handlers, gRPC services, or IPC endpoints in `CANFDApiProxy`.
|
||||
- **Request conversion**: `CreateCanConfigRequest` implies tight coupling with `CANFDApiProxy.Requests.CANConfigRequest`, suggesting this module is part of a request/response pipeline.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`CANConfigMessage` assumes 4 CAN interfaces**: Hardcoded array indices `[0]`–`[3]` in `CreateCanConfigRequest` will throw `IndexOutOfRangeException` if the input `CANConfigList` has fewer than 4 items. No validation is performed.
|
||||
- **Inconsistent property casing**: Some properties use `snake_case` (`status`, `Error`, `Calibration_date`, `Current_address`) while others use `PascalCase` (`Kernel_version`, `Serial_number`). This may reflect JSON payload conventions but can cause deserialization issues if not handled consistently (e.g., via `JsonPropertyName` attributes).
|
||||
- **`CANInfoInternal` is internal**: Though defined in the same file, `CANInfoInternal` and its nested types (`Can1`, `Can2`, etc.) are `internal` and not part of the public API. Do not rely on them externally.
|
||||
- **Missing null-safety**: None of the classes perform null checks in constructors or setters. Passing `null` to `CANInfo`/`CANState`/`CANStats`/`CANConfig` constructors will result in `NullReferenceException` at runtime.
|
||||
- **`Calibration_date` type**: `int` for a date is ambiguous—could be Unix timestamp (seconds) or `YYYYMMDD` integer. Clarify with API spec.
|
||||
- **`Ok` vs `status`/`Status`**: Multiple classes use `Ok` (e.g., `NetworkMessage`, `RecordingMessage`, `EventPinMessage`) while others use `status`/`Status`. This inconsistency may indicate legacy naming or different API versions.
|
||||
- **`UsbStatsMessage` complexity**: Deeply nested types (`Lifetime_Info`, `Spare_Block_Info`, etc.) suggest complex SSD health reporting. Ensure all fields are populated before use; missing nested objects may cause `NullReferenceException`.
|
||||
- **`ToString()` overrides**: Several classes override `ToString()` for debugging, but these are not used in serialization. Do not rely on them for logging or persistence.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/CanFDApiProxy/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T04:02:38.399382+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "09de3f64edd0a63b"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module is a .NET assembly named **CANFDApiProxy**, intended to serve as a proxy or wrapper layer for interacting with a CAN FD (Controller Area Network Flexible Data-rate) API—likely the Vector CANoe/CANoe.FD or similar automotive bus communication stack. Its role is to abstract low-level CAN FD operations (e.g., message transmission, reception, channel management) behind a managed .NET interface, enabling integration with higher-level .NET applications (e.g., test automation, simulation, or diagnostics tools) while maintaining compatibility with unmanaged CAN FD driver libraries via COM interop or P/Invoke. The assembly is versioned at `1.0.0.0`, is not visible to COM by default, and is owned by **VPG** (presumably Vector Product Group or a related entity).
|
||||
|
||||
## 2. Public Interface
|
||||
**No public types (classes, interfaces, structs, enums, or delegates) are defined in this file.**
|
||||
The file contains only assembly-level metadata attributes (e.g., `AssemblyTitle`, `AssemblyVersion`, `ComVisible`, `Guid`). It does not declare any executable code, types, or public APIs. Therefore, there are **no public functions, classes, or methods** documented here.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly identity is fixed:
|
||||
- `AssemblyTitle` = `"CANFDApiProxy"`
|
||||
- `AssemblyCompany` = `"VPG"`
|
||||
- `AssemblyCopyright` = `"Copyright © VPG 2025"`
|
||||
- `AssemblyVersion` and `AssemblyFileVersion` = `"1.0.0.0"`
|
||||
- `ComVisible` is set to `false`, meaning types in this assembly are *not* exposed to COM unless explicitly overridden at the type level (though no types are defined here, so this has no runtime effect).
|
||||
- The `Guid` attribute (`0a42ee20-660c-468d-9511-c32c9037cb15`) uniquely identifies the typelib if the assembly *were* exposed to COM (currently disabled).
|
||||
|
||||
## 4. Dependencies
|
||||
- **Runtime dependencies**: This assembly targets the .NET Framework (evidenced by `System.Reflection`, `System.Runtime.CompilerServices`, `System.Runtime.InteropServices`).
|
||||
- **External dependencies**: None directly declared in this file. However, given the name *CANFDApiProxy*, it is strongly implied that this assembly depends on unmanaged CAN FD libraries (e.g., `canfdapi.dll`, `vxlapi_fd.dll`, or Vector’s CANoe API), likely via P/Invoke or COM interop—but such dependencies are not visible in *this* file and must be inferred from other source files (not provided).
|
||||
- **Dependents**: Unknown from this file alone. Presumably consumed by other .NET modules in the VPG ecosystem (e.g., test harnesses, UI applications, or simulation frameworks).
|
||||
|
||||
## 5. Gotchas
|
||||
- **Misleading module scope**: This file contains *no implementation logic*—only metadata. Developers may mistakenly expect to find proxy API definitions here; the actual proxy types are likely in other files (e.g., `CanFDApiProxy.cs`, `CANFDProxy.cs`, or similar).
|
||||
- **Versioning**: Both `AssemblyVersion` and `AssemblyFileVersion` are hardcoded to `1.0.0.0`. This may indicate an initial release or placeholder state; ensure versioning is updated consistently across builds to avoid deployment or binding issues.
|
||||
- **COM visibility**: `ComVisible(false)` is set at the assembly level. If COM interop is intended, this must be overridden on specific types (e.g., `[ComVisible(true)]` on a public interface or class), but again, no such types exist in this file.
|
||||
- **No documentation comments**: The file lacks XML documentation (`///` comments), so tooling (e.g., IntelliSense, API docs) will not surface metadata about the assembly beyond its attributes.
|
||||
84
enriched-qwen3-coder-next/DataPRO/CanFDApiProxy/Requests.md
Normal file
84
enriched-qwen3-coder-next/DataPRO/CanFDApiProxy/Requests.md
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/CanFDApiProxy/Requests/SerialRequest.cs
|
||||
- DataPRO/CanFDApiProxy/Requests/CanPostRequest.cs
|
||||
- DataPRO/CanFDApiProxy/Requests/FileRequest.cs
|
||||
- DataPRO/CanFDApiProxy/Requests/ClocksRequest.cs
|
||||
- DataPRO/CanFDApiProxy/Requests/NetworkRequest.cs
|
||||
- DataPRO/CanFDApiProxy/Requests/LEDsRequest.cs
|
||||
- DataPRO/CanFDApiProxy/Requests/CANConfigRequest.cs
|
||||
- DataPRO/CanFDApiProxy/Requests/CanConfigItem.cs
|
||||
generated_at: "2026-04-16T04:02:28.102963+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "b4b7d8b4fcb0bb80"
|
||||
---
|
||||
|
||||
# Requests
|
||||
|
||||
## Documentation: `CANFDApiProxy.Requests` Module
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module defines a set of request classes used to serialize configuration and control commands for a CAN FD device API proxy layer. Each class corresponds to a specific type of operation (e.g., network configuration, LED control, CAN bus configuration, file operations, clock synchronization), and is intended for use in constructing JSON payloads sent to a backend service or embedded device. The module serves as a data contract layer—encapsulating structured input for remote API endpoints—without implementing business logic or I/O operations itself.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
All classes and enums are declared in the `CANFDApiProxy.Requests` namespace.
|
||||
|
||||
| Name | Type | Signature & Description |
|
||||
|------|------|-------------------------|
|
||||
| `SerialRequest` | class | `public class SerialRequest { public string serial { get; set; } }`<br>• Represents a request to perform an operation using a device serial number. |
|
||||
| `NetworkRequest` | class | `public class NetworkRequest { public bool dhcp { get; set; } public string set_address { get; set; } }`<br>• Configures network settings: `dhcp` enables/disables DHCP; `set_address` specifies a static IP address (format unspecified). |
|
||||
| `LEDsRequest` | class | `public class LEDsRequest { public string led { get; set; } public string cmd { get; set; } public string color { get; set; } }`<br>• Controls an LED: `led` identifies the LED (via `LedName`), `cmd` is `"on"`/`"off"`, `color` is `"red"`, `"green"`, or `"blue"` (via `LedColor`). |
|
||||
| `LedColor` | enum | `public enum LedColor { red, green, blue }`<br>• Valid LED colors. |
|
||||
| `LedCmd` | enum | `public enum LedCmd { on, off }`<br>• Valid LED commands. |
|
||||
| `LedName` | enum | `public enum LedName { can1, can2, can3, can4, pwr, sts, status }`<br>• Valid LED identifiers. |
|
||||
| `CANConfigRequest` | class | `public class CANConfigRequest { public config config { get; set; } public string Status { get; set; } }`<br>• Top-level request for CAN bus configuration. Contains a `config` object and an optional `Status` string (e.g., `"success"`). |
|
||||
| `config` | class | `public class config { public CanConfigItem can1 { get; set; } public CanConfigItem can2 { get; set; } public CanConfigItem can3 { get; set; } public CanConfigItem can4 { get; set; } }`<br>• Holds per-CAN-channel configuration (up to 4 channels). |
|
||||
| `CanConfigItem` | class | `public class CanConfigItem(int base_or_arb_bitrate, int base_or_arb_sjw, int data_bitrate, int data_sjw, string filetype, bool included, bool is_fd)`<br>• Constructor initializes all properties.<br>• Properties:<br> - `base_or_arb_bitrate`: int — Bitrate for arbitration/base phase (e.g., 500000).<br> - `base_or_arb_sjw`: int — Synchronization jump width for arbitration/base phase.<br> - `data_bitrate`: int — Bitrate for data phase (used only if `is_fd == true`).<br> - `data_sjw`: int — SJW for data phase.<br> - `filetype`: string — File type identifier (e.g., `"bin"`, `"hex"`).<br> - `included`: bool — Whether this channel’s config is active.<br> - `is_fd`: bool — Whether CAN FD mode is enabled.<br>• Includes `ToString()` overrides for debugging. |
|
||||
|
||||
> **Note**: `CanConfigItem` has no parameterless constructor. All instances must be created via the explicit constructor.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- `SerialRequest.serial` and `NetworkRequest.set_address` are expected to be non-null and non-empty when used, though not enforced in the class itself.
|
||||
- `LEDsRequest.led`, `cmd`, and `color` are expected to match values from `LedName`, `LedCmd`, and `LedColor` respectively—**but no runtime validation is performed**; mismatches may cause downstream errors.
|
||||
- `CanConfigItem` instances must be constructed with all 7 parameters; partial initialization is impossible due to lack of a parameterless constructor.
|
||||
- `config` object expects exactly 4 `CanConfigItem` properties (`can1`–`can4`), but they may be `null` unless explicitly set.
|
||||
- `CANConfigRequest.Status` is a string field with no defined format or allowed values in this module.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
- **Internal usage**: `CANConfigRequest` references `config`, which is defined in the same namespace (`CANFDApiProxy.Requests`).
|
||||
- **External usage**: `CANConfigRequest` imports `using CANFDApiProxy.Messages;`, indicating a dependency on the `CANFDApiProxy.Messages` namespace (not provided in source). This suggests `config` or related types may be shared or extended there.
|
||||
- **Consumers**: These request classes are likely used by higher-level API client classes (e.g., in `CANFDApiProxy.Client` or similar) to serialize requests to JSON for HTTP or serial transport.
|
||||
- **No external libraries** are imported beyond the standard `System` (implied by C# syntax).
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **No validation**: None of the request classes perform input validation (e.g., checking `serial` is non-empty, `set_address` is a valid IP, or `led`/`cmd`/`color` match expected enums). Validation must be handled externally.
|
||||
- **Enum mismatch risk**: `LEDsRequest` uses `string` properties (`led`, `cmd`, `color`) instead of the strongly-typed `LedName`, `LedCmd`, and `LedColor` enums. This invites typos (e.g., `"Red"` vs `"red"`) and runtime errors.
|
||||
- **`CanConfigItem` constructor is mandatory**: Since there is no parameterless constructor, deserialization frameworks (e.g., `System.Text.Json`) may fail unless custom converters or `JsonConstructor` attributes are applied.
|
||||
- **Ambiguous field semantics**:
|
||||
- `NetworkRequest.set_address`’s format (e.g., CIDR notation, `"192.168.1.10"`) is unspecified.
|
||||
- `FileRequest.path` and `ClocksRequest.time` are defined but no usage context is provided in this module.
|
||||
- `CANConfigRequest.Status` is present in the request type, suggesting it may be used for client-to-server feedback—unusual for a request object.
|
||||
- **Inconsistent visibility**: `SerialRequest` and `NetworkRequest` are `public`, while `CanPostRequest`, `FileRequest`, and `ClocksRequest` are `internal`. This implies only a subset of request types are part of the public API surface.
|
||||
- **No documentation on `filetype`**: Its purpose (e.g., firmware image type, config file format) is unclear from the source.
|
||||
|
||||
> **None identified from source alone** for `CanPostRequest`, `FileRequest`, and `ClocksRequest` beyond visibility and field names—behavior is entirely inferred from field names and naming conventions.
|
||||
|
||||
---
|
||||
|
||||
*End of documentation.*
|
||||
108
enriched-qwen3-coder-next/DataPRO/CustomWindow.md
Normal file
108
enriched-qwen3-coder-next/DataPRO/CustomWindow.md
Normal file
@@ -0,0 +1,108 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/CustomWindow/WindowMaximizeButton.cs
|
||||
- DataPRO/CustomWindow/WindowRestoreButton.cs
|
||||
- DataPRO/CustomWindow/WindowCloseButton.cs
|
||||
- DataPRO/CustomWindow/WindowMinimizeButton.cs
|
||||
- DataPRO/CustomWindow/Others.cs
|
||||
- DataPRO/CustomWindow/WindowButton.xaml.cs
|
||||
generated_at: "2026-04-16T03:48:20.453815+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "606b672d4fe748f9"
|
||||
---
|
||||
|
||||
# CustomWindow Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
This module provides specialized button controls for window caption/title bar operations (minimize, maximize/restore, close) in a WPF custom window implementation. It extends the standard `Button` class to support state-dependent iconography (normal vs. disabled states) and integrates with external XAML resources for visual assets. The module enables consistent, reusable UI components for non-standard window chrome, particularly in applications like DataPRO where standard window borders are replaced with custom-drawn title bars.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Classes (all public, non-abstract, inherit from `System.Windows.Controls.Button`):
|
||||
|
||||
- **`WindowButton`**
|
||||
*Base class for all window caption buttons.*
|
||||
- `public new object Content { get; set; }`
|
||||
Overrides `Button.Content`; sets the icon displayed when the button is enabled. Triggers `RefreshContent()` on change.
|
||||
- `public object ContentDisabled { get; set; }`
|
||||
Sets the icon displayed when the button is disabled. Triggers `RefreshContent()` on change.
|
||||
- `public CornerRadius CornerRadius { get; set; }`
|
||||
Gets/sets the corner radius of the button (default: `new CornerRadius()`).
|
||||
- `public object ActiveContent { get; set; }`
|
||||
Gets/sets the *current* content displayed (resolved from `Content` or `ContentDisabled` based on `IsEnabled`).
|
||||
- `public virtual Brush BackgroundDefaultValue { get; }`
|
||||
Returns the default background brush (resolved via `FindResource("DefaultBackgroundBrush")`).
|
||||
- `protected void RefreshContent()`
|
||||
Updates `ActiveContent` to `Content` if `IsEnabled` is true, otherwise to `ContentDisabled`. Automatically invoked on `IsEnabledChanged`.
|
||||
|
||||
- **`WindowMinimizeButton`**
|
||||
*Button for window minimize functionality.*
|
||||
- `public WindowMinimizeButton()`
|
||||
Constructor. Loads `WindowButtonMinimizeIcon` and `WindowButtonMinimizeIconDisabled` from `ButtonIcons.xaml` into `Content` and `ContentDisabled`, respectively.
|
||||
|
||||
- **`WindowMaximizeButton`**
|
||||
*Button for window maximize functionality.*
|
||||
- `public WindowMaximizeButton()`
|
||||
Constructor. Loads `WindowButtonMaximizeIcon` and `WindowButtonMaximizeIconDisabled` from `ButtonIcons.xaml` into `Content` and `ContentDisabled`, respectively.
|
||||
|
||||
- **`WindowRestoreButton`**
|
||||
*Button for window restore functionality (when maximized).*
|
||||
- `public WindowRestoreButton()`
|
||||
Constructor. Loads `WindowButtonRestoreIcon` and `WindowButtonRestoreIconDisabled` from `ButtonIcons.xaml` into `Content` and `ContentDisabled`, respectively.
|
||||
|
||||
- **`WindowCloseButton`**
|
||||
*Button for window close functionality.*
|
||||
- `public WindowCloseButton()`
|
||||
Constructor. Loads `WindowButtonCloseIcon` and `WindowButtonCloseIconDisabled` from `ButtonIcons.xaml` into `Content` and `ContentDisabled`, respectively.
|
||||
|
||||
### Structs/Enums:
|
||||
|
||||
- **`WindowButtonState`**
|
||||
`public enum WindowButtonState { Normal, Disabled, None }`
|
||||
Defines possible states for window buttons. *Note: This enum is declared but not used in the provided source files.*
|
||||
|
||||
### Type Converters:
|
||||
|
||||
- **`TypeConverterStringToUIElement`**
|
||||
*Converts string values to `TextBlock` for XAML property assignment.*
|
||||
- `public override bool CanConvertFrom(...)`
|
||||
Returns `true` only if `sourceType == typeof(string)`.
|
||||
- `public override object ConvertFrom(...)`
|
||||
Converts a string to a `TextBlock` with `Text = value`, `VerticalAlignment = Center`, and `Margin = new Thickness(3, 0, 0, 0)`. Used to enable `Caption="string"` syntax in XAML.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Content Consistency**: `ActiveContent` always equals `Content` when `IsEnabled == true`, and `ContentDisabled` when `IsEnabled == false`. This is enforced by `RefreshContent()` called on `IsEnabledChanged` and property setters.
|
||||
- **Resource Loading**: All button constructors *must* successfully load `ButtonIcons.xaml` from the `pack://application:,,,/CustomWindow;component/ButtonIcons.xaml` URI. Failure (e.g., missing resource) will cause a runtime exception.
|
||||
- **Dependency Property Overrides**: `Content` and `ContentDisabled` are *new* (not `override`) properties that wrap the base `Button.Content` dependency property. This hides the base property and enforces custom behavior.
|
||||
- **State-Driven Content**: `ActiveContent` is the *only* property directly bound to the visual content; `Content`/`ContentDisabled` are *sources* for `ActiveContent`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies:
|
||||
- **`ButtonIcons.xaml`**: Required XAML resource file containing `ResourceDictionary` entries for icons (e.g., `"WindowButtonMinimizeIcon"`, `"WindowButtonCloseIconDisabled"`).
|
||||
- **`WindowButton.xaml`**: XAML file defining the base `WindowButton` template (referenced via `InitializeComponent()` in the constructor).
|
||||
- **`CustomWindow` namespace**: All classes belong to this namespace; cross-references (e.g., `WindowButton`) are internal.
|
||||
|
||||
### External Dependencies:
|
||||
- **WPF Framework**:
|
||||
- `System.Windows` (`Application`, `Window`, `Button`, `ResourceDictionary`, `XamlReader`, `CornerRadius`, `Brush`)
|
||||
- `System.Windows.Controls` (`Button`, `TextBlock`, `VerticalAlignment`)
|
||||
- `System.Windows.Markup` (`XamlReader`)
|
||||
- `System.IO` (`Stream`)
|
||||
- **.NET Core/.NET Framework**: Base libraries (`System`, `System.ComponentModel`, `System.Globalization`).
|
||||
|
||||
### Inferred Usage:
|
||||
- `WindowButton` subclasses (`WindowMinimizeButton`, `WindowMaximizeButton`, `WindowRestoreButton`, `WindowCloseButton`) are likely used in a custom window template (e.g., `CustomWindow` class, not provided here).
|
||||
- `TypeConverterStringToUIElement` is likely applied to a `Caption` property in a custom window control (e.g., via `[TypeConverter(typeof(TypeConverterStringToUIElement))]`).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Hardcoded Resource URI**: The `pack://application:,,,/CustomWindow;component/ButtonIcons.xaml` URI is hardcoded in all button constructors. If the resource is moved, renamed, or the assembly name changes, all buttons will fail at runtime.
|
||||
- **No Fallback for Missing Resources**: If `ButtonIcons.xaml` or its expected keys (e.g., `"WindowButtonMaximizeIcon"`) are missing, `XamlReader.Load()` or dictionary access will throw an exception.
|
||||
- **`ActiveContent` is Not a Dependency Property**: While `ActiveContent` is a dependency property, it is *not* used for styling or data binding in the provided code. Its purpose is internal state management.
|
||||
- **`CornerRadius` Not Applied in Subclasses**: Subclasses (e.g., `WindowMinimizeButton`) have commented-out `CornerRadius` assignments. The current implementation relies on the base `CornerRadius` property, but no default is set in constructors.
|
||||
- **`BackgroundDefaultValue` is Virtual**: Subclasses *could* override `BackgroundDefaultValue`, but none do in the provided source.
|
||||
- **`TypeConverterStringToUIElement` is Unused in Source**: The converter is declared but not referenced in any property or class in the provided files. Its usage is inferred from comments but not verified.
|
||||
- **No Error Handling**: Resource loading and XAML parsing lack try/catch blocks. Failures will crash the constructor.
|
||||
88
enriched-qwen3-coder-next/DataPRO/CustomWindow/Properties.md
Normal file
88
enriched-qwen3-coder-next/DataPRO/CustomWindow/Properties.md
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/CustomWindow/Properties/Settings.Designer.cs
|
||||
- DataPRO/CustomWindow/Properties/AssemblyInfo.cs
|
||||
- DataPRO/CustomWindow/Properties/Resources.Designer.cs
|
||||
generated_at: "2026-04-16T04:04:30.243266+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "cd679b0f0e9e41f7"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## Documentation: `CustomWindow.Properties` Module
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module provides auto-generated infrastructure for application settings and resource management in the `CustomWindow` WPF assembly. It enables strongly-typed access to user-scoped settings via the `Settings` class and localized string/resource lookups via the `Resources` class. It serves as a supporting layer for configuration persistence and localization, but contains no business logic itself—its sole purpose is to expose .NET Framework’s `ApplicationSettingsBase` and `ResourceManager` APIs in a type-safe manner.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
All classes are `internal` (not `public`), and members are auto-generated. Only the following *internally accessible* APIs are exposed:
|
||||
|
||||
#### `Settings` Class
|
||||
- **Namespace**: `CustomWindow.Properties`
|
||||
- **Type**: `internal sealed partial class Settings : ApplicationSettingsBase`
|
||||
- **Static Property**:
|
||||
- `public static Settings Default { get; }`
|
||||
Returns the singleton instance of `Settings`, synchronized for thread safety via `ApplicationSettingsBase.Synchronized`. This is the standard entry point for reading/writing user settings.
|
||||
|
||||
#### `Resources` Class
|
||||
- **Namespace**: `CustomWindow.Properties`
|
||||
- **Type**: `internal sealed class Resources`
|
||||
- **Static Properties**:
|
||||
- `internal static ResourceManager ResourceManager { get; }`
|
||||
Lazily initializes and returns a `ResourceManager` instance bound to the `"CustomWindow.Properties.Resources"` base name in the current assembly.
|
||||
- `internal static CultureInfo Culture { get; set; }`
|
||||
Gets or sets the UI culture used for resource lookups (overrides the current thread’s `CurrentUICulture` for this class only).
|
||||
|
||||
> **Note**: No explicit resource properties (e.g., `public static string SomeString { get; }`) are visible in the source. These are generated at build time from `.resx` files and are not present in the provided `.Designer.cs` file.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- `Settings.Default` is guaranteed to be a thread-safe singleton (via `Synchronized` wrapper).
|
||||
- `Resources.ResourceManager` is lazily initialized exactly once per AppDomain (null-check + assignment is not thread-safe in the generated code, but `ResourceManager` itself is thread-safe for concurrent reads).
|
||||
- The `Settings` class inherits from `ApplicationSettingsBase`, implying it adheres to .NET’s standard settings semantics (e.g., per-user storage, `userSettings` section in config, etc.).
|
||||
- The assembly is **not COM-visible** (`[ComVisible(false)]`), so these types are not exposed to COM clients.
|
||||
- Resource fallback behavior is explicitly configured:
|
||||
- Theme-specific resources are *not* used (`ResourceDictionaryLocation.None`).
|
||||
- Generic resources are embedded in the assembly (`ResourceDictionaryLocation.SourceAssembly`).
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### Dependencies *of* this module:
|
||||
- `System.Configuration` (for `ApplicationSettingsBase`)
|
||||
- `System.Resources` (for `ResourceManager`, `Resources`)
|
||||
- `System.Globalization` (for `CultureInfo`)
|
||||
- `System.Windows` (via `[assembly: ThemeInfo(...)]`, required for WPF resource handling)
|
||||
|
||||
#### Dependencies *on* this module:
|
||||
- The `CustomWindow` WPF application (inferred from namespace and assembly attributes) uses this module for:
|
||||
- Reading/writing user settings via `CustomWindow.Properties.Settings.Default.[PropertyName]`.
|
||||
- Localizing UI strings and resources via `CustomWindow.Properties.Resources.[ResourceName]` (though actual resource names are not visible here).
|
||||
|
||||
> **Note**: No other modules in the codebase are referenced in the provided files.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **Auto-generated code**: Both `Settings.Designer.cs` and `Resources.Designer.cs` are marked as auto-generated. Manual edits will be overwritten on rebuild. Changes must be made to the corresponding `.settings` (for settings) or `.resx` (for resources) files.
|
||||
- **Missing resource properties**: The `Resources` class definition shown contains no strongly-typed resource properties (e.g., `public static string AppTitle { get; }`). Their absence here means they are either not yet defined or generated separately. Do not assume any specific resource keys exist.
|
||||
- **Thread-safety nuance**: While `Settings.Default` is thread-safe, *modifying* settings (e.g., `Settings.Default.MyProp = value`) should be done with care—`ApplicationSettingsBase` does not guarantee atomicity of compound operations.
|
||||
- **No versioning metadata**: Assembly version is hardcoded to `1.0.0.0` (both `AssemblyVersion` and `AssemblyFileVersion`). This may impact deployment or upgrade logic if settings are version-sensitive.
|
||||
- **No localization enabled by default**: The `[assembly: NeutralResourcesLanguage(...)]` attribute is commented out. Without it, resource fallback may behave unexpectedly if the current UI culture does not match the neutral language of the `.resx` files.
|
||||
- **No custom settings defined**: The `Settings` class has no properties declared in the provided source. This implies either:
|
||||
- Settings are defined elsewhere (e.g., in `Settings.settings` designer), or
|
||||
- The module is a skeleton with no active configuration keys.
|
||||
|
||||
None identified beyond the above.
|
||||
190
enriched-qwen3-coder-next/DataPRO/DASFactory.md
Normal file
190
enriched-qwen3-coder-next/DataPRO/DASFactory.md
Normal file
@@ -0,0 +1,190 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DASFactory/DASFactory.AutoDiscovery.cs
|
||||
- DataPRO/DASFactory/DASFactory.WinUSB.cs
|
||||
- DataPRO/DASFactory/DASFactory.CDCUSB.cs
|
||||
- DataPRO/DASFactory/DASFactory.Ribeye.cs
|
||||
- DataPRO/DASFactory/DASFactory.WindowsNotification.cs
|
||||
- DataPRO/DASFactory/DistributorSocket.cs
|
||||
- DataPRO/DASFactory/DASFactory.HID.cs
|
||||
generated_at: "2026-04-16T03:50:36.719547+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "440f548bb3fa7458"
|
||||
---
|
||||
|
||||
# DASFactory
|
||||
|
||||
**Documentation Page: DASFactory Device Discovery and Handling Module**
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
This module implements device discovery and lifecycle management for multiple hardware interface types (UDP multicast, HID, WinUSB, CDCUSB, and Ethernet-based Ribeye) within the DAS (Data Acquisition System) factory framework. It enables background scanning for UDP-based devices via multicast, real-time detection of USB/HID device insertion/removal via Windows notifications, and structured connection/disconnection workflows for each device type. The module serves as the core infrastructure for dynamically managing connected DAS devices in the system, ensuring devices are correctly identified, validated, and integrated into the broader DAS ecosystem.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
The module contains **no public classes**—all classes (`AutoDiscovery`, `WinUSBHandling`, `CDCUSBHandling`, `RibeyeHandling`, `HIDHandling`, `WindowsNotification`, `DistributorSocket`) are declared `internal`. Therefore, there is **no public surface area** exposed by this module.
|
||||
|
||||
However, the following **internal classes and methods** constitute the functional interface used by other internal modules (e.g., `DASFactory`):
|
||||
|
||||
#### `AutoDiscovery`
|
||||
- `void StartMulticastAutoDiscovery()`
|
||||
Starts a background task that periodically polls for UDP devices via `_dasFactory.AutoDiscoverMulticast(...)`. Uses a `CancellationToken` for cancellation. Ensures only one scan task runs at a time via `_multicastLock`.
|
||||
- `void StopMulticastAutoDiscovery()`
|
||||
Cancels the active scan task and waits for it to complete. Disposes and recreates the `CancellationTokenSource` if previously cancelled.
|
||||
- `IDiscoveredDevice[] GetDiscoveredDevices()`
|
||||
Returns a snapshot (copy) of all discovered devices since the last `StartMulticastAutoDiscovery()` call. Thread-safe via `_multicastLock`.
|
||||
|
||||
#### `WinUSBHandling`
|
||||
- Inherits from `WindowsNotification`.
|
||||
- Overrides `NotificationDeviceArrived`, `NotificationDeviceRemoved`.
|
||||
- `public override void UpdateConnectedDevices()`
|
||||
Enumerates connected WinUSB devices, checks for duplicates, and connects new ones.
|
||||
- `public override void UpdateDisconnectedDevices()`
|
||||
Detects and disconnects devices that are no longer present.
|
||||
- `public override void UpdateDeviceSetups()`
|
||||
Sets `this` as the handler for the associated `IDeviceSetup`.
|
||||
|
||||
#### `CDCUSBHandling`
|
||||
- Inherits from `WindowsNotification`.
|
||||
- Overrides `NotificationDeviceArrived`, `NotificationDeviceRemoved`.
|
||||
- `public override void UpdateConnectedDevices()`
|
||||
Enumerates CDCUSB devices (filtered by registry keys in `GetListOfConnectedDevices()`), checks for duplicates, and connects new ones.
|
||||
- `public override void UpdateDisconnectedDevices()`
|
||||
Detects and disconnects removed CDCUSB devices.
|
||||
- `public override void UpdateDeviceSetups()`
|
||||
Sets `this` as the handler for the associated `IDeviceSetup`.
|
||||
|
||||
#### `RibeyeHandling`
|
||||
- Implements `IDeviceSetup`.
|
||||
- `bool QueryInformation(ConnectedDevice dev)`
|
||||
Queries device metadata (serial number, LED count, firmware, supported modes/rates) via protocol commands (`QueryArmAndTriggerStatus`, `QuerySerialNumber`, `QueryNumberOfLEDs`). On failure, sets `dev.InUpdateMode = true`.
|
||||
- `ICommunication GetICommunication()` / `GetICommunication(ConnectedDevice dev)`
|
||||
Returns `EthernetRibeye` instances.
|
||||
- `IConnectedDevice GetIConnectedDevice(ICommunication comm)`
|
||||
Wraps `EthernetRibeye` in `ConnectedEthernetRibeye`.
|
||||
- `bool IsCorrectType(ConnectedDevice dev)`
|
||||
Returns `true` if `dev.Dev is ConnectedEthernetRibeye`.
|
||||
- `DASType GetDASType()` → `ETHERNET_RIBEYE`
|
||||
- `Guid GetGuid()` → `Guid.Empty`
|
||||
- `int GetProductId()` / `string GetProductIdString()` → `0` / `string.Empty`
|
||||
- `void SetHandler(DeviceHandling handler)` → no-op.
|
||||
|
||||
#### `WindowsNotification`
|
||||
- Abstract base class for device notification handlers.
|
||||
- Constructor registers for Windows device notifications via `DeviceManagement.RegisterForDeviceNotifications(...)`.
|
||||
- `protected abstract void NotificationDeviceArrived(ref Message m)`
|
||||
Called on device arrival (via `NotificationWndProc`).
|
||||
- `protected abstract void NotificationDeviceRemoved(ref Message m)`
|
||||
Called on device removal.
|
||||
- `protected virtual void NotificationWndProc(ref Message m)`
|
||||
Filters `WM_DEVICECHANGE` messages for `DBT_DEVICEARRIVAL` / `DBT_DEVICEREMOVECOMPLETE`, dispatching to abstract handlers.
|
||||
|
||||
#### `DistributorSocket`
|
||||
- `public bool IsConnected()`
|
||||
Returns `true` if `_sock` is non-null and connected.
|
||||
- `public void Disconnect()`
|
||||
Shuts down and closes the socket, disposes resources.
|
||||
- `public bool ReadLine(ref string target, ref bool stopFlag)`
|
||||
Reads a line from `_reader` with retry logic (up to `MAX_CONSECUTIVE_READ_ERRORS = 2`). Logs each message.
|
||||
- `public void SendAck()` / `SendNak()`
|
||||
Sends `"ACK"` or `"NAK"` over `_writer`, with logging and error handling.
|
||||
- `public bool KeepAliveEnabled()`
|
||||
Sends a keep-alive configuration string (`<...>`) to the remote endpoint and waits for a response. Sets `_keepAliveEnabled = true` on success.
|
||||
- `public void Dispose()`
|
||||
Closes and disposes the socket.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **`AutoDiscovery`**
|
||||
- `_scanTask` is `null` or completed only when no scan is running.
|
||||
- `_scanTask` is never started if already running (`lock` + null/completed check).
|
||||
- `_discoveredDevices` list is **append-only**: existing entries are never updated or removed during discovery; only new devices (by unique `Serial`) are added.
|
||||
- `ClearDiscoveredDevices()` is called at the start of each `DiscoveryWork` iteration.
|
||||
- Cancellation token is **not reusable**; once cancelled, a new `CancellationTokenSource` is created.
|
||||
|
||||
- **`WinUSBHandling`, `CDCUSBHandling`, `HIDHandling`**
|
||||
- Device path lists are deduplicated (case-insensitive) before use.
|
||||
- `CheckForConnectedWinUSBDups()` / `CheckForConnectedCDCUSBDups()` throw if duplicate device paths are detected.
|
||||
- `GetListOfConnectedDevices()` returns a list of device paths; for CDCUSB, paths must contain at least one registry key from `CDCUSBConnection.RegKeys` (case-insensitive substring match).
|
||||
- `ConnectWinUSBTimeout` / `ConnectCDCUSBTimeout` / `ConnectHIDTimeout` are set to `60000`, `60000`, and `1000` ms respectively.
|
||||
|
||||
- **`RibeyeHandling`**
|
||||
- `Samplerate2AAFilterDict` is immutable and pre-populated with 9 sample rates (500–100000 Hz), each mapped to `sampleRate / 5.0F`.
|
||||
- `QueryInformation` may silently retry `QueryArmAndTriggerStatus` on first boot (CRC initialization issue).
|
||||
- Module serial numbers are derived as `<DAS serial>-<Index>`; firmware versions default to `"0000"`.
|
||||
|
||||
- **`WindowsNotification`**
|
||||
- A hidden `NotificationForm` is created and shown (then hidden) to receive Windows messages.
|
||||
- Device notification registration is mandatory; failure throws an exception.
|
||||
- `RecipientHandle` and `DeviceNotifyHandle` are initialized in the constructor.
|
||||
|
||||
- **`DistributorSocket`**
|
||||
- TCP keep-alive is enabled and configured via `IOControlCode.KeepAliveValues`.
|
||||
- Connection retry loop respects `slicedbCanConnect`, `whKillMe`, and `_bShutDownByNow` flags.
|
||||
- `ReadLine` fails if `stopFlag` is true or `MAX_CONSECUTIVE_READ_ERRORS` is exceeded.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Internal Dependencies (from source):
|
||||
- **`DTS.Common.*` namespaces**:
|
||||
- `DTS.Common.Enums.DASFactory` (`DFConstantsAndEnums`, `MultiCastDeviceClasses`)
|
||||
- `DTS.Common.Interface.DASFactory` (`IDASFactory`, `IDiscoveredDevice`, `IDeviceSetup`)
|
||||
- `DTS.Common.DASResource`, `DTS.Common.DAS.Concepts`, `DTS.Common.ICommunication`, `DTS.Common.Utilities.Logging`, `DTS.Common.WINUSBConnection`, `DTS.Common.USBFramework`
|
||||
- **`DTS.DASLib.*` namespaces**:
|
||||
- `DTS.DASLib.Command.*` (e.g., `Ribeye` commands: `QueryArmAndTriggerStatus`, `QuerySerialNumber`, `QueryNumberOfLEDs`)
|
||||
- `DTS.DASLib.Connection.*`, `DTS.DASLib.Communication`, `DTS.DASLib.Service`
|
||||
- **System namespaces**:
|
||||
- `System.Collections.Concurrent`, `System.Threading`, `System.Windows.Forms`, `System.Net.Sockets`, `System.Runtime.InteropServices`
|
||||
|
||||
#### External Dependencies:
|
||||
- Windows API (via `DeviceManagement`, `FileIODeclarations`, `HIDeclarations`) for device enumeration and HID access.
|
||||
- `MyDeviceManagement.FindDeviceFromGuid(...)` (from `DTS.Common.USBFramework`) for device path enumeration.
|
||||
- `CDCUSBConnection.RegKeys` (from `DTS.Common.WINUSBConnection`) for CDCUSB path filtering.
|
||||
|
||||
#### Inferred Usage:
|
||||
- `AutoDiscovery` is used by `DASFactory` (via `_dasFactory` field) to enable multicast discovery.
|
||||
- `WinUSBHandling`, `CDCUSBHandling`, `HIDHandling`, `RibeyeHandling` are instantiated and wired into `DASFactory` for their respective device types.
|
||||
- `DistributorSocket` is used for remote communication (e.g., with a "slice db" server), likely in distributed acquisition scenarios.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`AutoDiscovery`**
|
||||
- Cancellation is **not idempotent**: once `tokenSource.Cancel()` is called, `tokenSource` is disposed and a new one is created. Reusing the same instance after cancellation is impossible.
|
||||
- `DiscoveryWork` always clears `_discoveredDevices` at the start of each loop iteration, meaning only devices discovered in the *current* scan cycle are retained (unless `StartMulticastAutoDiscovery` is called again).
|
||||
- `GetDiscoveredDevices()` returns a copy (`ToArray()`), but the internal list is not versioned—concurrent `UpdateDevices` calls may overwrite each other’s additions if not for the lock.
|
||||
|
||||
- **`WinUSBHandling`, `CDCUSBHandling`, `HIDHandling`**
|
||||
- Device path deduplication uses `string.IsNullOrEmpty(t)` and case-insensitive `Equals`, but `GetAllHIDDevices()` and `GetListOfConnectedDevices()` may return `null` on failure (not an empty list), which downstream code must handle.
|
||||
- `HIDHandling.ReadRegKeys()` silently clears `RegKeys` on exception; if registry access fails, no devices will match in `NotificationDeviceArrived`.
|
||||
- In `HIDHandling.NotificationDeviceArrived`, if `RegKeys` is empty (e.g., due to registry error), the device is ignored—even if it’s valid—until `ReadRegKeys()` is called again (e.g., on next arrival).
|
||||
- `WinUSBHandling` and `CDCUSBHandling` both call `CheckForConnected...Dups()` and throw if duplicates are found—this is a **hard failure**, not a warning.
|
||||
|
||||
- **`RibeyeHandling`**
|
||||
- `QueryInformation` may fail silently on first boot (CRC issue), but only retries once. If the second attempt fails, `QueryInformation` returns `false` and sets `dev.InUpdateMode = true`.
|
||||
- `Samplerate2AAFilterDict` is shared across all instances (static), but only 9 sample rates are supported. Using unsupported rates will cause a `KeyNotFoundException` if accessed.
|
||||
- `GetGuid()` returns `Guid.Empty`, implying this device type may not use GUID-based enumeration (unlike WinUSB/CDCUSB/HID).
|
||||
|
||||
- **`WindowsNotification`**
|
||||
- `NotificationForm` is created on the main thread; accessing it from other threads (e.g., in `Dispose`) is unsafe and commented-out code warns about cross-thread violations.
|
||||
- Device notification registration failure throws immediately in the constructor—no fallback.
|
||||
|
||||
- **`DistributorSocket`**
|
||||
- `KeepAliveEnabled()` sends a configuration string but does **not** verify the remote response beyond reading a non-empty line. It does not parse `<ACK>` (commented out).
|
||||
- `ReadLine` may return an empty string if `stopFlag` is set or errors exceed threshold—callers must check the return value.
|
||||
- `SLICE_DB_PORT = 8200` is hardcoded; no configuration support.
|
||||
|
||||
- **General**
|
||||
- All timeout values (`ConnectWinUSBTimeout`, etc.) are hardcoded in constructors and not configurable at runtime.
|
||||
- Logging uses `APILogger.LogString(...)` and `APILogger.Log(...)`, but no structured error codes—debugging relies on log parsing.
|
||||
- No unit tests or validation for `IDeviceSetup` implementations beyond type checks (`IsCorrectType`).
|
||||
40
enriched-qwen3-coder-next/DataPRO/DASFactory/Properties.md
Normal file
40
enriched-qwen3-coder-next/DataPRO/DASFactory/Properties.md
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DASFactory/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T04:26:03.347465+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "38071e427231f395"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module (`DataPRO/DASFactory/Properties/AssemblyInfo.cs`) is an assembly-level configuration file for the `DASFactory` .NET assembly. Its purpose is to define metadata attributes that describe the assembly—such as title, product name, version, and COM visibility—without containing any executable logic. It serves as a declarative manifest for build-time and runtime identification and integration, particularly relevant for deployment, versioning, and COM interop scenarios.
|
||||
|
||||
## 2. Public Interface
|
||||
This file contains **no public functions, classes, or methods**. It only declares assembly-level attributes via the `System.Reflection` and `System.Runtime.InteropServices` namespaces. All declarations are attribute usages on the `Assembly` object (e.g., `[assembly: AssemblyTitle(...)]`), which are consumed by the .NET runtime and tooling—not invoked programmatically.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning it cannot be consumed by COM clients unless explicitly overridden elsewhere (e.g., on specific types).
|
||||
- The assembly version is fixed at `1.0.0.0` for both `AssemblyVersion` and `AssemblyFileVersion`. No wildcard (`*`) is used for automatic build/revision numbering.
|
||||
- The `Guid` attribute is set to `"16aa1a8c-fcb8-4e68-b49c-91b5a486d990"` for typelib identification if COM exposure were enabled (currently disabled).
|
||||
- All culture-specific attributes (`AssemblyCulture("")`) indicate this is a neutral (non-localized) assembly.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Depends on**:
|
||||
- `System.Reflection` (for `AssemblyTitle`, `AssemblyDescription`, etc.)
|
||||
- `System.Runtime.InteropServices` (for `ComVisible`, `Guid`)
|
||||
- **Depends on nothing else** (no external project or library references are declared in this file).
|
||||
- **Used by**:
|
||||
- The .NET build system (to embed metadata into the compiled assembly manifest).
|
||||
- Runtime tools (e.g., `Assembly.GetName()`, reflection APIs, `FileVersionInfo`).
|
||||
- COM interop tools (e.g., `tlbexp.exe`)—though disabled, the GUID is present for potential future use.
|
||||
|
||||
## 5. Gotchas
|
||||
- **COM visibility is disabled globally**, so even if types in this assembly are `[ComVisible(true)]`, they will *not* be visible to COM unless the assembly-level `ComVisible(false)` is overridden per-type.
|
||||
- **Version numbers are hardcoded to `1.0.0.0`** with no wildcard usage—this may indicate legacy or manual versioning; no automatic build/revision incrementing occurs.
|
||||
- The `AssemblyCulture("")` implies a *neutral* (non-localized) assembly, but if localization were intended, this should contain a culture name (e.g., `"en-US"`).
|
||||
- The `AssemblyConfiguration("")` and `AssemblyCompany("")` fields are empty strings—no build configuration (e.g., `"Debug"`/`"Release"`) or company name is recorded here.
|
||||
- **No functional code exists** in this file; it is purely metadata. Misinterpreting it as containing business logic is a common mistake for new developers.
|
||||
- None identified from source alone.
|
||||
77
enriched-qwen3-coder-next/DataPRO/DASFactoryDb.Tests.md
Normal file
77
enriched-qwen3-coder-next/DataPRO/DASFactoryDb.Tests.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DASFactoryDb.Tests/DbWrapperShould.cs
|
||||
generated_at: "2026-04-16T03:45:35.889761+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "3a41cad42be76aa0"
|
||||
---
|
||||
|
||||
# DASFactoryDb.Tests
|
||||
|
||||
## Documentation: `DbWrapper` Module
|
||||
|
||||
### 1. Purpose
|
||||
The `DbWrapper` class serves as a centralized, singleton-style abstraction over database connection configuration and connection string generation for the *DASFactory* database (specifically the `DASFactory` database). It encapsulates connection parameters (`Server`, `DBName`, `Username`, `Password`) and exposes a method (`GetLocalDASFactoryConnectionString`) to construct SQL Server connection strings using either Windows Authentication (Trusted Connection) or SQL Authentication, depending on the `_usingNTLMAuthentication` flag. It also provides a static `Connected` state flag and a static `GetDeviceId` method that enforces connection state before proceeding. Its primary role is to decouple connection string construction logic from data access layers and enforce consistent authentication behavior.
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
- **`public static DbWrapper Connection { get; }`**
|
||||
Static property returning the singleton instance of `DbWrapper`. Multiple calls return the same reference (verified by test `Connection_ShouldBeSameReference`).
|
||||
|
||||
- **`public string Username { get; set; }`**
|
||||
Property to get or set the database username. Used only when `_usingNTLMAuthentication` is `false`.
|
||||
|
||||
- **`public string Password { get; set; }`
|
||||
Property to get or set the database password. Used only when `_usingNTLMAuthentication` is `false`.
|
||||
|
||||
- **`public string DBName { get; set; }`**
|
||||
Property to get or set the database name. Currently, tests hardcode `"DASFactory"` in generated connection strings, but this property is settable and used in tests (e.g., `DBName = "DataPro"`), implying it *should* influence the connection string—though the current implementation of `GetLocalDASFactoryConnectionString` ignores it and hardcodes `"DASFactory"`.
|
||||
|
||||
- **`public string Server { get; set; }`**
|
||||
Property to get or set the SQL Server instance name. Required for `GetLocalDASFactoryConnectionString`; `null` or empty triggers an exception.
|
||||
|
||||
- **`public static bool Connected { get; set; }`**
|
||||
Static property indicating whether the system is considered connected. Used by `GetDeviceId` to enforce connection state.
|
||||
|
||||
- **`public string GetLocalDASFactoryConnectionString()`**
|
||||
Instance method that returns a SQL Server connection string based on current `Server`, `DBName`, `Username`, `Password`, and `_usingNTLMAuthentication`.
|
||||
- If `_usingNTLMAuthentication == true`:
|
||||
`"Server={Server};Database=DASFactory;Trusted_Connection=TRUE;"`
|
||||
- If `_usingNTLMAuthentication == false`:
|
||||
`"Server={Server};Database=DASFactory;User Id={Username};Password={Password};"`
|
||||
- Throws `Exception` with message `"Empty Server"` if `Server` is `null` or empty.
|
||||
*(Note: `DBName` is hardcoded to `"DASFactory"` in all cases, despite the `DBName` property being settable.)*
|
||||
|
||||
- **`public static void ResetLocalDASFactoryConnection()`**
|
||||
Instance method (called via `sut.ResetLocalDASFactoryConnection()` in tests) used to reset internal state—specifically to re-enable `Trusted_Connection=TRUE` after a test modifies `_usingNTLMAuthentication`. Its implementation is not visible in this file, but its effect is to revert `_usingNTLMAuthentication` to `true`.
|
||||
|
||||
- **`public static string GetDeviceId(string serial)`**
|
||||
Static method that returns a device ID based on a serial number. Throws `Exception` with message `"Not connected"` if `Connected` is `false`. *(Note: Actual device ID lookup logic is not shown in this test file.)*
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **Singleton Instance**: `DbWrapper.Connection` must return the same reference on every call (test `Connection_ShouldBeSameReference` confirms this).
|
||||
- **Authentication Flag State**: `_usingNTLMAuthentication` is a *static* field initialized to `true`. It can be toggled (e.g., in tests), but tests expect it to be reset via `ResetLocalDASFactoryConnection()` to maintain test isolation.
|
||||
- **Server Validation**: `GetLocalDASFactoryConnectionString()` requires `Server` to be non-null and non-empty; otherwise, it throws an exception with message `"Empty Server"`.
|
||||
- **Hardcoded Database Name**: Despite `DBName` being a settable property, all generated connection strings use `"DASFactory"` as the database name. This is an implicit invariant: `DBName` is *not* used in connection string generation.
|
||||
- **Connection State Enforcement**: `GetDeviceId()` requires `Connected == true`; otherwise, it throws `"Not connected"`.
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
- **Test Dependencies** (from source file):
|
||||
- `NSubstitute` (for mocking in other tests, though not used in this specific file).
|
||||
- `NUnit` (for `[TestFixture]`, `[Test]`, `Assert`).
|
||||
- `System`, `System.Data` (for `IDbCommand`, `IDbConnection`, `ConnectionState`).
|
||||
- **Internal Dependencies** (inferred):
|
||||
- `DbWrapper` likely depends on `System.Data.SqlClient` (or equivalent) at runtime for actual database operations (e.g., `GetDASFactoryCommand` is referenced in an ignored test).
|
||||
- `DbWrapper` is used by other modules (e.g., tests reference `DbWrapper.GetDeviceId`, `DbWrapper.Connected`, `DbWrapper.Connection`), implying downstream consumers rely on it for connection management.
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`DBName` is ignored in connection string generation**: Despite being a public settable property, `GetLocalDASFactoryConnectionString()` hardcodes `"DASFactory"` as the database name. This is likely a bug or technical debt.
|
||||
- **Static mutable state**: `_usingNTLMAuthentication` is a *static* field, meaning its value persists across instances and tests unless explicitly reset. Tests must call `ResetLocalDASFactoryConnection()` to avoid cross-test pollution (as noted in the test comment: *"Important to reset the connection otherwise the class needs to be redesigned to not be singleton"*).
|
||||
- **Singleton design with mutable state**: The singleton pattern combined with mutable instance properties (`Server`, `Username`, etc.) and static mutable state (`_usingNTLMAuthentication`, `Connected`) makes the class difficult to test in isolation and prone to side effects.
|
||||
- **`GetDASFactoryCommand` is ignored**: The test `GetDASFactoryCommand_ShouldBeOpened` is marked `[Ignore("Not testing DAL")]`, indicating the actual data access logic is not unit-tested here. This method is not fully implemented or verified in this module.
|
||||
- **Exception types are generic**: All exceptions thrown are of type `Exception` (not custom or more specific types like `ArgumentException` or `InvalidOperationException`), which is not ideal for robust error handling.
|
||||
- **`ResetLocalDASFactoryConnection()` is not documented in source**: Its behavior is inferred solely from test usage. Its implementation details (e.g., whether it resets *only* `_usingNTLMAuthentication` or other state) are unknown.
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DASFactoryDb.Tests/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T03:53:22.026403+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "4ac858397bf9bb63"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## Documentation Page: `DASFactoryDb.Tests` Assembly
|
||||
|
||||
### 1. Purpose
|
||||
This assembly is a test project (`DASFactoryDb.Tests`) for the `DASFactoryDb` codebase. Its sole purpose is to house unit and/or integration tests for the database-related functionality of the main `DASFactoryDb` library. It does not contain production logic or expose public APIs for external consumption; it is strictly a validation and regression prevention artifact. The project follows standard .NET assembly conventions for test projects, including versioning and COM visibility settings.
|
||||
|
||||
### 2. Public Interface
|
||||
**No public API surface is exposed by this assembly.**
|
||||
The file `AssemblyInfo.cs` contains only assembly-level metadata attributes (e.g., `AssemblyTitle`, `AssemblyVersion`) and does not declare any public classes, interfaces, methods, or properties. Test logic (if any) would reside in other source files *not included* in the provided source set, and thus cannot be documented here.
|
||||
|
||||
### 3. Invariants
|
||||
- The assembly is **not COM-visible** (`ComVisible(false)`), meaning its types cannot be accessed via COM interop.
|
||||
- The assembly version is explicitly set to `1.0.0.0` for both `AssemblyVersion` and `AssemblyFileVersion`.
|
||||
- The `Guid` attribute (`d2e1efed-273b-4611-9190-dd1b42b9ef21`) uniquely identifies the typelib *if* the assembly were exposed to COM (which it is not).
|
||||
- The `AssemblyConfiguration` and `AssemblyCompany` attributes are empty strings, indicating no build configuration or corporate entity is recorded at the assembly level.
|
||||
|
||||
### 4. Dependencies
|
||||
- **Runtime dependencies**: Standard .NET Framework assemblies (implied by `System.Reflection`, `System.Runtime.CompilerServices`, `System.Runtime.InteropServices`).
|
||||
- **Project dependencies**: This test assembly *depends on* the `DASFactoryDb` main library (not shown), as is standard for test projects. However, no explicit project or package references are declared in the provided source.
|
||||
- **Consumers**: This assembly is consumed by a test runner (e.g., MSTest, NUnit, xUnit) during CI/CD or local testing. No other production code depends on it.
|
||||
|
||||
### 5. Gotchas
|
||||
- **No test logic is present in the provided source** — the file only contains metadata. Test classes and methods must reside in other `.cs` files within the project.
|
||||
- The `AssemblyVersion("1.0.0.0")` and `AssemblyFileVersion("1.0.0.0")` are hardcoded and do not use auto-incrementing build/revision numbers (e.g., `1.0.*`). This may complicate traceability in CI environments unless versioning is handled externally (e.g., via build scripts).
|
||||
- The empty `AssemblyConfiguration` and `AssemblyCompany` fields suggest minimal metadata hygiene; teams should verify whether these should be populated for compliance or deployment tracking.
|
||||
- **None identified from source alone** regarding behavioral quirks, as no executable logic is included.
|
||||
92
enriched-qwen3-coder-next/DataPRO/DASFactoryDb.md
Normal file
92
enriched-qwen3-coder-next/DataPRO/DASFactoryDb.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DASFactoryDb/DbWrapper.cs
|
||||
generated_at: "2026-04-16T03:44:18.623811+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "836c8383a0b90cbc"
|
||||
---
|
||||
|
||||
# DASFactoryDb
|
||||
|
||||
### **Purpose**
|
||||
The `DbWrapper` class serves as a minimal, internal database access abstraction layer for the `DASFactory` database, specifically targeting SQL Server. It encapsulates connection string construction, singleton-based instance management, and basic command execution for stored procedures. Its primary role is to provide a centralized, reusable mechanism for retrieving device IDs and handling SQL command execution with error propagation, while supporting future flexibility between local and centralized database configurations via static flags (`_usingCentralizedDB`, `_usingNTLMAuthentication`). The class is not intended for general-purpose data access but focuses on a narrow set of operations required by the DASFactory system.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
All members are `public` or `internal`, but the class is `partial` and its constructor is `protected`, suggesting it may be extended elsewhere in the codebase. Only the following are *publicly* accessible from outside the assembly (based on `public` modifiers):
|
||||
|
||||
- **`public static bool _usingCentralizedDB`**
|
||||
A static flag indicating whether the system should use a centralized database (currently always `false` per comments). Used for future configuration flexibility.
|
||||
|
||||
- **`public static bool _usingNTLMAuthentication`**
|
||||
A static flag indicating whether to use Windows Authentication (NTLM) for database connections (currently always `true`). Affects connection string generation.
|
||||
|
||||
- **`public static bool Connected`**
|
||||
A read/write static property that *always returns `false`* (per its `get => false;` implementation). The summary states it is “used to passively indicate connection status, does not perform any connection checking.” **Note:** This property is non-functional as implemented.
|
||||
|
||||
- **`public static DbWrapper Connection`**
|
||||
A static property implementing a thread-safe singleton pattern. Returns the single instance of `DbWrapper` (lazily initialized on first access). Uses `lock(dbLock)` to ensure thread-safe initialization.
|
||||
|
||||
- **`public string Server { get; set; }`**
|
||||
Gets or sets the database server name. Required for connection string generation; must be non-empty/whitespace when `GetLocalDASFactoryConnectionString()` is called.
|
||||
|
||||
- **`public string DBName { get; set; }`**
|
||||
Gets or sets the database name. *Not used in current implementation*—the connection string hardcodes `"Database=DASFactory;"`.
|
||||
|
||||
- **`public string Username { get; set; }`**
|
||||
Gets or sets the SQL Server username. Used only when `_usingNTLMAuthentication` is `false`.
|
||||
|
||||
- **`public string Password { get; set; }`**
|
||||
Gets or sets the SQL Server password. Used only when `_usingNTLMAuthentication` is `false`.
|
||||
|
||||
- **`public void ResetLocalDASFactoryConnection()`**
|
||||
Resets the cached connection string (`_localDASFactoryConnection = null`) and resets `_usingNTLMAuthentication` to `true`. Intended to force re-computation of the connection string on next access.
|
||||
|
||||
- **`public string GetLocalDASFactoryConnectionString()`**
|
||||
Returns a SQL Server connection string for the `DASFactory` database. Uses cached value if available; otherwise constructs it based on `Server`, `_usingNTLMAuthentication`, `Username`, and `Password`. Throws `Exception("Empty Server")` if `Server` is null/whitespace.
|
||||
- If `_usingNTLMAuthentication == true`: `"Server={Server};Database=DASFactory;Trusted_Connection=TRUE;"`
|
||||
- Else: `"Server={Server};Database=DASFactory;User Id={Username};Password={Password};"`
|
||||
|
||||
- **`public static int GetDeviceId(string serialNumber)`**
|
||||
Executes the stored procedure `sp_IDASCommunicationTableGetRecordId` with `@SerialNumber` as input. Returns the `RecordId` (as `int`) if found, or `-1` if no matching record exists. Throws `Exception("Not connected")` if `Connected` is `false` (which it always is, per the property implementation—see *Gotchas*). Disposes the underlying connection after use.
|
||||
|
||||
- **`internal static void ProcessReturn(SqlParameter errorNumber, SqlParameter errorMessage)`**
|
||||
Checks the `Value` of `errorNumber`. If non-null and non-zero, throws an `Exception` concatenating `errorNumber.Value` and `errorMessage.Value`. Used to propagate SQL stored procedure error codes/messages.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
- The `Server` property **must** be set to a non-null, non-whitespace string before calling `GetLocalDASFactoryConnectionString()`; otherwise, an exception is thrown.
|
||||
- The `Connected` property is *always* `false`, regardless of actual database state. Any code checking `if (!Connected)` will always throw an exception.
|
||||
- The `DbWrapper.Connection` singleton is lazily initialized and thread-safe via `lock(dbLock)`.
|
||||
- Connection strings are cached in `_localDASFactoryConnection`; subsequent calls return the cached value until `ResetLocalDASFactoryConnection()` is invoked.
|
||||
- `GetDeviceId()` always opens and disposes its own `SqlConnection` internally; it does not use the singleton’s state for persistence.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
- **Direct Dependencies (from imports):**
|
||||
- `System`
|
||||
- `System.Data`
|
||||
- `System.Data.SqlClient`
|
||||
- `DASFactoryDb.Connection` (used in `GetDASFactoryCommand()` via `Connection.GetLocalDASFactoryConnectionString()`)
|
||||
- **Inferred Usage:**
|
||||
- The stored procedure `sp_IDASCommunicationTableGetRecordId` must exist in the `DASFactory` database.
|
||||
- The `Connection` class (referenced in `GetDASFactoryCommand()`) must define `GetLocalDASFactoryConnectionString()`—likely in a separate file or module.
|
||||
- **Dependents (inferred):**
|
||||
- Any code calling `DbWrapper.Connection`, `GetDeviceId()`, or `GetLocalDASFactoryConnectionString()` (e.g., device lookup logic).
|
||||
- The `ProcessReturn()` method suggests integration with stored procedures that output `@ErrorNumber` and `@ErrorMessage` parameters.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
- **`Connected` is non-functional:** Its `get` accessor always returns `false`, so `GetDeviceId()` will *always* throw `"Not connected"`—this is likely a bug or incomplete implementation.
|
||||
- **Hardcoded database name:** `DBName` is unused; the connection string always uses `"DASFactory"`.
|
||||
- **No connection pooling or reuse:** `GetDASFactoryCommand()` creates and opens a *new* `SqlConnection` on every call, then disposes it in `GetDeviceId()`—inefficient for repeated calls.
|
||||
- **Exception message format in `ProcessReturn`:** Concatenates `errorNumber.Value` (likely an `int`) and `errorMessage.Value` (a `string`) without a separator, potentially causing ambiguous error messages (e.g., `"53Operation failed"`).
|
||||
- **Thread-safety gap:** While `Connection` singleton is thread-safe, `ResetLocalDASFactoryConnection()` modifies static state (`_usingNTLMAuthentication`) without locking—could cause race conditions if called concurrently with `GetLocalDASFactoryConnectionString()`.
|
||||
- **No async support:** All database operations are synchronous (`ExecuteReader()`), which may block threads in UI or high-throughput services.
|
||||
- **Missing null/empty checks in `GetDeviceId`:** Does not validate `serialNumber` before passing to the stored procedure.
|
||||
- **`_usingCentralizedDB` is unused:** Despite being declared, no logic in this file branches on its value.
|
||||
81
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/ARM.md
Normal file
81
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/ARM.md
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DASFactoryDb/ARM/ARM.cs
|
||||
generated_at: "2026-04-16T03:53:10.384931+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "dd0ee32e99af1e4e"
|
||||
---
|
||||
|
||||
# ARM
|
||||
|
||||
### **Purpose**
|
||||
This module provides a centralized static interface for updating the ARM (Armed/Recording Monitor) status of a Data Acquisition System (DAS) record in the database. It acts as a thin data-access wrapper that translates in-memory ARM state flags, metrics, and metadata into a stored procedure call (`sp_ArmStatusSet`) to persist the current operational state of a DAS unit—such as armed status, triggering, fault conditions, recording progress, and sensor readings—ensuring consistency between the application’s runtime state and the persisted state in the database.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
#### `ARM.SetArmStatus(...)`
|
||||
```csharp
|
||||
public static void SetArmStatus(
|
||||
int iDASRecordId,
|
||||
bool isArmed,
|
||||
bool isTriggered,
|
||||
bool isTriggerShorted,
|
||||
bool isStartShorted,
|
||||
bool isRecording,
|
||||
bool isFaulted,
|
||||
bool isInRealtime,
|
||||
bool isInFlashWrite,
|
||||
bool isUndefined,
|
||||
bool isInPostTestDiagnostics,
|
||||
double timeRemainingSeconds,
|
||||
double percentComplete,
|
||||
ulong totalSamples,
|
||||
ulong currentSample,
|
||||
uint sampleRate,
|
||||
double? inputMilliVolts,
|
||||
double? batteryMilliVolts,
|
||||
int? eventNumber,
|
||||
int recordingMode,
|
||||
string faultMessage,
|
||||
bool isRearming,
|
||||
bool hasBeenRecording,
|
||||
double? timeLeftInArm
|
||||
)
|
||||
```
|
||||
**Behavior**: Updates the ARM status for the DAS record identified by `iDASRecordId` by invoking the stored procedure `sp_ArmStatusSet`. All parameters map directly to corresponding database columns/parameters. If the database connection is not active (`!DbWrapper.Connected`), the method returns early without executing the procedure. It handles nullable types by substituting defaults (`0` for numerics, `""` for strings) before passing to SQL. It captures and processes output parameters (`@errorNumber`, `@errorMessage`, `@new_id`) via `DbWrapper.ProcessReturn`, and ensures the command connection is disposed in a `finally` block.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
- **Connection requirement**: The method performs no operation if `DbWrapper.Connected` is `false`.
|
||||
- **Non-nullability enforcement**: Nullable parameters (`double?`, `int?`) are coalesced to non-null defaults (`0` or `""`) before being passed to SQL—no `NULL` values are sent for any parameter.
|
||||
- **Stored procedure contract**: Assumes `sp_ArmStatusSet` exists and accepts the exact 24 parameters listed (including 3 output parameters).
|
||||
- **Resource cleanup**: The underlying `SqlCommand.Connection` is explicitly disposed after execution, regardless of success or failure.
|
||||
- **No return value**: The method does not expose the output values (`@errorNumber`, `@errorMessage`, `@new_id`) to callers—processing is delegated entirely to `DbWrapper.ProcessReturn`.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
- **Internal dependencies**:
|
||||
- `DbWrapper.Connected` (property) and `DbWrapper.GetDASFactoryCommand()` (method) — used to check connectivity and obtain a configured `SqlCommand`.
|
||||
- `DbWrapper.ProcessReturn(...)` — processes output parameters from the stored procedure call.
|
||||
- **External dependencies**:
|
||||
- `System.Data` and `System.Data.SqlClient` — for `SqlDbType`, `CommandType`, `SqlParameter`, `ParameterDirection`, and `IDbCommand`.
|
||||
- Database: Requires the stored procedure `sp_ArmStatusSet` to exist in the DASFactory database with the exact parameter list and types.
|
||||
|
||||
**Depended on by**: Presumably other components in the DAS system that need to update ARM status (e.g., recording state machines, fault handlers, telemetry services)—though not visible in this file.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
- **Silent no-op on disconnect**: If `DbWrapper.Connected` is `false`, the method returns without logging or raising an exception—this may mask connectivity issues.
|
||||
- **Loss of null semantics**: Nullable parameters (`inputMilliVolts`, `batteryMilliVolts`, `eventNumber`, `timeLeftInArm`) are converted to `0` or `""` when `null`, potentially overwriting meaningful `NULL` states in the database (e.g., “unknown” vs. “zero”).
|
||||
- **`ulong` → `int` truncation risk**: `totalSamples`, `currentSample` (`ulong`) are passed as `SqlDbType.Int` (signed 32-bit), which may cause silent overflow or incorrect values for large sample counts (> 2³¹−1).
|
||||
- **Hardcoded stored procedure name**: The procedure name `"sp_ArmStatusSet"` is hardcoded—no abstraction or configuration layer.
|
||||
- **No validation of input values**: No checks for invalid combinations (e.g., `isRecording == true` but `isArmed == false`)—assumes caller maintains logical consistency.
|
||||
- **Output parameters unused by caller**: Though `@new_id` is declared and returned, its value is not exposed—suggests possible legacy or incomplete implementation.
|
||||
|
||||
*None identified from source alone.* — *Note: The above gotchas are inferred from observed behavior and type mismatches; no explicit documentation or comments exist in the source.*
|
||||
74
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/Config.md
Normal file
74
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/Config.md
Normal file
@@ -0,0 +1,74 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DASFactoryDb/Config/Config.cs
|
||||
generated_at: "2026-04-16T03:52:17.979930+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "609ad832d02ccb50"
|
||||
---
|
||||
|
||||
# Config
|
||||
|
||||
## Documentation: `DASFactoryDb.Config.Config` Module
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
This module provides a thin, static wrapper around three SQL Server stored procedures (`sp_DASInfoInsert`, `sp_DASInfoClear`, and `sp_ConfigDataSet`) for managing DAS (Data Acquisition System) device metadata and configuration in the `DASFactoryDb` database. It abstracts low-level ADO.NET operations—including parameter binding, null handling, and error propagation—into strongly-typed C# methods. Its role is to ensure consistent, validated data persistence for DAS device information (e.g., MAC address, module limits, battery, calibration) and XML-based configuration blobs.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `int DASInfoInsert(int iDASRecordId, string macAddress, int owningDASId, uint maxNumberOfModules, ulong? maxEventStorageSpaceInBytes, ulong? numberOfBytesPerSampleClock, string batteryId, DateTime? calibrationDate)`
|
||||
- **Behavior**: Inserts or updates DAS device metadata by calling the `sp_DASInfoInsert` stored procedure. Returns the ID of the inserted/updated record (via `@new_id` output parameter).
|
||||
- **Null/Default Handling**:
|
||||
- `macAddress` → `string.Empty` if `null`.
|
||||
- `maxEventStorageSpaceInBytes`, `numberOfBytesPerSampleClock` → `0` if `null`.
|
||||
- `calibrationDate` → `SqlDateTime.MinValue` if `null` or less than `SqlDateTime.MinValue`.
|
||||
- **Error Handling**: Delegates to `DbWrapper.ProcessReturn` after execution; throws on non-zero `@errorNumber`.
|
||||
|
||||
#### `void DASInfoClear(int iDASRecordId)`
|
||||
- **Behavior**: Clears DAS device metadata by calling `sp_DASInfoClear`. Does nothing if `DbWrapper.Connected` is `false`.
|
||||
- **Note**: No return value; errors are propagated via `DbWrapper.ProcessReturn`.
|
||||
|
||||
#### `void SetConfiguration(int iDASRecordId, string xml, int fileStore)`
|
||||
- **Behavior**: Stores XML configuration data as UTF-8 encoded binary (`VarBinary`) by calling `sp_ConfigDataSet`. Returns the new configuration record ID via `@new_id` (not exposed in return value).
|
||||
- **Null/Default Handling**: No explicit null checks on `xml`; passes raw bytes (including `null` → `DBNull.Value` behavior depends on `SqlParameter` handling).
|
||||
- **Error Handling**: Same as above; skips execution if not connected.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- **Connection State**: `DASInfoClear` and `SetConfiguration` silently exit if `DbWrapper.Connected == false`. `DASInfoInsert` does *not* check connection state and will attempt execution regardless.
|
||||
- **Parameter Validation**:
|
||||
- `maxNumberOfModules` is bound as `SqlDbType.Int` despite being `uint`; potential overflow if `> int.MaxValue`.
|
||||
- `maxEventStorageSpaceInBytes` and `numberOfBytesPerSampleClock` are `ulong?` but bound as `SqlDbType.Int`; values > `int.MaxValue` will overflow silently (to negative or truncated values).
|
||||
- **Date Handling**: `calibrationDate` is clamped to `SqlDateTime.MinValue` (1753-01-01) if below it; `DateTime.MinValue` (0001-01-01) is converted to this minimum.
|
||||
- **Error Propagation**: All methods rely on `DbWrapper.ProcessReturn` to interpret `@errorNumber` and `@errorMessage`; non-zero `@errorNumber` likely throws an exception (behavior depends on `DbWrapper.ProcessReturn` implementation, not visible here).
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
- **Internal Dependencies**:
|
||||
- `DbWrapper` (static class): Provides `GetDASFactoryCommand()`, `Connected` property, and `ProcessReturn(SqlParameter, SqlParameter)`.
|
||||
- `System.Data`, `System.Data.SqlClient`, `System.Text`: For ADO.NET types and UTF-8 encoding.
|
||||
- **External Dependencies**:
|
||||
- SQL Server database with stored procedures:
|
||||
- `sp_DASInfoInsert`
|
||||
- `sp_DASInfoClear`
|
||||
- `sp_ConfigDataSet`
|
||||
- Assumed schema: Tables/columns matching parameter names (e.g., `@IDASCommunicationRecordId`, `@ConfigurationData`, `@ConfigStore`).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
- **Silent Data Truncation**: `maxEventStorageSpaceInBytes` and `numberOfBytesPerSampleClock` (`ulong?`) are cast to `int` (via `SqlDbType.Int`). Values > `2,147,483,647` will overflow or wrap, causing incorrect data.
|
||||
- **No Connection Guard in `DASInfoInsert`**: Unlike `DASInfoClear`/`SetConfiguration`, this method proceeds even if `DbWrapper.Connected == false`, risking runtime exceptions.
|
||||
- **`macAddress` Null Handling**: Converts `null` to `string.Empty` before binding, which may mask missing data (e.g., DB might accept empty string as valid).
|
||||
- **`xml` Parameter**: No validation or encoding checks; malformed XML or non-UTF-8 data could cause DB errors.
|
||||
- **Resource Management**: `cmd.Connection.Dispose()` in `finally` blocks may conflict with `DbWrapper`’s connection lifecycle if it manages pooled connections.
|
||||
- **Missing Return Value**: `SetConfiguration` retrieves `@new_id` but discards it; callers cannot confirm the inserted ID.
|
||||
- **No Timeout Configuration**: Command timeout defaults to `DbWrapper`’s implementation (not specified here).
|
||||
|
||||
*None identified beyond these.*
|
||||
78
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/DAS.md
Normal file
78
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/DAS.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DASFactoryDb/DAS/DAS.cs
|
||||
generated_at: "2026-04-16T03:52:32.887554+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "bd5dcbab40df1de5"
|
||||
---
|
||||
|
||||
# DAS
|
||||
|
||||
## Documentation: `DASFactoryDb.DAS.DAS` Module
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
This module provides a simplified data access layer for inserting records into the DAS (Device Acceptance System) factory communication table in a SQL Server database. It encapsulates the logic for calling the stored procedure `sp_IDASCommunicationTableSimpleInsert`, handling parameter binding, output parameter extraction, and error propagation via `DbWrapper.ProcessReturn`. Its role is to abstract low-level ADO.NET operations for a specific high-frequency insert operation, ensuring consistent handling of serial number, firmware version, and connection string data.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `InsertDASSimple(string serialNumber, string firmwareVersion, string connectString) → int`
|
||||
- **Behavior**: Executes the stored procedure `sp_IDASCommunicationTableSimpleInsert` with the provided input parameters (`@SerialNumber`, `@FirmwareVersion`, `@ConnectString`) and returns the newly inserted record’s ID (`@new_id`).
|
||||
- **Parameters**:
|
||||
- `serialNumber`: NVARCHAR(50) — Device serial number.
|
||||
- `firmwareVersion`: NVARCHAR(50) — Firmware version string.
|
||||
- `connectString`: NVARCHAR(255) — Connection string for the device.
|
||||
- **Output**:
|
||||
- Returns the integer value of the `@new_id` output parameter (the primary key of the inserted row).
|
||||
- **Error Handling**:
|
||||
- Delegates error processing to `DbWrapper.ProcessReturn`, passing the `@errorNumber` and `@errorMessage` output parameters.
|
||||
- Disposes the underlying `SqlConnection` in a `finally` block (via `cmd.Connection.Dispose()`).
|
||||
|
||||
> **Note**: Parameter name for `connectString` is misspelled as `"ConnectString"` (missing `@` prefix in the `SqlParameter` constructor), but the stored procedure likely expects `@ConnectString`. This is consistent with the source and must be preserved.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- **Parameter Constraints** (inferred from SQL types):
|
||||
- `serialNumber` must be ≤ 50 characters (NVARCHAR(50)).
|
||||
- `firmwareVersion` must be ≤ 50 characters (NVARCHAR(50)).
|
||||
- `connectString` must be ≤ 255 characters (NVARCHAR(255)).
|
||||
- **Execution Guarantee**:
|
||||
- The stored procedure is always invoked with `CommandType.StoredProcedure`.
|
||||
- Output parameters `@errorNumber`, `@errorMessage`, and `@new_id` are *always* expected and used.
|
||||
- **Resource Management**:
|
||||
- The `SqlCommand.Connection` is *always* disposed after execution, regardless of success or failure (via `finally` block).
|
||||
- **Return Semantics**:
|
||||
- The method *always* returns an `int` derived from `@new_id`; no null-check is performed on `newId.Value` before conversion (assumes non-null output from stored procedure).
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### **Internal Dependencies**
|
||||
- `DbWrapper.GetDASFactoryCommand()` — Provides a configured `SqlCommand` instance (connection, transaction context, etc.).
|
||||
- `DbWrapper.ProcessReturn(SqlParameter errorNumber, SqlParameter errorMessage)` — Handles error propagation based on output parameters (e.g., throws exception if `errorNumber ≠ 0`).
|
||||
|
||||
#### **External Dependencies**
|
||||
- `System.Data` (ADO.NET types: `SqlDbType`, `CommandType`, `ParameterDirection`)
|
||||
- `System.Data.SqlClient` (SQL Server client types: `SqlCommand`, `SqlParameter`)
|
||||
|
||||
#### **Downstream Consumers**
|
||||
- Any code calling `DAS.InsertDASSimple(...)` (e.g., factory test automation, device onboarding services).
|
||||
- The stored procedure `sp_IDASCommunicationTableSimpleInsert` in the target database (not included in source, but required at runtime).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
- **Parameter Name Typo**: The `SqlParameter` for `connectString` is constructed as `new SqlParameter("ConnectString", ...)` instead of `"@ConnectString"`. While ADO.NET typically ignores the `@` prefix in the constructor (it is added automatically), this is non-standard and could cause issues if `DbWrapper.GetDASFactoryCommand()` or the underlying connection setup expects strict naming.
|
||||
- **No Input Validation**: The method does *not* validate input lengths or nullability before passing values to SQL. Passing `null` or oversized strings may cause runtime errors (e.g., `SqlException` from the stored procedure or truncation).
|
||||
- **Assumes Non-null `@new_id`**: `Convert.ToInt32(newId.Value)` will throw `InvalidCastException` or `FormatException` if `@new_id` is `DBNull` or non-numeric.
|
||||
- **Resource Disposal**: While `cmd.Connection.Dispose()` is called, the `using` block on `cmd` does *not* dispose the connection (since `cmd.Connection` is externally managed by `DbWrapper`). This is safe *only if* `DbWrapper` does not reuse the connection after disposal — a subtle risk if `DbWrapper` manages pooled connections incorrectly.
|
||||
- **No Transaction Scope**: Inserts occur outside an explicit transaction; if atomicity with other operations is required, this method cannot be used directly.
|
||||
|
||||
> **None identified from source alone.**
|
||||
> *(Note: The above gotchas are inferred from code structure and common ADO.NET pitfalls; no explicit documentation or comments in the source clarify intent or constraints.)*
|
||||
123
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/Diagnostics.md
Normal file
123
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/Diagnostics.md
Normal file
@@ -0,0 +1,123 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DASFactoryDb/Diagnostics/Diagnostics.cs
|
||||
generated_at: "2026-04-16T03:52:56.599244+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "435708341e9b9055"
|
||||
---
|
||||
|
||||
# Diagnostics
|
||||
|
||||
## Documentation: `DASFactoryDb.Diagnostics.Diagnostics` Module
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module provides a set of static methods to interact with diagnostic-related database operations for DAS (Data Acquisition System) communication records. It serves as the primary interface for inserting, clearing, and managing diagnostic *actions* (configured test parameters) and diagnostic *results* (observed test outcomes) across channels and events. The module abstracts low-level ADO.NET database calls into higher-level operations, delegating actual data persistence to stored procedures in the DASFactory database.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
All methods are `public static` and reside in the `DASFactoryDb.Diagnostics.Diagnostics` class.
|
||||
|
||||
#### `ClearDiagnosticActionsAllChannels(int idasRecordId)`
|
||||
- **Behavior**: Clears *all* diagnostic action configurations for *all channels* associated with the given `idasRecordId`. Uses the stored procedure `sp_DiagnosticActionsClear`.
|
||||
- **Parameters**:
|
||||
- `idasRecordId`: ID of the DAS communication record to clear actions for.
|
||||
- **Note**: Passes `null` for `@DASChannelNumber` to indicate “all channels”.
|
||||
|
||||
#### `InsertDiagnosticAction(...)`
|
||||
- **Behavior**: Inserts a new diagnostic action configuration for a specific DAS channel. Uses the stored procedure `sp_DiagnosticsActionsInsert`.
|
||||
- **Parameters**:
|
||||
- `dasRecordId`: ID of the DAS communication record.
|
||||
- `dasChannelNumber`: Channel number (0-based or 1-based? — not specified in source).
|
||||
- Boolean flags indicating which diagnostic tests to perform (e.g., `measureExcitation`, `measureOffset`, `squibFireCheck`, etc.).
|
||||
- **Returns**: Output parameter `@new_id` (ID of inserted record) is captured but *not returned* by this method.
|
||||
|
||||
#### `ClearExistingDiagnosticsAllChannels(int idasRecordId = -1)`
|
||||
- **Behavior**: Clears *all* diagnostic *results* for a given DAS communication record (or *all records* if `idasRecordId == -1`). Uses the stored procedure `sp_DiagnosticsResultsClear`.
|
||||
- **Parameters**:
|
||||
- `idasRecordId`: Optional; defaults to `-1` (clear all records). If non-negative, clears only for that record.
|
||||
- **Note**: Passes `null` for both `@DASChannelNumber` and `@EventNumber`, indicating “all channels and events”.
|
||||
|
||||
#### `InsertAnalogDiagnosticResult(...)`
|
||||
- **Behavior**: Inserts a full analog diagnostic result record for a specific channel and event. Uses the stored procedure `sp_DiagnosticsResultsAnalogInsert`.
|
||||
- **Parameters**:
|
||||
- `iDASRecordId`, `dasChannelNumber`, `eventNumber`: Identifiers for the diagnostic result context.
|
||||
- Numerous `double`, `short?`, `bool?` parameters representing measured/calculated values (e.g., excitation, offset, noise, gain, shunt deflection, bridge resistance).
|
||||
- **Returns**: Output parameter `@new_id` is captured but *not returned*.
|
||||
|
||||
#### `InsertSquibDiagnosticResult(...)`
|
||||
- **Behavior**: Inserts a squib (pyro) fire diagnostic result, including raw time-series data (current, voltage, time axis) as binary blobs. Uses the stored procedure `sp_DiagnosticsResultsSquibInsert`.
|
||||
- **Parameters**:
|
||||
- `iDASRecordId`, `dasChannelNumber`, `eventNumber`: Identifiers.
|
||||
- `squibFireCurrentData`, `squibFireVoltageData`, `squibFireTimeAxis`: Arrays of `double` representing raw waveform data.
|
||||
- Optional metrics: `measuredDurationMS`, `measuredDelayMS`, pass/fail flags.
|
||||
- Calibration/scaling parameters: `squibThreshold`, `squibVoltageScaler`, `squibCurrentScaler`.
|
||||
- **Special Behavior**:
|
||||
- **Early return** if `squibFireCurrentData == null` (prevents exception in `BitConverter.GetBytes`).
|
||||
- Converts `double[]` arrays to `byte[]` via `BitConverter.GetBytes` before storing in `VARBINARY` parameters.
|
||||
|
||||
#### `InsertDigitalDiagnosticResult(...)`
|
||||
- **Behavior**: Inserts a digital diagnostic result (e.g., for digital input state verification). Uses the stored procedure `sp_DiagnosticsResultsDigitalInsert`.
|
||||
- **Parameters**:
|
||||
- `iDASRecordId`, `dasChannelNumber`, `eventNumber`: Identifiers.
|
||||
- `digitalInputActiveState`: Boolean indicating whether the digital input was in its active state.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **Database Connection Check**: Every method first checks `DbWrapper.Connected`. If `false`, the method returns early *without* executing any DB operation or raising an exception.
|
||||
- **Stored Procedure Execution**: All methods use `CommandType.StoredProcedure` and call `DbWrapper.ProcessReturn(errorNumber, errorMessage)` after execution. This implies:
|
||||
- Stored procedures are expected to set `@errorNumber` and `@errorMessage` output parameters.
|
||||
- `DbWrapper.ProcessReturn(...)` likely throws or logs on non-zero `@errorNumber`.
|
||||
- **Connection Disposal**: All `SqlCommand` objects are wrapped in `using` blocks, and `cmd.Connection.Dispose()` is called explicitly in `finally` blocks — ensuring connections are released even on failure.
|
||||
- **Null Handling for Parameters**: Parameters with nullable types (e.g., `double?`) are passed directly as `Value = nullableValue`. ADO.NET treats `null` as SQL `NULL`, which is consistent with the stored procedure expectations (e.g., `@EventNumber` can be `null` in `ClearExistingDiagnosticsAllChannels`).
|
||||
- **No Return of Output Values**: While `@new_id` and error parameters are declared and populated, only errors are processed via `DbWrapper.ProcessReturn(...)`. The `@new_id` values are *not* exposed to callers.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### **Internal Dependencies**
|
||||
- `DASFactoryDb.Diagnostics.Diagnostics` depends on:
|
||||
- `DbWrapper` (static class, not shown here) — provides:
|
||||
- `Connected` property
|
||||
- `GetDASFactoryCommand()` method (returns `SqlCommand`)
|
||||
- `ProcessReturn(SqlParameter errorNumber, SqlParameter errorMessage)` method
|
||||
- `System.Data`, `System.Data.SqlClient` — standard ADO.NET types.
|
||||
|
||||
#### **External Dependencies**
|
||||
- **Database**:
|
||||
- Stored procedures:
|
||||
- `sp_DiagnosticActionsClear`
|
||||
- `sp_DiagnosticsActionsInsert`
|
||||
- `sp_DiagnosticsResultsClear`
|
||||
- `sp_DiagnosticsResultsAnalogInsert`
|
||||
- `sp_DiagnosticsResultsSquibInsert`
|
||||
- `sp_DiagnosticsResultsDigitalInsert`
|
||||
- Tables implied by the procedures (not visible in source).
|
||||
- **Assumed Schema**:
|
||||
- Tables likely include `IDASCommunicationRecordId`, `DASChannelNumber`, `EventNumber` as composite keys or foreign keys.
|
||||
- Analog/digital/squib results stored in separate tables (based on procedure names).
|
||||
|
||||
#### **Dependents**
|
||||
- Unknown — not visible in this file. Likely consumed by higher-level diagnostic orchestration or test execution modules.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **Silent Failures on Disconnected State**: If `DbWrapper.Connected` is `false`, *all* methods return immediately with no indication of failure (no exception, no log). This may mask configuration or runtime issues.
|
||||
- **Missing Return of Inserted IDs**: The `@new_id` output parameter is declared and populated by the stored procedure but *never returned* to the caller. Callers cannot reference newly inserted records.
|
||||
- **Squib Data Null Guard is Incomplete**: While `squibFireCurrentData == null` triggers early return, `squibFireVoltageData` or `squibFireTimeAxis` being `null` would cause a `NullReferenceException` in the `foreach` loop. This is inconsistent and risky.
|
||||
- **Typo in Parameter Name**: In `InsertAnalogDiagnosticResult`, the parameter `@AutoZeroPercentDeviation ` has a trailing space in the name (`"AutoZeroPercentDeviation "`), which may cause a mismatch with the stored procedure definition if not also defined with a trailing space.
|
||||
- **No Validation on Channel/Event Numbers**: No checks for negative or out-of-range `dasChannelNumber` or `eventNumber`. Relies on DB constraints or stored procedure logic.
|
||||
- **Binary Data Conversion**: `double[]` → `byte[]` conversion assumes little-endian architecture (standard on .NET on Windows), but may differ on other platforms (though DAS systems are typically Windows-based).
|
||||
- **Ambiguous Channel Numbering**: Source does not clarify whether `dasChannelNumber` is 0-based or 1-based — critical for correct usage.
|
||||
|
||||
> **None identified from source alone** for other potential issues (e.g., transactional consistency, concurrency, error logging behavior beyond `ProcessReturn`).
|
||||
118
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/Download.md
Normal file
118
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/Download.md
Normal file
@@ -0,0 +1,118 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DASFactoryDb/Download/Download.cs
|
||||
generated_at: "2026-04-16T03:52:56.569022+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "8f2bca6182f06470"
|
||||
---
|
||||
|
||||
# Documentation: `DASFactoryDb.Download.Download` Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a set of static methods for managing event-related data in the DAS (Distributed Acoustic Sensing) factory database. Its primary role is to **clear or insert records related to event downloads, arm attempts, fault flags, event metadata, GUIDs, and download requests**—all scoped to a specific `IDASCommunicationRecordId`. It acts as a database abstraction layer, encapsulating calls to stored procedures for data integrity and separation of concerns, and ensures that operations are only executed when the database connection is active.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All methods are `public static` and belong to the `DASFactoryDb.Download.Download` class.
|
||||
|
||||
### Clearing Methods (all return `void`, accept `int idasRecordId`)
|
||||
|
||||
| Method | Signature | Behavior |
|
||||
|--------|-----------|----------|
|
||||
| `ClearExistingEventDownloadStatus` | `public static void ClearExistingEventDownloadStatus(int idasRecordId)` | Clears all existing download status entries for the given DAS communication record. Calls `sp_EventDownloadStatusClear`. |
|
||||
| `ClearExistingEventArmAttempts` | `public static void ClearExistingEventArmAttempts(int idasRecordId)` | Clears all arm attempt records for the given DAS communication record. Calls `sp_EventArmAttemptsClear`. |
|
||||
| `ClearExistingFaultFlags` | `public static void ClearExistingFaultFlags(int idasRecordId)` | Clears all fault flags for the given DAS communication record. Calls `sp_EventFaultFlagsClear`. |
|
||||
| `ClearExistingDownloadReports` | `public static void ClearExistingDownloadReports(int idasRecordId)` | Clears all download report entries for the given DAS communication record. Calls `sp_DownloadReportClear`. |
|
||||
| `ClearExistingEventGuids` | `public static void ClearExistingEventGuids(int idasRecordId)` | Clears all event GUIDs for the given DAS communication record. Calls `sp_EventGuidsClear`. |
|
||||
| `ClearExistingDownloadRequests` | `public static void ClearExistingDownloadRequests(int idasRecordId)` | Clears all download request entries for the given DAS communication record. Calls `sp_DownloadRequestsClear`. |
|
||||
| `ClearExistingUARTDownloadRequests` | `public static void ClearExistingUARTDownloadRequests(int idasRecordId)` | Clears all UART-specific download request entries for the given DAS communication record. Calls `sp_UARTDownloadRequestsClear`. |
|
||||
|
||||
### Insertion Methods (all return `void`, accept `idasRecordId` + event-specific parameters)
|
||||
|
||||
| Method | Signature | Behavior |
|
||||
|--------|-----------|----------|
|
||||
| `InsertEventFaultFlags` | `public static void InsertEventFaultFlags(int iDASRecordId, ushort faultFlag)` | Inserts a single fault flag for the given DAS record. Calls `sp_EventFaultFlagsInsert`. Returns `@new_Id` output parameter (not exposed). |
|
||||
| `InsertEventArmAttempts` | `public static void InsertEventArmAttempts(int iDASRecordId, int armAttempts)` | Inserts arm attempt count for the given DAS record. Calls `sp_EventArmAttemptsInsert`. Returns `@new_id` output parameter (not exposed). |
|
||||
| `InsertEventInfo` | `public static void InsertEventInfo(int iDASRecordId, int eventNumber, Guid testGUID, ushort faultFlags, int armAttempts, DateTime testTime, string testID, string description, bool hasBeenDownloaded, bool wasTriggered, string xml)` | Inserts core event metadata. Calls `sp_EventInfoInsert`. `testTime` is normalized to `SqlDateTime.MinValue` if `DateTime.MinValue`. `testGUID` is uppercased before insertion. `xml` is UTF-8 encoded and stored as `VarBinary`. Returns `@new_id`. |
|
||||
| `InsertEventDownloadStatus` | `public static void InsertEventDownloadStatus(int iDASRecordId, bool downloadStatus)` | Inserts download status (`Downloaded` flag) for the given DAS record. Calls `sp_EventDownloadStatusInsert`. Returns `@new_id`. |
|
||||
| `DownloadRequestInsert` | `public static void DownloadRequestInsert(int iDASRecordId, ushort eventNumber, int dasChannelNumber, ulong startSample, ulong endSample, ulong samplesToSkip, double startRecordTimeStampSec, double triggerTimeStampSec, double startRecordTimeStampNanoSec, double triggerTimestampNanoSec, bool PTPMasterSync)` | Inserts a standard (likely Ethernet-based) download request. Calls `sp_DownloadRequestsInsert`. Note: `@StartRecordTimestampNanoSec` parameter is incorrectly assigned `startRecordTimeStampSec` instead of `startRecordTimeStampNanoSec` (see *Gotchas*). |
|
||||
| `UARTDownloadRequestInsert` | `public static void UARTDownloadRequestInsert(int iDASRecordId, ushort eventNumber, ulong totalByteCount, ulong triggerByteCount, ulong faultByteCount, ulong startTimestamp, ulong endTimestamp, int baudRate)` | Inserts a UART-specific download request. Calls `sp_UARTDownloadRequestsInsert`. |
|
||||
| `EventGuidInsert` | `public static void EventGuidInsert(int iDASRecordId, Guid guid)` | Inserts a single event GUID for the given DAS record. Calls `sp_EventGuidsInsert`. `guid.ToString().ToUpper()` is used. Returns `@new_Id`. |
|
||||
|
||||
> **Note on Output Parameters**: All insertion methods declare output parameters (`@errorNumber`, `@errorMessage`, `@new_id`/`@new_Id`) and call `DbWrapper.ProcessReturn(errorNumber, errorMessage)` *except* `InsertEventFaultFlags`, which does **not** call `DbWrapper.ProcessReturn`. This is inconsistent and may lead to unhandled errors.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Database Connection Check**: Every method first checks `if (!DbWrapper.Connected) { return; }`. No operation proceeds if the database is not connected.
|
||||
- **Stored Procedure Execution**: All methods use `CommandType.StoredProcedure` and execute via `cmd.ExecuteNonQuery()`.
|
||||
- **Connection Disposal**: Each method disposes the command connection in a `finally` block (`cmd.Connection.Dispose()`), ensuring cleanup even on exceptions.
|
||||
- **Parameter Naming Consistency**: Stored procedure parameters consistently use `@IDASCommunicationRecordId`, `@errorNumber`, `@errorMessage`, and `@new_id`/`@new_Id`.
|
||||
- **GUID Normalization**: GUIDs passed to `InsertEventInfo` and `EventGuidInsert` are uppercased via `.ToString().ToUpper()`.
|
||||
- **DateTime Normalization**: `testTime == DateTime.MinValue` is converted to `SqlDateTime.MinValue` before insertion in `InsertEventInfo`.
|
||||
- **XML Encoding**: The `xml` parameter in `InsertEventInfo` is UTF-8 encoded before being passed as `VarBinary`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies
|
||||
- `DASFactoryDb.Download.Download` depends on:
|
||||
- `DbWrapper` (static class, not shown in source) — provides `Connected`, `GetDASFactoryCommand()`, and `ProcessReturn()` methods.
|
||||
- Standard .NET libraries: `System.Data`, `System.Data.SqlClient`, `System.IO`, `System.Text`, `System.Xml`.
|
||||
|
||||
### External Dependencies
|
||||
- **SQL Server Database** — requires the following stored procedures to exist:
|
||||
- `sp_EventDownloadStatusClear`
|
||||
- `sp_EventArmAttemptsClear`
|
||||
- `sp_EventFaultFlagsClear`
|
||||
- `sp_DownloadReportClear`
|
||||
- `sp_EventGuidsClear`
|
||||
- `sp_DownloadRequestsClear`
|
||||
- `sp_EventFaultFlagsInsert`
|
||||
- `sp_EventArmAttemptsInsert`
|
||||
- `sp_EventInfoInsert`
|
||||
- `sp_EventDownloadStatusInsert`
|
||||
- `sp_DownloadRequestsInsert`
|
||||
- `sp_UARTDownloadRequestsInsert`
|
||||
- `sp_UARTDownloadRequestsClear`
|
||||
- `sp_EventGuidsInsert`
|
||||
- **Database Schema** — expects tables/columns compatible with the above stored procedures.
|
||||
|
||||
### Who Depends on This Module?
|
||||
- Any code that needs to manage DAS event data in the database (e.g., event processing pipelines, download initiators, fault handlers). Not specified in source.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Parameter Mismatch in `DownloadRequestInsert`**:
|
||||
The parameter `@StartRecordTimestampNanoSec` is assigned `startRecordTimeStampSec` instead of `startRecordTimeStampNanoSec`. This is likely a copy-paste error and will cause incorrect timestamp data to be stored.
|
||||
```csharp
|
||||
// Current (incorrect):
|
||||
new SqlParameter("@StartRecordTimestampNanoSec", SqlDbType.Decimal)
|
||||
{ Value = startRecordTimeStampSec }); // ← should be startRecordTimeStampNanoSec
|
||||
```
|
||||
|
||||
- **Inconsistent Error Handling**:
|
||||
`InsertEventFaultFlags` does **not** call `DbWrapper.ProcessReturn(errorNumber, errorMessage)`, while all other insertion methods do. This may result in unhandled database errors (e.g., constraint violations, stored procedure errors) going silently unnoticed.
|
||||
|
||||
- **No Return of Output Values**:
|
||||
Although all methods declare and populate `@new_id`/`@new_Id` output parameters, none expose them to callers. If the new record ID is needed, callers must refactor the method or access it via `cmd.Parameters["@new_id"].Value` after execution (not possible here due to static encapsulation).
|
||||
|
||||
- **Silent Failures on Disconnection**:
|
||||
Methods return early if `!DbWrapper.Connected`, but no logging or exception occurs. Callers may assume success even when no operation was performed.
|
||||
|
||||
- **No Input Validation**:
|
||||
Methods do not validate input parameters (e.g., `idasRecordId` is not checked for negative values). Assumed valid by downstream stored procedures.
|
||||
|
||||
- **Case Sensitivity of GUIDs**:
|
||||
GUIDs are uppercased before insertion. If the database or downstream consumers expect lowercase or canonical format, mismatches may occur.
|
||||
|
||||
- **No Transaction Support**:
|
||||
Each method executes in its own implicit transaction (default ADO.NET behavior). If callers need atomicity across multiple operations (e.g., clear + insert), they must manage transactions externally.
|
||||
|
||||
- **String Length Assumptions**:
|
||||
Parameters like `@errorMessage` are declared with `SqlDbType.NVarChar, 255`. If stored procedures return longer messages, truncation may occur silently.
|
||||
|
||||
- **Missing `using` for `SqlParameter`**:
|
||||
Parameters are not wrapped in `using` blocks. While not strictly necessary (they’re not `IDisposable`), it’s inconsistent with best practices and may raise static analysis warnings.
|
||||
|
||||
None identified beyond the above.
|
||||
35
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/Properties.md
Normal file
35
enriched-qwen3-coder-next/DataPRO/DASFactoryDb/Properties.md
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DASFactoryDb/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T03:52:28.192883+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "4cb05f8c94826e69"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module is the `DASFactoryDb` .NET assembly, serving as a foundational data access layer component within the `DataPRO` product suite. Its primary role is to encapsulate database-related functionality—though the provided `AssemblyInfo.cs` file contains only metadata attributes and no executable logic—suggesting it is a supporting infrastructure assembly intended to be consumed by other modules (e.g., data access implementations, repositories, or ORM configurations). The assembly is not directly executable (no entry point) and exists solely to be referenced by other projects in the solution.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public API surface is defined in this file.**
|
||||
`AssemblyInfo.cs` is a metadata file used by the .NET build system to embed assembly-level attributes (e.g., version, title, COM visibility). It declares no classes, interfaces, methods, properties, or fields. All public-facing functionality—should it exist—is located in *other* source files not included here.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly identity is fixed at version `1.0.0.0` (both `AssemblyVersion` and `AssemblyFileVersion`).
|
||||
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning external COM clients cannot directly instantiate types from this assembly unless explicitly exposed via other means.
|
||||
- The GUID `49c60032-9c8a-4ea5-9e26-2f1663555759` is reserved for the type library (typelib) ID if the assembly is later exposed to COM.
|
||||
- No runtime invariants apply, as this file contains no executable code.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Dependencies of this assembly**: None. `AssemblyInfo.cs` only imports standard .NET attributes (`System.Reflection`, `System.Runtime.CompilerServices`, `System.Runtime.InteropServices`) and does not reference any external libraries or internal modules.
|
||||
- **Dependents**: This assembly is intended to be referenced by other projects (e.g., `DataPRO` core modules or database service layers), but no specific consumers are identifiable from this file alone.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Misleading file location**: The path `DataPRO/DASFactoryDb/Properties/AssemblyInfo.cs` suggests this assembly may contain database access logic (per the `DASFactoryDb` name), but this file provides no implementation—only metadata. Developers should not expect database-related APIs here.
|
||||
- **Versioning rigidity**: The `AssemblyVersion` is hardcoded to `1.0.0.0` with no wildcard (`*`), meaning build/revision numbers cannot auto-increment. This may complicate deployment or version tracking if not managed externally (e.g., via CI/CD).
|
||||
- **COM visibility**: While `ComVisible(false)` is set, developers integrating with legacy COM systems must ensure types requiring COM exposure are explicitly marked `[ComVisible(true)]` in *other* source files.
|
||||
- **No documentation**: `AssemblyDescription` and `AssemblyCulture` are empty, indicating incomplete assembly metadata—this may hinder automated tooling or documentation generation.
|
||||
|
||||
None identified beyond the above.
|
||||
141
enriched-qwen3-coder-next/DataPRO/DTS.Core.DbAPIWrapper.md
Normal file
141
enriched-qwen3-coder-next/DataPRO/DTS.Core.DbAPIWrapper.md
Normal file
@@ -0,0 +1,141 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DTS.Core.DbAPIWrapper/ApiInfo.cs
|
||||
- DataPRO/DTS.Core.DbAPIWrapper/DbApiWrapper.cs
|
||||
generated_at: "2026-04-16T03:50:33.707237+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "64f38e1e002da8cf"
|
||||
---
|
||||
|
||||
# DTS.Core.DbAPIWrapper
|
||||
|
||||
## Documentation: `DTS.Core.DbAPIWrapper` Module
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module serves as a thin, opinionated wrapper around the legacy `DbAPI` library to provide a consistent, authenticated, and async-friendly interface for interacting with database-backed test setup and DAS (Data Acquisition System) data. It encapsulates connection setup, user authentication, and API invocation logic, ensuring that all downstream consumers interact with the database through a controlled, validated channel—while abstracting away low-level error handling and state management (e.g., `ApiInfo` tracking of authenticated session context).
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `DbApiWrapper` class
|
||||
|
||||
##### Constructor
|
||||
```csharp
|
||||
public DbApiWrapper(
|
||||
string dbServer,
|
||||
string dbName,
|
||||
string dbUsername,
|
||||
string dbPassword,
|
||||
bool adAuthentication,
|
||||
bool useCentralizedDb,
|
||||
int? clientDbVersion = null)
|
||||
```
|
||||
- Initializes a new instance with raw connection parameters.
|
||||
- Internally constructs a `ConnectionDetails` object and stores it in `_connectionDetail`.
|
||||
- Does **not** connect to the database at construction time.
|
||||
|
||||
##### `AuthenticateUser`
|
||||
```csharp
|
||||
public void AuthenticateUser(string username, string password)
|
||||
```
|
||||
- Performs synchronous database connection and user login via `DbAPI.DbAPI.Connections.LoginUser`.
|
||||
- On success, populates `_apiInfo` with the first entry from `GetLoggedInUsers()` (a tuple of `IUserDbRecord` and `IConnectionDetails`).
|
||||
- Throws `UnauthorizedAccessException` if login fails or no logged-in users are returned.
|
||||
|
||||
##### `TestSetupsGet`
|
||||
```csharp
|
||||
public Tuple<ITestSetupRecord[], string[], ulong> TestSetupsGet(
|
||||
int? testSetupId = null,
|
||||
string? testSetupName = null,
|
||||
double defaultROIStart = double.NaN,
|
||||
double defaultROIEnd = double.NaN,
|
||||
bool defaultIgnoreShortedStart = false,
|
||||
bool defaultIgnoreShortedTrigger = false)
|
||||
```
|
||||
- Synchronous wrapper around `GetTestSetups`.
|
||||
- Returns a tuple:
|
||||
- `Item1`: Array of `ITestSetupRecord` (test setup definitions).
|
||||
- `Item2`: Array of `string` (error messages from the underlying API).
|
||||
- `Item3`: `ulong` error code returned by `TestSetupsGet`.
|
||||
- Throws `Exception` if authentication is missing or if the underlying call fails.
|
||||
|
||||
##### `TestSetupsGetAsync`
|
||||
```csharp
|
||||
public async Task<Tuple<ITestSetupRecord[], string[], ulong>> TestSetupsGetAsync(
|
||||
int? testSetupId = null,
|
||||
string? testSetupName = null,
|
||||
double defaultROIStart = double.NaN,
|
||||
double defaultROIEnd = double.NaN,
|
||||
bool defaultIgnoreShortedStart = false,
|
||||
bool defaultIgnoreShortedTrigger = false)
|
||||
```
|
||||
- Asynchronous wrapper that offloads `GetTestSetups` to a background thread via `Task.Run`.
|
||||
- Behavior and return semantics identical to `TestSetupsGet`.
|
||||
|
||||
##### `DASGet`
|
||||
```csharp
|
||||
public Tuple<IDASDBRecord[], ulong> DASGet(
|
||||
string? dasSerial = null,
|
||||
string? position = null)
|
||||
```
|
||||
- Synchronous wrapper around `GetDAS`.
|
||||
- Returns a tuple:
|
||||
- `Item1`: Array of `IDASDBRecord` (DAS device records).
|
||||
- `Item2`: `ulong` error code from `DASGet`.
|
||||
- Throws `Exception` if authentication is missing or underlying call fails.
|
||||
|
||||
##### `DASGetAsync`
|
||||
```csharp
|
||||
public async Task<Tuple<IDASDBRecord[], ulong>> DASGetAsync(
|
||||
string? dasSerial = null,
|
||||
string? position = null)
|
||||
```
|
||||
- Asynchronous wrapper for `GetDAS`, using `Task.Run`.
|
||||
- Behavior and return semantics identical to `DASGet`.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- `_apiInfo` **must** be non-null and contain non-null `UserDbRecord` and `ConnectionDetails` before any `GetTestSetups` or `GetDAS` call is made. Otherwise, an `Exception` with message `"Authentication is required"` is thrown.
|
||||
- `_connectionDetail` is initialized once in the constructor and never modified.
|
||||
- `Connect()` is called unconditionally in `AuthenticateUser`, and failure (non-zero return) throws an `Exception`.
|
||||
- `AuthenticateUser` expects `GetLoggedInUsers()` to return at least one entry; otherwise, it throws `UnauthorizedAccessException`.
|
||||
- All public methods (`TestSetupsGet`, `DASGet`, etc.) wrap internal calls in `try/catch` and re-throw with additional context (e.g., `"TestSetupsGet failed. {ex.Message}"`).
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### Internal Dependencies (from imports)
|
||||
- `DbAPI.Connections` – Provides `ConnectToDb`, `LoginUser`, `GetLoggedInUsers`, `TestSetups.TestSetupsGet`, and `DAS.DASGet`.
|
||||
- `DTS.Common.Interface.Database` – Defines `IUserDbRecord`, `IConnectionDetails`.
|
||||
- `DTS.Common.Interface.DataRecorders` – Defines `IDASDBRecord`.
|
||||
- `DTS.Common.Interface.TestSetups.TestSetupsList` – Defines `ITestSetupRecord`.
|
||||
|
||||
#### External Dependencies
|
||||
- The `DbAPI` native/managed interop library (not included in source).
|
||||
- `DTS.Common` assembly (contains shared interfaces and types).
|
||||
- Standard .NET `System` (for `Tuple`, `Task`, `Exception`, etc.).
|
||||
|
||||
#### Usage
|
||||
- This module is consumed by higher-level services or UI layers that need to fetch test setups or DAS records after authenticating a user.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **Authentication state is implicit and per-instance**: `_apiInfo` is stored as a private field; once `AuthenticateUser` succeeds, all subsequent calls on the same `DbApiWrapper` instance assume the session is valid. No explicit session invalidation or logout mechanism is exposed.
|
||||
- **`Connect()` is called twice in `AuthenticateUser`**: Once explicitly, and implicitly inside `LoginUser` (if `LoginUser` internally calls `ConnectToDb`). This may cause redundant connection attempts.
|
||||
- **`_ = userRecord;` is a no-op**: The result of `LoginUser`’s `out var userRecord` is assigned but discarded—only the `hr` return code is checked. This may indicate incomplete error handling or legacy code.
|
||||
- **Async methods use `Task.Run`**: This blocks a thread pool thread and does *not* provide true async I/O (e.g., no async DB APIs used). This may cause scalability issues under high load.
|
||||
- **`clientDbVersion` defaults to `0` if `null`**: The constructor uses `clientDbVersion.HasValue ? clientDbVersion.Value : 0`, which may mask missing version information.
|
||||
- **No validation on input parameters**: e.g., empty strings for `dbServer`, `dbName`, etc., are not explicitly rejected at construction time.
|
||||
- **`GetLoggedInUsers()` returns `Tuple<IUserDbRecord, IConnectionDetails>[]`**: The code assumes the first entry (`loggedInUsers[0]`) is valid—no fallback or selection logic is present.
|
||||
|
||||
> *None of the above constitute bugs per se, but they represent design decisions or legacy patterns that may surprise new developers.*
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO Installer/Source Files/Driver/DPInstallWrapper2/DPInstallWrapper2.cs
|
||||
generated_at: "2026-04-16T04:02:48.349215+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "eced6fe57fe04215"
|
||||
---
|
||||
|
||||
# DPInstallWrapper2
|
||||
|
||||
### **Purpose**
|
||||
This module is a thin command-line wrapper executable (`DPInstallWrapper2.exe`) designed to invoke `dpinst.exe` (the Microsoft Driver Package Installer) with specific arguments while masking its exit code. It exists to ensure that the driver installation process—regardless of `dpinst.exe`’s actual exit status—reports success (exit code `0`) to the calling installer, avoiding premature termination of the overall installation flow due to `dpinst.exe`’s known non-zero exit codes on successful operations.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
The module exposes a single public entry point:
|
||||
|
||||
- **`static int Main(string[] args)`**
|
||||
Entry point for the executable. Accepts command-line arguments, wraps arguments containing spaces in double quotes, constructs and launches `dpinst.exe` with the first four arguments (index `0` as the executable path, indices `1`–`3` as arguments), waits for its completion, and unconditionally returns `0` to the caller.
|
||||
- *Behavior*:
|
||||
- `args[0]` → path to `dpinst.exe`
|
||||
- `args[1]`, `args[2]`, `args[3]` → passed as arguments to `dpinst.exe`
|
||||
- Arguments containing spaces are quoted *before* constructing the argument string.
|
||||
- Always returns `0`, regardless of `dpinst.exe`’s exit code.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
- **Argument count**: Requires at least 4 arguments (`args.Length ≥ 4`); otherwise, `IndexOutOfRangeException` occurs at runtime (e.g., `args[3]` access).
|
||||
- **Argument quoting**: Only arguments at indices `1`, `2`, and `3` are processed for space-containing quoting; `args[0]` (the executable path) is *not* quoted, even if it contains spaces.
|
||||
- **Exit code masking**: The wrapper *always* returns `0`, discarding the actual exit code from `dpinst.exe`.
|
||||
- **Execution semantics**: The wrapper blocks until `dpinst.exe` exits (`WaitForExit()`), but does not propagate its output or error streams.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
- **Runtime**: .NET Framework (uses `System.Diagnostics.Process`).
|
||||
- **External tool**: Relies on `dpinst.exe` (Microsoft Driver Package Installer) being present at the path specified in `args[0]`.
|
||||
- **Caller**: Intended to be invoked by an external installer (e.g., an MSI or custom setup project) that expects a `0` exit code for success.
|
||||
- **No internal dependencies**: No external libraries beyond the core .NET runtime.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
- **Hardcoded argument count**: Assumes exactly 4 arguments (`args.Length == 4`). If fewer than 4 arguments are provided, a runtime exception occurs. If more than 4 are provided, they are silently ignored.
|
||||
- **Unsafe quoting logic**: Only checks for spaces in arguments at indices `1–3`; does not handle embedded quotes, backslashes, or other special characters that may break command-line parsing.
|
||||
- **`dpinst.exe` path vulnerability**: If `args[0]` contains spaces but is not quoted, `Process.Start()` will fail (e.g., `"C:\Program Files\dpinst.exe"`). The wrapper does *not* quote `args[0]`, unlike other arguments.
|
||||
- **No error logging**: No output, logging, or diagnostics are produced—failure of `dpinst.exe` is invisible to callers beyond the misleading success exit code.
|
||||
- **Historical workaround**: The comment explicitly states this is a workaround for `dpinst.exe` returning non-zero exit codes on success—a known quirk of older `dpinst.exe` versions, but may be unnecessary for newer versions.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO Installer/Source Files/Driver/DPInstallWrapper2/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T04:02:56.643467+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2b461d09745d539e"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module (`DPInstallWrapper2`) is an assembly containing metadata and configuration for a .NET installer wrapper component used in the DataPRO ecosystem. Its primary role is to define assembly-level attributes—such as title, version, and COM visibility settings—required for proper deployment, versioning, and integration with Windows Installer or COM-based installation infrastructure. It does not contain executable logic; it serves as a metadata container for build-time and runtime identification and registration.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public types or members are defined in this file.**
|
||||
This file (`AssemblyInfo.cs`) is strictly for assembly-level attributes and contains no classes, interfaces, methods, or properties. All content consists of `Assembly*` attributes applied via the `[assembly: ...]` syntax.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning its types cannot be accessed via COM interop unless explicitly exposed elsewhere (e.g., via `ComVisible(true)` on a specific type, though none exist here).
|
||||
- The assembly version is fixed at `1.0.0.0` for both `AssemblyVersion` and `AssemblyFileVersion`.
|
||||
- The `Guid` attribute (`bb0e5961-d169-4dab-ac55-72e1e71c1ef9`) uniquely identifies the typelib for COM registration purposes, though COM visibility is disabled.
|
||||
- No runtime invariants or stateful constraints apply, as this file contributes only compile-time metadata.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Dependencies**:
|
||||
- `System.Reflection`
|
||||
- `System.Runtime.CompilerServices`
|
||||
- `System.Runtime.InteropServices`
|
||||
These are standard .NET Framework namespaces (implicitly available in any .NET project targeting Windows).
|
||||
- **Dependents**:
|
||||
- This assembly is likely referenced by a larger installer project (e.g., WiX, InstallShield, or custom bootstrapper) that consumes its metadata (e.g., for versioning, signing, or COM registration).
|
||||
- No internal code in this file implies direct dependents; usage is inferred from the assembly’s role in the broader `DataPRO Installer` solution.
|
||||
|
||||
## 5. Gotchas
|
||||
- **No executable code**: This file should not be expected to contain logic; developers should not attempt to call or instantiate anything from it.
|
||||
- **COM visibility is disabled**: Despite the `Guid` attribute, COM clients cannot access types in this assembly due to `ComVisible(false)`. If COM exposure is needed, it must be enabled at the type level in *other* files (not present here).
|
||||
- **Version hardcoding**: Both `AssemblyVersion` and `AssemblyFileVersion` are fixed to `1.0.0.0`. This may indicate legacy or manual version management; automated build pipelines (e.g., CI/CD) may override these values, but the source as written does not support dynamic versioning.
|
||||
- **Empty metadata fields**: `AssemblyDescription`, `AssemblyConfiguration`, `AssemblyCompany`, and `AssemblyTrademark` are empty strings—this may cause ambiguity in deployment logs or system inventory tools.
|
||||
- **None identified from source alone.**
|
||||
34
enriched-qwen3-coder-next/DataPRO/DataPRO.Core.md
Normal file
34
enriched-qwen3-coder-next/DataPRO/DataPRO.Core.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO.Core/DataProConstants.cs
|
||||
generated_at: "2026-04-16T03:50:00.722601+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "1f1b18c028b06794"
|
||||
---
|
||||
|
||||
# DataPRO.Core
|
||||
|
||||
1. **Purpose**
|
||||
This module defines compile-time constants used across the DataPRO.Core assembly, specifically centralizing configuration file path resolution. Its role is to ensure consistent referencing of the application’s configuration file (`DataPRO.exe.config`) throughout the codebase, avoiding hardcoded string duplication and enabling future maintainability if the path needs to be updated.
|
||||
|
||||
2. **Public Interface**
|
||||
- `public static class DataProConstants`
|
||||
A static class containing only one public constant field:
|
||||
- `public const string CustomConfigPath = @"DataPRO.exe.config";`
|
||||
Represents the relative path to the application configuration file. *Note: An alternative absolute path (`@"C:\Program Files\DataPro\bin\DataPro.config"`) is commented out, indicating it was previously considered or used but is no longer active.*
|
||||
|
||||
3. **Invariants**
|
||||
- `CustomConfigPath` is guaranteed to be a non-null, non-empty string literal at compile time.
|
||||
- The value is fixed at compile time and cannot be modified at runtime.
|
||||
- The path is relative (not absolute), implying the configuration file is expected to reside in the application’s base directory (or current working directory, depending on deployment context).
|
||||
|
||||
4. **Dependencies**
|
||||
- **Depends on**: None (this is a pure constants container with no external dependencies).
|
||||
- **Depended on by**: Other modules within `DataPro.Core` (and potentially higher-level assemblies referencing `DataPro.Core`) that require access to the configuration file path. The commented-out absolute path suggests past or potential usage in deployment-specific contexts (e.g., installer logic, setup tools), but no direct callers are visible in the provided source.
|
||||
|
||||
5. **Gotchas**
|
||||
- The commented-out `CustomConfigPath` value (`@"C:\Program Files\DataPro\bin\DataPro.config"`) may indicate legacy behavior or platform-specific assumptions (e.g., Windows-only, 32-bit vs 64-bit install paths). Developers should avoid re-enabling it without verifying compatibility with current deployment practices (e.g., ClickOnce, MSIX, containerized environments).
|
||||
- The use of a *relative* path (`DataPRO.exe.config`) assumes the configuration file is co-located with the executable at runtime; this may not hold in all hosting scenarios (e.g., unit test runners, plugin architectures, or when the app is launched from a different working directory).
|
||||
- No validation or existence check is performed on the path—consumers must handle cases where the file is missing or unreadable.
|
||||
- None identified from source alone.
|
||||
75
enriched-qwen3-coder-next/DataPRO/DataPRO.Core/Config.md
Normal file
75
enriched-qwen3-coder-next/DataPRO/DataPRO.Core/Config.md
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO.Core/Config/DataProConfig.cs
|
||||
generated_at: "2026-04-16T04:27:34.469920+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "c18420fbff70f9a1"
|
||||
---
|
||||
|
||||
# Config
|
||||
|
||||
## Documentation: `DataProConfig` Module
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module provides centralized, static access to application configuration settings loaded from a *custom* configuration file (as specified by `DataProConstants.CustomConfigPath`). It abstracts the underlying `ConfigurationManager` mechanics to enable consistent retrieval of `<appSettings>` values and arbitrary configuration sections across the codebase—particularly by plugin code that requires access to non-standard configuration sections. Its existence ensures decoupling from direct `ConfigurationManager` usage and enforces use of a dedicated configuration file rather than the default `app.config`/`web.config`.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `public static Configuration AltConfig { get; }`
|
||||
- **Type**: Static property
|
||||
- **Behavior**: Returns the `Configuration` object loaded from the custom config file path (`DataProConstants.CustomConfigPath`). This is the primary handle to the entire configuration structure.
|
||||
- **Note**: The property name `AltConfig` is misleading—it is *not* an alternate; it is the *primary* configuration source for this module.
|
||||
|
||||
#### `public static string GetAppSetting(string key)`
|
||||
- **Type**: Static method
|
||||
- **Signature**: `string GetAppSetting(string key)`
|
||||
- **Behavior**: Retrieves the value of an `<add key="..." value="..." />` entry from the `<appSettings>` section of the custom config file. Returns `string.Empty` if the key is not found.
|
||||
- **Implementation detail**: Uses LINQ over `Config.AppSettings.Settings` (cast to `KeyValueConfigurationElement`) to locate the matching key.
|
||||
|
||||
#### `public static object GetSection(string sectionName)`
|
||||
- **Type**: Static method
|
||||
- **Signature**: `object GetSection(string sectionName)`
|
||||
- **Behavior**: Retrieves a custom configuration section (e.g., `<pluginLibrary>`, `<dataSources>`) by name from the custom config file. Returns `null` if the section is not defined or fails to load.
|
||||
- **Intended use**: Designed for plugin code to deserialize and consume plugin-specific configuration sections.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- The configuration file path is *fixed at initialization* and derived from `DataProConstants.CustomConfigPath`.
|
||||
- The configuration is loaded **once** during static initialization (via static constructor) and never reloaded during the application lifetime.
|
||||
- `GetAppSetting` **never throws** on missing keys—it returns `string.Empty`.
|
||||
- `GetSection` may return `null` if the section does not exist or fails to deserialize (e.g., due to schema mismatch), but the source does not indicate explicit error handling or logging.
|
||||
- The `Configuration` object (`Config`) is opened with `openReadOnly: true` (third parameter `true` in `OpenMappedExeConfiguration`), meaning writes are disallowed.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### Dependencies *on*:
|
||||
- `System.Configuration.ConfigurationManager` (for `OpenMappedExeConfiguration`, `GetSection`, `AppSettings`)
|
||||
- `System.Configuration` types: `Configuration`, `ExeConfigurationFileMap`, `ConfigurationUserLevel`, `KeyValueConfigurationElement`
|
||||
- `DataProConstants.CustomConfigPath` (assumed to be a `string` constant defining the path to the custom config file)
|
||||
|
||||
#### Dependencies *of*:
|
||||
- Plugin modules (via `GetSection`) to load plugin-specific configuration.
|
||||
- Any code needing access to `<appSettings>` or custom sections defined in the custom config file.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **Static initialization timing**: The config file is loaded at first access to *any* member of `DataProConfig`. If `DataProConstants.CustomConfigPath` points to a non-existent or inaccessible file, the static constructor will throw (e.g., `ConfigurationErrorsException`), potentially crashing app startup.
|
||||
- **No fallback behavior**: `GetAppSetting` returns `string.Empty` for missing keys—callers must explicitly check for this (e.g., `string.IsNullOrEmpty`) rather than relying on `null`.
|
||||
- **No validation**: Neither `GetAppSetting` nor `GetSection` validates the content or type of returned values. Consumers must handle parsing, casting, and validation themselves.
|
||||
- **Misleading property name**: `AltConfig` implies it is *optional* or *secondary*, but it is the *only* configuration source used by this module.
|
||||
- **No thread-safety documentation**: While `Configuration` objects are generally safe for concurrent reads, the source does not explicitly guarantee thread-safety.
|
||||
- **Assumes `<appSettings>` structure**: `GetAppSetting` assumes the config file contains a standard `<appSettings>` section; it does not handle custom section-based key-value storage.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO.Core/EventManager/EventManager.cs
|
||||
generated_at: "2026-04-16T04:27:50.546850+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "563530faa0be756e"
|
||||
---
|
||||
|
||||
# EventManager
|
||||
|
||||
## Documentation: `EventManager` Module
|
||||
|
||||
### 1. Purpose
|
||||
The `EventManager` class provides a central, static event-publishing/subscribing mechanism that decouples event producers from consumers. It enables components to publish typed events (`Publish<T>`) and subscribe to them with optional filtering (`Subscribe<T>`), while maintaining a diagnostic logging capability for runtime introspection. This module exists to support loose coupling in the system, avoiding direct dependencies between event emitters and listeners, and to aid debugging and monitoring via diagnostic events.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
- **`delegate void SubscriberCallbackDelegate<in T>(T item) where T : class`**
|
||||
Signature for event listener callbacks. Receives the event payload (`item`) of type `T`.
|
||||
|
||||
- **`delegate void DiagnosticCallbackDelegate(EventDiagnosticType eventType, Type t, object eventData, string listener)`**
|
||||
Signature for diagnostic event callbacks. Reports internal `EventManager` operations (e.g., add/remove listener, publish event) with context:
|
||||
- `eventType`: Kind of operation (`EventDiagnosticType`)
|
||||
- `t`: Event type being subscribed/published
|
||||
- `eventData`: Event payload (may be `null` for subscription/unsubscription events)
|
||||
- `listener`: Fully qualified method name and assembly (e.g., `"MyNamespace.MyClass.MyMethod, MyAssembly"`)
|
||||
|
||||
- **`static void Publish<T>(T eventData) where T : class`**
|
||||
Publishes an event of type `T`. Invokes all registered listeners for `T`, applying any per-listener filter. Skips if no listeners exist for `T`. Sends a diagnostic event for each invocation.
|
||||
|
||||
- **`static void Subscribe<T>(SubscriberCallbackDelegate<T> listener) where T : class`**
|
||||
Subscribes a listener (no filter) to events of type `T`. Internally calls `Subscribe<T>(listener, null)`.
|
||||
|
||||
- **`static void Subscribe<T>(SubscriberCallbackDelegate<T> listener, Predicate<T> eventFilter) where T : class`**
|
||||
Subscribes a listener with an optional filter (`eventFilter`). The listener is invoked only if `eventFilter(eventData)` returns `true`. Registers metadata (`EventMetaData<T>`) and sends a diagnostic event.
|
||||
|
||||
- **`static void UnSubscribe<T>(SubscriberCallbackDelegate<T> listener) where T : class`**
|
||||
Removes all subscriptions of `listener` for events of type `T`. Sends a diagnostic event.
|
||||
|
||||
- **`static void Clear()`**
|
||||
Removes *all* subscriptions for *all* event types. Sends a diagnostic event.
|
||||
|
||||
- **`static void SubscribeToDiagnosticEvents(DiagnosticCallbackDelegate listener)`**
|
||||
Registers a diagnostic listener. Sends a diagnostic event reporting the addition.
|
||||
|
||||
- **`static void UnSubscribeToDiagnosticEvents(DiagnosticCallbackDelegate listener)`**
|
||||
Removes a diagnostic listener. Sends a diagnostic event reporting the removal.
|
||||
|
||||
- **`static void ClearDiagnosticEvents()`**
|
||||
Removes *all* diagnostic listeners. Sends a diagnostic event.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **Type Safety**: All subscriptions and publications are strictly typed via generics (`T`). No type erasure occurs; `Subscribe<int>` and `Subscribe<string>` maintain separate listener lists.
|
||||
- **Filter Semantics**: Filters are *per-subscription* and *evaluated at publish time*. If `eventFilter == null`, the listener is always invoked.
|
||||
- **Listener Identity**: Unsubscription is based on *reference equality* of the delegate (`listener`). Two distinct delegates (even with identical implementation) are treated as different listeners.
|
||||
- **Diagnostic Consistency**: Every public mutation (`Subscribe`, `UnSubscribe`, `Publish`, `Clear`, diagnostic subscription changes) triggers exactly one `SendDiagnosticEvent` call.
|
||||
- **No Thread Safety**: The module is not thread-safe. Concurrent access to `SubscriberList` or `DiagnosticList` may cause corruption (no locking is present).
|
||||
- **Diagnostic Listener Isolation**: Diagnostic listeners do *not* receive diagnostics about their own registration/unregistration (e.g., `SubscribeToDiagnosticEvents` triggers a diagnostic, but the newly added listener does *not* receive it).
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
- **Internal Dependencies**:
|
||||
- `System` namespace (`System.Collections.Generic`, `System.Reflection`, `System`)
|
||||
- `EventDiagnosticType` enum (defined in same file)
|
||||
- `EventMetaData<T>` class (defined in same file, `internal` scope)
|
||||
- `SubscriberCallbackDelegate<T>` and `DiagnosticCallbackDelegate` delegates (defined in same file)
|
||||
|
||||
- **External Dependencies**:
|
||||
- None beyond standard .NET libraries (no external NuGet packages or framework dependencies beyond `mscorlib`).
|
||||
|
||||
- **Depended Upon**:
|
||||
- Any component in the `DataPro.Core` namespace (or referencing the assembly) may use `EventManager` to publish/subscribe to events.
|
||||
- Diagnostic consumers (e.g., logging, telemetry, debugging tools) subscribe via `SubscribeToDiagnosticEvents`.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`eventData` in `DiagnosticCallbackDelegate` may be `null`**: For subscription/unsubscription/diagnostic registration events, `eventData` is `null`. Diagnostic listeners must handle this.
|
||||
- **`listener` string may be `null`**: If `listenerMethod.DeclaringType` is `null` (e.g., static method in anonymous type), the `listener` string passed to the diagnostic callback is `null`.
|
||||
- **`Clear()` is global and destructive**: Removes *all* subscriptions across *all* event types—no selective clearing is supported.
|
||||
- **No deduplication on subscription**: Calling `Subscribe` twice with the *same* listener and filter adds *two* entries. Unsubscribing once removes *only one* entry (per `RemoveAll` logic). This may cause duplicate invocations if not managed carefully.
|
||||
- **Filter method reference in diagnostics**: When a filter is present, the diagnostic event reports `metaData.EventFilter.Method` as the listener method—*not* the callback method. This may be confusing if the filter and callback are defined in different methods.
|
||||
- **No weak references**: Listeners are held via strong references. If subscribers forget to `UnSubscribe`, they may be kept alive indefinitely (memory leak risk).
|
||||
- **Diagnostic events are synchronous and blocking**: Each diagnostic callback is invoked synchronously during `EventManager` operations. Slow diagnostic handlers will delay event publishing/subscription.
|
||||
- **`EventMetaData<T>` is internal**: Cannot be extended or inspected externally; behavior is fixed by the implementation.
|
||||
|
||||
None identified beyond the above.
|
||||
102
enriched-qwen3-coder-next/DataPRO/DataPRO.Core/PluginLib.md
Normal file
102
enriched-qwen3-coder-next/DataPRO/DataPRO.Core/PluginLib.md
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO.Core/PluginLib/PluginConfigData.cs
|
||||
- DataPRO/DataPRO.Core/PluginLib/PluginConfig.cs
|
||||
- DataPRO/DataPRO.Core/PluginLib/PluginConfigSectionHandler.cs
|
||||
- DataPRO/DataPRO.Core/PluginLib/PluginManager.cs
|
||||
generated_at: "2026-04-16T04:27:52.597409+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "a022d6fe08f41d94"
|
||||
---
|
||||
|
||||
# PluginLib
|
||||
|
||||
## Documentation: Plugin Configuration and Management Module
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
This module provides infrastructure for managing plugins in the DataPRO system using Managed Extensibility Framework (MEF). It defines configuration structures for specifying plugin directories, a static configuration accessor (`PluginConfig`), and a singleton `PluginManager` responsible for discovering, loading, and resolving plugin assemblies from configured directories. The module enables dynamic plugin discovery and composition at runtime based on MEF exports, while enforcing strict validation of plugin folder paths and thread-safe initialization.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `PluginConfigData`
|
||||
- **`string[] PluginFolders`**
|
||||
Public field annotated with `[XmlArrayItem("Folder")]`. Holds an array of strings representing plugin folder paths, deserialized from XML configuration.
|
||||
|
||||
#### `PluginConfig`
|
||||
- **`const string DataProPlugins = "dataProPlugins"`**
|
||||
Constant key used to locate the base plugin configuration setting in app.config.
|
||||
- **`string GetDataProPluginsSetting(string setting)`**
|
||||
Concatenates the value of the `"dataProPlugins"` app setting (retrieved via `DataProConfig.GetAppSetting`) with the provided `setting`, separated by a dot (`.`). Used to construct full setting names for plugin-specific configuration.
|
||||
|
||||
#### `PluginConfigSectionHandler`
|
||||
- **`FilterHashKeyCollection HashKeys`**
|
||||
Configuration property accessor for the `"PluginFolders"` element. Returns a `FilterHashKeyCollection` containing `FilterHashElement` instances parsed from the configuration section.
|
||||
|
||||
#### `FilterHashKeyCollection`
|
||||
- **`FilterHashElement this[int idx]`**
|
||||
Indexer to access `FilterHashElement` items by zero-based index.
|
||||
- **`protected override ConfigurationElement CreateNewElement()`**
|
||||
Returns a new `FilterHashElement` instance (used internally by .NET configuration system).
|
||||
- **`protected override object GetElementKey(ConfigurationElement element)`**
|
||||
Returns the `Key` property of the given `FilterHashElement` (used for internal collection management).
|
||||
|
||||
#### `FilterHashElement`
|
||||
- **`string Key`**
|
||||
Required, key property (marked `IsKey = true`). Represents the identifier/name for the configuration entry.
|
||||
- **`string Value`**
|
||||
Optional property. Stores the associated value (e.g., a file path).
|
||||
|
||||
#### `PluginManager`
|
||||
- **`static T GetPlugin<T>() where T : class`**
|
||||
Returns a *single* MEF-exported instance of type `T`. Throws an exception (implicitly, via MEF) if zero or more than one export of type `T` exists. Returns `null` if no export is found.
|
||||
- **`static T GetPlugin<T>(string configPluginSetting) where T : class`**
|
||||
Returns a *specific* MEF-exported instance of type `T` by matching `item.Value.ToString() == configPluginSetting`. Returns `null` if no matching plugin is found.
|
||||
- **`static IEnumerable<Lazy<T>> GetPlugins<T>() where T : class`**
|
||||
Returns *all* MEF-exported instances of type `T` as `Lazy<T>` objects.
|
||||
- **`List<Assembly> GetPluginList<T>() where T : class`**
|
||||
Returns a deduplicated list of `Assembly` objects from directories in the MEF catalog that contain at least one part (plugin). *Note: This method returns after processing only the first `DirectoryCatalog` in the catalog list; subsequent catalogs are ignored.*
|
||||
- **`static PluginManager GetPluginManager()`**
|
||||
Thread-safe singleton accessor. Lazily initializes and returns the single `PluginManager` instance.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **Configuration Section Requirement**: The `"DataPro.Core.PluginLib.Config"` section *must* be present in the configuration file (`DataPro.config`). If absent, `PluginManager` constructor throws an `Exception`.
|
||||
- **Plugin Directory Validation**: Every `FilterHashElement.Value` (interpreted as a plugin directory path) *must* point to an existing directory. If any directory does not exist, `PluginManager` constructor throws an `IOException`.
|
||||
- **Thread Safety**: `PluginManager` is implemented as a singleton with lazy initialization protected by a `lock` on `ThreadLock`. All public static methods (`GetPlugin`, `GetPlugins`, `GetPluginManager`) are safe for concurrent use.
|
||||
- **Assembly Loading Scope**: Assemblies are loaded *only* from directories specified in the configuration section. No fallback to other paths occurs during initialization.
|
||||
- **MEF Composition Contract**: `GetPlugin<T>()` assumes exactly one export of type `T` exists; otherwise, MEF behavior (exception or `null`) applies. `GetPlugin<T>(string)` relies on `ToString()` of the exported instance for selection—this is fragile and not type-safe.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### *This module depends on:*
|
||||
- `System.Configuration` (for `ConfigurationSection`, `ConfigurationElement`, etc.)
|
||||
- `System.ComponentModel.Composition` (for MEF types: `AggregateCatalog`, `CompositionContainer`, `DirectoryCatalog`, `Export`, `Lazy<T>`)
|
||||
- `System.IO` (for `DirectoryInfo`, `FileInfo`, `Assembly.LoadFrom`)
|
||||
- `System.Reflection` (for `Assembly`, `AssemblyName`)
|
||||
- `DataPro.Core.Config` (specifically `DataProConfig.GetSection` and `DataProConfig.GetAppSetting`)
|
||||
|
||||
#### *This module is depended on by:*
|
||||
- Any component requiring plugin resolution (e.g., via `PluginManager.GetPlugin<T>()`).
|
||||
- Configuration infrastructure that consumes `"DataPro.Core.PluginLib.Config"` section.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`GetPluginList<T>()` is incomplete**: It returns after processing only the *first* `DirectoryCatalog` in `PluginCatalog.Catalogs`, ignoring all subsequent plugin directories. This is likely a bug.
|
||||
- **`GetPlugin<T>(string)` uses `ToString()` for selection**: Matching plugins by `item.Value.ToString()` is unreliable and not robust—plugins may not override `ToString()` meaningfully, and this approach cannot distinguish between multiple instances of the same type.
|
||||
- **Redundant assembly loading logic**: The constructor contains a loop that loads assemblies manually (`Assembly.LoadFrom`) *after* adding `DirectoryCatalog` to the `AggregateCatalog`. MEF’s `DirectoryCatalog` already loads assemblies on-demand; this manual loading is unnecessary and may cause duplicate loads or version conflicts.
|
||||
- **No error handling for assembly resolution**: The `CurrentDomain_AssemblyResolve` event handler is defined but *never subscribed* to `AppDomain.CurrentDomain.AssemblyResolve`. Dependency resolution failures will not be handled.
|
||||
- **Path handling comment is misleading**: The commented-out `IsPathRooted` check includes a typo ("absolete" instead of "absolute") and is disabled—no validation of path absoluteness occurs at runtime.
|
||||
- **`PluginConfigData` unused in runtime logic**: This class is defined but *not referenced anywhere* in the provided codebase. It appears to be a legacy or incomplete deserialization helper.
|
||||
- **No cleanup/disposal**: `PluginManager` holds unmanaged resources (`CompositionContainer`, catalogs, loaded assemblies). No `IDisposable` implementation or finalizer is present—potential memory leaks if the app domain is long-lived and plugins are reloaded.
|
||||
36
enriched-qwen3-coder-next/DataPRO/DataPRO.Core/Properties.md
Normal file
36
enriched-qwen3-coder-next/DataPRO/DataPRO.Core/Properties.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO.Core/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T04:27:57.613025+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "aa0ae952c15fedf2"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module (`DataPRO.Core`) is an internal .NET assembly containing core functionality for the DataPro system. Based solely on the provided source file, it serves as a foundational library with no exposed business logic—its primary documented role is to define assembly-level metadata (title, version, culture, COM visibility) and is likely consumed by other modules in the DataPro ecosystem. No executable or declarative logic beyond assembly attributes is present in this file.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public types, functions, classes, or methods are defined in this file.**
|
||||
The file contains only assembly-level attributes (via `System.Reflection` and `System.Runtime.InteropServices` attributes). All content is metadata, not executable code or API surface.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning it cannot be consumed by COM clients unless explicitly overridden on individual types (none present here).
|
||||
- The assembly version is fixed at `1.0.0.0` for both `AssemblyVersion` and `AssemblyFileVersion`.
|
||||
- The `Guid` attribute uniquely identifies the typelib (`bdf5ad7a-51db-4ad0-8186-d1ead7405848`) *if* the assembly were exposed to COM (which it is not).
|
||||
- The assembly title is `"DataPro.Core"` and copyright is set to `© 2016`.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Runtime dependencies**: Requires `System.Runtime.InteropServices` and `System.Reflection` (standard .NET Framework/BCL namespaces).
|
||||
- **Consumers**: Not determinable from this file alone. As a core library, it is likely referenced by other projects in the `DataPRO` solution (e.g., `DataPRO.UI`, `DataPRO.Services`), but no explicit references are declared here.
|
||||
|
||||
## 5. Gotchas
|
||||
- **No functional logic**: This file is purely metadata and should not be used to infer business behavior or API contracts.
|
||||
- **Versioning**: The use of `AssemblyVersion("1.0.0.0")` without wildcard (`*`) means build/revisions are static—no automatic incrementing.
|
||||
- **COM compatibility**: Despite the `Guid` attribute, `ComVisible(false)` renders the typelib GUID irrelevant for actual COM interop.
|
||||
- **Missing documentation**: `AssemblyDescription` and `AssemblyCompany` are empty strings; no product or vendor details are embedded.
|
||||
- **Copyright year**: Hardcoded to 2016—may be outdated if the assembly has been maintained since.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO.Core/ServiceManager/IServicePublishedEvent.cs
|
||||
- DataPRO/DataPRO.Core/ServiceManager/ServicePublishedEvent.cs
|
||||
- DataPRO/DataPRO.Core/ServiceManager/ServiceManager.cs
|
||||
generated_at: "2026-04-16T04:28:06.522630+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "30d34b17e2e0aff8"
|
||||
---
|
||||
|
||||
# ServiceManager
|
||||
|
||||
## Documentation: ServiceManager Module
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
The `ServiceManager` module implements a lightweight service registry pattern for managing singleton service implementations in the DataPRO core system. It enables components to publish concrete implementations of service interfaces and retrieve them later without tight coupling—publishers and consumers need not know each other’s identities. The module also emits `IServicePublishedEvent` notifications via the `EventManager` whenever a service is published or unpublished, supporting reactive service lifecycle monitoring.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `ServiceManager` (static class)
|
||||
|
||||
- **`void Publish<T>(T item) where T : class`**
|
||||
Publishes a singleton service implementation `item` for interface type `T`. Throws `ArgumentException` if `T` is already published. Fires a `ServicePublishedEvent` with `IsPublished = true`.
|
||||
|
||||
- **`void Publish(object item, IEnumerable<Type> interfaceList, bool skipPublishedInterfaces)`**
|
||||
Publishes `item` for each interface type in `interfaceList`. If `skipPublishedInterfaces` is `false`, throws `ArgumentException` on encountering an already-published interface; otherwise, silently skips it. Fires `ServicePublishedEvent` for each *newly* published interface.
|
||||
|
||||
- **`bool Exists<T>() where T : class`**
|
||||
Returns `true` if an implementation for interface type `T` is currently published; `false` otherwise.
|
||||
|
||||
- **`bool Exists(Type t)`**
|
||||
Overload of `Exists<T>` using a runtime `Type` instance.
|
||||
|
||||
- **`T Get<T>() where T : class`**
|
||||
Returns the published implementation for interface type `T`. Throws `ArgumentException` if no implementation is published.
|
||||
|
||||
- **`void Clear<T>() where T : class`**
|
||||
Unpublishes the implementation for interface type `T`. Fires a `ServicePublishedEvent` with `IsPublished = false` before removal.
|
||||
|
||||
- **`void Clear(IEnumerable<Type> interfaceList)`**
|
||||
Unpublishes all implementations whose interface types are in `interfaceList`. Fires `ServicePublishedEvent` for each removed interface.
|
||||
|
||||
> **Note**: All methods are thread-unsafe. No synchronization is applied to the internal `Services` dictionary.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **Uniqueness per interface**: At most one implementation may be published per interface type (`Type`) at any time. Attempting to publish a second implementation for an already-published interface results in an `ArgumentException`, unless `skipPublishedInterfaces = true` in the bulk `Publish` overload.
|
||||
- **Event emission guarantee**: Every successful `Publish` or `Clear` operation (i.e., one that modifies the registry) emits exactly one `ServicePublishedEvent` via `EventManager.EventManager.Publish<IServicePublishedEvent>`.
|
||||
- **No partial failure in bulk operations**: In `Publish(object, IEnumerable<Type>, bool)`, if an exception occurs (e.g., duplicate interface with `skipPublishedInterfaces = false`), the operation is aborted, and no further interfaces in the list are processed. However, interfaces *already processed* before the failure remain published (no rollback).
|
||||
- **Event payload consistency**: The `ServicePublishedEvent.ServiceType` always matches the interface type being published/unpublished, and `IsPublished` reflects the operation direction (`true` for publish, `false` for clear).
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
- **Internal dependencies**:
|
||||
- `System.Collections.Generic.Dictionary<Type, object>` for storage.
|
||||
- `EventManager.EventManager` (from `DataPro.Core.EventManager`)—used in `SendServicePublishedEvent` to dispatch events.
|
||||
- **External dependencies**:
|
||||
- `IServicePublishedEvent` and `ServicePublishedEvent` (defined in the same `DataPro.Core.ServiceManager` namespace).
|
||||
- `System.Type` for interface identification.
|
||||
|
||||
- **Depended upon by**:
|
||||
- Components that need to register or resolve singleton services (e.g., UI modules, data providers).
|
||||
- Event subscribers listening to `IServicePublishedEvent` for service lifecycle tracking.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **No support for multiple implementations per interface**: The registry strictly enforces one implementation per interface. Overriding a service requires explicit `Clear<T>()` first.
|
||||
- **No null-check on `item` in `Publish<T>`**: Passing `null` as `item` will succeed (and store `null` in the dictionary), leading to a `NullReferenceException` on subsequent `Get<T>()` calls. Consider adding validation if nulls are undesirable.
|
||||
- **Bulk `Publish` does not validate `item` implements all requested interfaces**: If `item` does not actually implement one or more types in `interfaceList`, the dictionary stores the reference, but `Get<T>()` for that interface will return `null` (via `as T`), potentially causing runtime errors later.
|
||||
- **No thread safety**: Concurrent calls to `Publish`, `Get`, or `Clear` may corrupt the internal dictionary or cause race conditions (e.g., two threads publishing the same interface may both succeed before the duplicate check completes).
|
||||
- **Event emission is synchronous**: `SendServicePublishedEvent` calls `EventManager.EventManager.Publish`, which may block the caller until all event handlers complete. Long-running handlers could impact performance.
|
||||
- **No versioning or deprecation support**: Once a service is published, there is no mechanism to signal obsolescence or migration paths.
|
||||
|
||||
> **None identified from source alone.**
|
||||
*(Note: The above gotchas are inferred from code structure and behavior—not assumptions.)*
|
||||
205
enriched-qwen3-coder-next/DataPRO/DataPRO.Core/Settings.md
Normal file
205
enriched-qwen3-coder-next/DataPRO/DataPRO.Core/Settings.md
Normal file
@@ -0,0 +1,205 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO.Core/Settings/SettingsChangedEventArgs.cs
|
||||
- DataPRO/DataPRO.Core/Settings/SettingsCollection.cs
|
||||
generated_at: "2026-04-16T04:27:33.942396+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "d5502ead5db3d623"
|
||||
---
|
||||
|
||||
# `SettingsCollection<TKey, TItem>` Module Documentation
|
||||
|
||||
---
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
The `SettingsCollection<TKey, TItem>` class provides a dictionary-based collection that notifies subscribers of changes (add, remove, modify, clear) via the `CollectionItemPropertyChanged` event. It extends `IDictionary<TKey, TItem>` to offer standard dictionary operations while adding reactive behavior for UI binding or state synchronization scenarios. This module exists to decouple state mutation from side-effect logic (e.g., persistence, UI updates) by enabling consumers to subscribe to change events rather than manually tracking mutations.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `SettingsCollection<TKey, TItem> : IDictionary<TKey, TItem>`
|
||||
|
||||
#### Event
|
||||
|
||||
- **`CollectionItemPropertyChanged`**
|
||||
`event EventHandler<SettingsChangedEventArgs<TKey, TItem>>`
|
||||
Fired whenever an item is added, removed, modified, or the collection is cleared.
|
||||
|
||||
#### Properties (from `IDictionary<TKey, TItem>`)
|
||||
|
||||
- **`this[TKey key]`**
|
||||
`TItem this[TKey key] { get; set; }`
|
||||
Gets or sets the value for the specified `key`. Setting a value fires a `Modified` event (note: *incorrectly* fires `Add` per implementation—see *Gotchas*).
|
||||
|
||||
- **`Keys`**
|
||||
`ICollection<TKey> Keys { get; }`
|
||||
Returns the collection of keys.
|
||||
|
||||
- **`Values`**
|
||||
`ICollection<TItem> Values { get; }`
|
||||
Returns the collection of values.
|
||||
|
||||
- **`Count`**
|
||||
`int Count { get; }`
|
||||
Returns the number of key-value pairs.
|
||||
|
||||
- **`IsReadOnly`**
|
||||
`bool IsReadOnly { get; }`
|
||||
Always `false`.
|
||||
|
||||
#### Methods (from `IDictionary<TKey, TItem>`)
|
||||
|
||||
- **`Add(TKey key, TItem value)`**
|
||||
Adds a key-value pair. Fires `CollectionItemPropertyChanged` with `ChangeSettingType.Add`.
|
||||
|
||||
- **`Add(KeyValuePair<TKey, TItem> item)`**
|
||||
Adds a key-value pair. Fires `CollectionItemPropertyChanged` with `ChangeSettingType.Add`.
|
||||
|
||||
- **`Remove(TKey key)`**
|
||||
Removes the entry with the specified `key`. Returns `true` if removed. Fires `CollectionItemPropertyChanged` with `ChangeSettingType.Remove`.
|
||||
|
||||
- **`Remove(KeyValuePair<TKey, TItem> item)`**
|
||||
Removes the entry matching the key of `item`. Returns `true` if removed. Fires `CollectionItemPropertyChanged` with `ChangeSettingType.Remove`.
|
||||
|
||||
- **`Clear()`**
|
||||
Removes all entries. Fires `CollectionItemPropertyChanged` with `ChangeSettingType.ClearAll`.
|
||||
|
||||
- **`ContainsKey(TKey key)`**
|
||||
`bool ContainsKey(TKey key)`
|
||||
Returns `true` if `key` exists.
|
||||
|
||||
- **`Contains(KeyValuePair<TKey, TItem> item)`**
|
||||
`bool Contains(KeyValuePair<TKey, TItem> item)`
|
||||
Returns `true` if both key and value exist in the collection.
|
||||
|
||||
- **`TryGetValue(TKey key, out TItem value)`**
|
||||
`bool TryGetValue(TKey key, out TItem value)`
|
||||
Returns `true` and sets `value` if `key` exists.
|
||||
|
||||
- **`CopyTo(KeyValuePair<TKey, TItem>[] array, int arrayIndex)`**
|
||||
Throws `NotImplementedException`.
|
||||
|
||||
- **`GetEnumerator()`**
|
||||
`IEnumerator<KeyValuePair<TKey, TItem>> GetEnumerator()`
|
||||
Returns an enumerator over the collection.
|
||||
|
||||
- **`IEnumerable.GetEnumerator()`**
|
||||
Explicit implementation of `IEnumerable.GetEnumerator()`.
|
||||
|
||||
---
|
||||
|
||||
### `SettingsChangedEventArgs<TKey, TItem> : EventArgs`
|
||||
|
||||
#### Constructors
|
||||
|
||||
- **`SettingsChangedEventArgs(ChangeSettingType changeType)`**
|
||||
Initializes with only the `ChangeType`.
|
||||
|
||||
- **`SettingsChangedEventArgs(ChangeSettingType changeType, TKey key)`**
|
||||
Initializes with `ChangeType` and `Key`.
|
||||
|
||||
- **`SettingsChangedEventArgs(ChangeSettingType changeType, TKey key, TItem item)`**
|
||||
Initializes with `ChangeType`, `Key`, and `Item`.
|
||||
|
||||
#### Properties
|
||||
|
||||
- **`ChangeType`**
|
||||
`ChangeSettingType ChangeType { get; }`
|
||||
Type of change (`Add`, `Remove`, `Modified`, or `ClearAll`).
|
||||
|
||||
- **`Key`**
|
||||
`TKey Key { get; }`
|
||||
Key associated with the change (may be default if `ClearAll`).
|
||||
|
||||
- **`Item`**
|
||||
`TItem Item { get; }`
|
||||
Value associated with the change (may be default if `Remove` or `ClearAll`).
|
||||
|
||||
---
|
||||
|
||||
### `ChangeSettingType` Enum
|
||||
|
||||
- **`Add = 0`**
|
||||
A new item was added.
|
||||
|
||||
- **`Remove = 1`**
|
||||
An item was removed.
|
||||
|
||||
- **`Modified = 3`**
|
||||
An existing item’s value was updated.
|
||||
|
||||
- **`ClearAll = 4`**
|
||||
The entire collection was cleared.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Event Firing**:
|
||||
- `Add`, `Remove`, and `ClearAll` always fire an event.
|
||||
- `this[key] = value` *always* fires an event (with `ChangeType.Add`, per implementation—see *Gotchas*).
|
||||
- Events are fired *after* the underlying dictionary is mutated (i.e., state is consistent at event time).
|
||||
|
||||
- **Event Arguments**:
|
||||
- For `Add`/`Modified`: `Key` and `Item` are non-null/non-default (assuming `TKey`/`TItem` allow it); `ChangeType` is `Add`.
|
||||
- For `Remove`: `Item` is default (`default(TItem)`); `ChangeType` is `Remove`.
|
||||
- For `ClearAll`: `Key` and `Item` are default; `ChangeType` is `ClearAll`.
|
||||
|
||||
- **No Partial Updates**:
|
||||
Only full additions, removals, or clears trigger events—no partial or batched updates.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **`System.Collections.Generic`**
|
||||
Provides `Dictionary<TKey, TItem>`, `ICollection<TKey>`, `ICollection<TItem>`, `IEnumerator<T>`, `IDictionary<TKey, TItem>`.
|
||||
- **`System`**
|
||||
Provides `EventArgs`, `EventHandler<T>`, `NotImplementedException`, `enum`.
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- **`DataPRO.Core.Settings` namespace**
|
||||
Used internally by consumers (e.g., `SettingsChangedEventArgs` and `ChangeSettingType` are public and likely used elsewhere in the codebase to handle settings changes).
|
||||
|
||||
### Inferred Usage:
|
||||
- Likely consumed by UI layers or configuration managers that need to react to settings changes (e.g., saving to disk, updating UI controls).
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Incorrect `Modified` Event Type**:
|
||||
The indexer setter (`this[TKey key] { set { ... } }`) fires `ChangeSettingType.Add` instead of `ChangeSettingType.Modified`. This is inconsistent with the semantic meaning of "modify" and may mislead consumers expecting `Modified` for updates.
|
||||
**Example**:
|
||||
```csharp
|
||||
collection["foo"] = "bar"; // Fires Add, not Modified
|
||||
```
|
||||
|
||||
- **`CopyTo` Not Implemented**:
|
||||
`CopyTo(KeyValuePair<TKey, TItem>[], int)` throws `NotImplementedException`. This violates the `ICollection<KeyValuePair<TKey, TItem>>` contract and may cause runtime failures if used (e.g., via LINQ’s `ToArray()` or `ToList()`).
|
||||
|
||||
- **`Contains(KeyValuePair<TKey, TItem>)` Semantics**:
|
||||
Checks both key *and* value equality. This is stricter than typical dictionary `Contains` behavior (which usually checks only key), and may cause confusion.
|
||||
|
||||
- **No Validation on Keys/Values**:
|
||||
No checks for `null` keys (if `TKey` is a reference type) or duplicate keys—relies on underlying `Dictionary<TKey, TItem>` to throw `ArgumentNullException`/`ArgumentException`.
|
||||
|
||||
- **No Thread Safety**:
|
||||
No synchronization primitives are used. Concurrent access may corrupt state or cause race conditions in event firing.
|
||||
|
||||
- **Event Subscribers May Receive Unexpected `Item` Values**:
|
||||
For `Remove` and `ClearAll`, `Item` is `default(TItem)`. Consumers must not assume `Item` is always meaningful.
|
||||
|
||||
- **No `Modified` Event for Direct Assignment**:
|
||||
Since the indexer uses `Add` semantics, there is no way to distinguish between *adding a new key* and *updating an existing key* via the event—unless the consumer tracks state themselves.
|
||||
|
||||
- **Historical Quirk**:
|
||||
The `ClearAll` event omits `Key` and `Item` (both `default`), while other operations populate them. This is consistent with the enum design but may require special handling in event handlers.
|
||||
|
||||
---
|
||||
|
||||
*Documentation generated from source files only. No external behavior or assumptions beyond the provided code.*
|
||||
288
enriched-qwen3-coder-next/DataPRO/DataPRO.md
Normal file
288
enriched-qwen3-coder-next/DataPRO/DataPRO.md
Normal file
@@ -0,0 +1,288 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/IActionButtonContainer.cs
|
||||
- DataPRO/DataPRO/WaitCursor.cs
|
||||
- DataPRO/DataPRO/IPageContent.cs
|
||||
- DataPRO/DataPRO/DataProMainWindow.xaml.cs
|
||||
- DataPRO/DataPRO/BoolToOppositeBoolConverter.cs
|
||||
- DataPRO/DataPRO/TranslateExtension.cs
|
||||
- DataPRO/DataPRO/Settings.cs
|
||||
- DataPRO/DataPRO/PageActionButtonsGroup.xaml.cs
|
||||
- DataPRO/DataPRO/PageContentHeaderControl.xaml.cs
|
||||
- DataPRO/DataPRO/DataProSession.cs
|
||||
- DataPRO/DataPRO/LicensingFooter.xaml.cs
|
||||
- DataPRO/DataPRO/PageContentControl.xaml.cs
|
||||
- DataPRO/DataPRO/WindowResizer.cs
|
||||
- DataPRO/DataPRO/PageActionControlsRibbon.xaml.cs
|
||||
- DataPRO/DataPRO/PageActionButtonsRibbon.xaml.cs
|
||||
- DataPRO/DataPRO/PageSearchControl.xaml.cs
|
||||
- DataPRO/DataPRO/PageNavControlsGroup.xaml.cs
|
||||
- DataPRO/DataPRO/PageMainContentControl.xaml.cs
|
||||
- DataPRO/DataPRO/NavGraphStep.xaml.cs
|
||||
generated_at: "2026-04-16T03:49:31.452209+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "1010e7b302783464"
|
||||
---
|
||||
|
||||
# DataPROWin7 Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides core infrastructure and UI framework components for the DataPROWin7 application, a Windows-based data acquisition and analysis system. It establishes foundational patterns for page navigation, search functionality, licensing display, and user permission management, while integrating with Prism-based modular architecture (via Unity container and region management). The module enables structured UI composition through interfaces like `IPageContent` and `IActionButtonContainer`, supports WPF-specific utilities (e.g., `WaitCursor`, `TranslateExtension`), and enforces permission-based visibility and enabled states for UI controls.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Interfaces
|
||||
|
||||
#### `IActionButtonContainer`
|
||||
- `DataPROWin7.Controls.ActionButton[] GetActionButtons()`
|
||||
Returns all action buttons managed by the container.
|
||||
- `void OnActionButtonPress(DataPROWin7.Controls.ActionButton button)`
|
||||
Handles press events for action buttons.
|
||||
- `void OnActionComboBoxChange(DataPROWin7.Controls.ActionComboBox comboBox)`
|
||||
Handles selection change events for action combo boxes.
|
||||
- `void OnActionComboBoxDropDownClose(DataPROWin7.Controls.ActionComboBox comboBox)`
|
||||
Handles dropdown close events for action combo boxes.
|
||||
- `void OnActionRadioButtonPress(DataPROWin7.Controls.ActionRadioButton button)`
|
||||
Handles press events for action radio buttons.
|
||||
|
||||
#### `IPageContent`
|
||||
- `void StartSearch(string term)`
|
||||
Initiates a search operation using the provided search term.
|
||||
- `bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`
|
||||
Validates the page content; populates `errors` and `warnings` lists; `displayWindow` controls whether validation errors are shown in a UI dialog.
|
||||
- `void OnSetActive()`
|
||||
Called when the page becomes the active content (e.g., on navigation to the page).
|
||||
- `void SetPermissions(DTS.Slice.Users.User.UserPermissionLevels actualPermission, DTS.Slice.Users.User.UserPermissionLevels requiredPermission)`
|
||||
Configures UI state based on user permissions (e.g., enabling/disabling controls).
|
||||
- `void UnSet(Action OnComplete = null)`
|
||||
Cleans up resources allocated during `OnSetActive`; optional callback after cleanup.
|
||||
- `bool OnButtonPress(Controls.PageButton button)`
|
||||
Handles presses of page-specific buttons; returns `true` if handled.
|
||||
- `object GetPageContent()`
|
||||
Returns the underlying content object (e.g., view model or data model).
|
||||
- `bool KeyDown(object sender, System.Windows.Input.KeyEventArgs e)`
|
||||
Handles key press events; returns `true` if the event was handled.
|
||||
|
||||
### Classes
|
||||
|
||||
#### `WaitCursor`
|
||||
- `WaitCursor()`
|
||||
Sets the mouse cursor to `Cursors.Wait` and stores the previous cursor. Implements `IDisposable`.
|
||||
- `void Dispose()`
|
||||
Restores the previously stored cursor.
|
||||
|
||||
#### `BoolToOppositeBoolConverter`
|
||||
- `object Convert(object value, Type targetType, object parameter, CultureInfo culture)`
|
||||
Converts a `bool` to its logical opposite (`!value`). Throws `InvalidOperationException` if `targetType` is not `bool`.
|
||||
- `object ConvertBack(...)`
|
||||
Throws `NotSupportedException`.
|
||||
|
||||
#### `TranslateExtension`
|
||||
- `TranslateExtension(string key)`
|
||||
Constructor storing the resource key.
|
||||
- `override object ProvideValue(IServiceProvider serviceProvider)`
|
||||
Retrieves localized string from `StringResources.ResourceManager` using `_key`; returns `"#stringnotfound#"` or `"#stringnotfound# <key>"` if not found.
|
||||
|
||||
#### `DataProSession`
|
||||
- `DataProSession()`
|
||||
Default constructor.
|
||||
- `void CreateSession()`
|
||||
Initializes Prism infrastructure (bootstrapper, container, event aggregator, region manager) using default config.
|
||||
- `void CreateSession(string customConfigPath)`
|
||||
Initializes Prism infrastructure using a custom configuration path.
|
||||
- `void Terminate()`
|
||||
Placeholder for shutdown logic (currently empty).
|
||||
- `IUnityContainer Container { get; }`
|
||||
Gets the Unity container after session creation.
|
||||
- `IEventAggregator EventAggregator { get; }`
|
||||
Gets the Prism event aggregator.
|
||||
- `IRegionManager RegionManager { get; }`
|
||||
Gets the Prism region manager.
|
||||
- `string CustomConfigPath { get; set; }`
|
||||
Gets/sets the custom configuration path used during session creation.
|
||||
|
||||
#### `PageContentHeaderControl`
|
||||
- `bool UsesSearchControl { get; set; }`
|
||||
Controls visibility of search controls (`searchTextBlock`, `searchTextBox`). Raises `PropertyChanged` for `"UsesSearchControl"`.
|
||||
- `bool UsesSelectControl { get; set; }`
|
||||
Controls visibility of select controls (`selectTextBlock`, `selectComboBox`). Raises `PropertyChanged` for `"UsesSearchControl"` (note: property name mismatch in `SetProperty` call).
|
||||
|
||||
#### `LicensingFooter`
|
||||
- `Color BackgroundColor { get; }`
|
||||
Gets the footer background color (from `BrushesAndColors.Brush_ApplicationLicensingFooterBackground` if `MainWindow` is `MainWindow`).
|
||||
- `void OnSetActive()`
|
||||
Updates licensing info and triggers `UpdateLicensingBar()` asynchronously.
|
||||
- `string LicensedTo { get; set; }`
|
||||
Licensed entity name.
|
||||
- `string FooterMessage { get; set; }`
|
||||
Combined validation/license expiration messages.
|
||||
- `string LicenseType { get; set; }`
|
||||
License type string (e.g., `"Professional Edition"`).
|
||||
- `string DataProVersion { get; set; }`
|
||||
Version string (e.g., `"DataPRO 3.1.0 - "`).
|
||||
|
||||
#### `PageContentControl`
|
||||
- `object MainContent { get; set; }`
|
||||
Gets/sets the main content; on set, calls `OnSetActive()` on the content if it implements `IPageContent`.
|
||||
- `Color ContentBackgroundColor { get; set; }`
|
||||
Background color; syncs to `NavControl` and `MainContentControl`.
|
||||
- `bool UsesNavControl { get; set; }`
|
||||
Controls visibility of navigation control (`NavControl`).
|
||||
- `bool IsInSetMainContentActive()`
|
||||
Returns `true` if `MainContent` is currently being set/activated.
|
||||
- `ContentControl GetMainContentControl()`
|
||||
Returns the internal `MainContentControl`.
|
||||
- `virtual void UnSet()`
|
||||
Calls `NavControl.UnSet()` if `UsesNavControl`.
|
||||
- `virtual bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`
|
||||
Delegates validation to `NavControl` or `MainContent` (if `IPageContent`).
|
||||
- `virtual void OnSetActive()`
|
||||
Calls `NavControl.OnSetActive()` if `UsesNavControl`.
|
||||
|
||||
#### `PageActionControlsRibbon`
|
||||
- `void SetGroups(PageActionControlsGroup[] groups)`
|
||||
Adds groups to the ribbon grid.
|
||||
- `void SetGroups(Controls.ActionRadioButton[] groups)`
|
||||
Adds radio button groups to the ribbon grid (stored separately in `_newRadioButtons`).
|
||||
- `Controls.ActionButton GetButton(string id)`
|
||||
Searches all groups for a button with `UniqueId == id`; throws `NullReferenceException` if not found.
|
||||
- `Controls.ActionButton[] GetButtons()`
|
||||
Returns all buttons from all groups.
|
||||
- `Controls.ActionLabel GetLabel(string id)`
|
||||
Searches all groups for a label with `UniqueId == id`; throws `NullReferenceException` if not found.
|
||||
- `Controls.ActionComboBox GetComboBox(string id)`
|
||||
Searches all groups for a combo box with `UniqueId == id`; throws `NullReferenceException` if not found.
|
||||
|
||||
#### `PageSearchControl`
|
||||
- `void ClearSearchTerm()`
|
||||
Clears the `searchTextBox.Text`.
|
||||
- `bool UsesSearchControl { get; set; }`
|
||||
Controls search visibility; raises `PropertyChanged` for `"SearchVisibility"`.
|
||||
- `bool UsesSelectControl { get; set; }`
|
||||
Controls select control visibility.
|
||||
- `Visibility SearchVisibility { get; }`
|
||||
Computed visibility (`Visible` if `UsesSearchControl`, else `Collapsed`).
|
||||
- `int RaiseSearchDelay { get; set; }`
|
||||
Debounce delay (ms) for search events; if `> 0`, uses `DispatcherTimer`.
|
||||
- `event SearchDelegate OnSearch`
|
||||
Raised after search term changes (debounced if `RaiseSearchDelay > 0`).
|
||||
|
||||
#### `PageNavControlsGroup`
|
||||
- `UserPermissionLevels GetRequiredPermission()`
|
||||
Gets `_requiredPermission`.
|
||||
- `UserPermissionLevels GetDefaultRolePermission(DefaultRoles role)`
|
||||
Returns default permission per role (`Read`, `Edit`, `Admin`, etc.).
|
||||
- `void SetEnabled(bool bEnable)`
|
||||
Enables/disables control based on user permission vs. `_requiredPermission`.
|
||||
- `bool GetDefaultRoleVisibility(DefaultRoles role)`
|
||||
Returns visibility per role based on `_requiredPermission`.
|
||||
- `string UniqueId { get; set; }`
|
||||
Unique identifier.
|
||||
- `string GetName()`
|
||||
Returns `UniqueId`.
|
||||
- `long GetID()` / `void SetID(long id)`
|
||||
Gets/sets `_id`.
|
||||
- `void SetVisible(bool bShow)`
|
||||
Sets visibility based on `CurrentUser.IsShowTabFlagSet(this)`.
|
||||
- `int SetControls(UserControl[] controls, int startingRow)`
|
||||
Adds controls to `navControlGrids` grid; returns number of rows used.
|
||||
|
||||
#### `PageMainContentControl`
|
||||
- `ContentControl GetContentControl()`
|
||||
Returns internal `contentControl`.
|
||||
- `object MainContent { get; set; }`
|
||||
Gets/sets `contentControl.Content`.
|
||||
- `Color BackgroundColor { get; set; }`
|
||||
Background color.
|
||||
- `static void MarkWarning(Control tb)`
|
||||
Sets `BorderBrush` to `Orange` and `BorderThickness` to `2.0` for `NavStep` controls.
|
||||
- `static void MarkInvalid(Control tb)`
|
||||
Applies error styles (e.g., `PageContentTextBoxErrorStyle`) or sets red border for various control types.
|
||||
- `static void MarkInvalid(TextBlock tb)`
|
||||
Sets `Foreground` to `Red`.
|
||||
- `static void MarkValid(Control tb)`
|
||||
Restores default styles for various control types.
|
||||
- `static void MarkValid(TextBlock tb)`
|
||||
Sets `Foreground` to `Black`.
|
||||
|
||||
#### `NavGraphStep`
|
||||
- `string Title { get; }`
|
||||
Step title (read-only).
|
||||
- `string SerialNumber { set; }`
|
||||
Sets `sensorSerialNumber.Text`; toggles visibility.
|
||||
- `string AxisUnit { set; }`
|
||||
Sets `axisUnit.Text`; toggles visibility.
|
||||
- `Color GraphStepColor { get; set; }`
|
||||
Graph step background color.
|
||||
- `bool GraphChannel { get; set; }`
|
||||
Controls visibility of `GraphColorVisibility`, `TextVisibility`, and `PartitionVisibility`.
|
||||
- `Visibility GraphColorVisibility { get; }`
|
||||
`Visible` if `GraphChannel`, else `Collapsed`.
|
||||
- `Visibility TextVisibility { get; set; }`
|
||||
Controls text visibility.
|
||||
- `Visibility PartitionVisibility { get; set; }`
|
||||
Controls partition visibility.
|
||||
- `IPageContent NavStepContent { get; set; }`
|
||||
Content associated with the step.
|
||||
- `void SetStatus(StatusTypes status)`
|
||||
Updates button/text colors based on `StatusTypes.Current` or `NotCurrent`.
|
||||
- `void SetCurrent()`
|
||||
Sets button background to `LightGray`.
|
||||
- `void SetInvalid()` / `void SetValid()`
|
||||
Placeholder methods (currently no-op).
|
||||
|
||||
### Routed Events (PageActionButtonsRibbon)
|
||||
- `FirstGroupFirstButtonClickedEvent`, `FirstGroupSecondButtonClickedEvent`, `FirstGroupThirdButtonClickedEvent`
|
||||
- `SecondGroupFirstButtonClickedEvent`, `SecondGroupSecondButtonClickedEvent`, `SecondGroupThirdButtonClickedEvent`
|
||||
- `ThirdGroupThirdButtonClickedEvent`, `FourthGroupFirstButtonClickedEvent`, `FourthGroupSecondButtonClickedEvent`, `FourthGroupThirdButtonClickedEvent`
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`IPageContent.OnSetActive()`** must be called exactly once when a page becomes active, and **`IPageContent.UnSet()`** must be called before the page is deactivated or destroyed.
|
||||
- **`WaitCursor`** must be used in a `using` block to ensure cursor restoration; no manual `Dispose()` calls should be missed.
|
||||
- **`TranslateExtension`** always returns a non-null string; missing keys are indicated by `"#stringnotfound#"` prefix.
|
||||
- **`PageContentControl.MainContent`** setter prevents re-entrancy via `_bSettingMainContentActive` flag.
|
||||
- **`PageNavControlsGroup.SetEnabled()`** respects user permissions: controls are disabled if user permission level < `_requiredPermission`.
|
||||
- **`PageNavControlsGroup.SetVisible()`** respects `CurrentUser.IsShowTabFlagSet(this)` when `bShow` is `true`.
|
||||
- **`PageSearchControl.RaiseSearchDelay`** must be `>= 0`; negative values are coerced to `0`.
|
||||
- **`PageMainContentControl.MarkInvalid/MarkValid`** methods must be called only on supported control types (e.g., `TextBox`, `ComboBox`, `ChannelCodeBuilder`, etc.).
|
||||
- **`NavGraphStep.GraphChannel`** affects multiple computed properties (`GraphColorVisibility`, `TextVisibility`, `PartitionVisibility`); changes must be propagated via `SetProperty`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Dependencies
|
||||
- **Prism (Unity)**: `Prism.Events`, `Prism.Regions`, `Prism.Ioc`, `Unity` (used in `DataProSession`).
|
||||
- **DTS.Slice.Users**: `DTS.Slice.Users.User.UserPermissionLevels`, `DTS.Slice.Users.User.DefaultRoles`, `DTS.Slice.Users.IUIItems` (used in `PageNavControlsGroup`).
|
||||
- **DTS.Common**: `DTS.Common.Controls`, `DTS.Common.SharedResource.Strings` (used in `LicensingFooter`, `TranslateExtension`).
|
||||
- **WPF Framework**: `System.Windows`, `System.Windows.Input`, `System.Windows.Media`, `System.Windows.Controls`, `System.Windows.Threading`.
|
||||
- **C1.WPF**: `C1.WPF` (used in `PageMainContentControl` for `C1NumericBox`).
|
||||
- **System.Configuration**: Implicitly used via `Settings` class (auto-generated).
|
||||
|
||||
### Internal Dependencies
|
||||
- **`DataPROWin7.Controls` namespace**: `ActionButton`, `ActionComboBox`, `ActionRadioButton`, `ActionLabel`, `PageButton`, `NavStep`, `ChannelCodeBuilder`, `ChannelNameBuilder`, `SupportedExcitationControl`, `DatePicker`, `C1NumericBox`, `ItemsControl`, `GroupBox`, `PageActionControlsGroup`, `PageActionButtonsGroup`.
|
||||
- **`DataPROWin7.Properties.Settings`**: Auto-generated settings class.
|
||||
- **`App` class**: Used in `LicensingFooter`, `PageNavControlsGroup`, `PageContentControl` to access `CurrentUser`, `LicenseValidationResult`, `GetVersionString()`.
|
||||
- **`BrushesAndColors`**: Used in `LicensingFooter`, `NavGraphStep` for color resources.
|
||||
|
||||
### Inferred Usage
|
||||
- `DataProMainWindow` initializes with `LoginControl2` as initial content.
|
||||
- `PageContentControl` and `PageNavControlsGroup` are used together for hierarchical navigation.
|
||||
- `PageSearchControl` is integrated into `PageContentHeaderControl` and `PageContentControl`.
|
||||
- `LicensingFooter` is likely hosted in the main window's footer area.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`PageContentHeaderControl.UsesSelectControl` setter**: Calls `SetProperty(..., "UsesSearchControl")` instead of `"UsesSelectControl"` — likely a typo causing incorrect `PropertyChanged` notifications.
|
||||
- **`PageActionControlsRibbon.SetGroups(ActionRadioButton[])`**: Stores radio button groups in `_newRadioButtons` but does not expose them via public methods (only `_groups` is used in `GetButtons`, `GetLabel`, `GetComboBox`).
|
||||
- **`PageActionButtonsRibbon`**: Button click handlers (`FirstGroupFirstButton_Click`, etc.) raise routed events but do not handle selection changes for combo boxes (handlers are empty).
|
||||
- **`DataProSession.CreateBootstrapper()`**: Bootstrapper is created only once; re-creation is blocked. Attempting to re-initialize after termination may fail silently (returns `null`).
|
||||
- **`WaitCursor`**: Does not handle multi-threading or nested usage; overlapping `WaitCursor` instances may restore incorrect cursors.
|
||||
- **`BoolToOppositeBoolConverter.ConvertBack`**: Always throws `NotSupportedException`; not suitable for two-way bindings.
|
||||
- **`PageContentControl.MainContent` setter**: Skips setting if `_bSettingMainContentActive` is `true`, preventing re-entrancy but potentially ignoring updates during activation.
|
||||
- **`NavGraphStep.SetInvalid()` / `SetValid()`**: Methods are empty stubs; no visual feedback for invalid states is implemented.
|
||||
- **`LicensingFooter.UpdateLicensingBar()`**: Runs `UpdateLicensingBar()` on a background thread (`Task.Run`), but UI properties (`LicensedTo`, `FooterMessage`, etc.) are updated directly — may cause cross-thread exceptions if not thread-safe (though `INotifyPropertyChanged` is typically handled on UI thread in WPF).
|
||||
- **`PageSearchControl.RaiseSearchDelay`**: If `RaiseSearchDelay == 0`, `_raiseSearchTimer` is set to `null` and not reused; repeated searches may recreate the timer unnecessarily.
|
||||
- **`PageNavControlsGroup.SetControls`**: Row definitions are added dynamically; if `startingRow` is reused across calls, rows may overlap or misalign.
|
||||
- **`PageContentControl.Validate`**: If `UsesNavControl` is `false` and `MainContent` is not `IPageContent`, validation returns `true` without validation.
|
||||
@@ -0,0 +1,240 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/CollectDataSubControls/PreTestDiagnostics.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/AssignSensorsSLICE.xaml.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ListViewTemplateSelector.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/SupportClasses.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/PostTestDiagnostics.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/SensorLayout.xaml.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/SquibResistanceCheck.xaml.cs
|
||||
generated_at: "2026-04-16T04:06:01.990477+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "0a4f100e80f6bda8"
|
||||
---
|
||||
|
||||
# CollectDataSubControls
|
||||
|
||||
**Documentation Page: SubControls Module**
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
This module (`DataPROWin7.SubControls`) provides WPF user interface controls and supporting infrastructure for the DataPRO application’s test workflow—specifically for diagnostics (pre- and post-test), sensor assignment/layout, squib resistance verification, and UI template selection. It encapsulates UI logic for interactive test steps, integrates with low-level DAS (Data Acquisition System) communication services, and manages state transitions during test execution. The module is tightly coupled to the `DataPROPage` and `RunTestBase` classes, serving as the view layer for test sequence steps.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `PreTestDiagnostics`
|
||||
- **`PreTestDiagnostics()`**
|
||||
Default constructor; initializes base class with default parameters.
|
||||
- **`PreTestDiagnostics(DataPROPage page)`**
|
||||
Constructor accepting a `DataPROPage`; passes `page` and `DiagnosticsType.PRE` to `DiagnosticsBase`.
|
||||
|
||||
#### `PostTestDiagnostics`
|
||||
- **`PostTestDiagnostics()`**
|
||||
Default constructor; initializes base class with default parameters.
|
||||
- **`PostTestDiagnostics(DataPROPage page)`**
|
||||
Constructor accepting a `DataPROPage`; passes `page` and `DiagnosticsType.POST` to `DiagnosticsBase`.
|
||||
- **`override void RunCurStep()`**
|
||||
Overrides base behavior to warn users when post-test diagnostics run on a *mixed system* (i.e., at least one DAS unit—e.g., G5—does not support post-test diagnostics). If diagnostics can run but some units are incompatible, displays a warning via `DoWarning()` before proceeding.
|
||||
- **`override void UnSet(Action OnComplete = null)`**
|
||||
Overrides base `UnSet` to disable navigation steps and transition all DAS units to low-power mode via `GoToLowPower()`.
|
||||
|
||||
#### `AssignSensorsSLICE`
|
||||
- **`AssignSensorsSLICE()`**
|
||||
Default constructor; calls `InitializeComponent()`.
|
||||
|
||||
#### `ListViewTemplateSelector`
|
||||
- **`event PropertyChangedEventHandler PropertyChanged`**
|
||||
Implements `INotifyPropertyChanged`.
|
||||
- **`DataTemplate LargeItemListTemplate { get; set; }`**
|
||||
Template used when `Mode == Modes.LargeList`.
|
||||
- **`DataTemplate SmallItemListTemplate { get; set; }`**
|
||||
Template used when `Mode == Modes.SmallList`.
|
||||
- **`enum Modes { SmallList, LargeList }`**
|
||||
Defines two display modes.
|
||||
- **`Modes Mode { get; set; }`**
|
||||
Gets/sets current mode; raises `PropertyChanged` on change.
|
||||
- **`int NumberOfItems { get; set; }`**
|
||||
Sets number of items; automatically updates `Mode` based on `ClientSize` and fixed item dimensions (`LargeItemWidth = 600`, `LargeItemHeight = 110`).
|
||||
*Behavior*: If `NumberOfItems > floor(ClientSize.Height / 110) * floor(ClientSize.Width / 600)`, sets `Mode = Modes.SmallList`; otherwise `Modes.LargeList`.
|
||||
- **`Size ClientSize { get; set; }`**
|
||||
Gets/sets client area size; triggers recalculation of `Mode` based on same logic as `NumberOfItems`.
|
||||
- **`override DataTemplate SelectTemplate(object item, DependencyObject container)`**
|
||||
Returns `LargeItemListTemplate` if `Mode == LargeList`, `SmallItemListTemplate` if `SmallList`, or defaults to `SmallItemListTemplate`.
|
||||
|
||||
#### `SupportClasses`
|
||||
- **Thread data classes (POCOs)**
|
||||
Used to pass state to background threads:
|
||||
- `RunArmThreadData`, `BasicInfoThreadData`, `HardwareThreadData`: each contains a single `ManualResetEvent DoneEvent`.
|
||||
- `AutoProgressionThreadData`: adds `CancelEvent`, `DelayMilliSeconds`.
|
||||
- `GenericThreadData`: comprehensive payload including:
|
||||
- `List<IDASCommunication> DAS`
|
||||
- `ManualResetEvent ResetEvent`, `CancelEvent`, `MissingHardwareEvent`
|
||||
- `ApplicationStatusTypes CurrentStatus`
|
||||
- `Controls.StatusRibbon CtrlStatusRibbon`
|
||||
- `List<string> DASList`, `CheckTrigger`, `DoneAction`, `TTSImport`, `SuppressWarning`
|
||||
- **`enum TestIDFixedPrefixSuffixValues`**
|
||||
Values: `NOT_FIXED = -1`, `None = 0`, `TimeStamp = 1`, `TestSetupName = 2`.
|
||||
- **`class TestIDPreFixSuffix`**
|
||||
Wraps a fixed prefix/suffix value or arbitrary string:
|
||||
- **`TestIDFixedPrefixSuffixValues FixedValue`**
|
||||
Immutable; set via constructor.
|
||||
- **`override string ToString()`**
|
||||
Returns `"TESTID_PREFIX_SUFFIX_" + FixedValue.ToString()` for fixed values; otherwise returns the stored string.
|
||||
- **`class TestIDPreFixSuffixHelper : BasePropertyChanged`**
|
||||
Wraps `TestIDPreFixSuffix` and provides localized string via `StringResources.ResourceManager`.
|
||||
- **`override string ToString()`**
|
||||
Returns localized string if available; otherwise falls back to `TestIDPreFixSuffix.ToString()`.
|
||||
- **`override bool Equals(object obj)`**
|
||||
Compares `FixedValue`; if both are `NOT_FIXED`, compares string representations.
|
||||
|
||||
#### `SensorLayout`
|
||||
- **`event PropertyChangedEventHandler PropertyChanged`**
|
||||
Implements `INotifyPropertyChanged`.
|
||||
- **`DataModel.HardwareChannel[] Channels { get; set; }`**
|
||||
Gets/sets `Hardware.Channels`; raises property change notifications.
|
||||
- **`string DASType`, `string DASSerial`, `string ModuleSerialNumber`, `string ModuleNumberText`**
|
||||
Read-only properties derived from `Hardware`; return `"N/A"` if `Hardware == null`.
|
||||
- **`DataModel.DASHardware Hardware { get; set; }`**
|
||||
Gets/sets current hardware; raises property change notifications for all dependent properties.
|
||||
- **`DataModel.TestObject TestObject { get; set; }`**
|
||||
Gets/sets test object; triggers `RepopulateSensors()` on change.
|
||||
- **`Sensor[] Sensors { get; set; }`**
|
||||
Lazily computed array of unassigned `Sensor` objects (see `RepopulateSensors()`).
|
||||
- **`class Sensor : BasePropertyChanged`**
|
||||
- `bool Selected`, `Color BackgroundColor`, `string SerialNumber`, `string Description`, `string EngineeringUnits`, `string SensorRanges`
|
||||
- `DTS.SensorDB.SensorData DataModelSensor`
|
||||
- `Visibility AssignButtonVisibility { get; set; }`
|
||||
- **`Visibility AssignButtonVisibility { get; set; }`**
|
||||
Sets `AssignButtonVisibility` on all `Sensor` instances via `Parallel.ForEach`.
|
||||
- **`void RepopulateSensors()`**
|
||||
Clears cached `_sensors` list and raises `PropertyChanged("Sensors")`.
|
||||
- **`void HardwareChannelList_SelectionChanged(...)`**
|
||||
Syncs selection state between `HardwareChannel` and `Sensor` lists; scrolls `lvSensors` to selected sensor.
|
||||
- **`void btnSensorAssign_Click(...)`**
|
||||
Assigns first selected `HardwareChannel` to selected `Sensor`; updates selection state and repopulates sensors.
|
||||
- **`void HardwareUnassign_Click(...)`**
|
||||
Clears `Sensor` on clicked `HardwareChannel`; repopulates sensors.
|
||||
|
||||
#### `SquibResistanceCheck`
|
||||
- **`SquibResistanceCheck(DataPROPage page)`**
|
||||
Constructor initializing `_squibTable`, setting `ctrlSquibContainer.Content`.
|
||||
- **`override void UnSet(Action OnComplete = null)`**
|
||||
Resets `RunNow`, `_bFactoryChanged`; calls base `UnSet`.
|
||||
- **`override Color AggregateStatusColor { get; set; }`**
|
||||
Syncs `ctrlStatusRibbon.AggregateStatusColor`.
|
||||
- **`override string AggregateStatusText { get; set; }`**
|
||||
Syncs `ctrlStatusRibbon.SetStatusTextNoTranslate`.
|
||||
- **`override void SetStatus(ApplicationStatusTypes status)`**
|
||||
Updates status text and color for statuses: `IDLE`, `Cancelled`, `SettingConfiguration`, `Passed`, `FailedArmCheckListSetConfig`, `Failed`, `Validating`.
|
||||
- **`void Bypass(BypassCompleteDelegate bypassComplete)`**
|
||||
Marks as bypassed, sets all DAS statuses to `Cancelled`, turns excitation back on, and invokes `bypassComplete`.
|
||||
- **`override void RunCurStep()`**
|
||||
Sets `RunNow = true`, calls `Reset()`.
|
||||
- **`void Reset()`**
|
||||
Resets state, clears `_squibTable`, calls `PrepareForResistanceCheck()`, and queues `WorkFunc` on `ThreadPool`.
|
||||
- **`void PrepareForResistanceCheck()`**
|
||||
Sets `ArmCheckActions.PerformSquibResistanceCheck = true` on all DAS units; adds `CurrentTest` to `_squibTable`.
|
||||
- **`private void WorkFunc(object o)`**
|
||||
Main execution logic:
|
||||
- Waits for configuration if not yet run (up to 30s).
|
||||
- Checks safety switch (arm state) for TOM tests.
|
||||
- Calls `DiagnosticsService.PerformArmCheck()` on all DAS units.
|
||||
- Calls `ArmingService.CheckAlreadyLevelTriggered()`.
|
||||
- On success, runs `DoDoneCalculations()`.
|
||||
- Handles cancellation, timeouts, and errors via `SetStatus()` and `_page.ReportErrors()`.
|
||||
- **`private void DoDoneCalculations()`**
|
||||
Updates `_squibTable` per DAS, generates report, sets status to `Passed` or `Failed` with details.
|
||||
- **`protected override bool DummyArm => ...`**
|
||||
Returns `true` if `CurrentTest.CheckoutMode` is active.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **`PreTestDiagnostics` / `PostTestDiagnostics`**:
|
||||
- `DiagnosticsType.PRE` or `DiagnosticsType.POST` is passed to `DiagnosticsBase` and never changed.
|
||||
- `RunCurStep()` in `PostTestDiagnostics` *only* issues warnings for mixed systems where diagnostics *can* run (i.e., `canRun == true`) but at least one unit does not support post-test diagnostics.
|
||||
|
||||
- **`SensorLayout`**:
|
||||
- `Hardware` must be non-null to populate `Channels`, `DASType`, `DASSerial`, etc.
|
||||
- `Sensors` list is lazily computed and cached in `_sensors`; repopulated only when `TestObject` changes or explicitly via `RepopulateSensors()`.
|
||||
- `AssignButtonVisibility` is set uniformly across all `Sensor` instances via `Parallel.ForEach`.
|
||||
|
||||
- **`SquibResistanceCheck`**:
|
||||
- `WorkFunc` waits up to 30 seconds for configuration; exits early on timeout or cancel.
|
||||
- `PerformArmCheck` is skipped for any DAS if `CurrentTest.CheckForTOM()` is true *and* switch is not armed.
|
||||
- `_bFactoryChanged` flag short-circuits execution and triggers early exit with `"FactoryHasChanged"` exception.
|
||||
|
||||
- **`ListViewTemplateSelector`**:
|
||||
- `Mode` is *always* determined by comparing `NumberOfItems` to `floor(ClientSize.Height / 110) * floor(ClientSize.Width / 600)`.
|
||||
- Default fallback in `SelectTemplate` is `SmallItemListTemplate`.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Internal Dependencies
|
||||
- **Base Classes**:
|
||||
- `DiagnosticsBase` (inherited by `PreTestDiagnostics`, `PostTestDiagnostics`)
|
||||
- `BasePropertyChanged` (used by `TestIDPreFixSuffixHelper`, `SensorLayout.Sensor`)
|
||||
- `IPageContent` (implemented by `SquibResistanceCheck`)
|
||||
- `UserControl` (base for `AssignSensorsSLICE`, `SensorLayout`, `SquibResistanceCheck`)
|
||||
- **Data Model**:
|
||||
- `DataModel.HardwareChannel`, `DataModel.DASHardware`, `DataModel.TestObject`, `DataModel.Sensors`
|
||||
- **UI Controls**:
|
||||
- `Controls.StatusRibbon`
|
||||
- `Controls.HardwareDiscoveryControl` (used in `SquibResistanceCheck`)
|
||||
- **Resource/Strings**:
|
||||
- `DTS.Common.SharedResource.Strings.StringResources`
|
||||
- `DTS.SensorDB.SensorModelCollection`, `DTS.SensorDB.SensorsCollection`
|
||||
|
||||
#### External Dependencies (via `using`)
|
||||
- `DTS.Common.*` (enums, base classes, utilities, service interfaces)
|
||||
- `DTS.DASLib.Service.*` (e.g., `DiagnosticsService`, `ArmingService`, `ConfigurationService`)
|
||||
- `DTS.Slice.Users` (permission-related)
|
||||
- `DTS.Common.Utilities.Logging.APILogger`
|
||||
- WPF namespaces (`System.Windows.*`)
|
||||
|
||||
#### Inferred Callers
|
||||
- `DataPROPage` and `RunTestBase` (from `UnSet`, `RunCurStep`, `SetStatus`, `Validate` usage).
|
||||
- `App` (via `(App)Application.Current`) for `DASFactory`, `DoMessageBox`, `SetAppBusy`, `SetLowPowerMode`, `CheckSafetyState`.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`PostTestDiagnostics.RunCurStep()`**:
|
||||
Warning is *only* issued when diagnostics *can* run (`canRun == true`) but some units (e.g., G5) do not support post-test diagnostics. If diagnostics *cannot* run at all, this logic is bypassed—no warning is generated here.
|
||||
|
||||
- **`SensorLayout.Sensors` computation**:
|
||||
- The `GetAttachedModules()` loop is commented out and `modules` is never assigned, so module-level sensor assignment is effectively disabled.
|
||||
- Uses `AsParallel()` for channel filtering but may be inefficient for large lists.
|
||||
|
||||
- **`SquibResistanceCheck.WorkFunc`**:
|
||||
- Hardcoded timeout of 30 seconds for configuration (line: `totalTimeWaited < 30000`).
|
||||
- Polling loop for DAS count (`while (das.Count == 0 && count < 60)`) blocks for up to 60 seconds; cancellation is only checked *between* iterations.
|
||||
- `TurnExcitationBackOnIfNeeded()` is called in `DoneHandler` and `Bypass`, but not in `UnSet` or error paths—excitation state may be inconsistent.
|
||||
|
||||
- **`ListViewTemplateSelector`**:
|
||||
- `ClientSize` default (`1000, 800`) may not reflect actual UI container size; `NumberOfItems` and `ClientSize` updates are independent—changing one does not automatically trigger recalculation of the other unless explicitly set.
|
||||
|
||||
- **`TestIDPreFixSuffixHelper`**:
|
||||
- `Equals()` falls back to `base.Equals()` for non-matching `FixedValue`, which may lead to reference equality instead of value equality if not overridden in `BasePropertyChanged`.
|
||||
|
||||
- **`AssignButtonVisibility` in `SensorLayout`**:
|
||||
Uses `Parallel.ForEach` to set visibility on all sensors—this may cause race conditions if `Sensors` list is modified concurrently.
|
||||
|
||||
- **`PreTestDiagnostics` / `PostTestDiagnostics`**:
|
||||
As noted in comments, *most* logic resides in `DiagnosticsBase`; these classes are thin wrappers. Ensure `DiagnosticsBase` behavior is understood before modifying.
|
||||
|
||||
- **`SquibResistanceCheck`**:
|
||||
`DummyArm` overrides `RunTestBase.DummyArm`; behavior depends on `CurrentTest.CheckoutMode`. Ensure `CheckoutMode` is set correctly for test scenarios.
|
||||
|
||||
---
|
||||
|
||||
*No other significant gotchas were identified from the source alone.*
|
||||
@@ -0,0 +1,129 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ArmCheckList/EventLinesTable.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ArmCheckList/ClockSyncTable.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ArmCheckList/TemperatureTable.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ArmCheckList/TiltSensorTable.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ArmCheckList/SensorIdTable.cs
|
||||
generated_at: "2026-04-16T04:14:49.287907+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "5fdc0f3742fb96a2"
|
||||
---
|
||||
|
||||
# Documentation: ArmCheckList Table Controls
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides WPF-based data grid controls for displaying and validating results from the DAS (Data Acquisition System) ArmCheck diagnostic phase. Each table class (`EventLinesTable`, `ClockSyncTable`, `TemperatureTable`, `TiltSensorTable`, `SensorIdTable`) serves a distinct validation purpose: verifying event line integrity, clock synchronization status, temperature readings, tilt sensor data, and sensor ID correctness respectively. These controls are embedded in the `DataPROPage` UI and update dynamically as DAS units complete their ArmCheck process, providing immediate visual feedback (via status column coloring) on pass/fail/NA conditions.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes inherit from `Controls.GenericTable2` and share common patterns. Public methods are documented per class.
|
||||
|
||||
### `EventLinesTable`
|
||||
|
||||
- **`UpdateDas(IDASCommunication das, bool ignoreShortedStartCompletion)`**
|
||||
Updates the table row corresponding to `das` with ArmCheck results. Sets `Trigger` and `Start` columns based on `das.ArmCheckResults.EventLineShorted` and `das.ArmCheckResults.StartLineShorted`. Marks row as *Failed* if any shorted condition is true (or if `ArmCheckResults` is null), unless `ignoreShortedStartCompletion` is true for start-line shorts. Updates `_bIsPassed` flag.
|
||||
|
||||
- **`Clear()`**
|
||||
Resets `_bIsPassed` to `true`, clears `_dt`, and calls `Update()`.
|
||||
|
||||
- **`IsPassed(ref List<string> errors)`**
|
||||
Returns `_bIsPassed`. If `false`, adds `StringResources.ArmCheckList_EventLines` to `errors`.
|
||||
|
||||
- **`AddDas(IDASCommunication das, IDictionary<string, DataModel.DASHardware> lookup)`**
|
||||
Creates a new row for `das`, populating `DAS` (from `lookup[das.SerialNumber].ToString()`), `Start`, `Trigger` (both `false`), `Status` (`StringResources.ArmChecklist_NA`), and `UserData` (the `das` object).
|
||||
|
||||
### `ClockSyncTable`
|
||||
|
||||
- **`UpdateDas(IDASCommunication das)`**
|
||||
Updates the row for `das`. Uses `Utils.IsClockSynced(...)` with stored `ClockSyncProfile` (`dasProfiles[das.SerialNumber]`) and hardware type. Sets `Status` to *Synced*, *NotSynced*, or *NA*. Sets `_bPassed = false` if clock is not synced *or* if `EnableClockSourceSelect` is true and sync data is unavailable. Logs exceptions.
|
||||
|
||||
- **`Clear()`**
|
||||
Resets `_bPassed` to `true`, clears `_dt`, calls `Update()`.
|
||||
|
||||
- **`IsPassed(ref List<string> errors)`**
|
||||
Returns `_bPassed`. If `false`, adds `StringResources.ArmCheckList_ClockSync` to `errors`.
|
||||
|
||||
- **`AddDas(IDASCommunication das, ClockSyncProfile profile, IDictionary<string, DataModel.DASHardware> lookup)`**
|
||||
Creates a row for `das`, storing `profile` in `dasProfiles`. Populates `DAS`, `ClockProfile` (localized enum description), `Status` (`NA`), and `UserData`.
|
||||
|
||||
### `TemperatureTable`
|
||||
|
||||
- **`UpdateDas(IDASCommunication das)`**
|
||||
Updates the row for `das`. Builds a comma-separated string of non-NaN pre-arm temperatures from `das.ArmCheckResults.TemperaturesPre`, using `GetTemperatureString(i)` to map channel index to localized name (e.g., *MCU Temperature*, *Temperature1*). Sets `Status` to *Failed* if `TemperaturesPre` is null or `ArmCheckResults` is null.
|
||||
|
||||
- **`Clear()`**
|
||||
Resets `_bPassed` to `true`, clears `_dt`, calls `Update()`.
|
||||
|
||||
- **`IsPassed(ref List<string> errors)`**
|
||||
Returns `_bPassed`. If `false`, adds `StringResources.ArmCheckList_Temperature` to `errors`.
|
||||
|
||||
- **`AddDas(IDASCommunication das, IDictionary<string, DataModel.DASHardware> lookup)`**
|
||||
Creates a row for `das`, populating `DAS`, `Temperature` (`NA`), `Status` (`NA`), and `UserData`.
|
||||
|
||||
### `TiltSensorTable`
|
||||
|
||||
- **`UpdateDas(IDASCommunication das)`**
|
||||
Updates rows for `das` and its active external tilts. For external tilts, matches rows by `DAS:tiltID:tiltSerial` (via `GetExternalTiltDASName`). Populates `SystemID`, `SystemLocation`, `SensorDegreesX/Y/Z` from `das.ArmCheckResults.TiltDegrees` (internal) or `IndexedTiltDegrees[tiltID]` (external). Sets `Status` to *Failed* if tilt data is unavailable.
|
||||
|
||||
- **`Clear()`**
|
||||
Resets `_bPassed` to `true`, clears `_dt`, calls `Update()`.
|
||||
|
||||
- **`IsPassed(ref List<string> errors)`**
|
||||
Returns `_bPassed`. If `false`, adds `StringResources.ArmChecklist_TiltFailure` to `errors` (only once, via `Contains` check).
|
||||
|
||||
- **`AddDas(IDASCommunication das)`**
|
||||
Creates one row per active external tilt (using `GetExternalTiltDASName`) or one row for `das.SerialNumber` if no external tilts. All columns initialized to `NA`.
|
||||
|
||||
### `SensorIdTable`
|
||||
|
||||
- **`UpdateDas(IDASCommunication das)`**
|
||||
Matches rows by `DASPlusChannelNumber` (format: `DAS:Channel`). Extracts channel index from last 3 chars of `DASPlusChannelNumber`. Validates `das.ArmCheckResults.SensorIds[index]` contains the expected `SensorId` from the row. Sets `Status` to *Success* or *SensorIdNotOnChannel*. Sets `_bpassed = false` if any row fails.
|
||||
|
||||
- **`Clear()`**
|
||||
Clears `_dt`, sets `_bpassed = true`, calls `Update()`.
|
||||
|
||||
- **`IsPassed(ref List<string> errors)`**
|
||||
Returns `_bpassed`. If `false`, adds `StringResources.ArmCheckList_SensorId` to `errors`.
|
||||
|
||||
- **`Add(DataModel.TestTemplate testSetup)`**
|
||||
Populates rows for all enabled, non-blank channels in `testSetup`. Uses `testSetup.GetHardware()` and `GetSensor()` to extract sensor metadata. Creates one row per channel with `Group`, `Channel`, `SensorSerialNumber`, `SensorDescription`, `DASSerial`, `DASPlusChannelNumber`, `HardwareChannelNumber`, `SensorId`, and `Status` (`NA`).
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Row Matching**: Each `UpdateDas` method matches rows using `UserData` (a reference to `IDASCommunication`) or derived identifiers (`SerialNumber`, `DASPlusChannelNumber`, `DAS:tiltID:tiltSerial`). Rows are updated only once per `UpdateDas` call (via `break` after first match).
|
||||
- **Status Column Semantics**: `Status` column values are drawn from `StringResources` (`ArmChecklist_NA`, `ArmChecklist_Success`, `ArmChecklist_Failed`, `ArmChecklist_Synced`, `ArmChecklist_NotSynced`, `ArmChecklist_SensorIdNotOnChannel`). The `NA` value is used for uninitialized rows.
|
||||
- **Pass/Fail Aggregation**: Each table maintains a private boolean (`_bIsPassed`, `_bPassed`, `_bpassed`) that is `true` initially and set to `false` if any row fails validation. `IsPassed` reports this aggregate.
|
||||
- **UI Coloring**: Status column background color is determined by value: `NA` → *Idle* (gray), `Success`/`Synced` → *Complete* (green), `Failed`/`NotSynced`/`SensorIdNotOnChannel` → *Failed* (red). Non-status columns may also be grayed if `NA`.
|
||||
- **Thread Safety**: `_bIsPassed`, `_bPassed`, `_bpassed` are marked `volatile` to ensure visibility across threads.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies
|
||||
- **Base Class**: All classes inherit from `Controls.GenericTable2` (not shown, but assumed to provide WPF DataGrid integration, `DataTable` binding, and `Update()` method).
|
||||
- **WPF Controls**: Uses `C1.WPF.DataGrid` (ComponentOne DataGrid) for column definitions and rendering.
|
||||
- **Resource Strings**: `StringResources` (from `DTS.Common.SharedResource.Strings`) provides localized status strings.
|
||||
- **Brushes**: `BrushesAndColors` (from `DTS.Common`) provides status-specific `SolidColorBrush` instances.
|
||||
|
||||
### External Dependencies
|
||||
- **DAS Interface**: `IDASCommunication` (from `DTS.Common.Interface.DASFactory`) is the primary data source for DAS state and results.
|
||||
- **Data Models**: `DataModel.DASHardware`, `DataModel.TestTemplate`, `DataModel.HardwareChannel`, `DataModel.HardwareChannel` (from `DataModel` namespace).
|
||||
- **DAS Service**: `DTS.DASLib.Service` (for `ArmCheckResults`, `DASInfo`, `ConfigData`, `TemperaturesPre`, etc.).
|
||||
- **Utils**: `Utils.IsClockSynced` (from `DTS.Common`) for clock sync logic.
|
||||
- **Logging**: `APILogger` (from `DTS.Common.Utilities.Logging`) for exception logging.
|
||||
|
||||
### Inferred Callers
|
||||
- These tables are instantiated and managed by `DataPROPage` (from `DataPROWin7.SubControls`) during the ArmCheck workflow. They are likely populated via `AddDas`/`Add` during setup and updated via `UpdateDas` as each DAS completes diagnostics.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Serial Number Reliability**: `EventLinesTable.UpdateDas` explicitly comments that serial numbers may be "decorated" (e.g., modified/overlaid), so it matches on both `UserData` (reference) and `das.SerialNumber` (value).
|
||||
- **`ignoreShortedStartCompletion` Flag**: In `EventLinesTable`, start-line shorted status sets `Start = true` unconditionally, but only sets `bFailed = true` if `ignoreShortedStartCompletion` is `false`. This flag is passed in at call time, but its usage is not documented in the source.
|
||||
- **`SetRowStatus` Stub**: `TiltSensorTable` declares a private method `SetRowStatus(string serialNumber, PassStatus status)` that is called but has an empty implementation. This may indicate incomplete functionality or tech debt.
|
||||
- **`SensorIdTable` Row Matching**: Matches on `DASPlusChannelNumber` by parsing the last 3 characters as the channel number. This assumes a fixed format (`DAS:XXX`) and may break if channel numbers exceed 3 digits or formatting changes.
|
||||
- **`ClockSyncTable` Conditional Failure**: Clock sync can fail *even if sync data is available* if `Common.SerializedSettings.EnableClockSourceSelect` is true and sync data is missing. This is a configuration-dependent validation rule.
|
||||
- **`TemperatureTable` Channel Mapping**: `GetTemperatureString` maps `TempLogChannelBits` enum values to localized names. If `TemperaturesPre` array length exceeds the defined enum values, channels will be skipped (empty string).
|
||||
- **`SensorIdTable` Channel Parsing**: Extracts channel number via `Substring(snAndCh.Length - 3, 3)`. This assumes `DASPlusChannelNumber` is always at least 3 characters and the last 3 chars are numeric. Non-compliant data may cause `TryParse` to fail (defaulting to `-1`).
|
||||
- **`NA` vs. `Success` Coloring**: `EventLinesTable` and `SensorIdTable` explicitly reference issue #7525 to explain why `NA` is gray (not green). This is a known UI fix, not a bug, but worth noting for consistency.
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ArmSystem/ArmSystemDAS.cs
|
||||
generated_at: "2026-04-16T04:13:27.837796+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "eadc1821d7af0f46"
|
||||
---
|
||||
|
||||
# ArmSystem
|
||||
|
||||
## Documentation: `ArmSystemDAS` Class
|
||||
|
||||
### 1. Purpose
|
||||
`ArmSystemDAS` is a data transfer object (DTO) and UI-bound model class used to represent the state and configuration of a Data Acquisition System (DAS) unit during the *arming* phase of a test in the DataPRO application. It aggregates DAS-specific metadata (e.g., serial number, status, streaming address), test context (e.g., test object, sample rate), and trigger-related flags. It inherits from `BasePropertyChanged`, enabling data binding in WPF UIs (e.g., to display live DAS status in the ArmSystem control panel). Its primary role is to decouple UI presentation logic from low-level DAS communication interfaces (`IDASCommunication`, `DASHardware`) and provide a stable, observable property set for binding.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### Constructors
|
||||
- **`ArmSystemDAS()`**
|
||||
Default parameterless constructor. Initializes all properties to their default values (e.g., `StreamingAddress = "---"`). Used for deserialization or deferred initialization.
|
||||
|
||||
- **`ArmSystemDAS(IDASCommunication connectedDAS, string das, string testTemplateRate)`**
|
||||
Initializes the instance using an active `IDASCommunication` connection and metadata. Sets:
|
||||
- `SerialNumber` from `connectedDAS.SerialNumber`
|
||||
- `DAS` from `das` (a display name)
|
||||
- `TestSampleRate` from `testTemplateRate`
|
||||
- `StreamingAddress` from `connectedDAS.UDPStreamAddress`
|
||||
- `CareAboutTrigger` via `GetCareAboutTrigger(connectedDAS, null)`
|
||||
|
||||
- **`ArmSystemDAS(IDASCommunication connectedDAS, DASHardware h, string testTemplateRate, IGroup group)`**
|
||||
Initializes using hardware metadata and group context. Sets:
|
||||
- `SerialNumber` from `h.SerialNumber`
|
||||
- `DAS` from `h.ToString()` *or* `h.SerialNumber` depending on `Properties.Settings.Default.ShowCompactHardware`
|
||||
- `TestSampleRate` from `testTemplateRate`
|
||||
- `TestObject` from `group.DisplayName`
|
||||
- `StreamingAddress` from `connectedDAS?.UDPStreamAddress ?? "---"` (falls back to `"---"` if `connectedDAS` is `null`)
|
||||
- `CareAboutTrigger` via `GetCareAboutTrigger(connectedDAS, h)`
|
||||
|
||||
#### Static Method
|
||||
- **`static bool GetCareAboutTrigger(IDASCommunication idas, DASHardware h)`**
|
||||
Determines whether the current DAS unit should be considered for trigger-related monitoring during arming. Logic:
|
||||
- If `h` is non-null and `h.IsSLICEEthernetController` → return `false`
|
||||
- Else if `idas` is non-null and `idas.IsEthernetDistributor()` → return `false`
|
||||
- Else if `idas` is non-null → return `idas.GetCanCheckArmStatus()`
|
||||
- Else → return `true`
|
||||
*Note:* This method exists to handle edge cases where `DASHardware` and `IDASCommunication` objects may be inconsistent or incomplete (e.g., for certain Ethernet distributors or SLICE controllers that do not reliably report arming status).
|
||||
|
||||
#### Properties (all observable via `INotifyPropertyChanged`)
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `BatteryVoltageStatus` | `string` | Current battery voltage status (e.g., "OK", "LOW"). |
|
||||
| `colFaults` | `string` | Collision fault status (note: lowercase field name; likely a typo for "collFaults"). |
|
||||
| `DAS` | `string` | Display name of the DAS unit (either hardware string or serial number, per settings). |
|
||||
| `TestSampleRate` | `string` | Sample rate configured for the test (e.g., "1000 Hz"). |
|
||||
| `SerialNumber` | `string` | Unique hardware serial number. |
|
||||
| `InputVoltageStatus` | `string` | Input voltage status (e.g., "OK", "FAIL"). |
|
||||
| `Status` | `string` | General DAS status (e.g., "ARMED", "IDLE"). |
|
||||
| `StreamingAddress` | `string` | UDP streaming address (defaults to `"---"` if unavailable). |
|
||||
| `TestObject` | `string` | Display name of the test object/group (from `IGroup.DisplayName`). |
|
||||
| `TimeLeftInArm` | `string` | Estimated time remaining in the arming state (e.g., "00:01:30"). |
|
||||
| `EventNumber` | `string` | Event identifier (e.g., "EVT-12345"). |
|
||||
| `Triggered` | `bool` | Whether the DAS has triggered (UI state flag). |
|
||||
| `CareAboutTrigger` | `bool` | Whether trigger monitoring is applicable for this DAS (set at construction). |
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- All properties use `SetProperty(ref field, value, propertyName)` internally, ensuring `INotifyPropertyChanged` notifications are raised for UI binding.
|
||||
- `StreamingAddress` is initialized to `"---"` and only updated if a valid `UDPStreamAddress` is available (e.g., from `IDASCommunication`).
|
||||
- `DAS` property value depends on `Properties.Settings.Default.ShowCompactHardware`:
|
||||
- `true` → uses `h.ToString()`
|
||||
- `false` → uses `h.SerialNumber`
|
||||
- `CareAboutTrigger` is determined *once* at construction and never updated dynamically (no setter logic beyond initialization).
|
||||
- `colFaults` uses a non-standard lowercase field/property name (likely a naming inconsistency).
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
**Imports/Usings:**
|
||||
- `DataPROWin7.DataModel` → Provides `DASHardware`, `IGroup`, and possibly `IDASCommunication`.
|
||||
- `DTS.Common.Base` → Provides `BasePropertyChanged` (base class for observable models).
|
||||
- `DTS.Common.Interface.DASFactory` → Provides `IDASCommunication` interface.
|
||||
- `DTS.Common.Interface.Groups.GroupList` → Provides `IGroup` interface.
|
||||
|
||||
**Consumers (inferred):**
|
||||
- UI controls in `DataPROWin7.CollectDataSubControls.ArmSystem` (e.g., XAML views bound to `ArmSystemDAS` instances).
|
||||
- Code that constructs `ArmSystemDAS` objects (e.g., arming workflow logic) using `IDASCommunication`, `DASHardware`, and `IGroup` instances.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
- **Case inconsistency**: Property `colFaults` uses camelCase (`col` not `Col`), while all other properties use PascalCase. This may cause issues with serialization (e.g., JSON) or reflection-based tools expecting consistent casing.
|
||||
- **Ambiguous `DAS` property**: Its value depends on a global setting (`Properties.Settings.Default.ShowCompactHardware`), which may vary per user/session. UI consumers should not assume `DAS` is always a serial number.
|
||||
- **`StreamingAddress` fallback**: When `connectedDAS` is `null` in the 3rd constructor, `StreamingAddress` defaults to `"---"`. This may mask missing data if not handled explicitly.
|
||||
- **`GetCareAboutTrigger` edge case**: When *both* `idas` and `h` are `null`, it returns `true` by default. This is documented as a fallback for legacy cases but could lead to incorrect trigger monitoring if invoked without valid inputs.
|
||||
- **No validation**: Properties accept arbitrary string/boolean values without validation (e.g., `Status` could be set to `"INVALID"` without error).
|
||||
- **No methods beyond constructors**: This is a pure DTO—no business logic beyond initialization and property access.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/CollectDataSubControls/CheckHardware/Hardware.cs
|
||||
generated_at: "2026-04-16T04:13:41.949380+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "4fdd9ed10fc466a6"
|
||||
---
|
||||
|
||||
# CheckHardware
|
||||
|
||||
### **Purpose**
|
||||
This module defines the `Hardware` class, a view-model-like wrapper around a `DASHardware` domain object, intended for use in UI tree structures (e.g., the hardware tree in the “Hardware step of run test”). It aggregates hardware metadata (serial number, connection type, channels), resolves associated `DASHelper` instances for communication, and optionally flattens hierarchical hardware relationships (e.g., SLICE6 racks with linked child devices) when `ShowCompactHardware` is enabled—addressing legacy ambiguity in distinguishing ECM/SPS devices that share an IP but differ by serial number.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
- **`public string SerialNumber { get; }`**
|
||||
Exposes the serial number of the underlying `_hardware` object. Read-only; derived directly from `_hardware.SerialNumber`.
|
||||
|
||||
- **`public string Connection { get; }`**
|
||||
Exposes the connection string of `_hardware`. Read-only; derived from `_hardware.Connection`.
|
||||
|
||||
- **`public string Channels { get; }`**
|
||||
Returns a formatted string of channel information by calling the static method `DASHardware.GetChannelsString(_hardware)`. Behavior depends on the implementation of that method (not shown here).
|
||||
|
||||
- **`public Hardware[] ChildrenHardware { get; }`**
|
||||
An array of `Hardware` instances representing child devices. Populated only if `ShowCompactHardware` is `true` *and* `_hardware.LinkedDASSerials` is non-null/non-empty. Children are constructed recursively using `serialNumberToHardware` and `connectionToDasHelper` dictionaries.
|
||||
|
||||
- **`public HardwareDiscoveryControl.DASHelper DASHelper { get; }`**
|
||||
Resolves and stores a `DASHelper` instance used for device communication. Resolution priority:
|
||||
1. `connectionToDasHelper[hardware.SerialNumber]` (serial-number-first lookup, per comment #10754)
|
||||
2. `connectionToDasHelper[hardware.ConnectionUSBAware2]` (fallback to USB-aware connection string)
|
||||
If neither key exists, this property remains `null`.
|
||||
|
||||
- **`public Hardware(DASHardware hardware, Dictionary<string, DASHardware> serialNumberToHardware, Dictionary<string, HardwareDiscoveryControl.DASHelper> connectionToDasHelper, IDictionary<string, DASHardware> allHardwareLookup)`**
|
||||
Constructor. Initializes the instance and optionally populates `ChildrenHardware` when `ShowCompactHardware` is enabled. Uses `serialNumberToHardware` and `allHardwareLookup` (though `allHardwareLookup` is unused in the constructor body). Populates `DASHelper` via lookup in `connectionToDasHelper`. If `hardware.LinkedDASSerials` is null and `hardware.IsPseudoRack()` returns `true`, it populates `hardware.LinkedDASSerials` by calling `DASHardware.GetChildrenDAS(hardware.SerialNumber, serialNumberToHardware)`.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
|
||||
- `SerialNumber`, `Connection`, and `Channels` are immutable after construction and reflect the state of `_hardware` at construction time.
|
||||
- `DASHelper` is resolved *once* during construction and never updated—even if `connectionToDasHelper` contents change later.
|
||||
- `ChildrenHardware` is populated *only* if `Properties.Settings.Default.ShowCompactHardware` is `true`. Otherwise, it is an empty array.
|
||||
- When `ShowCompactHardware` is enabled and `hardware.LinkedDASSerials` is null, it is *mutated* on the underlying `_hardware` object (via assignment to `hardware.LinkedDASSerials`). This side effect persists beyond the constructor.
|
||||
- Child `Hardware` instances are constructed *without* passing `serialNumberToHardware` (the 4th parameter is `null` in the recursive call), meaning nested children will not expand further unless `serialNumberToHardware` is passed explicitly (but it is not). Thus, only one level of children is supported in compact mode.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
|
||||
**Imports/Usings indicate dependencies on:**
|
||||
- `DataPROWin7.Controls` (namespace for UI controls, e.g., `HardwareDiscoveryControl`)
|
||||
- `DataPROWin7.DataModel` (contains `DASHardware`, `Properties.Settings`)
|
||||
- `DTS.Common.Base` (contains `BasePropertyChanged`, base class for property-change notification)
|
||||
|
||||
**Explicit dependencies in constructor:**
|
||||
- `DASHardware` (domain model for hardware metadata)
|
||||
- `Dictionary<string, DASHardware> serialNumberToHardware` (for resolving child devices by serial)
|
||||
- `Dictionary<string, HardwareDiscoveryControl.DASHelper> connectionToDasHelper` (for resolving communication helpers)
|
||||
- `IDictionary<string, DASHardware> allHardwareLookup` (declared but *unused* in the constructor body)
|
||||
|
||||
**Depended on by:**
|
||||
- UI components consuming the tree view (e.g., `HardwareDiscoveryControl`), inferred from the namespace `DataPROWin7.CollectDataSubControls.CheckHardware` and usage of `HardwareDiscoveryControl.DASHelper`.
|
||||
- Likely consumed by XAML views (via data binding) due to inheritance from `BasePropertyChanged`.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
|
||||
- **Side effect on input `hardware`**: If `ShowCompactHardware` is enabled and `hardware.LinkedDASSerials` is null, the constructor *mutates* `_hardware.LinkedDASSerials` by assigning it a value derived from `DASHardware.GetChildrenDAS(...)`. This is not obvious from the public interface and may cause unexpected behavior if the same `DASHardware` instance is reused elsewhere.
|
||||
- **Unused parameter**: `allHardwareLookup` is declared but never used in the constructor. Its purpose is unclear.
|
||||
- **Shallow recursion**: Child `Hardware` instances are constructed with `serialNumberToHardware: null`, preventing deeper nesting of children beyond one level—even if the underlying hardware hierarchy is deeper.
|
||||
- **Ambiguous `DASHelper` resolution**: If both `hardware.SerialNumber` and `hardware.ConnectionUSBAware2` exist as keys in `connectionToDasHelper`, only the serial-number match is used. If neither exists, `DASHelper` is `null` with no warning.
|
||||
- **Hardcoded setting dependency**: Behavior changes based on `Properties.Settings.Default.ShowCompactHardware`, which is a runtime configuration. This makes unit testing and deterministic behavior harder without mocking or stubbing settings.
|
||||
- **No null-safety for `connectionToDasHelper`**: The constructor checks `null != connectionToDasHelper` before dictionary lookups, but if `connectionToDasHelper` is `null`, `DASHelper` will remain `null` silently—no exception or logging occurs.
|
||||
- **Commented tech debt**: The inline comment `//10754 Hardware step of run test tree view needs improvement...` indicates known limitations in handling shared-IP devices (ECM/SPS), suggesting this logic is a temporary workaround.
|
||||
@@ -0,0 +1,184 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Diagnostics/CanDiagnosticResult.xaml.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Diagnostics/DigitalInputDiagnosticResult.xaml.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Diagnostics/TCDiagnosticResult.xaml.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Diagnostics/DiagnosticResult.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Diagnostics/DigitalInputDiagnostics.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Diagnostics/DiagnosticChannel.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Diagnostics/TestObjectHelper.cs
|
||||
generated_at: "2026-04-16T04:14:35.190945+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "fd3a4b19571aa1b4"
|
||||
---
|
||||
|
||||
# Diagnostics
|
||||
|
||||
### **Purpose**
|
||||
This module provides the data models and UI controls for displaying diagnostic results in the DataPRO Windows application. It defines structured data classes (e.g., `DiagnosticResult`, `DigitalInputDiagnostics`, `DiagnosticChannel`) that encapsulate diagnostic status, thresholds, and channel metadata, and exposes corresponding WPF `UserControl` classes (`CanDiagnosticResult`, `DigitalInputDiagnosticResult`, `TCDiagnosticResult`) for rendering diagnostic UI elements. The module serves as the bridge between low-level hardware diagnostic data (from `DTS.Common` libraries) and the UI layer, enabling consistent presentation of pass/fail/untested states, threshold comparisons, and channel-specific diagnostics across analog, digital input, CAN, and thermocouple sensors.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
#### **`DiagnosticResult` (class)**
|
||||
*Namespace:* `DataPROWin7.CollectDataSubControls.Diagnostics`
|
||||
*Inherits:* `BasePropertyChanged`
|
||||
*Purpose:* Immutable data model for a single diagnostic result entry (e.g., voltage, resistance). Supports optional subline (secondary) display fields.
|
||||
|
||||
- **Constructor**
|
||||
```csharp
|
||||
DiagnosticResult(
|
||||
string name, DiagnosticStatus status, string lowTitle, string actualTitle, string highTitle,
|
||||
double lowThresholdValue, double highThresholdValue, double actualValue, int decimalPlaces,
|
||||
string subLine1LowTitle = null, string subLine1ActualTitle = null, string subLine1HighTitle = null,
|
||||
double subLine1LowThresholdValue = double.NaN, double subLine1HighThresholdValue = double.NaN,
|
||||
double subLine1ActualValue = double.NaN, int subLineDecimalPlaces = 2,
|
||||
string actualValueDecimalFormat = null)
|
||||
```
|
||||
Initializes a diagnostic result. Sets `HasSubLine1 = true` if `subLine1ActualTitle` is non-null/whitespace. Formats numeric values per specified decimal places and format. Sets `BackgroundColor` based on `status` (Passed/Failed/Untested).
|
||||
|
||||
- **Properties**
|
||||
- `string Name`
|
||||
- `string LowTitle`, `ActualTitle`, `HighTitle`
|
||||
- `string SubLine1LowTitle`, `SubLine1ActualValueText`, `SubLine1HighTitle` *(only populated if `HasSubLine1`)*
|
||||
- `string LowThresholdText`, `ActualValueText`, `HighThresholdText`
|
||||
- `string SubLine1LowThresholdText`, `SubLine1HighThresholdText` *(only populated if `HasSubLine1`)*
|
||||
- `bool HasSubLine1` *(read-only; derived from constructor args)*
|
||||
- `DiagnosticStatus Status` *(with side effect: updates `BackgroundColor`)*
|
||||
- `Color BackgroundColor` *(bindable; changes based on `Status` and selection state)*
|
||||
|
||||
#### **`DigitalInputDiagnostics` (class)**
|
||||
*Namespace:* `DataPROWin7.CollectDataSubControls.Diagnostics`
|
||||
*Inherits:* `BasePropertyChanged`
|
||||
*Purpose:* Data model for digital input channel diagnostics, exposing translated strings for mode, state, and status.
|
||||
|
||||
- **`SetChannel(DiagnosticChannel channel)`**
|
||||
Updates internal `_channel` reference and raises `PropertyChanged` for all public properties.
|
||||
|
||||
- **Properties**
|
||||
- `string ChannelName`, `HardwareChannelName`, `SensorName` *(derived from `_channel`)*
|
||||
- `string ChannelMode` *(e.g., `"CCNC"`, `"THL"`; maps `DigitalInputModes` to localized strings)*
|
||||
- `string Status` *(e.g., `"Passed"`, `"Untested"`; maps `DiagnosticStatus`)*
|
||||
- `string InitialState` *(e.g., `"Open"`, `"Low"`; depends on `InputMode`, hardware type, and `_diagnostics.DigitalInputActiveState`)*
|
||||
- `string ExpectedInitialState` *(e.g., `"Closed"`, `"High"`; default state per `InputMode`)*
|
||||
|
||||
#### **`DiagnosticChannel` (class)**
|
||||
*Namespace:* `DataPROWin7.CollectDataSubControls.Diagnostics`
|
||||
*Inherits:* `BasePropertyChanged`
|
||||
*Purpose:* Wraps a `HardwareChannel` for UI display, adding selection state and status-based styling.
|
||||
|
||||
- **Constructor**
|
||||
```csharp
|
||||
DiagnosticChannel(HardwareChannel channel, CalibrationEnforcement enforcement = None, CalibrationBehaviors behavior = NonLinearIfAvailable)
|
||||
```
|
||||
Subscribes to `HardwareChannel.PropertyChanged` to update UI when `DiagnosticStatus` changes.
|
||||
|
||||
- **Properties**
|
||||
- `HardwareChannel HardwareChannel` *(read-only)*
|
||||
- `bool Selected` *(bindable; triggers `BackgroundColor`/`ForegroundColor` updates)*
|
||||
- `Color BackgroundColor` *(depends on `Selected` and `HardwareChannel.DiagnosticStatus`)*
|
||||
- `Color ForegroundColor` *(depends on `Selected`)*
|
||||
- `string SerialNumber`, `SerialNumberWithAxis`, `ChannelName`, `ChannelNumberText`
|
||||
- `string Status` *(e.g., `"Passed"`, `"Performing Diagnostics"`)*
|
||||
- `CalibrationEnforcement CalibrationEnforcement`, `CalibrationBehaviors CalibrationBehavior`
|
||||
|
||||
#### **`TestObjectHelper` (class)**
|
||||
*Namespace:* `DataPROWin7.CollectDataSubControls.Diagnostics`
|
||||
*Inherits:* `BasePropertyChanged`
|
||||
*Purpose:* Aggregates diagnostic status for a test group (e.g., a test object), managing hardware-level diagnostics and determining overall group status.
|
||||
|
||||
- **Constructor**
|
||||
```csharp
|
||||
TestObjectHelper(bool bWarnOnFailedBattery, IGroup group, DiagnosticsBase.DiagnosticsType type, TestTemplate test)
|
||||
```
|
||||
Populates `TestObjectHardwareHelpers` by analyzing channels and hardware in `test`. Sets `ContainsTOM` if any hardware is a TOM type.
|
||||
|
||||
- **Properties**
|
||||
- `bool ContainsTOM` *(read-only; set in constructor)*
|
||||
- `IGroup Group`
|
||||
- `string DisplaySerialNumber`, `Description`
|
||||
- `bool Selected` *(bindable; triggers `BackgroundColor`/`ForegroundColor` updates)*
|
||||
- `Color BackgroundColor`, `ForegroundColor` *(depends on `Selected` and `Status`)*
|
||||
- `ApplicationStatusTypes Status` *(computed from `TestObjectHardwareHelpers`)*
|
||||
- `ApplicationStatusTypes DiagnosticStatus` *(computed from channel/DAS status; triggers `Status` update)*
|
||||
- `bool HaveRunDiagnostics` *(bindable; indicates if diagnostics have run)*
|
||||
- `string DiagnosticStatusText` *(e.g., `"Passed"`, `"Failed"`)*
|
||||
- `HardwareHelper[] TestObjectHardwareHelpers`
|
||||
|
||||
- **Methods**
|
||||
- `bool AllHaveRunDiagnostics(bool postTestDiagnostics)`
|
||||
- `void ClearDiagnostics()` *(resets `HaveRunDiagnostics`, `Status`, and underlying hardware diagnostics)*
|
||||
|
||||
#### **`UserControl` Classes**
|
||||
*Namespace:* `DataPROWin7.CollectDataSubControls`
|
||||
|
||||
- **`CanDiagnosticResult : UserControl`**
|
||||
- Constructor: `CanDiagnosticResult()`
|
||||
- *No custom logic beyond WPF initialization.*
|
||||
|
||||
- **`DigitalInputDiagnosticResult : UserControl`**
|
||||
- Constructor: `DigitalInputDiagnosticResult()`
|
||||
- *No custom logic beyond WPF initialization.*
|
||||
|
||||
- **`TCDiagnosticResult : UserControl, INotifyPropertyChanged`**
|
||||
- Constructor: `TCDiagnosticResult()`
|
||||
- **Methods:**
|
||||
- `protected void SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)`
|
||||
Raises `PropertyChanged` if `field` changes. Used for `INotifyPropertyChanged` implementation.
|
||||
- *No custom logic beyond WPF initialization and `INotifyPropertyChanged` support.*
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
1. **`DiagnosticResult`**
|
||||
- `HasSubLine1` is `true` **iff** `subLine1ActualTitle` is non-null/whitespace in the constructor.
|
||||
- `BackgroundColor` is updated **only** when `Status` is set (via `set` accessor), never during construction.
|
||||
- Numeric fields (`LowThresholdText`, `ActualValueText`, etc.) are `string.Empty` if the corresponding value is `double.NaN`.
|
||||
|
||||
2. **`DiagnosticChannel`**
|
||||
- `BackgroundColor`/`ForegroundColor` changes are triggered by `Selected` changes **or** `HardwareChannel.DiagnosticStatus` changes (via `_channel_PropertyChanged`).
|
||||
- `ChannelNumberText` appends calibration enforcement info (e.g., `"(Linear)")` only if `CalibrationEnforcement != None && CalibrationBehavior == UseBothIfAvailable`.
|
||||
|
||||
3. **`TestObjectHelper`**
|
||||
- `DiagnosticStatus` is `IDLE` if `HaveRunDiagnostics == false`.
|
||||
- `DiagnosticStatus` is `Failed` if **any** channel (non-squib/non-digital) has `DiagnosticStatus.Failed`.
|
||||
- `DiagnosticStatus` is `IDLE` if **any** channel (non-squib/non-digital) has `DiagnosticStatus.Untested`.
|
||||
- `ContainsTOM` is set **once** during construction and never updated.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
#### **Imports/References (from source)**
|
||||
- **Core Libraries:**
|
||||
- `System.Windows.Controls` (WPF UI)
|
||||
- `System.ComponentModel` (`INotifyPropertyChanged`)
|
||||
- `DTS.Common`, `DTS.Common.Base`, `DTS.Common.Enums`, `DTS.Common.Interface.*` (hardware/data model abstractions)
|
||||
- `DataPROWin7.DataModel`, `DataPROWin7.Common` (internal data structures)
|
||||
- `DTS.Common.SharedResource.Strings` (localized strings: `StringResources.*`)
|
||||
- `BrushesAndColors` (custom color constants; inferred from usage)
|
||||
|
||||
#### **Depended-on Modules**
|
||||
- `DiagnosticResult`, `DigitalInputDiagnostics`, `DiagnosticChannel`, `TestObjectHelper` are used by UI controls (e.g., `CanDiagnosticResult`, `DigitalInputDiagnosticResult`, `TCDiagnosticResult`) and likely by parent diagnostic views (not shown).
|
||||
- `TestObjectHelper` depends on `HardwareHelper` (not in source) and `DASHardware` (from `DTS.Common`).
|
||||
|
||||
#### **Depends-on Modules**
|
||||
- `DiagnosticResult` depends on `DiagnosticStatus` (from `DTS.Common.Interface.Sensors.AnalogDiagnostics`).
|
||||
- `DigitalInputDiagnostics` depends on `DigitalInputModes` (from `DTS.Common.Enums.Hardware`) and `StringResources`.
|
||||
- `TestObjectHelper` depends on `IGroup`, `TestTemplate`, `HardwareHelper`, `ApplicationStatusTypes`.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
1. **`DiagnosticChannel.DiagnosticsInProgress` is declared but never set** (per comment: *"I don't see this set anywhere"*). Its value is always `false`.
|
||||
2. **`DigitalInputDiagnostics.ExpectedInitialState` returns `"---"` for TDAS/G5 hardware** (per fix comments: *9912*, *10342*), even though other hardware types return expected states.
|
||||
3. **`DiagnosticResult` is immutable** after construction—no setters for its properties. `Status` is the only mutable field, and it triggers `BackgroundColor` updates.
|
||||
4. **`TCDiagnosticResult` implements `INotifyPropertyChanged` but provides no properties**—`SetField` is unused in the source. Likely intended for future expansion.
|
||||
5. **`TestObjectHelper.Status` setter is a no-op** (only raises `OnPropertyChanged`); status is computed via getters.
|
||||
6. **`TestObjectHelper.AllHaveRunDiagnostics` excludes squib channels in post-test diagnostics** (per comment *29948*), but includes them in pre-test diagnostics.
|
||||
7. **`DiagnosticChannel.ChannelName` may return `"Digital setting"` or `"Squib setting"`** (via `SensorConstants.IsTestSpecific...`), overriding the raw channel name.
|
||||
8. **`DiagnosticChannel.BackgroundColor` logic is complex**:
|
||||
- Selected state uses `*_ActionBackground` colors.
|
||||
- `Untested` uses `Color_ItemBackground` (not `Color_ActionBackground` when unselected).
|
||||
9. **`DiagnosticResult` uses `"N" + decimalPlaces` format** (e.g., `"N2"`), but `actualValueDecimalFormat` can override this for the actual value.
|
||||
@@ -0,0 +1,165 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Download/ThreadData.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Download/DownloadInfo.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Download/EventData.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Download/TestObject.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Download/PhysicalHardware.cs
|
||||
generated_at: "2026-04-16T04:14:16.362086+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f5e0cfd79674608e"
|
||||
---
|
||||
|
||||
# Download
|
||||
|
||||
## Documentation: Download Module Data Structures
|
||||
|
||||
### 1. Purpose
|
||||
This module provides core data models and supporting classes for managing download operations in the DataPRO Windows application. It defines structured data containers (`DownloadInfo`, `EventData`), thread synchronization primitives (`DownloadThreadData`), and UI-facing view models (`TestObject`, `PhysicalHardware`) that represent logical groupings (e.g., test objects, DAS units/racks) and their download status, progress, and visual properties. These classes decouple business logic from UI rendering while enabling status tracking, progress reporting, and hierarchical hardware relationships (e.g., racks containing child DAS units).
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `DownloadInfo` (public class)
|
||||
- **`List<IDASCommunication> DasList { get; set; }`**
|
||||
List of DAS communication interfaces to be operated on during a download.
|
||||
- **`long[] ChannelIdList { get; set; }`**
|
||||
Array of channel IDs targeted for download.
|
||||
|
||||
#### `EventData` (internal class)
|
||||
- **`List<EventInfoAggregate> Events { get; set; }`**
|
||||
List of event aggregates (from `DTS.Common.SerializationPlus`) representing events to be processed.
|
||||
|
||||
#### `DownloadThreadData` (internal class)
|
||||
- **`ManualResetEvent OverwriteDataEvent { get; set; }`**
|
||||
Synchronization event used to signal completion or readiness for data overwrite operations.
|
||||
- **`ManualResetEvent PartialDownloadEvent { get; set; }`**
|
||||
Synchronization event used to signal completion or readiness for partial download operations.
|
||||
|
||||
#### `TestObject` (public class, inherits `BasePropertyChanged`)
|
||||
- **`void SetPercentComplete(IDASCommunication das, int percent)`**
|
||||
Updates the download progress (`percent`) for a specific `IDASCommunication` instance. Updates internal `_lookup` dictionary and raises `TestObjectDownloadStatusText` property change.
|
||||
- **`void SetStatus(ApplicationStatusTypes status)`**
|
||||
Sets the overall `Status` of the `TestObject`.
|
||||
- **`void SetStatus(IDASCommunication das, ApplicationStatusTypes status)`**
|
||||
Updates status for a specific DAS. If the DAS belongs to the `Group.IncludedHardware`, propagates status to the overall `Status`. Handles aggregation logic: `Finished` only sets overall status if *all* DAS units are finished; `Failed`/`ROIFailed` immediately set overall status.
|
||||
- **`void ClearPercent()`**
|
||||
Clears `_lookup` and `_currentStatus` dictionaries.
|
||||
- **`IGroup Group { get; set; }`**
|
||||
Reference to the logical group this `TestObject` represents.
|
||||
- **`string DisplaySerialNumber { get; }`**
|
||||
Returns `Group.DisplayName`.
|
||||
- **`string Template { get; }`**
|
||||
Returns `Group.Description`.
|
||||
- **`string TestObjectImagePath { get; set; }`**
|
||||
Path to the image file used for the test object (e.g., `"Assets/LightGray.png"`). Setting raises `TestObjectImage` change.
|
||||
- **`ImageSource TestObjectImage { get; }`**
|
||||
Returns a `BitmapImage` constructed from `TestObjectImagePath` using `pack://application:,,,/ResourceFile.xaml`.
|
||||
- **`bool Selected { get; set; }`**
|
||||
UI selection state. Changing it raises `BackgroundColor` and `ForegroundColor` changes.
|
||||
- **`Color BackgroundColor { get; }`**
|
||||
Returns background color based on `Selected` state and `Status` (e.g., `Brush_ApplicationStatus_Complete_ActionBackground` if selected and finished).
|
||||
- **`Color ForegroundColor { get; }`**
|
||||
Returns foreground color based on `Selected` state (`Color_ActionForeground` if selected, else `Color_ItemForeground`).
|
||||
- **`ApplicationStatusTypes Status { get; set; }`**
|
||||
Current status of the download operation. Valid values: `IDLE`, `Downloading`, `UARTDownloading`, `Finished`, `Failed`, `ROIFailed`, `Cancelled`, `CancelledPartial`.
|
||||
- **`string TestObjectDownloadStatusText { get; }`**
|
||||
Returns localized status string (e.g., `"Download_Finished"`, `"Download_Downloading"`) based on `Status`.
|
||||
|
||||
#### `PhysicalHardware` (public class, inherits `BasePropertyChanged`)
|
||||
- **`void SetStatus(ApplicationStatusTypes status)`**
|
||||
Sets the overall `Status`.
|
||||
- **`void SetStatus(IDASCommunication das, ApplicationStatusTypes status)`**
|
||||
Sets `Status` only if `das.SerialNumber` matches `Hardware.SerialNumber`.
|
||||
- **`void SetPercentComplete(IDASCommunication das, int percent)`**
|
||||
Updates progress for a child DAS (if `Hardware` is a rack). If children exist, computes weighted average progress from `_percentCompleteBySerialNumber`. Otherwise, updates `_percentDone` only if `das.SerialNumber == Hardware.SerialNumber`.
|
||||
- **`void SetPercentComplete(int percent)`**
|
||||
Directly sets `_percentDone` and raises `PhysicalHardwareDownloadStatusText` change.
|
||||
- **`DataModel.DASHardware Hardware { get; set; }`**
|
||||
Sets the underlying hardware model. When set, if `Hardware.IsPseudoRack()` is true, populates `_childrenHardwareSerialNumbers` by querying active devices from `DASFactory` and matching via `DownstreamMACAddresses` (for SLICE6 distributors) or `ConnectString` (IP address) for other racks.
|
||||
- **`string DASImagePath { get; set; }`**
|
||||
Path to hardware-specific image. Setter raises `DASImage` change. Getter dynamically resolves image path based on `Hardware.GetHardwareTypeEnum()` (e.g., `"Assets/Hardware/TDAS_TOM_Front.jpg"` for `HardwareTypes.TOM`).
|
||||
- **`ImageSource DASImage { get; }`**
|
||||
Returns a `BitmapImage` constructed from `DASImagePath` using `pack://application:,,,/ResourceFile.xaml`.
|
||||
- **`string HardwareType { get; }`**
|
||||
Returns hardware type string via `DiagnosticsBase.GetHardwareString(Hardware)`.
|
||||
- **`HardwareTypes GetHardwareTypeEnum()`**
|
||||
Returns `Hardware.GetHardwareTypeEnum()`.
|
||||
- **`bool Selected { get; set; }`**
|
||||
UI selection state. Changing it raises `BackgroundColor` and `ForegroundColor` changes.
|
||||
- **`Color BackgroundColor { get; }`**
|
||||
Returns background color based on `Selected` state and `Status` (same logic as `TestObject.BackgroundColor`).
|
||||
- **`Color ForegroundColor { get; }`**
|
||||
Returns foreground color based on `Selected` state (same logic as `TestObject.ForegroundColor`).
|
||||
- **`int _percentDone { private }`**
|
||||
Internal field storing overall download progress percentage.
|
||||
- **`void Clear()`**
|
||||
Resets `_percentDone` to `0`.
|
||||
- **`string PhysicalHardwareDownloadStatusText { get; }`**
|
||||
Returns status string with progress (e.g., `"Downloading 45%"` or `"UARTDownloading 100%"`) or plain `Status.ToString()` if not downloading.
|
||||
- **`string DownloadSpeedText { get; }`**
|
||||
Returns progress as `"X kB/sec"` (note: value is `_percentDone`, likely a placeholder or misnamed; actual speed not computed).
|
||||
- **`ApplicationStatusTypes Status { get; set; }`**
|
||||
Current status of the download operation (same values as `TestObject.Status`).
|
||||
- **`string Name { get; }`**
|
||||
Returns `Hardware.GetHardware().SerialNumber`.
|
||||
- **`string Connection { get; }`**
|
||||
Returns `Hardware.GetHardware().IPAddress`.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- **`TestObject.Group` must be non-null** when `SetStatus(IDASCommunication, ApplicationStatusTypes)` or `SetPercentComplete(IDASCommunication, int)` is called, as it is used to determine `IncludedHardware` membership.
|
||||
- **`PhysicalHardware.Hardware` must be set before calling `SetPercentComplete(IDASCommunication, int)` or `SetStatus(IDASCommunication, ApplicationStatusTypes)`** to ensure correct child DAS matching.
|
||||
- **`ApplicationStatusTypes` values used in `Status` are strictly limited to:** `IDLE`, `Downloading`, `UARTDownloading`, `Finished`, `Failed`, `ROIFailed`, `Cancelled`, `CancelledPartial`.
|
||||
- **Progress reporting (`_percentDone`, `_lookup`) assumes values are in the range [0, 100]**, though no explicit validation is present.
|
||||
- **`PhysicalHardware` aggregates child progress only if `_childrenHardwareSerialNumbers` is non-empty**, computed as integer average of child percentages.
|
||||
- **`TestObject.SetStatus(IDASCommunication, ApplicationStatusTypes)` only updates overall `Status` if the DAS’s serial number maps to a DAS ID present in `Group.IncludedHardware`** (via `_serialNumberToDASId` and `GetDASId`).
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Imports/References
|
||||
- **`DTS.Common.Interface.DASFactory.IDASCommunication`**
|
||||
Used in `DownloadInfo`, `TestObject`, `PhysicalHardware` to represent DAS communication interfaces.
|
||||
- **`DTS.Common.SerializationPlus.EventInfoAggregate`**
|
||||
Used in `EventData` for event aggregates.
|
||||
- **`DTS.Common.Base.BasePropertyChanged`**
|
||||
Base class for `TestObject` and `PhysicalHardware` (enables `INotifyPropertyChanged`).
|
||||
- **`System.Windows.Media`** (WPF)
|
||||
Used for `ImageSource`, `BitmapImage`, `Color`, `BrushesAndColors`.
|
||||
- **`DataPROWin7.SubControls.BrushesAndColors`**
|
||||
Provides static color constants for status-based UI theming.
|
||||
- **`DataPROWin7.DataModel.DASHardware`**
|
||||
Used in `PhysicalHardware.Hardware` and for hardware type resolution.
|
||||
- **`DTS.Common.DiagnosticsBase`**
|
||||
Used in `PhysicalHardware.HardwareType` to get hardware string representation.
|
||||
- **`DTS.Common.SharedResource.Strings.StringResources`**
|
||||
Provides localized strings for status text (e.g., `Download_Finished`).
|
||||
- **`DbOperations.DASGet`**
|
||||
Used in `TestObject.GetDASId` to query DAS ID by serial number.
|
||||
- **`App.DASFactory.GetActiveDevices()`**
|
||||
Used in `PhysicalHardware.Hardware` setter to discover child DAS units.
|
||||
|
||||
#### Dependencies
|
||||
- **Consumers**: Likely used by download controller/view models (not present in source) to drive UI and coordinate download workflows.
|
||||
- **No direct consumers in source**, but public visibility of `DownloadInfo`, `TestObject`, and `PhysicalHardware` implies external usage.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
- **`PhysicalHardware.DownloadSpeedText` is misleading**: It returns `_percentDone + " kB/sec"` (e.g., `"45 kB/sec"`), but `_percentDone` represents *percentage*, not actual throughput. No real speed calculation is performed.
|
||||
- **`TestObject.GetDASId` uses `DbOperations.DASGet`**: This implies database access; failure to initialize the DB or invalid serial numbers will return `-1`, causing the DAS to be excluded from status updates.
|
||||
- **`PhysicalHardware.Hardware` setter has complex child-DAS discovery logic**: Behavior differs for `IsSLICE6Distributor` vs. other rack types (MAC-based vs. IP-based matching). This may be fragile if network topology changes or `ConnectString` format varies.
|
||||
- **No null-safety for `Hardware.GetHardware()`**: In `PhysicalHardware.Name` and `Connection`, calling `GetHardware()` on a null `_hardware` would throw `NullReferenceException`.
|
||||
- **`TestObject.SetStatus` aggregation logic is stateful**: `_currentStatus` dictionary accumulates entries; `ClearPercent()` clears it, but no other cleanup is exposed. If `SetStatus` is called after `ClearPercent`, old DAS entries may be missing.
|
||||
- **`TestObject.SetPercentComplete` only updates `_lookup` if `_lookup.ContainsKey(das.SerialNumber)`**: If a DAS serial number is not pre-registered, progress is silently ignored.
|
||||
- **`PhysicalHardware.SetPercentComplete(IDASCommunication, int)` silently ignores non-child DAS units** when `_childrenHardwareSerialNumbers` is non-empty (via `return`), potentially masking misconfiguration.
|
||||
- **`TestObject.TestObjectImage` and `PhysicalHardware.DASImage` construct `BitmapImage` on every getter call**: This may cause performance issues if bound frequently in UI; no caching is implemented.
|
||||
- **No thread-safety guarantees**: `DownloadThreadData` exposes `ManualResetEvent` for synchronization, but `TestObject`/`PhysicalHardware` state (e.g., `_lookup`, `_currentStatus`) is not thread-safe. Concurrent access could cause race conditions.
|
||||
- **`TestObject` and `PhysicalHardware` share identical status/color logic**: This duplication suggests a common interface or base class was considered but not implemented.
|
||||
|
||||
None identified beyond these.
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Realtime/PairedTargetData.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Realtime/GraphPlotInfo.xaml.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Realtime/RealtimeDASHelper.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Realtime/MeterMode.xaml.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Realtime/MeterGraph.xaml.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/Realtime/RealtimePlot.cs
|
||||
generated_at: "2026-04-16T04:14:00.954730+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "48134bd9ebc25201"
|
||||
---
|
||||
|
||||
# Documentation: Realtime Data Collection Subcontrols
|
||||
|
||||
## 1. Purpose
|
||||
This module provides UI and data management infrastructure for real-time data acquisition and visualization in the DataPRO Windows application. It supports two primary display modes—**Meter Mode** (for single-channel summary views) and **Plot Mode** (for time-series graphing)—and coordinates with hardware abstraction layers (`IDASCommunication`) to manage channel-specific data (`SampleData[]`) and device communication. The module ensures only active channels (those currently displayed) are processed, with special handling for TDAS hardware that requires per-module identification.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `PairedTargetData`
|
||||
- **`PairedTargetData(SampleData[] newData, IDASCommunication newTarget)`**
|
||||
Constructor initializing the data buffer (`Data`) and target communication interface (`Target`) for a single channel’s real-time samples.
|
||||
- **`void CheapDispose()`**
|
||||
Explicitly nulls `Data` and `Target` references to release memory *without* implementing `IDisposable`. Intended for cleanup when the object remains in a `ConcurrentQueue` but is no longer needed (primarily to release `SampleData[]` and `IDASCommunication` references).
|
||||
|
||||
### `GraphPlotInfo`
|
||||
- **`GraphPlotInfo()`**
|
||||
Constructor initializing the `UserControl` and binding to its XAML layout.
|
||||
- **`RealtimePlot MyRealtimePlot { get; }`**
|
||||
Exposes a single `RealtimePlot` instance used for plot-mode visualization.
|
||||
- **`void FixSelectedValueText(Controls.RealtimeChart.RealtimeChannel channel)`**
|
||||
Updates the `ddlSelectedChannel.Text` UI element to display the string representation of the given `channel`.
|
||||
- **`bool SetProperty<T>(ref T storage, T value, string propertyName = null)`**
|
||||
Base `INotifyPropertyChanged` helper: updates `storage` to `value` and raises `PropertyChanged` if changed. Returns `true` if the value was updated.
|
||||
- **`void OnPropertyChanged(string propertyName = null)`**
|
||||
Raises the `PropertyChanged` event for the specified property name.
|
||||
|
||||
### `RealtimeDASHelper`
|
||||
- **`RealtimeDASHelper(RealtimeChart.RealtimeChannel channel)`**
|
||||
Constructor storing the `Channel` property (used for identifying which channel this helper manages).
|
||||
- **`static string[] GetKeys(RealtimeChart.RealtimeChannelAggregate chart)`**
|
||||
Generates unique identifiers for DAS devices in the given `chart`:
|
||||
- For non-TDAS hardware: returns `ch.Hardware.SerialNumber`.
|
||||
- For TDAS hardware (`TDAS_Pro_Rack`, `TDAS_LabRack`): returns `DASSerialNumber_ModuleArrayIndex`.
|
||||
Used to deduplicate or route communication to specific DAS modules.
|
||||
|
||||
### `MeterMode`
|
||||
- **`MeterMode()`**
|
||||
Constructor initializing the `UserControl` and its XAML layout.
|
||||
- **`string MainChannelName { get; }`**
|
||||
Returns the `MeterName` of the `mainChart` (a `MeterGraph` instance).
|
||||
- **`void SetRealtimeChannel(Controls.RealtimeChart.RealtimeChannel channel)`**
|
||||
Reconfigures the UI to display data for the given `channel`:
|
||||
- Clears existing subgraphs.
|
||||
- If `channel.Channels.Length > 1`, populates `SubGraphsGrid` with multiple `MeterGraph` instances (one per sub-channel).
|
||||
- Otherwise, configures `mainChart` with the single channel’s metadata (ISO code, hardware channel, sensor SN).
|
||||
- **`void SetMainValueText(string text)`**
|
||||
Updates `mainChart.CurrentAverageText` with `text`.
|
||||
- **`void SetValueText(string id, string text)`**
|
||||
Updates `CurrentAverageText` of the subgraph identified by `id` (via `ch.GetId()`).
|
||||
|
||||
### `MeterGraph`
|
||||
- **`MeterGraph()`**
|
||||
Constructor initializing the `UserControl` and XAML layout.
|
||||
- **`string CurrentAverageText { get; set; }`**
|
||||
Binds to the UI’s average value display. Defaults to `"N/A"` (from `StringResources.Table_NA`).
|
||||
- **`bool ToggleDigitalState { set; }`**
|
||||
Sets background/foreground colors based on digital input state:
|
||||
- `true` → Red background, white foreground (active/toggled state).
|
||||
- `false` → Green background, black foreground (default state).
|
||||
- **`string MeterName { get; set; }`**
|
||||
Binds to the meter’s label. Resets background/foreground to transparent/black on change.
|
||||
- **`string MeterISOCode { get; set; }`**
|
||||
Binds to the ISO code display.
|
||||
- **`Visibility ISOCodeVisibility { get; }`**
|
||||
Returns `Visible` if `SerializedSettings.ISOViewMode` is `ISOAndUserCode` or `ISOOnly`; otherwise `Collapsed`.
|
||||
- **`string SensorSN { get; set; }`**
|
||||
Sets the sensor serial number, but *suppresses display* if `MeterName` contains the value (avoids redundancy).
|
||||
- **`Visibility SensorSNVisbility { get; }`**
|
||||
Returns `Visible` if `SensorSN` is non-empty/whitespace; otherwise `Collapsed`.
|
||||
- **`string HardwareChannel { get; set; }`**
|
||||
Binds to the hardware channel identifier.
|
||||
|
||||
### `RealtimePlot`
|
||||
- **`RealtimePlot()`**
|
||||
Constructor (inherits from `BasePropertyChanged`).
|
||||
- **`RealtimePlot.Tags`**
|
||||
Enum defining property names used in `OnPropertyChanged` calls (e.g., `ISOCode`, `CurrentAverageText`).
|
||||
- **`SolidColorBrush PlotBackground { get; set; }`**
|
||||
Returns `White` if `SelectedChannel` is `null`; otherwise returns the stored `_brush`.
|
||||
- **`Controls.RealtimeChart.RealtimeChannel[] AvailableChannels { get; set; }`**
|
||||
Gets/sets the list of channels available for selection.
|
||||
- **`Controls.RealtimeChart.RealtimeChannel SelectedChannel { get; set; }`**
|
||||
Gets/sets the currently selected channel. On change:
|
||||
- Resets `CurrentAverageText` to `"N/A"`.
|
||||
- Raises `OnPropertyChanged` for *all* `Tags` enum values.
|
||||
- Calls `RealtimeControl?.PlotSelectedChannelChanged(this)` if `RealtimeControl` is set.
|
||||
- **`int GetSelectedIndex()`**
|
||||
Returns the zero-based index of `SelectedChannel` in `AvailableChannels`, or `-1` if not found.
|
||||
- **`string ISOCode { get; }`**
|
||||
Returns `SelectedChannel.ISOCode` or `"N/A"` if `SelectedChannel` is `null`.
|
||||
- **`string ChannelName { get; }`**
|
||||
Returns `SelectedChannel.ChannelName` or `"N/A"` if `SelectedChannel` is `null`.
|
||||
- **`string SensorSerial { get; }`**
|
||||
Returns `SelectedChannel.SensorsString` or `"N/A"` if `SelectedChannel` is `null`.
|
||||
- **`string SensorPolarity { get; }`**
|
||||
Returns `SelectedChannel.Polarity` or `"N/A"` if `SelectedChannel` is `null`.
|
||||
- **`Visibility SensorPolarityVisibility { get; }`**
|
||||
Returns `Collapsed` if `SelectedChannel?.Polarity` is `null`/empty; otherwise `Visible`.
|
||||
- **`Visibility AvailableChannelsVisibility { get; set; }`**
|
||||
Controls visibility of the channel selection dropdown.
|
||||
- **`Visibility RealtimePlotVisibility { get; set; }`**
|
||||
Controls visibility of the entire plot control (used for show/hide operations per issue FB 13750).
|
||||
- **`string CurrentAverageText { get; set; }`**
|
||||
Binds to the current average value display.
|
||||
- **`string Units { get; set; }`**
|
||||
Binds to the units display.
|
||||
- **`string Max { get; set; }`**, **`Min { get; set; }`**, **`Ave { get; set; }`**
|
||||
Binds to the max/min/average value displays.
|
||||
- **`string HardwareChannel { get; }`**
|
||||
Returns `SelectedChannel.HardwareChannelString` or `"N/A"` if `SelectedChannel` is `null`.
|
||||
|
||||
## 3. Invariants
|
||||
- `PairedTargetData.Data` and `Target` must be non-null at construction but may be set to `null` via `CheapDispose()`.
|
||||
- `RealtimePlot.SelectedChannel` being `null` implies no channel is selected; in this state:
|
||||
- `CurrentAverageText`, `ISOCode`, `ChannelName`, `SensorSerial`, `SensorPolarity`, and `HardwareChannel` all return `"N/A"`.
|
||||
- `PlotBackground` is `White`.
|
||||
- `MeterGraph.SensorSN` is suppressed (set to `""`) if `MeterName` contains the value, ensuring no redundant display.
|
||||
- `MeterGraph.ISOCodeVisibility` and `SensorSNVisbility` depend solely on `SerializedSettings.ISOViewMode` and `SensorSN` content, respectively.
|
||||
- `RealtimeDASHelper.GetKeys()` uses hardware type (`TDAS_Pro_Rack`/`TDAS_LabRack`) to determine key format; other hardware uses serial number only.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Imports/References**:
|
||||
- `DTS.Common.Interface.DASFactory` (`IDASCommunication` interface).
|
||||
- `DTS.DASLib.Service` (likely provides `SampleData` type).
|
||||
- `DTS.Common.Enums.Hardware` (`HardwareTypes`, `IsoViewMode`).
|
||||
- `DTS.Common.SharedResource.Strings` (`StringResources.Table_NA`).
|
||||
- `DataPROWin7.Controls` (contains `RealtimeChart.RealtimeChannel`, `RealtimeChart.RealtimeChannelAggregate`).
|
||||
- `DataPROWin7.Common` (contains `SerializedSettings`).
|
||||
- **Consumers**:
|
||||
- `RealtimePlot` is used by `GraphPlotInfo` and likely bound to XAML.
|
||||
- `MeterMode` and `MeterGraph` are `UserControl` subclasses, implying usage in XAML views.
|
||||
- `RealtimeDASHelper` is used to generate DAS keys for routing data (likely by a higher-level controller not shown).
|
||||
- **Depends on**:
|
||||
- `BasePropertyChanged` (from `DTS.Common.Base`) for `RealtimePlot`.
|
||||
- `INotifyPropertyChanged` pattern for data binding in `GraphPlotInfo`, `MeterMode`, and `MeterGraph`.
|
||||
|
||||
## 5. Gotchas
|
||||
- `PairedTargetData.CheapDispose()` does *not* implement `IDisposable`; callers must ensure proper disposal of `SampleData[]` and `IDASCommunication` through other means.
|
||||
- `MeterGraph.SensorSN` suppresses display if `MeterName` contains the sensor SN—this is a heuristic that may fail if sensor SNs are substrings of channel names.
|
||||
- `MeterMode.SetRealtimeChannel()` has commented-out ISO/non-ISO mode logic (marked `//TODO Remove Non-ISO Mode code`), suggesting legacy behavior may still be active.
|
||||
- `RealtimePlot.SelectedChannel` setter raises `OnPropertyChanged` for *all* `Tags` enum values, which may cause unnecessary UI updates.
|
||||
- `RealtimeDASHelper.GetKeys()` uses `ch.Hardware.DASSerialNumber` for TDAS keys, but `ch.Hardware.SerialNumber` for others—ensure consistency in hardware property naming.
|
||||
- `MeterGraph.ToggleDigitalState` is a *setter-only* property; its value is not stored, so it cannot be queried or persisted.
|
||||
- `GraphPlotInfo.FixSelectedValueText()` updates `ddlSelectedChannel.Text` directly but does not bind to a property (commented-out `RebindMyRealtimePlot` suggests potential data-binding issues).
|
||||
@@ -0,0 +1,231 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ResolveChannels/SensorOutOfPosition.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ResolveChannels/ExtraEIDsTable.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ResolveChannels/SensorsOutofPositionTable.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ResolveChannels/ResolvedChannelsTable.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ResolveChannels/ChannelsToResolveTable.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ResolveChannels/HardwareChannelsTable.cs
|
||||
generated_at: "2026-04-16T04:15:08.688374+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "a9dba4b05459423e"
|
||||
---
|
||||
|
||||
# ResolveChannels
|
||||
|
||||
## Documentation: ResolveChannels Module – Channel Resolution UI Tables
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
This module provides a set of WPF-based data grid tables used in the *Resolve Channels* step of the DataPRO test setup workflow. Its purpose is to visualize and enable manual resolution of channel mismatches between logical channels (as defined in the test setup) and physical channels (as present on hardware modules). Specifically, it displays unresolved channels, channels with mismatched EIDs (Sensor ID out of position), channels with extra/unexpected EIDs, and resolved channel assignments. The module supports drag-and-drop interactions to assign or unassign logical-to-physical channel mappings.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `SensorOutOfPosition` (DataPROWin7.CollectDataSubControls.ResolveChannels)
|
||||
|
||||
- **`SensorOutOfPosition(string currentChannel, string originalChannel, string sensorId, string sensor)`**
|
||||
Constructor. Initializes immutable properties representing a sensor whose EID was found on a different physical channel than originally assigned.
|
||||
|
||||
- **`CurrentChannel` (string, read-only)**
|
||||
The physical channel *currently* reporting the sensor’s EID.
|
||||
|
||||
- **`OriginalChannel` (string, read-only)**
|
||||
The physical channel *expected* to report the sensor’s EID.
|
||||
|
||||
- **`SensorId` (string, read-only)**
|
||||
The EID (sensor ID) of the sensor.
|
||||
|
||||
- **`Sensor` (string, read-only)**
|
||||
Human-readable sensor description (e.g., serial number or type).
|
||||
|
||||
---
|
||||
|
||||
#### `ExtraEIDsTable` (DataPROWin7.SubControls)
|
||||
|
||||
- **`UnSet()`**
|
||||
Clears the table by setting `ItemsSource` to `null`.
|
||||
|
||||
- **`UpdateTable(TableHelper[] items)`**
|
||||
Populates the table with `TableHelper` instances representing channels with EIDs not present in the test setup.
|
||||
|
||||
- **`TableHelper` (nested class)**
|
||||
- **`TableHelper(string channelName, string eid, string sensorName)`**
|
||||
Constructor. Stores channel, EID, and sensor name for display.
|
||||
- **`ChannelName` (string, read-only)**
|
||||
- **`EID` (string, read-only)**
|
||||
- **`SensorName` (string, read-only)**
|
||||
|
||||
- **`ColumnIds` enum**
|
||||
Defines column order: `ChannelName`, `EID`, `SensorName`.
|
||||
|
||||
---
|
||||
|
||||
#### `SensorsOutOfPositionTable` (DataPROWin7.CollectDataSubControls.ResolveChannels)
|
||||
|
||||
- **`UnSet()`**
|
||||
Clears the table by setting `ItemsSource` to `null`.
|
||||
|
||||
- **`UpdateTable(SensorOutOfPosition[] items)`**
|
||||
Populates the table with `SensorOutOfPosition` instances.
|
||||
|
||||
- **`ColumnIds` enum**
|
||||
Defines column order: `CurrentChannel`, `OriginalChannel`, `SensorId`, `Sensor`.
|
||||
|
||||
- **Constructor**
|
||||
`SensorsOutOfPositionTable(ContentControl parentControl, DataPROPage page, ResolveChannels resolveChannels)`
|
||||
Initializes grid columns, sets `SelectionMode = None`, and configures binding to `SensorOutOfPosition` properties.
|
||||
|
||||
---
|
||||
|
||||
#### `ResolvedChannelsTable` (DataPROWin7.SubControls)
|
||||
|
||||
- **`UnSet()`**
|
||||
Clears the underlying `DataTable` rows and reassigns `DataTable`.
|
||||
|
||||
- **`Update(ResolveChannels.ManuallyResolvedChannel[] channels)`**
|
||||
Populates the table with manually resolved channel mappings. Each row includes:
|
||||
- DAS serial/module info
|
||||
- Logical channel name
|
||||
- Sensor info
|
||||
- Resolved logical channel object
|
||||
|
||||
- **`ColumnIds` enum (private)**
|
||||
`DAS`, `ChannelName`, `Sensor`, `ResolvedChannel`.
|
||||
|
||||
- **Constructor**
|
||||
`ResolvedChannelsTable(ContentControl parentControl, DataPROPage page)`
|
||||
Initializes a `System.Data.DataTable` with typed columns and WPF DataGrid columns bound to the table.
|
||||
|
||||
---
|
||||
|
||||
#### `ChannelsToResolveTable` (DataPROWin7.SubControls)
|
||||
|
||||
- **`UnSet()`**
|
||||
Clears the underlying `DataTable` rows.
|
||||
|
||||
- **`Update(ResolveChannels.UnresolvedChannel[] channels)`**
|
||||
Populates the table with unresolved channels. For each channel:
|
||||
- Channel name (ISO view mode)
|
||||
- Sensor serial number (via `SensorsCollection.GetSensorById`)
|
||||
- Sensor type (Squib/Digital Input/Digital Output/IEPE/Analog)
|
||||
- Status message (e.g., `Issue` field)
|
||||
- `UnresolvedChannel` object (for drag/drop)
|
||||
|
||||
- **`ColumnIds` enum (private)**
|
||||
`ChannelName`, `SensorName`, `Type`, `StatusMessage`, `UnresolvedChannel`.
|
||||
|
||||
- **`DRAG_FORMAT` (const string)**
|
||||
`"UnresolvedChannel []"` — custom format used when dragging unresolved channels.
|
||||
|
||||
- **Drag-and-drop overrides**
|
||||
- **`StartDragging()`**
|
||||
Serializes selected `UnresolvedChannel` objects using `DRAG_FORMAT`.
|
||||
- **`DoDrop(IDataObject, DataGridCell, string)`**
|
||||
On drop (from hardware table), calls `_resolveChannels.ManuallyResolveChannels(dasChannels, logicalChannels)`.
|
||||
|
||||
- **Constructor**
|
||||
`ChannelsToResolveTable(ContentControl parentControl, DataPROPage page, ResolveChannels resolveChannels)`
|
||||
Sets `SelectionMode = MultiRow`, configures columns, and registers drag/drop formats.
|
||||
|
||||
---
|
||||
|
||||
#### `HardwareChannelsTable` (DataPROWin7.SubControls)
|
||||
|
||||
- **`Update(TestTemplate test, Dictionary<string, UnresolvedChannel> resolvedChannels, List<ManuallyResolvedChannel> manuallyResolvedChannels, Dictionary<string, HardwareChannel> channelLookup)`**
|
||||
Populates the table with hardware channels. Filters out unsupported/irrelevant channels (e.g., squib pairs, RTC, high-G below cutoff). Populates rows with:
|
||||
- DAS/module serial
|
||||
- Physical channel name
|
||||
- IEPE support status
|
||||
- Logical channel name (if resolved)
|
||||
- Sensor info (`---` if none)
|
||||
- Flags: `ManuallyAssigned`, `SensorIDMissing`, `SensorIdOutOfPlace`
|
||||
- Remove command (button) with associated `HardwareChannel` parameter
|
||||
|
||||
- **`Update(DASHardware[] hardware, ...)`**
|
||||
Overload accepting raw hardware array.
|
||||
|
||||
- **`UnSet()`**
|
||||
Clears the underlying `DataTable`.
|
||||
|
||||
- **`ViewMode` (property, `ChannelViews` enum)**
|
||||
Controls filtering: `ALL`, `Assigned`, `Open`, `Manual`.
|
||||
|
||||
- **`ScrollIntoFocus(HardwareChannel channel)`**
|
||||
Scrolls the grid to show the row for the given hardware channel.
|
||||
|
||||
- **`btnRemoveCellTemplate_Click(object parameter)`**
|
||||
Event handler for remove button: calls `_resolveChannels.ManuallyUnresolveChannel(channel)`.
|
||||
|
||||
- **`ColumnIds` enum**
|
||||
Includes: `DAS`, `Module`, `PhysicalChannelName`, `IEPESupport`, `LogicalChannelName`, `Sensor`, `DASChannel`, `RemoveCommand`, `CMDParam`, `CMD_ENABLED`, `ManuallyAssigned`, `UsingSensorId`, `SensorIDMissing`, `SensorIdOutOfPlace`.
|
||||
|
||||
- **Drag-and-drop overrides**
|
||||
- **`StartDragging()`**
|
||||
Serializes selected `HardwareChannel` objects (excludes locked/assigned channels, high-G below cutoff). Uses `DTS.Common.Classes.Hardware.DragAndDropPayload.FORMAT`.
|
||||
- **`DoDrop(IDataObject, DataGridCell, string)`**
|
||||
On drop (from `ChannelsToResolveTable`), calls `_resolveChannels.ManuallyResolveChannels(dasChannels, logicalChannels)`.
|
||||
|
||||
- **Constructor**
|
||||
`HardwareChannelsTable(ContentControl parentControl, DataPROPage page, object owningControl)`
|
||||
Initializes `DataTable`, WPF columns, remove button column, drag/drop formats, and registers cell background coloring logic (`HardwareChannelsTable_LoadedCellPresenter`).
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **`SensorOutOfPosition` instances are immutable** — all properties are read-only and set only in the constructor.
|
||||
- **`ExtraEIDsTable` and `SensorsOutOfPositionTable` use `ItemsSource`** — they are bound to arrays of view models (`TableHelper[]`, `SensorOutOfPosition[]`) and cleared via `UnSet()`.
|
||||
- **`ResolvedChannelsTable`, `ChannelsToResolveTable`, and `HardwareChannelsTable` use `System.Data.DataTable`** — they populate a typed `DataTable` and assign it to `DataTable`.
|
||||
- **`HardwareChannelsTable` filters channels during `Update()`** — skips squib pairs (by incrementing `i`), RTC channels, and high-G channels below 500 SPS.
|
||||
- **`HardwareChannelsTable` disables remove button for locked EIDs** — if a sensor’s EID is assigned to a *different* physical channel, `CMD_ENABLED` is `false`.
|
||||
- **`ChannelsToResolveTable` allows multi-row selection** — `SelectionMode = MultiRow`.
|
||||
- **`SensorsOutOfPositionTable` and `ExtraEIDsTable` disable selection** — `SelectionMode = None`.
|
||||
- **`HardwareChannelsTable` supports drag/drop in both directions** — from hardware to unresolved, and vice versa.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Imports/References
|
||||
- `DTS.Common.*` (Base, Enums, SharedResource.Strings, Classes, Utils)
|
||||
- `DTS.SensorDB.SensorsCollection`
|
||||
- `C1.WPF.DataGrid` (WPF DataGrid control)
|
||||
- `System.Data` (`DataTable`, `DataColumn`, `DataRow`)
|
||||
- `System.Windows` (WPF drag/drop, data binding, `IDataObject`)
|
||||
- `DataPROWin7.DataModel` (`HardwareChannel`, `DASHardware`)
|
||||
- `DataPROWin7.SubControls` (`ResolveChannels`, `EditObjectSensorsControl`)
|
||||
- `DataPROWin7.CollectDataSubControls.ResolveChannels` (internal namespace)
|
||||
|
||||
#### Usage
|
||||
- **Consumed by**: `ResolveChannels` control (inferred from constructor parameters and `_resolveChannels` field).
|
||||
- **Depends on**:
|
||||
- `ResolveChannels.ManuallyResolveChannels()` and `ManuallyUnresolveChannel()` methods.
|
||||
- `ResolveChannels.GetHWIDForSensorId()` (for EID locking).
|
||||
- `DTS.SensorDB.SensorsCollection.SensorsList.GetSensorById()` (to get sensor serial/type).
|
||||
- `Common.SerializedSettings.ISOViewMode`, `WarnOnEIDPositionSwap`.
|
||||
- `DFConstantsAndEnums.TSR_AIR_HIGH_G_CUTOFF_RATE_SPS`.
|
||||
- `StringResources.*` for localized headers/columns.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **Squib channels skip next row** — in `HardwareChannelsTable.Update()`, when a squib channel is encountered, `i++` skips the next channel (squibs use two physical channels per sensor).
|
||||
- **`Module` column is hidden but still defined** — `ColumnIds.Module` exists but is not displayed; `DAS` column includes module info when needed.
|
||||
- **`TableHelper` is only used by `ExtraEIDsTable`** — not shared with `SensorsOutOfPositionTable`.
|
||||
- **`ResolvedChannelsTable` uses `ChannelRepresentation`** — to format DAS/module serial numbers.
|
||||
- **`ChannelsToResolveTable` uses `DRAG_FORMAT = "UnresolvedChannel []"`** — a custom format distinct from hardware drag format.
|
||||
- **`HardwareChannelsTable` has complex row coloring** — `HardwareChannelsTable_LoadedCellPresenter` sets background based on:
|
||||
- `SensorIdOutOfPlace` (if `WarnOnEIDPositionSwap`)
|
||||
- `SensorIDMissing`
|
||||
- `UsingSensorId` (EID locked elsewhere)
|
||||
- Sensor presence + manual assignment
|
||||
- **`HardwareChannelsTable` disables drag for high-G channels below cutoff** — even if previously deleted (see comments referencing issue #30144).
|
||||
- **`HardwareChannelsTable` allows drag of TSRAIR free channels** — even if `sensor != "---"` but `LogicalChannelName == NA`.
|
||||
- **`UnSet()` does not reset `DataTable`/`ItemsSource` to new instances** — only clears rows/items. Reuse requires reassignment.
|
||||
- **No validation in `SensorOutOfPosition` constructor** — assumes caller provides consistent `currentChannel`/`originalChannel`/`sensorId`/`sensor`.
|
||||
@@ -0,0 +1,147 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ReviewFile/Graph.cs
|
||||
- DataPRO/DataPRO/CollectDataSubControls/ReviewFile/AbstractedFromReviewFile.cs
|
||||
generated_at: "2026-04-16T04:13:23.091145+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f6b79616651ff1f8"
|
||||
---
|
||||
|
||||
# ReviewFile
|
||||
|
||||
## Documentation: `Graph` and `AbstractedFromReviewFile` Classes
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
The `Graph` class is a UI-facing data model representing a single graph in the review file view, supporting dynamic status indication (via `WaitText`) and visibility toggling (`ShowGraph`/`ShowWait`). It is used in the `ReviewFile` sub-control to display channel data graphs and their metadata. The `AbstractedFromReviewFile` class serves as a higher-level controller managing collections of `Graph` instances, handling memory cleanup of underlying channel resources (`UnSet`), graph selection (`CurrentGraph`), and utility functions for channel naming, ordering, and ROI (Region of Interest) file regeneration. Together, they bridge serialized test data (`TestSetup.Graph`) and the WPF UI layer, abstracting resource lifecycle and UI state management.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `Graph` class (`DataPROWin7.CollectDataSubControls.ReviewFile.Graph`)
|
||||
|
||||
- **`public string Notes { get; set; }`**
|
||||
Gets or sets user-provided notes associated with the graph. Bound via `SetProperty` for change notification.
|
||||
|
||||
- **`public void IncrementStatusCount()`**
|
||||
Increments internal `_statusCount` (0–3), wrapping to 0 after exceeding 3. Triggers `OnPropertyChanged("WaitText")` to update the waiting animation string.
|
||||
|
||||
- **`public string WaitText { get; }`**
|
||||
Returns a dynamic string: `"Please wait, rendering graph {Name}"` appended with `_statusCount` periods (`.`). Used for UI progress indication. *Not* a property setter—computed on each access.
|
||||
|
||||
- **`public Visibility ShowGraph { get; set; }`**
|
||||
Gets or sets visibility of the graph control (`Visible`/`Collapsed`). Setting it triggers `OnPropertyChanged` for `"ShowGraph"`, `"ShowWait"`, and `"ChartData"`.
|
||||
|
||||
- **`public Visibility ShowWait { get; }`**
|
||||
Computed property: `Collapsed` if `ShowGraph == Visible`; otherwise `Visible`. Used to toggle a wait indicator UI element.
|
||||
|
||||
- **`public string Name { get; set; }`**
|
||||
Gets or sets the graph’s display name.
|
||||
|
||||
- **`public string Description { get; set; }`**
|
||||
Gets or sets the graph’s description.
|
||||
|
||||
- **`public override string ToString()`**
|
||||
Returns `_name`.
|
||||
|
||||
#### `AbstractedFromReviewFile` class (`DataPROWin7.CollectDataSubControls.AbstractedFromReviewFile`)
|
||||
|
||||
- **`public void UnSet()`**
|
||||
Releases resources associated with `CurrentGraph` and clears the `_graphs` list. Calls `ClearCurrentChannelsMemory()` first.
|
||||
|
||||
- **`public TestSetup.Graph CurrentGraph { get; set; }`**
|
||||
Gets or sets the currently selected graph. On set, disposes resources of the prior graph (if different) and raises `OnPropertyChanged` for `"GraphName"` and `"HardwareChannelName"`.
|
||||
|
||||
- **`public ICollection<Graph> Graphs { get; }`**
|
||||
Returns the internal `_graphs` list as a read-only collection.
|
||||
|
||||
- **`public RangeDataViewOptions RangeDisplayMode { get; set; }`**
|
||||
Gets or sets the current range display mode (`Auto`, `PercentageOfFullScale`, or `FixedValue`).
|
||||
|
||||
- **`public double CurrentFixedRangePercentageOfFullScale { get; set; }`**
|
||||
Stores the current fixed range as a percentage of full scale (e.g., `100.0`).
|
||||
|
||||
- **`public double CurrentFixedRangeValue { get; set; }`**
|
||||
Stores the current fixed range value (e.g., `5000.0`).
|
||||
|
||||
- **`public static string SingleChannelGraphNameFromChannel(Test.Module.Channel channel, bool foreignData)`**
|
||||
Constructs a display name for a channel graph:
|
||||
- If `Properties.Settings.Default.DisplayChannelName2` is `true`, uses `"{ChannelName2} - {ChannelDescriptionString}"`.
|
||||
- Otherwise, uses `ChannelDescriptionString`.
|
||||
- Appends `" (Calculated)"` if `channel` is a `CalculatedChannel`.
|
||||
- Appends `" data was not generated by DataPRO"` if `foreignData` is `true`.
|
||||
|
||||
- **`public static int CompareDisplayOrders(Test.Module.Channel a, Test.Module.Channel b)`**
|
||||
Compares two channels by `AbsoluteDisplayOrder`. Returns `-1`, `0`, or `1`. Handles `null` inputs (null < non-null).
|
||||
|
||||
- **`public DTS.Slice.Control.Event.Module.Channel ToEMCChannel(TestSetup.Graph.Channel serializedChannel)`**
|
||||
Returns the underlying `emc` (Event.Module.Channel) from `serializedChannel.TestChannel.emc`, or `null` if absent or cast fails. Logs via `APILogger` on failure.
|
||||
|
||||
- **`public static void RegenerateROI(string dtsFilePath, string testId, out string alternateDTS)`**
|
||||
Generates an ROI (Region of Interest) DTS file if `Common.SerializedSettings.DeriveROIFromAll` is `true` and `dtsFilePath` contains `"ALL"`.
|
||||
- Sets `alternateDTS` to `dtsFilePath.Replace("ALL", "ROI")`.
|
||||
- If `alternateDTS` exists, reads ROI start/end from `Setup/*.xml` (via `GetROIStartAndEndFromSetupXML`) and channel names from the DTS file.
|
||||
- Calls `SubControls.Download.CopyAndTrim(...)` to generate the ROI file.
|
||||
- Falls back to `SetupXML` parsing if ROI DTS is unreadable.
|
||||
|
||||
- **`private static void GetChannelNamesAndStartStopFromSetupXML(...)`**
|
||||
Helper for `RegenerateROI`: reads channel names from `TestSetup` and start/end times from `SetupXML`.
|
||||
|
||||
- **`private static void GetROIStartAndEndFromSetupXML(string dtsFilePath, out double start, out double end)`**
|
||||
Parses `Setup/*.xml` for `<ROIStart>` and `<ROIEnd>` tags. Throws `FileNotFoundException` if no XML file found.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **`_statusCount`** is always in the range `[0, 3]` after `IncrementStatusCount()` completes.
|
||||
- **`ShowGraph` and `ShowWait`** are mutually exclusive: `ShowGraph == Visible` ⇔ `ShowWait == Collapsed`.
|
||||
- **`CurrentGraph`** resources are cleaned up before assignment to a new value (via `ClearCurrentChannelsMemory()`).
|
||||
- **`Graphs` list** is cleared only via `UnSet()`; no other public method modifies it.
|
||||
- **`WaitText`** is *not* cached; it recomputes `_statusCount` and `_name` on each access.
|
||||
- **`ToEMCChannel`** returns `null` if `serializedChannel.TestChannel.emc` is `null` or not assignable to `DTS.Slice.Control.Event.Module.Channel`.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Dependencies *of* `Graph`:
|
||||
- `DTS.Common.Base.BasePropertyChanged` (base class for `INotifyPropertyChanged` implementation).
|
||||
- WPF `Visibility` enum.
|
||||
|
||||
#### Dependencies *of* `AbstractedFromReviewFile`:
|
||||
- `DataPROWin7.CollectDataSubControls.ReviewFile.Graph` (uses `Graph` type directly).
|
||||
- `DTS.Common.Base.BasePropertyChanged` (base class).
|
||||
- `DTS.Serialization.SliceRaw.File` (reads DTS files).
|
||||
- `DTS.Common.Utilities.Logging.APILogger` (logs errors).
|
||||
- `DTS.Common.SharedResource.Strings.StringResources` (for localized error messages).
|
||||
- `TestSetup.Graph`, `TestSetup`, `Test`, `Test.Module.Channel`, `Test.Module.CalculatedChannel` (from `TestSetup`/`Test` model).
|
||||
- `DTS.Slice.Control.Event.Module.Channel` (for `ToEMCChannel`).
|
||||
- `Properties.Settings.Default` (accesses `DisplayChannelName2` setting).
|
||||
- `Common.SerializedSettings.DeriveROIFromAll` (global setting).
|
||||
- `SubControls.Download.CopyAndTrim` (file generation utility).
|
||||
- Standard .NET: `System.IO`, `System.Collections.Generic`, `System.Linq`, `System.Globalization`, `System.Windows`.
|
||||
|
||||
#### Dependencies *on* `AbstractedFromReviewFile`:
|
||||
- UI controls (e.g., XAML bindings to `Graphs`, `CurrentGraph`, `WaitText`, `ShowGraph`, `RangeDisplayMode`).
|
||||
- Likely instantiated/managed by a parent view model or control in `CollectDataSubControls`.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`WaitText` is not thread-safe**: `_statusCount` is modified by `IncrementStatusCount()` without synchronization. If called from multiple threads, the animation may behave erratically.
|
||||
- **`ShowGraph` setter triggers `OnPropertyChanged` for `"ChartData"`**: This implies consumers of `ChartData` must be prepared for notifications even if `ChartData` itself is not a property of `Graph`.
|
||||
- **`ToEMCChannel` silently returns `null` on failure**: No exception is thrown if `emc` is missing or mis-typed—consumers must check for `null`.
|
||||
- **`RegenerateROI` assumes file structure**: Relies on `dtsFilePath` being in a specific path (e.g., `...\TEST\BIN\ALL\test.dts`) to derive `Setup/*.xml` location. Fails if structure differs.
|
||||
- **`GetROIStartAndEndFromSetupXML` uses fragile XML parsing**: Scans line-by-line for `<ROIStart>`/`<ROIEnd>` tags without XML parsing libraries. Fails if tags are nested or formatted differently.
|
||||
- **`CurrentFixedRange*` fields are public fields, not properties**: Direct mutation bypasses change notifications; UI may not update if these are bound.
|
||||
- **`orderedChannels` is a public field**: Not encapsulated; could be modified externally without notification.
|
||||
- **`ClearCurrentChannelsMemory` disposes `PersistentChannelInfo` and calls `UnSet()`**: If `UnSet()` is called multiple times (e.g., via `CurrentGraph` reassignment), double-disposal risks exist (though `PersistentChannelInfo.Dispose()` may be safe idempotent—source not provided to confirm).
|
||||
- **`Name` is used in `WaitText` but not validated**: If `Name` is `null`, `WaitText` will include `"Please wait, rendering graph "` followed by `"null"` (string interpolation behavior in `StringBuilder.Append(object)`).
|
||||
|
||||
None identified beyond these.
|
||||
315
enriched-qwen3-coder-next/DataPRO/DataPRO/Common.md
Normal file
315
enriched-qwen3-coder-next/DataPRO/DataPRO/Common.md
Normal file
@@ -0,0 +1,315 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Common/IPageGrid.cs
|
||||
- DataPRO/DataPRO/Common/UsedInGroup.cs
|
||||
- DataPRO/DataPRO/Common/UsedInTestSetup.cs
|
||||
- DataPRO/DataPRO/Common/IFullScreenCapable.cs
|
||||
- DataPRO/DataPRO/Common/UsedIn.cs
|
||||
- DataPRO/DataPRO/Common/WindowWrapper.cs
|
||||
- DataPRO/DataPRO/Common/UsageReport.cs
|
||||
- DataPRO/DataPRO/Common/INavStepContent.cs
|
||||
- DataPRO/DataPRO/Common/CommonStyles.xaml.cs
|
||||
- DataPRO/DataPRO/Common/WaitCursor.cs
|
||||
- DataPRO/DataPRO/Common/DeviceSelected.cs
|
||||
- DataPRO/DataPRO/Common/TimeUnits.cs
|
||||
- DataPRO/DataPRO/Common/Negative.cs
|
||||
- DataPRO/DataPRO/Common/PageHelper.cs
|
||||
- DataPRO/DataPRO/Common/SQLConversion.cs
|
||||
- DataPRO/DataPRO/Common/BoolToVisibilityConverter.cs
|
||||
- DataPRO/DataPRO/Common/InvertVisibilityConverter.cs
|
||||
- DataPRO/DataPRO/Common/HardwareIPRanges.cs
|
||||
- DataPRO/DataPRO/Common/Transition.cs
|
||||
- DataPRO/DataPRO/Common/ToastWindow.xaml.cs
|
||||
- DataPRO/DataPRO/Common/ModalDialog.xaml.cs
|
||||
- DataPRO/DataPRO/Common/GroupedItemControl.cs
|
||||
- DataPRO/DataPRO/Common/DataPROTabItem.cs
|
||||
- DataPRO/DataPRO/Common/DbAccess.cs
|
||||
generated_at: "2026-04-16T04:06:41.007079+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "ff478277c20f6904"
|
||||
---
|
||||
|
||||
# DataPROWin7.Common Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
This module (`DataPROWin7.Common`) provides foundational infrastructure components for the DataPRO Windows 7 application. It defines shared interfaces, data models, UI helpers, converters, and database initialization utilities used across the application’s UI and data layers. Its role is to decouple cross-cutting concerns—such as navigation state management, UI state transitions, cursor handling, and hardware/database metadata caching—from domain-specific logic, enabling consistent behavior and reuse across modules like Data Recorders, Sensor Database, and Test Setup pages.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Interfaces
|
||||
- **`IPageGrid`**
|
||||
```csharp
|
||||
void OnSetActive();
|
||||
```
|
||||
Called when a page becomes active (e.g., during navigation). Intended for page-specific initialization or UI updates.
|
||||
|
||||
- **`IFullScreenCapable`**
|
||||
```csharp
|
||||
void GoFullScreen();
|
||||
void GoSmallScreen();
|
||||
```
|
||||
Enables toggling between full-screen and normal windowed display modes. *Note: Interface is internal (`interface` without `public` modifier).*
|
||||
|
||||
- **`INavStepContent`**
|
||||
```csharp
|
||||
void UnSet(Action OnComplete = null);
|
||||
```
|
||||
Invoked when the current test setup changes, allowing UI cleanup (e.g., clearing fields). Optional completion callback.
|
||||
|
||||
### Classes
|
||||
- **`UsedInGroup`**
|
||||
```csharp
|
||||
public class UsedInGroup { public string Name { get; set; } }
|
||||
```
|
||||
Represents a group context where an item is used (e.g., in group-based configurations).
|
||||
|
||||
- **`UsedInTestSetup`**
|
||||
```csharp
|
||||
public class UsedInTestSetup { public string Name { get; set; } }
|
||||
```
|
||||
Represents a test setup context where an item is used.
|
||||
|
||||
- **`UsedIn`**
|
||||
```csharp
|
||||
public class UsedIn { public string Type { get; set; } public string Name { get; set; } }
|
||||
```
|
||||
Generic metadata for tracking where an item is used (e.g., in groups or test setups). `Type` indicates context (e.g., `"Group"` or `"TestSetup"`).
|
||||
|
||||
- **`WindowWrapper`**
|
||||
```csharp
|
||||
public class WindowWrapper : System.Windows.Forms.IWin32Window
|
||||
```
|
||||
Wraps a Win32 `HWND` (`IntPtr`) for interop with WinForms APIs (e.g., dialog hosting). Constructor: `WindowWrapper(IntPtr handle)`.
|
||||
|
||||
- **`UsageReport`**
|
||||
```csharp
|
||||
public class UsageReport { public List<DeviceSelected> SelectedDevices { get; set; } }
|
||||
```
|
||||
Container for usage report data, populated from Data Recorders/Sensor Database tabs (FB 12774).
|
||||
|
||||
- **`DeviceSelected`**
|
||||
```csharp
|
||||
public class DeviceSelected
|
||||
{
|
||||
public string Type { get; set; }
|
||||
public string SerialNumber { get; set; }
|
||||
public DateTime CalDueDate { get; set; }
|
||||
public List<UsedIn> Groups { get; set; }
|
||||
public List<UsedIn> TestSetups { get; set; }
|
||||
}
|
||||
```
|
||||
Represents a selected device for usage reporting, including calibration due date and usage contexts (FB 12774).
|
||||
|
||||
- **`TimeUnits`**
|
||||
```csharp
|
||||
public class TimeUnits : BasePropertyChanged
|
||||
{
|
||||
public enum Units { MilliSeconds, Seconds }
|
||||
public Units MyUnits { get; set; }
|
||||
public string ToShortString() { ... }
|
||||
}
|
||||
```
|
||||
Encapsulates time unit selection (`ms` or `s`). `ToShortString()` returns `"ms"` or `"s"`. Inherits `BasePropertyChanged` for property change notifications.
|
||||
|
||||
- **`Negative`**
|
||||
```csharp
|
||||
public class Negative : IValueConverter
|
||||
{
|
||||
public static Negative Instance { get; }
|
||||
public object Convert(object value, ...) { ... }
|
||||
public object ConvertBack(...) { throw ...; }
|
||||
}
|
||||
```
|
||||
XAML value converter that negates `double` values. `ConvertBack` is unimplemented.
|
||||
|
||||
- **`BoolToVisibilityConverter`**
|
||||
```csharp
|
||||
public sealed class BoolToVisibilityConverter : IValueConverter
|
||||
{
|
||||
public Visibility TrueValue { get; set; } // default: Visible
|
||||
public Visibility FalseValue { get; set; } // default: Collapsed
|
||||
public object Convert(...) { ... }
|
||||
public object ConvertBack(...) { ... }
|
||||
}
|
||||
```
|
||||
Converts `bool` to `Visibility` (and vice versa). Configurable `TrueValue`/`FalseValue` (defaults: `Visible`/`Collapsed`).
|
||||
|
||||
- **`InvertVisibilityConverter`**
|
||||
```csharp
|
||||
public sealed class InvertVisibilityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(...) { ... } // Visible ↔ Collapsed
|
||||
public object ConvertBack(...) { ... }
|
||||
}
|
||||
```
|
||||
Inverts `Visibility` values (`Visible` ↔ `Collapsed`). Returns `Visible` for non-`Visibility` inputs.
|
||||
|
||||
- **`PageHelper`**
|
||||
```csharp
|
||||
internal static class PageHelper
|
||||
{
|
||||
public static int GetTabAndButtonFontSize()
|
||||
}
|
||||
```
|
||||
Retrieves tab/page button font size from app settings, clamped to `[Min, Max]` range (FB 44523). Returns `Min` if out of bounds.
|
||||
|
||||
- **`SQLConversion`**
|
||||
```csharp
|
||||
public static class SQLConversion
|
||||
{
|
||||
public static string ConvertInternalVersionToYear(int sqlVersion)
|
||||
}
|
||||
```
|
||||
Maps SQL Server internal version numbers to release years (e.g., `12` → `"2014"`, `16` → `"2022"`). Returns `"{version} (Internal)"` for unknown versions.
|
||||
|
||||
- **`WaitCursor`**
|
||||
```csharp
|
||||
public class WaitCursor : IDisposable
|
||||
{
|
||||
public WaitCursor();
|
||||
public void Dispose();
|
||||
}
|
||||
```
|
||||
Temporarily sets the mouse cursor to `Cursors.Wait` during disposal. Ensures cursor restoration via `IDisposable`.
|
||||
|
||||
- **`HardwareIPRanges`**
|
||||
```csharp
|
||||
public class HardwareIPRanges
|
||||
{
|
||||
public IPRange[] IPRanges { get; set; }
|
||||
public void AddIPRange(IPRange r);
|
||||
public void AddRange(IPRange[] ranges);
|
||||
public HardwareIPRanges(); // Loads from "HWIPRanges.txt"
|
||||
}
|
||||
```
|
||||
Loads IP ranges from `HWIPRanges.txt` (comma-separated start/end IPs) for hardware discovery/ping sweeps. Logs exceptions via `APILogger`.
|
||||
|
||||
- **`Transition`**
|
||||
```csharp
|
||||
public class Transition : FrameworkElement
|
||||
{
|
||||
public enum TransitionState { A, B }
|
||||
public object Source { get; set; }
|
||||
public object DisplayA { get; set; }
|
||||
public object DisplayB { get; set; }
|
||||
public TransitionState State { get; set; }
|
||||
}
|
||||
```
|
||||
A WPF `FrameworkElement` that swaps `Source` between `DisplayA` and `DisplayB` based on `State`. Initialized to `State.A`.
|
||||
|
||||
- **`ToastWindow`**
|
||||
```csharp
|
||||
public partial class ToastWindow : Window
|
||||
{
|
||||
public ToastWindow(string screenShotFilename);
|
||||
}
|
||||
```
|
||||
Displays a non-modal notification in the lower-right corner. Auto-closes after 2 seconds. Clicking opens the screenshot file. Used for screenshot notifications (FB 15332).
|
||||
|
||||
- **`ModalDialog`**
|
||||
```csharp
|
||||
public partial class ModalDialog : UserControl
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public void SetParent(UIElement parent);
|
||||
public bool ShowHandlerDialog(string message);
|
||||
public void OkButton_Click(...);
|
||||
public void CancelButton_Click(...);
|
||||
public UserControl MyContent { set { ... } }
|
||||
}
|
||||
public interface IModalDialogContent
|
||||
{
|
||||
void SetCancelEvent(ModalDialog.ButtonEvent ev);
|
||||
void SetOKEvent(ModalDialog.ButtonEvent ev);
|
||||
}
|
||||
```
|
||||
A reusable modal dialog overlay. `ShowHandlerDialog` blocks until user clicks OK/Cancel. `MyContent` setter wires events for content implementing `IModalDialogContent`.
|
||||
|
||||
- **`GroupedItemControl`**
|
||||
```csharp
|
||||
public class GroupedItemControl : Control
|
||||
{
|
||||
public static RoutedCommand ClickCommand { get; }
|
||||
public ImageSource Image { get; set; }
|
||||
public int ResourceId { get; set; }
|
||||
public string Title { get; set; }
|
||||
public DataModel.TabPageItem TabItem { get; set; }
|
||||
}
|
||||
```
|
||||
A custom control for tab/page tiles. Triggers `ClickCommand` (handled by `MainWindow.GroupedItemControlClicked`). *Note: `Subtitle` property is commented out.*
|
||||
|
||||
- **`DataPROTabItem`**
|
||||
```csharp
|
||||
public class DataPROTabItem : TabItem
|
||||
{
|
||||
public void SetReferringTab(DataPROTabItem tab);
|
||||
public void GoToNewPage(UserControl o);
|
||||
public void ClearPreviousPages();
|
||||
public void GoToPreviousPage(bool setActive);
|
||||
public TabPageItem Item { get; }
|
||||
public DataPROTabItem(TabPageItem item);
|
||||
}
|
||||
```
|
||||
Extends `TabItem` to manage navigation history. Supports forward/back navigation, caching of test setup names (FB 15748), and special handling for `RunTestBase`/`EditTestSetupPage`.
|
||||
|
||||
- **`DbAccess`**
|
||||
```csharp
|
||||
public abstract class DbAccess
|
||||
{
|
||||
public static void InitializeGroupHardwareIds();
|
||||
public static void InitializeTestSetupHardwareIds();
|
||||
public static void InitializeDASIdChannelIndexGroupIdList();
|
||||
public static void InitializeBaseModuleChannelIndexList();
|
||||
public static void InitializeDASIds();
|
||||
public static void InitializeGroupChannelIds();
|
||||
public static void InitializeStaticGroupNames();
|
||||
public static void InitializeEmbeddedGroupIdList();
|
||||
public static void InitializeTestSetupGroupIds();
|
||||
public static void InitializeTestSetupNames();
|
||||
}
|
||||
```
|
||||
Static methods to populate `GroupHelper`/`TestSetupHelper` caches from the database. Used during application startup to avoid repeated DB queries.
|
||||
|
||||
### Helpers
|
||||
- **`CommonStyles.ToolTipEventHandler`**
|
||||
```csharp
|
||||
public void ToolTipEventHandler(object sender, ToolTipEventArgs e)
|
||||
```
|
||||
Publishes `HelpTextEvent` via Prism’s `IEventAggregator` for context-sensitive help.
|
||||
|
||||
## 3. Invariants
|
||||
- **`IPageGrid.OnSetActive()`**: Must be called exactly once per page activation (e.g., during `DataPROTabItem.GoToNewPage`).
|
||||
- **`IFullScreenCapable`**: `GoFullScreen`/`GoSmallScreen` must be symmetric (no partial states).
|
||||
- **`INavStepContent.UnSet`**: Must be idempotent and safe to call multiple times.
|
||||
- **`WaitCursor`**: Must restore the original cursor on `Dispose`, even if exceptions occur.
|
||||
- **`HardwareIPRanges`**: Requires `HWIPRanges.txt` in the application directory; malformed lines are silently skipped (exceptions logged).
|
||||
- **`Transition`**: `Source` property changes trigger an immediate swap to the opposite display (`A`/`B`).
|
||||
- **`SQLConversion.ConvertInternalVersionToYear`**: Only supports known SQL Server versions (12–16); others return `(Internal)`.
|
||||
- **`DbAccess` methods**: All assume database connectivity; failures are silently ignored (no exceptions thrown).
|
||||
|
||||
## 4. Dependencies
|
||||
- **Imports/References**:
|
||||
- `System.Windows.Forms` (`IWin32Window` for `WindowWrapper`).
|
||||
- `Prism.Ioc`, `Prism.Events` (`IEventAggregator`, `ContainerLocator`).
|
||||
- `DTS.Common.*` (e.g., `DTS.Common.Events`, `DTS.Common.Base`, `DTS.Common.Storage`, `DTS.Common.Classes.*`).
|
||||
- `System.Data`, `System.Data.SqlClient` (ADO.NET for `DbAccess`).
|
||||
- `System.Windows`, `System.Windows.Data` (WPF converters).
|
||||
- **Consumers**:
|
||||
- `DataPROWin7.DataModel` (`TabPageItem`, `DataPROPage`).
|
||||
- `DataPROWin7.TSRAIRGo.ViewModel` (`NavigationViewModel`).
|
||||
- `DataPROWin7.App` (`App.Current`, `CurrentUser`).
|
||||
- `MainWindow` (handles `GroupedItemControl.ClickCommand`).
|
||||
|
||||
## 5. Gotchas
|
||||
- **`Negative.ConvertBack`**: Throws `NotImplementedException`; not suitable for two-way binding.
|
||||
- **`InvertVisibilityConverter.ConvertBack`**: Returns `Visibility.Visible` for non-`Visibility` inputs (not `null`).
|
||||
- **`HardwareIPRanges` constructor**: Reads `HWIPRanges.txt` synchronously on instantiation; may block startup if file is large or network-mounted.
|
||||
- **`ModalDialog.ShowHandlerDialog`**: Uses a blocking loop with `Dispatcher.Invoke`/`Thread.Sleep` (a "DoEvents" hack); may cause reentrancy issues.
|
||||
- **`DataPROTabItem` caching**: `_currentTestName` is static; may cause incorrect navigation if multiple tabs are used concurrently.
|
||||
- **`DbAccess` methods**: All are static and mutate global state (`GroupHelper`, `TestSetupHelper`); not thread-safe or testable in isolation.
|
||||
- **`TimeUnits.ToShortString`**: Throws `NotSupportedException` for unknown units (should be `ArgumentException` per .NET conventions).
|
||||
- **`PageHelper.GetTabAndButtonFontSize`**: Relies on `Properties.Settings.Default` and `DTS.Common.Constants`; external dependency not visible in source.
|
||||
- **`IFullScreenCapable`**: Interface is internal (no `public` modifier), limiting its use outside the assembly.
|
||||
- **`GroupedItemControl`**: `Subtitle` property is commented out; developers may assume it exists.
|
||||
- **`WindowWrapper`**: Does not validate `IntPtr` (e.g., `IntPtr.Zero` is accepted).
|
||||
151
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls.md
Normal file
151
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls.md
Normal file
@@ -0,0 +1,151 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/GridFullScreen.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CollectSelectControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/EditChannelCodesControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/UserListControl.cs
|
||||
- DataPRO/DataPRO/Controls/RealtimeFullScreen.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/ViewGraphSelectControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/StatusRibbon.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/EditTestEngineerDetailsControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/EditUserInfoControl.xaml.cs
|
||||
generated_at: "2026-04-16T04:06:17.374735+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "26c4adb7225a573b"
|
||||
---
|
||||
|
||||
# Documentation: DataPROWin7.Controls Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides WPF `UserControl` implementations for various UI pages in the DataPRO application, primarily supporting user management, test configuration, channel code editing, and real-time data visualization. It serves as the presentation layer for structured workflows such as user creation/editing, test setup selection, channel code management, and full-screen real-time chart navigation. The controls implement `IPageContent` to integrate with the application’s page navigation system and `INotifyPropertyChanged` for data binding to WPF views.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `GridFullScreen`
|
||||
- **`MyFullscreenObject`** (`object`): Gets/sets the object (typically a chart) to display in full-screen mode. Uses `SetProperty` for change notification.
|
||||
- **`closeButton_Click`** (`void`): Event handler for the close button; calls `MainWindow.GoToPreviousPage()` to exit full-screen mode.
|
||||
|
||||
### `CollectSelectControl`
|
||||
- **`NextStepButtonFocus`** (`bool`): Gets/sets focus state for the next-step button.
|
||||
- **`NextStepFocusLost`** (`bool`): Gets/sets focus-lost state for the next-step button.
|
||||
- **`Validate()`** (`bool`): Always returns `true`; no validation logic implemented.
|
||||
- **`GetPageContent()`** (`object`): Loads test setups from database table `tblTestSetups` into a `List<TestSetupInfo>` and binds to `testSetupGrid.ItemsSource`. Only executes once per session (`refreshing` flag).
|
||||
- **`TestSetupInfo`** class: DTO with properties `TestSetupName`, `Description`, `SamplesPerSecond` (string), and `Mode` (`RecordingModes` enum).
|
||||
|
||||
### `EditChannelCodesControl`
|
||||
- **`MY_ID`** (`const string`): Page identifier `"Prepare_AdditionalDetails_Page_ChannelCodeDetails"`.
|
||||
- **`Page`** (`DataPROPage`): Setter-only property to store the parent page reference.
|
||||
- **`Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`** (`bool`): Delegates validation to `_vm.Validate(displayWindow)`.
|
||||
- **`OnSetActive()`** (`void`): Initializes view model via `InitializeVMsIfNeeded()` and calls `_vm.OnSetActive()`.
|
||||
- **`Delete()`** (`void`): Deletes selected channel codes after user confirmation (via `DoMessageBox`). Uses `Dispatcher` for UI-thread operations.
|
||||
- **`Save()`** (`void`): Calls `_vm.Save()`.
|
||||
|
||||
### `UserListControl`
|
||||
- **`TableColumns`** (`enum`): Defines grid columns: `DisplayName`, `UserName`, `Role`, `LastModified`, `LastModifiedBy`, `DatabaseId`.
|
||||
- **`SelectedUser`** (`User`): Gets/sets the currently selected single user (from `UserCollection.GetUser`).
|
||||
- **`SelectedUsers`** (`User[]`): Gets/sets array of selected users (from `UserCollection.GetUser`).
|
||||
- **`UpdateList()`** (`void`): Clears and repopulates `DataTable` with filtered users from `UserCollection.GetAllUsers` and `FilterUsers`.
|
||||
|
||||
### `RealtimeFullScreen`
|
||||
- **`RTB`** (`RunTestBase`): Gets/sets the parent run-test controller.
|
||||
- **`RealtimePage`** (`SubControls.Realtime`): Setter-only to store reference to the underlying real-time page.
|
||||
- **`MyChart`** (`RealtimeChart`): Gets/sets the chart to display in full-screen mode.
|
||||
- **`EnableRealtimePrevious(bool)` / `EnableRealtimeNext(bool)`**: Enables/disables `backButton`/`nextButton`.
|
||||
- **`BackButtonVisibility`** (`Visibility`), **`HasBackButton`** (`bool`): Control visibility of back button.
|
||||
- **`NextButtonVisibility`** (`Visibility`), **`HasNextButton`** (`bool`): Control visibility of next button.
|
||||
- **`OnSetActive(RealtimeChart myChart)`** (`void`): Sets `MyChart`.
|
||||
- **`nextButton_Click`** (`void`): Navigates to next channel in `_myChart` (if `UseTestChannelOrder` is false); otherwise calls `RTB.GoNext()`.
|
||||
- **`backButton_Click`** (`void`): Navigates to previous channel in `_myChart` (if `UseTestChannelOrder` is false); otherwise calls `RTB.GoPrev()`.
|
||||
- **`closeButton_Click`** (`void`): Restores plot layout via `_realtimePage.AssignPlotsAccordingToFullScreen()`, calls `RemoveFullScreenPlotInfo()` and `DetermineLayout()`, then navigates back via `GoToSmallScreenRealtime()`.
|
||||
|
||||
### `ViewGraphSelectControlDelete`
|
||||
- **`BrowseFocusLost`** (`bool`): Gets/sets focus-lost state for browse button.
|
||||
- **`TestItemLongString`** (`string`): Gets/sets the long string of the currently edited test item.
|
||||
- **`SelectedTestAdded`** / **`SelectedTestRemoved`** (`bool`): Properties that trigger `OnPropertyChanged` when set (used for UI updates).
|
||||
- **`FileNameList`** (`TestInfo[]`): Gets/sets array of test items displayed in grid.
|
||||
- **`SelectedTest`** (`DataModel.TestTemplate`): Gets/sets currently selected test template.
|
||||
- **`testNameGrid_BeginningEdit`** (`void`): Event handler toggles `Included` flag on `TestInfo` and sets `SelectedTestAdded`/`SelectedTestRemoved`.
|
||||
- **`ParseDate(string timestamp)` / `ParseTime(string timestamp)`**: Extracts date/time substrings from timestamp (hardcoded format assumptions).
|
||||
|
||||
### `StatusRibbon`
|
||||
- **`Prepend`** (`string`, DP): Used to construct resource key `Prepend_Status` for status text lookup.
|
||||
- **`Status`** (`string`): Sets status text; triggers `AggregateStatusText` update.
|
||||
- **`ProgressBarValue`** (`int`): Gets/sets progress (0–100).
|
||||
- **`SetProgressValue(int)`** (`void`): Thread-safe wrapper for `ProgressBarValue`.
|
||||
- **`ProgressBarVisibility`** (`Visibility`): Gets/sets progress bar visibility.
|
||||
- **`SetProgressBarVisibility(Visibility)`** (`void`): Thread-safe wrapper.
|
||||
- **`AggregateStatusText`** (`string`): Returns translated status text via `StringResources.ResourceManager.GetString(Prepend + Status)`, or fallback if not found.
|
||||
- **`SetStatusTextNoTranslate(string)`** (`void`): Sets raw status text without translation.
|
||||
- **`AggregateStatusColor`** (`Color`): Gets/sets ribbon background color.
|
||||
- **`SetAggregateStatusColor(Color)`** (`void`): Thread-safe wrapper.
|
||||
- **`AlertVisibility`** (`Visibility`): Controls alert icon visibility.
|
||||
- **`TextColor`** (`SolidColorBrush`): Gets/sets text color (changes on alert toggle).
|
||||
- **`SetAlert(bool)`** (`void`): Thread-safe method to toggle alert state (changes text color and alert visibility).
|
||||
|
||||
### `EditTestEngineerDetailsControl`
|
||||
- **`TestEngineers`** (`DataModel.TestEngineerDetails[]`): Gets/sets list of engineers; ensures trailing blank entry for new input.
|
||||
- **`Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`** (`bool`): Validates engineer names (non-empty, unique). Adds errors for duplicates or missing names.
|
||||
- **`Save()`** (`void`): Syncs `_testEngineers` list to persistent storage (`DataModel.TestEngineerDetailsList.TestEngineerList`).
|
||||
- **`Delete()`** (`void`): Deletes selected engineers after confirmation; ensures blank entry remains.
|
||||
- **`OnSetActive()`** (`void`): Loads current engineers from `DataModel.TestEngineerDetailsList.TestEngineerList`.
|
||||
- **`SelectedEngineerItems`** (`ObservableCollection<DataModel.TestEngineerDetails>`): Tracks selected items (used by XAML).
|
||||
- **`TextBox_LostFocus`** / **`ListViewItem_LostFocus`**: Ensures blank entry is added and selection state is synchronized.
|
||||
|
||||
### `EditUserInfoControl`
|
||||
- **`CurrentUser`** (`User`): Gets/sets the user being edited/added.
|
||||
- **`IsAdd`** (`bool`): Gets/sets whether the control is in "add user" mode.
|
||||
- **`UserName`** / **`DisplayName`**: Gets/sets user properties; setters update `CurrentUser`.
|
||||
- **`UserRoles`** (`UserRoleData[]`): Returns array of role display objects (localized via `StringResources`).
|
||||
- **`UserRoleIndex`** (`int`): Gets/sets selected role index.
|
||||
- **`IsNotDefaultUser`** (`bool`): Returns `true` if `CurrentUser` is not a default user.
|
||||
- **`Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`** (`bool`): Validates role selection, unique username (on add), and non-empty display name.
|
||||
- **`Reset()`** (`void`): Clears validation markers on all fields.
|
||||
- **`OnSetActive()`** (`void`): Triggers property changes for `Tags` enum values.
|
||||
- **`UserTags`** (`string`): Gets/sets comma-separated tags via `CurrentUser.GetTagsArray`/`SetTags`.
|
||||
- **`LastModified`** / **`LastModifiedBy`**: Read-only properties for display.
|
||||
- **`LocalOnly`** (`bool`): Gets/sets `CurrentUser.LocalOnly` (only when adding).
|
||||
- **Password handling**: Uses sentinel `"***THISHASNTCHANGED***"` to detect unchanged passwords; updates `CurrentUser.SetPassword` only when changed.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`IPageContent` Implementation**: All controls implement `IPageContent`, requiring methods `Validate`, `OnSetActive`, `UnSet`, `Reset`, `GetPageContent`, and optional `SetPermissions`, `KeyDown`, `StartSearch`, `OnButtonPress`.
|
||||
- **`INotifyPropertyChanged`**: All controls implement `INotifyPropertyChanged` with consistent `SetProperty`/`OnPropertyChanged` helpers.
|
||||
- **`Refresh` Flags**: `CollectSelectControl` and `ViewGraphSelectControlDelete` use `refreshing` flags to prevent reloading data on every `GetPageContent()` call.
|
||||
- **Dispatcher Thread Safety**: UI updates in `StatusRibbon`, `EditChannelCodesControl`, `EditTestEngineerDetailsControl`, and `RealtimeFullScreen` use `Dispatcher.BeginInvoke` for thread-safe operations.
|
||||
- **Blank Entry Invariant**: `EditTestEngineerDetailsControl` and `EditUserInfoControl` maintain trailing blank entries for new input (enforced in setters and `HasBlank()` checks).
|
||||
- **Password Sentinel**: `EditUserInfoControl` uses `"***THISHASNTCHANGED***"` as sentinel for unchanged passwords.
|
||||
- **Database Access**: `CollectSelectControl` queries `[tblTestSetups]` via `DTS.Storage.DbOperations`; `UserListControl` uses `UserCollection.GetAllUsers` and `FilterUsers`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Dependencies (from imports):
|
||||
- **WPF**: `System.Windows.*`, `C1.WPF.*` (ComponentOne FlexGrid), `Prism.*` (Prism framework), `Unity` (DI container).
|
||||
- **Domain Models**: `DataModel.*`, `DTS.Slice.Users`, `DTS.Common.*`, `DTS.Common.Interface.Channels.ChannelCodes`.
|
||||
- **Storage**: `DTS.Storage`, `DTS.Common.Storage`.
|
||||
- **Resources**: `DTS.Common.SharedResource.Strings` (`StringResources`).
|
||||
|
||||
### Internal Dependencies:
|
||||
- **Page Navigation**: `DataPROPage`, `MainWindow`, `App`, `PageButton`, `PageErrorEvent`, `PageSelectionChanged`.
|
||||
- **View Models**: `IChannelCodesListViewModel`, `IChannelCodesListView` (resolved via Prism DI).
|
||||
- **User Management**: `UserCollection`, `User`, `UserPermissionLevels`.
|
||||
- **Real-time System**: `RunTestBase`, `RealtimeChart`, `SubControls.Realtime`.
|
||||
|
||||
### Inferred Consumers:
|
||||
- `DataPROPage` (hosting these controls as page content).
|
||||
- `MainWindow` (for navigation: `GoToPreviousPage`, `GoToSmallScreenRealtime`, `RemoveFullScreenPlotInfo`, `DetermineLayout`).
|
||||
- `App` (for `DoMessageBox`, `FilterUsers`, `GetAllIUIItems`).
|
||||
- `DTS.Slice.Users.UserCollection` (for user management).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`CollectSelectControl`**: `GetPageContent()` only populates data once (`refreshing` flag). Subsequent calls return cached data without reloading. This may cause stale data if the database changes during runtime.
|
||||
- **`ViewGraphSelectControlDelete`**: Constructor calls `_fileNameList = new TestInfo[0]` but `testNameGrid.ItemsSource` is never set in `GetPageContent()` (commented-out code suggests incomplete implementation).
|
||||
- **`RealtimeFullScreen`**: `nextButton_Click` and `backButton_Click` have dual behavior based on `Properties.Settings.Default.UseTestChannelOrder`. When `false`, it manually cycles channels in `_myChart` (not `RTB`), which may conflict with expected navigation if `RTB` is the authoritative source.
|
||||
- **`UserListControl`**: `DatabaseId` column is collapsed (`Visibility.Collapsed`) to handle duplicate default usernames (e.g., Admin, Guest). This is a workaround for a known data model limitation.
|
||||
- **`EditTestEngineerDetailsControl`**: `SelectedEngineerItems` is a public `ObservableCollection` but is not bound in the provided code; selection state is managed manually via `ListViewItem_LostFocus`.
|
||||
- **`EditUserInfoControl`**: Password validation (`CheckPasswords`) marks both password fields invalid if they mismatch, but does not clear errors on subsequent valid input unless `Reset()` is called.
|
||||
- **`StatusRibbon`**: `AggregateStatusText` uses lazy initialization (`_aggregateStatusText = null`) and falls back to `"##resource not found: {0}{1}"` if translation fails. This may expose raw keys in production if resources are missing.
|
||||
- **`RealtimeFullScreen`**: `closeButton_Click` calls `_realtimePage.AssignPlotsAccordingToFullScreen()` and `DetermineLayout()` *after* removing plot info, implying a specific sequence is required to restore layout correctly. Reordering these calls may break layout restoration.
|
||||
- **`EditUserInfoControl`**: `IsNotDefaultUser` setter is empty; it is read-only despite being declared with `{ set; }`.
|
||||
73
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/Common.md
Normal file
73
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/Common.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/Common/CommonFunctions.cs
|
||||
generated_at: "2026-04-16T04:16:26.431534+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "6a5d7099d6a37368"
|
||||
---
|
||||
|
||||
# Common
|
||||
|
||||
### **Purpose**
|
||||
This module provides a centralized, static helper function for initializing and creating thermocouple (TC) and auxiliary channels specific to a SLICE hardware platform within the DataPRO system. It acts as a convenience wrapper that abstracts the low-level channel creation logic by fetching required sensor definitions and channel defaults from the database and passing them to `GroupChannel.CreateSLICETCChannels`, enabling consistent setup of test-specific channels during group configuration or editing.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
#### `CommonFunctions.CreateSLICETCChannels`
|
||||
```csharp
|
||||
public static void CreateSLICETCChannels(
|
||||
GroupChannel.AddChannelsToGroupDelegate addChannels,
|
||||
GroupChannel.GetMaxDisplayOrderDelegate getMaxDisplayOrder,
|
||||
DASHardware hardware,
|
||||
IGroup group,
|
||||
bool bEditGroup)
|
||||
```
|
||||
- **Behavior**: Initializes and creates SLICE-specific thermocouple, stream-out, and UART channels for a given `IGroup`. It retrieves channel defaults from the database (`DbOperations.GetChannelSettingDefaults()`), fetches predefined sensor definitions by serial number (`SensorConstants.TEST_SPECIFIC_THERMOCOUPLER`, `TEST_SPECIFIC_STREAM_OUT_SERIAL`, `TEST_SPECIFIC_UART_SERIAL`), configures the thermocoupler sensor’s `Bridge` property to `Thermocoupler`, and delegates the actual channel creation to `GroupChannel.CreateSLICETCChannels(...)`.
|
||||
- **Parameters**:
|
||||
- `addChannels`: Delegate used to register newly created channels with the group.
|
||||
- `getMaxDisplayOrder`: Delegate used to determine the next available display order index.
|
||||
- `hardware`: The target `DASHardware` instance to which channels are being added.
|
||||
- `group`: The `IGroup` instance to which channels are being added.
|
||||
- `bEditGroup`: Boolean flag indicating whether the operation is part of editing an existing group (`true`) or creating a new one (`false`).
|
||||
|
||||
#### Delegates (Declared but not invoked internally)
|
||||
- `addChannelsToGroupDelegate`: Alias for `GroupChannel.AddChannelsToGroupDelegate`.
|
||||
- `getMaxDisplayOrderDelegate`: Alias for `GroupChannel.GetMaxDisplayOrderDelegate`.
|
||||
> **Note**: These delegates are declared in `CommonFunctions` but are not used beyond being passed to `CreateSLICETCChannels`. Their purpose is to decouple this module from direct dependencies on `GroupChannel` types in its public surface.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
- The `thermocoupler` sensor *must* be successfully retrieved via `SensorConstants.TEST_SPECIFIC_THERMOCOUPLER`; otherwise, a `NullReferenceException` or similar will occur (no null-check is present in the source).
|
||||
- The `hardware`, `group`, `addChannels`, and `getMaxDisplayOrder` parameters *must not* be `null`; no validation is performed.
|
||||
- `SensorConstants.BridgeType.Thermocoupler` is *always* assigned to `thermocoupler.Bridge`, overriding any prior value.
|
||||
- Channel defaults are sourced unconditionally from `DbOperations.GetChannelSettingDefaults()`—no fallback or error handling is present if defaults are unavailable.
|
||||
- The underlying `GroupChannel.CreateSLICETCChannels` method is assumed to enforce ordering and uniqueness constraints; this wrapper does not add additional validation.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
#### **Internal Dependencies (used by this module)**
|
||||
- `DTS.Common.Classes.Groups` (for `GroupChannel` types and delegates)
|
||||
- `DTS.Common.Enums.Sensors` (for `SensorConstants`, `BridgeType`)
|
||||
- `DTS.Common.Storage` (for `DbOperations`)
|
||||
- `DTS.Common.Interface.Groups.GroupList` (for `IGroup`)
|
||||
- `DataPROWin7.DataModel` (for `DASHardware`)
|
||||
- `DTS.Common.Interface.Channels` (for `IGroupChannel`)
|
||||
|
||||
#### **External Dependencies (this module is used by)**
|
||||
- Not specified in the source. However, given its static nature and placement in `DataPROWin7.Controls`, it is likely invoked by UI or group-editing components (e.g., group configuration dialogs) that need to instantiate SLICE-specific channel sets.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
- **Hardcoded sensor serial numbers**: Reliance on `SensorConstants.TEST_SPECIFIC_*` implies these are *test-specific* or *default* sensors; using this function in non-test contexts may yield incorrect or missing sensors if constants are not updated.
|
||||
- **No error handling**: If any sensor lookup fails (e.g., `GetSensorBySerialNumber` returns `null`), the method will throw at runtime (e.g., `NullReferenceException` when accessing `.Bridge`).
|
||||
- **Delegate aliasing**: The delegate declarations (`addChannelsToGroupDelegate`, `getMaxDisplayOrderDelegate`) are redundant—they are direct aliases for `GroupChannel.*Delegate` types and add no abstraction value. This may cause confusion about their necessity.
|
||||
- **Ambiguous `bEditGroup` semantics**: The source does not clarify how `bEditGroup` affects behavior (e.g., overwrite vs. append channels). Behavior is delegated entirely to `GroupChannel.CreateSLICETCChannels`.
|
||||
- **No documentation on channel count or ordering**: The function does not specify how many channels are created or how display order is computed—this is implementation detail of `GroupChannel.CreateSLICETCChannels`.
|
||||
|
||||
> **None identified from source alone** for additional gotchas beyond those explicitly visible in the code.
|
||||
@@ -0,0 +1,283 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/ChannelsNavStepToggleList.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/UI_TEST.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/combobox.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/checkbox.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/radiobutton.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/ParametersNavStepToggleList.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/CustomTickBar.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/RealtimeChannelToggleButton.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/NavStepActionButton.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/NavStepRadioButton.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/ModalLicensePrompt.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/ModalUserPrompt.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/RealtimeListContainerButton.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/NavStepToggleList.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/ActionComboBox.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/ActionLabel.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/ActionRadioButton.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/CustomUIElements/PageButton.xaml.cs
|
||||
generated_at: "2026-04-16T04:17:43.854971+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2b032ec7fcd8e96c"
|
||||
---
|
||||
|
||||
# Documentation: `DataPROWin7.Controls.CustomUIElements` Module
|
||||
|
||||
---
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a suite of custom WPF UI controls used to construct the navigation and data selection interface in the DataPRO application. Its primary role is to implement interactive, hierarchical toggle lists (e.g., for selecting DAS or calculated channels), state-aware radio/toggle buttons, action buttons, and modal prompts—each integrated with permission management, Prism event aggregation for help text, and state synchronization with the main application page (`HomePage`). The controls abstract complex UI state logic (e.g., mutual exclusion between root toggle lists, dynamic channel visibility updates) and enforce consistent behavior across test setup and run-time workflows.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Classes in `DataPROWin7.Controls.CustomUIElements`
|
||||
|
||||
#### `ChannelsNavStepToggleList`
|
||||
- **Constructor**:
|
||||
`ChannelsNavStepToggleList(string text, string id, string groupName)`
|
||||
Initializes the control, sets `MainButton` text, ID, and group name. Calls `InitializeComponent()`.
|
||||
|
||||
- **`MainStateChange()`** (override):
|
||||
No-op implementation. Overrides base `NavStepToggleList.MainStateChange()` but does not invoke any additional logic.
|
||||
|
||||
#### `ParametersNavStepToggleList`
|
||||
- **Constructor**:
|
||||
`ParametersNavStepToggleList(string text, string id, string groupName)`
|
||||
Initializes the control, sets `MainButton` text, ID, and group name. Calls `InitializeComponent()`.
|
||||
|
||||
- **`MainStateChange()`** (override):
|
||||
When the root button is checked, calls `TurnOffOtherNavCheckListButtons(this)` on the current `HomePage` instance to ensure only one `NavStepToggleList` root is active at a time.
|
||||
|
||||
#### `RealtimeChannelToggleButton`
|
||||
- **Constructors**:
|
||||
- `RealtimeChannelToggleButton()`
|
||||
- `RealtimeChannelToggleButton(DataModel.HardwareChannel channel)`
|
||||
- `RealtimeChannelToggleButton(DTS.Common.ISO.CalculatedValueClass channel)`
|
||||
Initializes base `NavStepRadioButton` with channel name; stores reference to `HardwareChannel` or `CalculatedChannel`.
|
||||
|
||||
- **Properties**:
|
||||
- `HardwareChannel` (`DataModel.HardwareChannel`) – read-only; identifies the hardware channel.
|
||||
- `CalculatedChannel` (`DTS.Common.ISO.CalculatedValueClass`) – read-only; identifies the calculated channel.
|
||||
- `RealtimeChannel` (`RealtimeChart.RealtimeChannel`) – read-write; runtime reference to the channel object.
|
||||
|
||||
#### `RealtimeToggleListRootButton`
|
||||
- **Constructors**:
|
||||
- `RealtimeToggleListRootButton()`
|
||||
- `RealtimeToggleListRootButton(DataModel.DASHardware h)`
|
||||
- `RealtimeToggleListRootButton(DTS.Common.ISO.CalculatedValueClass[] cc)`
|
||||
Initializes root button with label (e.g., "DAS" or "Calculated Channels") and populates `_channelButtons` dictionary with `RealtimeChannelToggleButton`s for each channel (initially collapsed).
|
||||
|
||||
- **Methods**:
|
||||
- `UpdateRealtimeChannels(RealtimeChart.RealtimeChannel[] channels)`
|
||||
Maps `RealtimeChannel`s to internal `_channelButtons` by channel ID, updates button text, and sets `RealtimeChannel` property.
|
||||
- `UpdateList()` (override)
|
||||
Makes root button visible; sets visibility of child buttons based on whether their `RealtimeChannel` is non-null.
|
||||
|
||||
#### `NavStepToggleList`
|
||||
- **Constructor**:
|
||||
`NavStepToggleList()`
|
||||
Initializes `MainButton` (a `NavStepRadioButton`), sets initial `Visibility = Collapsed`, and subscribes `MainStateChange` to `MainButton.OnStateChanged`.
|
||||
|
||||
- **Properties**:
|
||||
- `CheckState` (`bool`) – read-only; reflects `MainButton.CheckState`.
|
||||
- `PanelVisibility` (`Visibility`) – bindable; controls visibility of child list panel.
|
||||
|
||||
- **Methods**:
|
||||
- `ChangeState(bool on)` – explicitly sets root button state and triggers `MainStateChange()`.
|
||||
- `MainStateChange()` (virtual) – toggles `PanelVisibility`, unselects other root lists, and notifies `HomePage`/`Realtime` of changes.
|
||||
- `UpdateList()` (virtual) – resets root button to unchecked, hides panel.
|
||||
- `SetText(string text)` – sets `MainButton` text.
|
||||
- `SetList(NavStepRadioButton[] children)` – adds child buttons to `panelListItems`.
|
||||
- `GetChildren()` – returns array of child buttons.
|
||||
|
||||
#### `NavStepRadioButton`
|
||||
- **Constructors**:
|
||||
- `NavStepRadioButton()`
|
||||
- `NavStepRadioButton(string text)`
|
||||
Initializes `navStepText` and `navStepButton`.
|
||||
|
||||
- **Properties**:
|
||||
- `Id` (`string`) – read-write; arbitrary identifier.
|
||||
- `CheckState` (`bool`) – read-write; reflects `navStepButton.IsChecked`.
|
||||
- `_bLastState` (`volatile bool`) – internal state tracking.
|
||||
|
||||
- **Methods**:
|
||||
- `SetText(string text)` – updates `navStepText.Text`.
|
||||
- `navStepButton_Click(object sender, RoutedEventArgs e)` (virtual) – toggles state, invokes `OnStateChanged`, and notifies `HomePage.NavButtonCheckChanged(this)`.
|
||||
|
||||
#### `CustomTickBar`
|
||||
- **Inherits**: `TickBar`
|
||||
|
||||
- **Properties**:
|
||||
- `TextArray` (`string[]`) – default: `["Low", "Med", "High", "Very High", "MAX"]`.
|
||||
|
||||
- **Methods**:
|
||||
- `OnRender(DrawingContext dc)` (override) – renders tick labels using `TextArray` at calculated positions; falls back to empty string on index overflow.
|
||||
|
||||
#### `combobox`, `checkbox`, `radiobutton`
|
||||
- **Methods**:
|
||||
- `ToolTipEventHandler(object sender, ToolTipEventArgs e)`
|
||||
Handles tooltip events by publishing `HelpTextEvent` via Prism `IEventAggregator`, with `HelpTextEventArg` containing `sender` and `e`. Sets `e.Handled = true`.
|
||||
|
||||
#### `NavStepActionButton`
|
||||
- **Constructor**:
|
||||
`NavStepActionButton(string id, ActionFiredDelegate action)`
|
||||
Initializes `Id`, resolves `ButtonText` from `StringResources`, and sets `OnActionFired` handler.
|
||||
|
||||
- **Properties**:
|
||||
- `Id` (`string`) – bindable; used to fetch `ButtonText` and for logging/action dispatch.
|
||||
- `ButtonText` (`string`) – bindable; localized display text.
|
||||
|
||||
- **Methods**:
|
||||
- `SetVisible(bool bShow)` – sets `Visibility`.
|
||||
- `actionButton_Click(object sender, RoutedEventArgs e)` – fires `OnActionFired(Id)`, with special handling for `"ArmSystemStopMonitoring"` to switch `Id` to `"ArmSystemStartMonitoring"` when button text matches `StringResources.Record_Attach`.
|
||||
|
||||
#### `ActionComboBox`, `ActionLabel`, `ActionRadioButton`, `PageButton`
|
||||
- **Common Interface**: Implements `DTS.Slice.Users.IUIItems` (via `GetID()`, `SetID()`, `GetName()`, `GetRequiredPermission()`, `GetDefaultRolePermission()`, `GetDefaultRoleVisibility()`).
|
||||
|
||||
- **Shared Properties/Methods**:
|
||||
- `UniqueId` (`string`) – bindable identifier.
|
||||
- `DisplayText` (`string`) – bindable localized text.
|
||||
- `SetVisible(bool bShow)` / `SetVisible(Visibility)` – visibility control based on user permissions.
|
||||
- `SetEnabled(bool bShow)` – enables/disables control.
|
||||
- `ActionButtonContainer` (`IActionButtonContainer`) – reference to parent page for action callbacks.
|
||||
|
||||
- **Specific Methods**:
|
||||
- `ActionComboBox`: `ComboBox_SelectionChanged`, `ComboBox_DropDownClosed` → delegate to `ActionButtonContainer`.
|
||||
- `ActionRadioButton`: `Button_Click` → `ActionButtonContainer.OnActionRadioButtonPress(this)`.
|
||||
- `PageButton`: `Button_Click` → logs user action, then calls `_page.OnButtonPress(this)` or `_mainWindow.OnButtonPress(this)`.
|
||||
|
||||
#### `ModalLicensePrompt`, `ModalUserPrompt`
|
||||
- **Common Interface**: Implements `IModalContent` (via `OnSetActive()`).
|
||||
|
||||
- **Shared Properties**:
|
||||
- `PromptString`, `CheckboxString`, `IsboxChecked` – bindable.
|
||||
- `ReusableMessageBox` (`bool`) – indicates if prompt is reused generically.
|
||||
- `CloseTime` (`DateTime`, `ModalUserPrompt` only) – tracks last close time (e.g., for stale message detection).
|
||||
- `DefaultButton` (`PageButton`) – bindable; sets focus and default behavior.
|
||||
|
||||
- **Methods**:
|
||||
- `SetButtons(PageButton[] buttons)` – dynamically adds buttons to `buttonGrid`.
|
||||
- `GetButtons()` – returns internal button list.
|
||||
- `OnSetActive()` – sets `DefaultButton` as default and focuses it.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Root Toggle List Mutual Exclusion**:
|
||||
When a `NavStepToggleList` root button is checked (`CheckState = true`), `MainStateChange()` calls `TurnOffOtherNavCheckListButtons(this)` on `HomePage`, ensuring only one root list is active at a time.
|
||||
|
||||
- **Child Button Visibility**:
|
||||
In `RealtimeToggleListRootButton`, child `RealtimeChannelToggleButton`s are initially `Collapsed`. After `UpdateRealtimeChannels()` and `UpdateList()`, visibility is determined by whether `RealtimeChannel` is non-null.
|
||||
|
||||
- **State Consistency**:
|
||||
`NavStepRadioButton.CheckState` and `_bLastState` must be kept in sync during UI-driven toggling (`navStepButton_Click`). `_bSetting` is declared but unused in current code.
|
||||
|
||||
- **Permission-Based Visibility**:
|
||||
Controls implementing `IUIItems` (`ActionComboBox`, `ActionLabel`, `ActionRadioButton`, `PageButton`) rely on `CurrentUser.IsShowTabFlagSet(this)` and `GetPermission()` to determine visibility/enabled state.
|
||||
|
||||
- **Resource Fallback**:
|
||||
`DisplayText`/`ButtonText` fall back to `"#resource_notfound#<id>"` if `StringResources.ResourceManager.GetString(id)` returns `null`.
|
||||
|
||||
- **TickBar Rendering**:
|
||||
`CustomTickBar.OnRender()` assumes `TextArray.Length >= (Maximum - Minimum) / TickFrequency + 1`; otherwise, labels beyond bounds are rendered as empty strings.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies (from source)
|
||||
- **Base Classes/Interfaces**:
|
||||
- `NavStepToggleList` inherits from `UserControl`.
|
||||
- `NavStepRadioButton` inherits from `UserControl`.
|
||||
- `RealtimeChannelToggleButton` inherits from `NavStepRadioButton`.
|
||||
- `RealtimeToggleListRootButton` inherits from `NavStepToggleList`.
|
||||
- `CustomTickBar` inherits from `TickBar`.
|
||||
- `ModalLicensePrompt`, `ModalUserPrompt` implement `IModalContent`.
|
||||
- `Action*` controls implement `DTS.Slice.Users.IUIItems`.
|
||||
|
||||
- **Data Models**:
|
||||
- `DataModel.HardwareChannel`
|
||||
- `DataModel.DASHardware`
|
||||
- `DTS.Common.ISO.CalculatedValueClass`
|
||||
- `RealtimeChart.RealtimeChannel`
|
||||
|
||||
- **Prism & DI**:
|
||||
- `Prism.Ioc.IContainerLocator` (for `ContainerLocator.Container`)
|
||||
- `Prism.Events.IEventAggregator`
|
||||
- `DTS.Common.Events.HelpTextEvent`, `HelpTextEventArg`
|
||||
|
||||
- **Resources & Strings**:
|
||||
- `DTS.Common.SharedResource.Strings.StringResources`
|
||||
|
||||
- **Logging**:
|
||||
- `DTS.Common.Utilities.Logging.APILogger`
|
||||
|
||||
- **UI Infrastructure**:
|
||||
- `MainWindow` (via `Application.Current.MainWindow`)
|
||||
- `HomePage` (via `GetMainContent()`)
|
||||
- `SubControls.Realtime`
|
||||
- `DataPROPage`, `RunTestBase`
|
||||
|
||||
### External Dependencies (inferred)
|
||||
- WPF (`System.Windows.*`)
|
||||
- Prism Library (event aggregation, DI)
|
||||
- DTS Common libraries (`DTS.*`)
|
||||
- .NET Framework (WPF, `System.Windows.Forms.DialogResult` in `Modal*Prompt`)
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`ChannelsNavStepToggleList.MainStateChange()` is a no-op**:
|
||||
Despite overriding `MainStateChange()`, it does nothing—likely legacy or placeholder code. `ParametersNavStepToggleList` provides the actual behavior.
|
||||
|
||||
- **`_bSetting` is unused**:
|
||||
`NavStepRadioButton` declares `volatile bool _bSetting = false;` but never writes to it; may be vestigial.
|
||||
|
||||
- **`RealtimeToggleListRootButton` visibility logic**:
|
||||
Child buttons are set to `Collapsed` during construction and only made visible in `UpdateList()` *if* their `RealtimeChannel` is assigned. If `UpdateRealtimeChannels()` is not called before `UpdateList()`, all children remain hidden.
|
||||
|
||||
- **`NavStepActionButton` ID mutation side effect**:
|
||||
For `"ArmSystemStopMonitoring"`, `Id` is mutated to `"ArmSystemStartMonitoring"` during `actionButton_Click` if `ButtonText == Record_Attach`. This is a documented workaround (comment: "20097") but risks confusion if `Id` is used elsewhere.
|
||||
|
||||
- **`ModalLicensePrompt.DialogResult` is immutable**:
|
||||
`DialogResult` is initialized to `DialogResult.Cancel` and never updated. Its purpose is unclear—likely intended for dialog result propagation but not implemented.
|
||||
|
||||
- **`CustomTickBar` assumes fixed font metrics**:
|
||||
`OnRender()` uses hardcoded `Verdana`, size `8`, and `FlowDirection.LeftToRight`. Text width calculation (`formattedText.Width`) may break if font rendering changes or DPI scales unexpectedly.
|
||||
|
||||
- **Permission checks assume `CurrentUser` is set**:
|
||||
Controls like `PageButton.SetVisible(bool)` and `SetEnabled(bool)` check `(Application.Current as App).CurrentUser != null` before accessing permissions. If `CurrentUser` is `null`, visibility defaults to `Visible` or behavior may be inconsistent.
|
||||
|
||||
- **`combobox`, `checkbox`, `radiobutton` are partial classes**:
|
||||
Only `ToolTipEventHandler` is defined in source; XAML and other members (e.g., `InitializeComponent`) are in corresponding `.xaml` files. Behavior of tooltip event handling is consistent across them.
|
||||
|
||||
- **No explicit `IDisposable` usage**:
|
||||
None of the controls implement `IDisposable`, though `RealtimeToggleListRootButton` uses `Dictionary<string, RealtimeChannelToggleButton>`—no cleanup logic is visible.
|
||||
|
||||
- **`RealtimeChannelToggleButton` constructor overloads**:
|
||||
Overloads accept `HardwareChannel` or `CalculatedValueClass`, but both call `base(channel.ToString())` or `base(channel.Name)`. Ensure `ToString()`/`Name` is stable and unique to avoid ID collisions.
|
||||
|
||||
- **`NavStepRadioButton.CheckState` setter updates `_bLastState`**:
|
||||
Setting `CheckState = value` updates `_bLastState = value`, but `navStepButton.IsChecked` is set directly. If `CheckState` is set programmatically, `_bLastState` may diverge from actual UI state until next click.
|
||||
|
||||
- **`PageButton.SetEnabled()` uses `Dispatcher`**:
|
||||
`SetEnabled(bool)` marshals to `Dispatcher` if needed, but `SetVisible(bool)` does not—potential thread-safety issue if called from non-UI threads.
|
||||
|
||||
- **`ModalUserPrompt.CloseTime` is public but not auto-updated**:
|
||||
`CloseTime` is exposed but never set in the provided code. Its purpose (e.g., for stale message logic) is unclear without implementation.
|
||||
|
||||
- **`IUIItems` permission methods are `virtual` but not overridden**:
|
||||
All permission-related methods (`GetDefaultRolePermission`, `GetDefaultRoleVisibility`) are `virtual` but have no overrides in the source—suggesting extensibility is intended but unused here.
|
||||
|
||||
---
|
||||
|
||||
*Documentation generated from provided source files. No behaviors or APIs were inferred beyond what is explicitly present.*
|
||||
167
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/DAS.md
Normal file
167
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/DAS.md
Normal file
@@ -0,0 +1,167 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/DAS/EditDASRecordControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DAS/DataRecodersTileControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DAS/TOMDiagnostics.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DAS/ImportDASRecordControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DAS/ExportDASRecordControl.xaml.cs
|
||||
generated_at: "2026-04-16T04:16:31.420624+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "cf3acdb0f02477ab"
|
||||
---
|
||||
|
||||
# Documentation: DAS UI Controls Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides user interface controls for managing Data Acquisition System (DAS) hardware records within the DataPRO application. It supports core workflows: **adding/editing** individual DAS records (`EditDASRecordControl`), **importing** DAS records from XML files (`ImportDASRecordControl`), **exporting** selected DAS records to XML files (`ExportDASRecordControl`), and **displaying a tile-based view** of DAS hardware with calibration status (`DataRecodersTileControl`). Additionally, `TOMDiagnostics` provides a dedicated UI for visualizing and inspecting Time-Out Monitor (TOM) diagnostic test results. The module acts as the presentation layer for DAS hardware management, integrating with Prism-based view models and Unity-based dependency injection to decouple UI logic from data and business logic.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `EditDASRecordControl`
|
||||
- **`EditDASRecordControl(DataPROPage page)`**
|
||||
Constructor. Initializes the control and associates it with the parent `DataPROPage`.
|
||||
- **`void SetHardware(DataModel.DASHardware hardware, bool isAdd)`**
|
||||
Sets the hardware record to be edited (or `null` for new record). Attaches/detaches `PropertyChanged` handlers to detect model changes post-initialization.
|
||||
- **`void Save()`**
|
||||
Invokes `_vm.Save()` to persist the current hardware state, then updates page state to `Saved`.
|
||||
- **`bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`**
|
||||
Validates the current hardware record. Checks for `null` ISO hardware type and delegates validation to `_vm.Validate(...)`. Returns `false` if validation fails.
|
||||
- **`void OnSetActive()`**
|
||||
Called when the control becomes active. Initializes view models, sets `_vm.AllowStandin = false`, and calls `_vm.Activated()`.
|
||||
- **`void SetPermissions(UserPermissionLevels actualPermission, UserPermissionLevels requiredPermission)`**
|
||||
Controls UI visibility/enabled state based on user permissions. Collapses and disables `ViewContainer` if `actualPermission == Deny`; otherwise enables only if `actualPermission >= Edit`.
|
||||
|
||||
### `ImportDASRecordControl`
|
||||
- **`ImportDASRecordControl(DataPROPage page)`**
|
||||
Constructor. Initializes control and instantiates `DataRecordersControl` for hardware selection.
|
||||
- **`void OnSetActive()`**
|
||||
Activates the control: loads hardware list, resets state, and sets status to `Waiting`.
|
||||
- **`void Reset()`**
|
||||
Clears import state: resets `ImportFile`, clears `includedDASLookup`, updates hardware list, and re-runs validation.
|
||||
- **`void Import()`**
|
||||
Starts asynchronous import via `ImportFunc`, which validates, then calls `ImportTestSetup.ImportDASList(...)`.
|
||||
- **`bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`**
|
||||
Currently always returns `true`; no validation logic implemented.
|
||||
- **`void btnFolderBrowse_Click(...)`**
|
||||
Opens file dialog to select an XML file. Parses XML, migrates version if needed, normalizes IDs, and triggers `ImportTestSetup.ImportExportFile(...)`.
|
||||
|
||||
### `ExportDASRecordControl`
|
||||
- **`ExportDASRecordControl(DataPROPage page)`**
|
||||
Constructor. Initializes control and sets up `DataRecordersControl`.
|
||||
- **`void OnSetActive()`**
|
||||
Initializes view models, subscribes to `HardwareListHardwareIncludedEvent`, loads hardware list, and resets state.
|
||||
- **`void Export()`**
|
||||
Triggers export. If export file exists, prompts user via `FileOverwriteWarning`; otherwise calls `ExportFunc`.
|
||||
- **`bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`**
|
||||
Validates that `ExportFile` is non-empty and at least one DAS is selected (`_includedDAS.Count > 0`). Adds appropriate error messages.
|
||||
- **`void btnFolderBrowse_Click(...)`**
|
||||
Opens save dialog to select export file path.
|
||||
- **`void btnSelectAll_Click(...)` / `btnSelectNone_Click(...)`**
|
||||
Selects/deselects all hardware in the list, updating `_includedDAS` and calling `_hardwareListVm.SetIncluded(...)`.
|
||||
|
||||
### `DataRecodersTileControl`
|
||||
- **`DataRecodersTileControl(DataRecordersPage page)`**
|
||||
Constructor. Associates control with parent `DataRecordersPage`.
|
||||
- **`void OnSetActive()`**
|
||||
Calls `OnSetActiveAsync()` on a background thread to initialize VMs, set views, and load hardware.
|
||||
- **`void UpdateList()`**
|
||||
Reloads hardware list via `_hardwareListVm.GetHardware(...)`.
|
||||
- **`void StartSearch(string term)`**
|
||||
Filters hardware list via `_hardwareListVm.Filter(term)`.
|
||||
- **`void UnSet(...)`**
|
||||
Calls `_hardwareListVm.Unset()` to clean up subscriptions/resources.
|
||||
- **`DataModel.DASHardware[] SelectedHardware { get; set; }`**
|
||||
Bound to selected hardware; triggers `INotifyPropertyChanged`.
|
||||
|
||||
### `TOMDiagnostics`
|
||||
- **`void SetChannel(DataModel.HardwareChannel c)`**
|
||||
Sets the channel to diagnose. Updates all bound properties and redraws current/voltage/time series on chart.
|
||||
- **`string DelayMSText`, `DurationMSText`, `OutputPeakCurrentText`, `OutputPeakVoltageText`, `ExpectedDelayText`, `ExpectedDurationText`**
|
||||
Read-only properties providing formatted diagnostic values. Return `"N/A"` or status strings (`"Passed"`, `"Failed"`, `"N/A"`) based on `_hardwareChannel` state.
|
||||
- **`SolidColorBrush DurationBackground`, `SquibDelayBackground`**
|
||||
Returns color brush based on `_hardwareChannel.DurationStatus` / `DelayStatus`: `Failed` → red, `Passed` → green, `Untested` → idle color.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`EditDASRecordControl`**
|
||||
- `_vm` and `_vmHWList` are lazily initialized in `InitializeVmsIfNeeded()` and never null after first use.
|
||||
- `PropertyChanged` handlers for `_vm.Hardware` are attached only when `_vm.Hardware` implements `INotifyPropertyChanged`.
|
||||
- `_bInOnSetActive` flag prevents spurious `SetModifiedState` calls during initialization.
|
||||
- `Validate(...)` always adds `"UnknownDASType"` error if `_vm.GetISOHardware()` returns `null`.
|
||||
|
||||
- **`ImportDASRecordControl`**
|
||||
- `includedDASLookup` dictionary is cleared on `Reset()` and `UnSet()`.
|
||||
- `_bLoading` flag prevents column change events from modifying `includedDASLookup` during bulk loading.
|
||||
- XML import version migration uses `FileUtils.DataPRO20XmlVersion` constant.
|
||||
|
||||
- **`ExportDASRecordControl`**
|
||||
- `_includedDAS` dictionary tracks selected hardware by serial number.
|
||||
- `HardwareListHardwareIncludedEvent` subscription is added in `OnSetActive()` and removed in `UnSet()`.
|
||||
- Export file path is validated before export; empty path or zero selection count fails validation.
|
||||
|
||||
- **`DataRecodersTileControl`**
|
||||
- `OnSetActive()` delegates to `OnSetActiveAsync()` to avoid blocking UI thread.
|
||||
- `_hardwareListVm` is initialized once and reused.
|
||||
|
||||
- **`TOMDiagnostics`**
|
||||
- `SetChannel(...)` marshals to UI thread via `Dispatcher` if called from non-UI thread.
|
||||
- `RESULTS_FORMAT = "N3"` used consistently for numeric display.
|
||||
- `seriesCurrent.Values` and `seriesThreshold.Values` are cleared and repopulated in `UpdateCurrentValues()` under lock.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports/References
|
||||
- **Prism**: `IContainerRegistry`, `IEventAggregator`, `INotifyPropertyChanged`, `Prism.Ioc`, `Unity` (via `UnityContainer`).
|
||||
- **DTS Common Libraries**:
|
||||
- `DTS.Common.Interface.Hardware.AddEditHardware` (`IAddEditHardwareViewModel`, `IAddEditHardwareView`)
|
||||
- `DTS.Common.Interface.DASFactory.Diagnostics.HardwareList` (`IHardwareListViewModel`, `IHardwareListView`, `IHardwareListOverdueView`, `ISLICE6TreeView`)
|
||||
- `DTS.Common.Storage` (`DbOperations`, `DbVersion`)
|
||||
- `DTS.Common.SharedResource.Strings` (`StringResources`)
|
||||
- `DTS.Common.Events.Hardware.HardwareList` (`HardwareListHardwareSelectedEvent`, `HardwareListHardwareIncludedEvent`)
|
||||
- `DTS.Common.Interface.Sensors.AnalogDiagnostics`
|
||||
- `DTS.Common.Utilities.Logging` (`APILogger`)
|
||||
- `DTS.Slice.Users` (`UserPermissionLevels`)
|
||||
- **Data Model**: `DataModel.DASHardware`, `DataModel.HardwareChannel`, `DASHardwareList`, `DASHardware`, `DataRecordersControl`, `DataPROPage`, `DataRecordersPage`.
|
||||
- **System**: `System.Windows`, `System.ComponentModel`, `System.Threading`, `System.Xml`, `System.Windows.Forms`.
|
||||
|
||||
### Dependencies
|
||||
- **`ContainerLocator.Container`** (Unity container) for resolving view models and views.
|
||||
- **`Common.SerializedSettings`** for calibration period values.
|
||||
- **`ImportTestSetup`** and **`ExportTestSetup`** static classes for import/export logic.
|
||||
- **`FileUtils`** for XML version migration and normalization.
|
||||
- **`BrushesAndColors`** for status color brushes.
|
||||
|
||||
### Depended Upon
|
||||
- **`DataPROPage` / `DataRecordersPage`**: Hosts these controls; provides page-level state (`SetModifiedState`, `ReportErrors`, `EditSelectedHardware`).
|
||||
- **`IAddEditHardwareViewModel` / `IHardwareListViewModel`**: View models are resolved and injected into controls.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`EditDASRecordControl`**
|
||||
- `SetHardware(...)` detaches `PropertyChanged` from old hardware *before* assigning new hardware—critical for avoiding memory leaks or stale handlers.
|
||||
- `_bInOnSetActive` is used to suppress `SetModifiedState` during initialization, but only within `OnSetActive()`. Changes made in other contexts (e.g., programmatic model updates) will still mark the page as modified.
|
||||
- `Validate(...)` adds `"UnknownDASType"` error *before* calling `_vm.Validate(...)`, so `_vm.Validate(...)` may add additional errors/warnings.
|
||||
|
||||
- **`ImportDASRecordControl`**
|
||||
- `ImportFunc` runs on a background thread, but `SetStatus`/`SetProgress` marshal to UI thread via `Dispatcher`.
|
||||
- `includedDASLookup` is keyed by `hardware.GetHardware().GetId()` (likely serial number), but `GetHardware()` may return a wrapper—ensure consistency with `DASHardwareList.GetList()`.
|
||||
|
||||
- **`ExportDASRecordControl`**
|
||||
- `HardwareListHardwareIncludedEvent` subscription uses `ThreadOption.PublisherThread` and is *not* kept alive by GC (no `keepSubscriberReferenceAlive: true`). If publisher disposes before export, subscription may be lost.
|
||||
- `FileOverwriteWarning` blocks export via `ManualResetEvent.WaitOne()` on UI thread—risk of deadlock if `Export()` is called from UI thread and `DoMessageBox` blocks.
|
||||
|
||||
- **`DataRecodersTileControl`**
|
||||
- `OnSetActive()` calls `OnSetActiveAsync()` which uses `Dispatcher.Invoke(...)` internally—this can cause re-entrancy if `OnSetActive()` is called rapidly.
|
||||
- `UpdateList()` catches exceptions but logs only to `APILogger` and publishes `PageErrorEvent`—no UI feedback beyond event.
|
||||
|
||||
- **`TOMDiagnostics`**
|
||||
- `GetVoltageChannel()` assumes voltage channel immediately follows current channel in `_hardwareChannel.Hardware.Channels`. If channel ordering is not guaranteed, this may return incorrect channel or `null`.
|
||||
- `seriesThreshold.Values` is initialized as a 2-element array for plotting a horizontal line, but `seriesThreshold.XValues` uses only first/last time values—assumes uniform time axis.
|
||||
- `UpdateCurrentValues()` and `UpdateTimeAxis()` use `lock (MyLock)` but `seriesCurrent`/`seriesThreshold` are UI-bound collections—ensure thread-safety of `DoubleCollection` assignment.
|
||||
|
||||
- **General**
|
||||
- `IPageContent.SetPermissions(...)` implementations in `ImportDASRecordControl`, `ExportDASRecordControl`, and `DataRecodersTileControl` are empty stubs—permissions are not enforced in those controls.
|
||||
- `Validate(...)` in `ImportDASRecordControl` and `ExportDASRecordControl` have different behaviors: the former does nothing, the latter enforces file path and selection.
|
||||
- `DataRecodersTileControl` and `ExportDASRecordControl` both resolve `IHardwareListViewModel`, but `ExportDASRecordControl` additionally sets `SelectView` and `SelectView.InitializeColumns(false)`. Mixing these controls may cause view model state conflicts if not properly isolated.
|
||||
@@ -0,0 +1,209 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/DAS/HardwareDiscovery/ChannelDiscoveryTable.cs
|
||||
- DataPRO/DataPRO/Controls/DAS/HardwareDiscovery/AutoDiscoveredDASTable.cs
|
||||
generated_at: "2026-04-16T04:18:57.654528+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "bffba9fcd1521154"
|
||||
---
|
||||
|
||||
# HardwareDiscovery
|
||||
|
||||
**Documentation Page: Hardware Discovery Tables**
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
This module provides two specialized data grid tables—`ChannelDiscoveryTable` and `AutoDiscoveredDASTable`—used during hardware discovery in the DataPRO system’s Quick Data Collection workflow. `ChannelDiscoveryTable` displays discovered sensor channels (analog, digital input, or SQUIB) with associated metadata (location, sensor ID, channel name), enabling user review and assignment. `AutoDiscoveredDASTable` shows actual DAS (Data Acquisition System) hardware units detected on the network, including their type, serial number, channel count, configuration options (for SLICE2_SIM), and status, supporting user selection and final commit of hardware configuration.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `ChannelDiscoveryTable`
|
||||
|
||||
- **`CountTags` enum**
|
||||
Tags used for property change notifications: `DigitalInCount`, `SquibCount`, `AnalogCount`.
|
||||
|
||||
- **`DigitalInCount`, `SquibCount`, `AnalogCount` (properties)**
|
||||
Read/write integer properties tracking counts of discovered channel types. Updates trigger property change notifications via `SetProperty`.
|
||||
|
||||
- **`CountCount()`**
|
||||
Recalculates and updates `_digitalInCount`, `_squibCount`, and `_analogCount` by iterating over `Rows`, extracting `ChannelHelper` from each row, retrieving its `SensorData`, and categorizing based on `SensorConstants.BridgeType`.
|
||||
*Note:* Only rows with valid `DataRowView`, `ChannelHelper`, and non-null `SensorData` are counted.
|
||||
|
||||
- **`GetOnlineSensors()`**
|
||||
Returns an array of `DTS.SensorDB.SensorData` objects corresponding to sensors referenced in the table rows. For each row:
|
||||
- Extracts `ChannelHelper` from `ChannelHelper` column.
|
||||
- Skips if `channelHelper.Sensor` is null/empty.
|
||||
- Retrieves `SensorData` via `DTS.SensorDB.SensorsCollection.SensorsList.GetSensorBySerialNumber(channelHelper.SensorSerialNumber)`.
|
||||
- *Bug/Gap:* The method initializes `OnlineSensors` but **never adds** retrieved `sd` to the list before returning `OnlineSensors.ToArray()` → always returns empty array.
|
||||
|
||||
- **`ChannelHelper` class**
|
||||
A helper class wrapping a channel and its associated sensor/group metadata.
|
||||
|
||||
- **Constructor**:
|
||||
`ChannelHelper(DTS.SensorDB.SensorData sd, string hchannel, IGroupChannel channel, IGroup group)`
|
||||
Initializes internal state.
|
||||
|
||||
- **Properties**:
|
||||
- `Channel` (`IGroupChannel`), `Group` (`IGroup`) — read-only references.
|
||||
- `GetSensorData()` → `DTS.SensorDB.SensorData` — returns internal `_sd`.
|
||||
- `HardwareString` (`string`) — returns `_hardwareString`.
|
||||
- `Sensor` (`string`) — returns formatted sensor info: `"Unknown({SensorId})"` if `_sd` is null; else `"{SerialNumber}({Comment})"`.
|
||||
- `SensorSerialNumber` (`string`) — returns `_sd.SerialNumber` or `""`.
|
||||
- `Location` (`string`) — returns `_hardwareString` if non-empty/whitespace; else `StringResources.Table_NA`.
|
||||
- `SensorId` (`string`) — returns `_sd.EID` if `_sd` is non-null; else `_id`.
|
||||
|
||||
- **`CompareTo(ChannelHelper rhs)`**
|
||||
Implements `IComparable<ChannelHelper>`:
|
||||
- Compares `_hardwareString` lexicographically using `NaturalStringComparer` if both non-null.
|
||||
- Falls back to comparing `_sd` (via `SensorData.CompareTo`) if hardware strings are null/empty.
|
||||
- Handles null checks for `rhs`, `_hardwareString`, `_sd`, and `_id`.
|
||||
|
||||
- **`UpdateChannels(ChannelHelper[] foundChannels)`**
|
||||
Clears `DataTable.Rows`, then for each `ChannelHelper` in `foundChannels`:
|
||||
- Creates a new `DataRow`.
|
||||
- Sets values for columns: `Location`, `ChannelName`, `Sensor`, `SensorId`, `ChannelHelper`.
|
||||
- `ChannelName` uses `ch.Channel.IsoChannelName`.
|
||||
- `SensorId` uses `ch.GetSensorData().EID` — **assumes `_sd` is non-null** (will throw if null).
|
||||
- Adds row to table.
|
||||
- Calls `CountCount()` to update counts.
|
||||
|
||||
- **`Fields` enum**
|
||||
Defines column names: `ChannelName`, `Sensor`, `SensorId`, `Location`, `ChannelHelper`.
|
||||
|
||||
- **`SetSensors(IGroup groupToAddTo, Dictionary<IGroup, IGroupChannel[]> groupToGroupChannel, DataModel.TestTemplate testSetup)`**
|
||||
Commits current channel assignments from the table to the system model:
|
||||
- Builds `hwidToSensorSNForClaimedChannels` mapping `"DASId_DASChannelIndex"` → `Sensor.DatabaseId`.
|
||||
- Iterates over all groups’ channels (via `_hardwareDiscoveryControl.GetGroups()` and `groupToGroupChannel`).
|
||||
- For each channel with valid `DASId`, `DASChannelIndex`, and `SensorId`, if its hardware ID is in `hwidToSensorSNForClaimedChannels` but maps to a *different* sensor, calls `ch.SetHardwareChannel(null)` to unassign it.
|
||||
- Returns `newGroupChannels.ToArray()` — **always empty**, as `newGroupChannels` is never populated.
|
||||
|
||||
- **`UnSet()`**
|
||||
Clears all rows from `DataTable`.
|
||||
|
||||
- **Constructor**
|
||||
`ChannelDiscoveryTable(ContentControl containerControl, DataPROPage page, Location location, HardwareDiscoveryControl hardwareDiscoveryControl)`
|
||||
Initializes grid with:
|
||||
- `IsReadOnly = false`, `CanUserEditRows = true`, `CanUserFilter = false`, `CanUserAddRows = false`, `CanUserSort = false`, `SelectionMode = None`.
|
||||
- Dynamically creates columns based on `Fields` enum and `_location` (e.g., `SensorId` column only added if `location == TestSetups`).
|
||||
- Registers `LoadedCellPresenter` handler.
|
||||
|
||||
#### `AutoDiscoveredDASTable`
|
||||
|
||||
- **`Clear()`**
|
||||
Clears `_dt.Rows` and reassigns `DataTable = _dt`.
|
||||
|
||||
- **`Update(DTS.DASLib.Service.IDASCommunication[] das)`**
|
||||
Populates table with DAS devices:
|
||||
- Iterates over `das`, creates rows, populates columns via `ColumnIds` enum.
|
||||
- Key logic:
|
||||
- `DASType`: Maps `IDAS` hardware type to localized string (e.g., `SLICE2_SIM` → `"SLICE2 SIM"`).
|
||||
- `DASStatus`: Hardcoded to `Strings.StringResources.AutoDetectDASControl_Connected`.
|
||||
- `ChannelsColumn`: Uses `AutoDetectDASControl.GetChannelsString(idas)`.
|
||||
- `Configuration`, `AvailableConfigurations`, `SelectedConfiguration`: Special handling for `SLICE2_SIM` only (see below).
|
||||
- `CMD_ENABLED`: `true` only for `SLICE2_Base` and `SLICE2_SIM`.
|
||||
- Assigns `DataTable = _dt` at end.
|
||||
|
||||
- **`GetSelectedConfiguration(IDASCommunication das)`**
|
||||
Returns configuration string based on `das.DASInfo.Modules.Length` for `SLICE2_SIM`:
|
||||
- `3 modules` → `"MegaSampleConfig"`
|
||||
- `4 modules` → `"800kSampleConfig"`
|
||||
- `5 modules` → `"700kSampleConfig"`
|
||||
- `6+ modules` → `"600kSampleConfig"`
|
||||
- For non-`SLICE2_SIM`, returns `"MAX"`.
|
||||
|
||||
- **`GetAvailableConfigurations(IDASCommunication das)`**
|
||||
Returns `AVAILABLE_SLICE2_CONFIGURATIONS` for `SLICE2_SIM`; otherwise `["MAX"]`.
|
||||
|
||||
- **`CommitDAS()`**
|
||||
Commits selected DAS devices to the system model:
|
||||
- Iterates over rows:
|
||||
- Skips if `Included` is `false` → sets status to `"Skipped"`.
|
||||
- Skips if device is armed (`DASArmStatus.IsArmed`) → sets status to `"Armed"`.
|
||||
- Skips if `ChannelCount == 0` (except for `SLICE_Distributor`/`SLICE_EthernetController`) → sets status to `"NoChannels"`.
|
||||
- Adds/updates hardware via `DataModel.DASHardwareList.GetList().Commit(h)`.
|
||||
- Handles `HardwareTypeChangedException` by marking as `"Updated"`.
|
||||
- Calls `DataTable.AcceptChanges()`.
|
||||
|
||||
- **`_dt_ColumnChanged(...)`**
|
||||
Handles `DataTable.ColumnChanged` events:
|
||||
- Only processes `"SelectedConfiguration"` changes (ignores during `_bUpdating`).
|
||||
- Parses new config string to determine `maxModules`:
|
||||
- `"MegaSampleConfig"` → 3
|
||||
- `"800kSampleConfig"` → 4
|
||||
- `"700kSampleConfig"` → 5
|
||||
- `"600kSampleConfig"` → 6
|
||||
- Calls `SetMaxModuleCount(maxModules)` on `IDASReconfigure` interface, then resets `DASInfo`, `ConfigData`, and flags (`DiagnosticsHasBeenRun`, `ConfigureHasBeenRun`).
|
||||
- Triggers requery via `(ParentPage as AutoDetectDASPage).RequeryConfig()` if applicable.
|
||||
|
||||
- **`CalculateMaxModules(int sps)`**
|
||||
*Unused in current code.* Returns module count based on sample rate threshold.
|
||||
|
||||
- **Constructor**
|
||||
`AutoDiscoveredDASTable(ContentControl parentControl, DataPROPage page)`
|
||||
Initializes `_dt`, sets grid properties (`SelectionMode = None`, `IsReadOnly = false`), and:
|
||||
- Dynamically creates columns for `ColumnIds` (some as `DataGridBoundColumn`, some as `DataGridTemplateColumn` for `Configuration`).
|
||||
- Registers `_dt.ColumnChanged` handler.
|
||||
- Sets `HeaderColor`.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **`ChannelDiscoveryTable`**:
|
||||
- `DataTable` must contain rows with `ChannelHelper` objects in the `ChannelHelper` column.
|
||||
- `CountCount()` must be called after any row modification to keep `DigitalInCount`, `SquibCount`, `AnalogCount` accurate.
|
||||
- `SensorId` column value is derived from `ChannelHelper.GetSensorData().EID` — assumes `_sd` is non-null (no null-safety).
|
||||
- `Location` column value is `HardwareString` if present; otherwise `Table_NA`.
|
||||
|
||||
- **`AutoDiscoveredDASTable`**:
|
||||
- `SelectedConfiguration` changes trigger reconfiguration of `SLICE2_SIM` devices via `SetMaxModuleCount`.
|
||||
- `Included` column determines whether a DAS is committed; skipped devices are not added/updated.
|
||||
- Devices with `ChannelCount == 0` are rejected unless type is `SLICE_Distributor` or `SLICE_EthernetController`.
|
||||
- `_bUpdating` flag prevents recursive updates during `ColumnChanged`.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### `ChannelDiscoveryTable`
|
||||
- **Imports/Usings**:
|
||||
- `DTS.Common.Classes.Groups`, `DTS.Common.Enums.Sensors`, `DTS.Common.Interface.Channels`, `DTS.Common.Interface.Groups.GroupList`, `DTS.Common.Storage`, `DTS.Common.Utilities`, `DTS.Common.SharedResource.Strings`, `DTS.Common`.
|
||||
- **Key Dependencies**:
|
||||
- `DTS.SensorDB.SensorsCollection.SensorsList.GetSensorBySerialNumber(string)` — to resolve sensor metadata.
|
||||
- `ChannelHelper` relies on `SensorData` from `DTS.SensorDB.SensorData`.
|
||||
- `StringResources` for localized strings (e.g., `HardwareDiscoveryControl_Unknown`, `Table_NA`).
|
||||
- `NaturalStringComparer` for sorting.
|
||||
- Inherits from `GenericTable2` (base grid class).
|
||||
- **Consumers**:
|
||||
- Used by `HardwareDiscoveryControl` (via `_hardwareDiscoveryControl` field) — likely instantiated in discovery UI flow.
|
||||
|
||||
#### `AutoDiscoveredDASTable`
|
||||
- **Imports/Usings**:
|
||||
- `System`, `System.Collections.Generic`, `System.Linq`, `System.Text`.
|
||||
- **Key Dependencies**:
|
||||
- `DTS.DASLib.Service.IDASCommunication`, `DTS.DASLib.Service.IDASReconfigure`, `DTS.DASLib.DASFactory`, `DataModel.DASHardware`, `DataModel.DASHardwareList`, `ISODll.Hardware.HardwareTypes`, `Strings.StringResources`.
|
||||
- `AutoDetectDASControl.GetChannelsString(IDASCommunication)` — static helper.
|
||||
- `App.Current.DASFactory.GetActiveDevices()` — for requery.
|
||||
- **Consumers**:
|
||||
- Used by `AutoDetectDASPage` (via `ParentPage is AutoDetectDASPage` check in `_dt_ColumnChanged`).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`ChannelDiscoveryTable.GetOnlineSensors()` always returns empty array** — the method populates `sd` but never adds it to `OnlineSensors`. Likely a bug or incomplete implementation.
|
||||
- **`ChannelDiscoveryTable.SetSensors()` returns empty array** — `newGroupChannels` is declared but never populated; return value is meaningless.
|
||||
- **`ChannelDiscoveryTable.UpdateChannels()` assumes `_sd` is non-null** — `ch.GetSensorData().EID` will throw `NullReferenceException` if `ChannelHelper` was constructed with null `sd`.
|
||||
- **`AutoDiscoveredDASTable._dt_ColumnChanged` uses hardcoded string `"SelectedConfiguration"`** — fragile if column name changes.
|
||||
- **`AutoDiscoveredDASTable.CommitDAS()` has commented-out logic** — `DataModel.DASHardwareList.GetList().Replace(dbHw, h)` and `Delete(dbHw)` are commented, suggesting incomplete handling of hardware type changes.
|
||||
- **`AutoDiscoveredDASTable.CalculateMaxModules()` is unused** — present but never called.
|
||||
- **Hardcoded configuration strings** — e.g., `"MAX"`, `"800kSampleConfig"` — rely on exact string matches from `StringResources`. Localization mismatches could break behavior.
|
||||
- **`ChannelDiscoveryTable` constructor uses `page.TileColor`** — but `GenericTable2` base constructor signature differs between files (one uses `"ChannelDiscoveryTable"`, another `"AutoDiscoveredDASTable"` as name). Ensure consistency.
|
||||
- **No validation of `channelHelper.HardwareString` format** — assumed to be `"DASId_DASChannelIndex"` in `SetSensors`, but no explicit parsing or validation.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,268 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/DataExports/DataEmptyExportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DataExports/DataSimpleChapter10ExportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DataExports/DataHDFExportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DataExports/DataSimpleXLSXExportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DataExports/DataToyotaExportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DataExports/DataSimpleCSVExportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DataExports/DataDiademExportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DataExports/DataSimpleTSVExportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DataExports/DataCSVExportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/DataExports/DataROIAwareBase.cs
|
||||
generated_at: "2026-04-16T04:16:12.195142+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "ead3d3af68210a93"
|
||||
---
|
||||
|
||||
# Export Options Controls Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides UI controls for configuring export options for various data export formats (CSV, TSV, XLSX, HDF, Chapter 10, Diadem, Toyota TDM) within the DataPRO application. Each control encapsulates format-specific settings and validation logic, and many inherit from `DataROIAwareBase` to support region-of-interest (ROI)-based filtering and channel selection. These controls are used in the export configuration UI to allow users to customize how data is exported, including format selection, filtering options, channel inclusion/exclusion, and format-specific parameters like sub-sampling or header inclusion.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `DataEmptyExportOptions`
|
||||
- **`DataEmptyExportOptions()`**
|
||||
Constructor that initializes the control and calls `InitializeComponent()`. No export options are exposed; this is a placeholder control.
|
||||
- **`DataEmptyExportOption` (nested class)**
|
||||
A minimal `INotifyPropertyChanged` implementation used as a base or placeholder for option objects. Provides `SetProperty<T>` and `OnPropertyChanged` helpers.
|
||||
|
||||
### `DataSimpleChapter10ExportOptions : DataROIAwareBase`
|
||||
- **`Filtered` (bool, default `true`)**
|
||||
Indicates whether filtered data export is enabled.
|
||||
- **`UnFiltered` (bool, default `false`)**
|
||||
Indicates whether unfiltered data export is enabled.
|
||||
- **`IncludeSecondaryHeader` (bool, default `true`)**
|
||||
Controls inclusion of a secondary time header in the export (see comment referencing issue 33199).
|
||||
- **`UseAnalogFormat` (bool, default `true`)**
|
||||
Indicates whether analog format is selected for export.
|
||||
- **`UsePCMFormat` (bool, default `false`)**
|
||||
Indicates whether PCM format is selected for export.
|
||||
- **`ValidatePage(ref List<string> errors)` (override)**
|
||||
Validates export configuration:
|
||||
- Ensures ROI suffixes are unique.
|
||||
- Ensures exactly one of `UsePCMFormat` or `UseAnalogFormat` is `true`.
|
||||
- Adds appropriate error messages if validation fails.
|
||||
|
||||
### `DataHDFExportOptions : UserControl, INotifyPropertyChanged`
|
||||
- **`ExportADC` (bool, default `true`)**
|
||||
Controls whether raw ADC data is included in the HDF export.
|
||||
- **`ExportMV` (bool, default `true`)**
|
||||
Controls whether millivolt (mV) data is included.
|
||||
- **`ExportUnfilteredEU` (bool, default `true`)**
|
||||
Controls whether unfiltered engineering units (EU) data is included.
|
||||
- **`IncludeLogs` (bool, default `true`)**
|
||||
Controls inclusion of log data in the export.
|
||||
- **`IncludeReports` (bool, default `true`)**
|
||||
Controls inclusion of report data.
|
||||
- **`IncludeSetup` (bool, default `true`)**
|
||||
Controls inclusion of setup data.
|
||||
- **`IncludeDTSFile` (bool, default `true`)**
|
||||
Controls inclusion of the DTS file.
|
||||
- **`ValidatePage(ref List<string> errors)`**
|
||||
Validates that at least one of `ExportADC`, `ExportMV`, or `ExportUnfilteredEU` is `true`. Adds `StringResources.HDFExport_MethodRequired` if none are selected.
|
||||
|
||||
### `DataSimpleXLSXExportOptions : DataROIAwareBase`
|
||||
- **`ExportXLSXUnfiltered` (bool)**
|
||||
Indicates whether unfiltered data should be exported.
|
||||
- **`ExportXLSXFiltered` (bool)**
|
||||
Indicates whether filtered data should be exported.
|
||||
- **`ExportHeaders` (ObservableCollection<IExportHeader>)**
|
||||
Collection of export header definitions.
|
||||
- **`StartSearch(string term)`**
|
||||
No-op stub method.
|
||||
- **`ValidatePage(ref List<string> errors)` (override)**
|
||||
Validates:
|
||||
- At least one of `ExportXLSXUnfiltered` or `ExportXLSXFiltered` is `true`.
|
||||
- An event is selected.
|
||||
- ROI suffixes are unique.
|
||||
- At least one ROI is enabled.
|
||||
- `_roiChannelsVm.Validate()` succeeds.
|
||||
|
||||
### `DataToyotaExportOptions : DataROIAwareBase`
|
||||
- **`CurrentOptions` (DataToyotaExportOption)**
|
||||
Exposes a nested option object with the following properties:
|
||||
- `SubSample` (ushort, default `1`)
|
||||
- `ROIVisibility` (Visibility, default `Collapsed`)
|
||||
- `AddROIVisibility` (Visibility, default `Collapsed`)
|
||||
- `ChannelDetailsVisibility` (Visibility, computed based on `AddROIVisibility`)
|
||||
- `RecordingMode` (RecordingModes, default `CircularBuffer`)
|
||||
- **`StartSearch(string term)`**
|
||||
No-op stub.
|
||||
- **`ValidatePage(ref List<string> errors)` (override)**
|
||||
Validates:
|
||||
- An event is selected.
|
||||
- ROI suffixes are unique.
|
||||
- At least one ROI is enabled.
|
||||
- `_roiChannelsVm.Validate()` succeeds.
|
||||
|
||||
### `DataSimpleCSVExportOptions : DataROIAwareBase, INotifyPropertyChanged`
|
||||
- **`ExportCSVUnfiltered` (bool, default `false`)**
|
||||
- **`ExportCSVFiltered` (bool, default `false`)**
|
||||
- **`ExportCSVMV` (bool, default `false`)**
|
||||
- **`ExportCSVADC` (bool, default `false`)**
|
||||
All indicate which data types to include in CSV export.
|
||||
- **`ExportHeaders` (ObservableCollection<IExportHeader>)**
|
||||
Collection of export header definitions.
|
||||
- **`SubSample` (ushort, default `1`)**
|
||||
Sub-sampling factor for export.
|
||||
- **`StartSearch(string term)`**
|
||||
No-op stub.
|
||||
- **`ValidatePage(ref List<string> errors)` (override)**
|
||||
Validates:
|
||||
- At least one of `ExportCSVUnfiltered`, `ExportCSVFiltered`, `ExportCSVADC`, or `ExportCSVMV` is `true`.
|
||||
- ROI suffixes are unique.
|
||||
- At least one ROI is enabled.
|
||||
- `_roiChannelsVm.Validate()` succeeds.
|
||||
|
||||
### `DataDiademExportOptions : UserControl, INotifyPropertyChanged`
|
||||
- **`DiademChannelName200` (ExportOptionHelper)**
|
||||
Configures channel name mapping for Diadem reserved field 200.
|
||||
- **`DiademUserComment201` (ExportOptionHelper)**
|
||||
Configures user comment mapping for Diadem reserved field 201.
|
||||
- **`DiademReserved1_301` (ExportOptionHelperReserved1)**
|
||||
Configures reserved field 301 (supports group name or AAF Rate per comment).
|
||||
- **`DiademReserved2_302` (ExportOptionHelperReserved2)**
|
||||
Configures reserved field 302 (supports channel sensitivity per comment).
|
||||
- **`DataDiademExportOption` (nested class)**
|
||||
Placeholder class with `INotifyPropertyChanged` support (no properties defined in source).
|
||||
- **`SelectAllText(object sender, RoutedEventArgs e)`**
|
||||
Event handler to select all text in a `TextBox`.
|
||||
|
||||
### `DataSimpleTSVExportOptions : DataROIAwareBase`
|
||||
- **`ExportTSVUnfiltered` (bool)**
|
||||
- **`ExportTSVFiltered` (bool)**
|
||||
Indicate which data types to include in TSV export.
|
||||
- **`SubSample` (ushort, default `1`)**
|
||||
Sub-sampling factor.
|
||||
- **`SPS` (double)**
|
||||
Samples per second; used to compute max file size for filtered exports.
|
||||
- **`ActualStartSeconds`, `ActualEndSeconds` (double)**
|
||||
Time range for filtered export size estimation.
|
||||
- **`NumberOfChannels` (int)**
|
||||
Number of channels; used in size estimation.
|
||||
- **`ValidatePage(ref List<string> errors)` (override)**
|
||||
Validates:
|
||||
- At least one of `ExportTSVUnfiltered` or `ExportTSVFiltered` is `true`.
|
||||
- An event is selected.
|
||||
- ROI suffixes are unique.
|
||||
- At least one ROI is enabled.
|
||||
- `_roiChannelsVm.Validate()` succeeds.
|
||||
- For filtered export, checks that estimated export size ≤ `MAX_SUPPORTED_SAMPLES` (2,000,000,000 samples), adding `StringResources.ExportDataTooLargeToFilter` if exceeded.
|
||||
|
||||
### `DataCSVExportOptions : UserControl, INotifyPropertyChanged`
|
||||
- **`CurrentOptions` (DataCSVExportOption)**
|
||||
Exposes a nested option object with:
|
||||
- `IndividualFiles` (bool, default `false`)
|
||||
- `IncludeFieldHeaders` (bool, default `true`)
|
||||
- `FieldSeparator` (string, default `","`)
|
||||
- `CustomColumnOrder` (bool, default `false`)
|
||||
- `IncludedFields` (object[]), `IncludedColumns` (string[]), `AvailableColumns` (string[])
|
||||
Collections for column ordering.
|
||||
- `Name` (string, default `"new setting options"`)
|
||||
- `FileName` (string, default `"DataDB.csv"`)
|
||||
- `Folder` (string, default `""`)
|
||||
- `CustomColumnOrderVisibility` (Visibility, computed)
|
||||
- `ColumnOrderHeight` (GridLength, computed)
|
||||
- `FilenameVisibility` (Visibility, computed)
|
||||
- Methods: `Add(List<int>)`, `Remove(List<int>)`, `RemoveAll()`
|
||||
- **`ColumnOrderHeight` (GridLength)**
|
||||
Public property that always returns `GridLength(0, Auto)`; setter is no-op.
|
||||
|
||||
### `DataROIAwareBase : UserControl, INotifyPropertyChanged, IDataROIAwareBase`
|
||||
Base class for export controls that support ROI-aware configuration.
|
||||
|
||||
#### Properties
|
||||
- **`RegionsOfInterest` (BindingList<IRegionOfInterest>)**
|
||||
List of ROI objects; triggers `ChannelDetailsVisibility` updates.
|
||||
- **`EventsToDownload` (BindingList<IDownloadEvent>)**
|
||||
List of events to download.
|
||||
- **`DataStart`, `DataEnd`, `PreTriggerSeconds`, `PostTriggerSeconds` (double)**
|
||||
Time range and trigger timing metadata.
|
||||
- **`ROIVisibility`, `EventsVisibility`, `AddROIVisibility`, `ChannelDetailsVisibility` (Visibility)**
|
||||
UI visibility flags for ROI/event sections.
|
||||
- **`RecordingMode` (RecordingModes, default `CircularBuffer`)**
|
||||
Recording mode (e.g., `CircularBuffer`, `Triggered`).
|
||||
- **`RemoveROICommand`, `AddROICommand` (RoutedCommand)**
|
||||
Commands for ROI management.
|
||||
|
||||
#### Methods
|
||||
- **`SetGroups(ITestSetup, Dictionary<string, IDASHardware>)`**
|
||||
Initializes ROI channel groups.
|
||||
- **`SetTest(string path)`**
|
||||
Loads test data at given path.
|
||||
- **`ValidateROISuffix(Control roiControl)`**
|
||||
Returns `true` if all ROI suffixes are unique; marks control invalid/valid.
|
||||
- **`ValidateEventSelected()`**
|
||||
Returns `true` if at least one event in `EventsToDownload` is enabled.
|
||||
- **`ValidateROIEnabled(Control roiControl)`**
|
||||
Returns `true` if no ROI section visible or at least one ROI is enabled.
|
||||
- **`AddROI`, `RemoveROI` (protected)**
|
||||
Command handlers for ROI management.
|
||||
- **`ValidatePage(ref List<string> errors)` (virtual)**
|
||||
Default implementation returns `true`; overridden in derived classes.
|
||||
|
||||
#### Events
|
||||
- **`PropertyChanged` (INotifyPropertyChanged)**
|
||||
Standard property change notification.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`DataROIAwareBase`-derived controls**:
|
||||
- `RegionsOfInterest` must have unique `Suffix` values for valid export (validated by `ValidateROISuffix`).
|
||||
- At least one event must be enabled in `EventsToDownload` for valid export (validated by `ValidateEventSelected`).
|
||||
- If ROI section is visible, at least one ROI must be enabled (validated by `ValidateROIEnabled`).
|
||||
- `_roiChannelsVm.Validate()` must succeed for export to be valid (checked in `ValidatePage` overrides).
|
||||
- `ChannelDetailsVisibility` is `Visible` only if `AddROIVisibility == Visibility.Visible`; otherwise, it reflects the input value.
|
||||
|
||||
- **Format-specific invariants**:
|
||||
- `DataSimpleChapter10ExportOptions`: Exactly one of `UsePCMFormat` or `UseAnalogFormat` must be `true`.
|
||||
- `DataHDFExportOptions`: At least one of `ExportADC`, `ExportMV`, or `ExportUnfilteredEU` must be `true`.
|
||||
- `DataSimpleXLSXExportOptions`, `DataSimpleCSVExportOptions`, `DataSimpleTSVExportOptions`: At least one of the primary format flags (e.g., `ExportXLSXUnfiltered`/`ExportXLSXFiltered`) must be `true`.
|
||||
- `DataSimpleTSVExportOptions`: For filtered export, estimated sample count (`SPS × (End − Start) × NumberOfChannels`) must not exceed `MAX_SUPPORTED_SAMPLES` (2,000,000,000).
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies
|
||||
- **`DataROIAwareBase`** is used by:
|
||||
- `DataSimpleChapter10ExportOptions`
|
||||
- `DataSimpleXLSXExportOptions`
|
||||
- `DataToyotaExportOptions`
|
||||
- `DataSimpleCSVExportOptions`
|
||||
- `DataSimpleTSVExportOptions`
|
||||
- **`IDataROIAwareBase`** interface is implemented by `DataROIAwareBase`.
|
||||
- **`IRegionOfInterestChannelsViewModel`** (`_roiChannelsVm`) is resolved via Unity container in `DataROIAwareBase.InitializeVMs()`.
|
||||
- **`IEventAggregator`** (Prism) is used to subscribe to `RegionOfInterestChannelsSelectedEvent`.
|
||||
- **`IUnityContainer`** (Unity) is used for dependency resolution.
|
||||
|
||||
### External Dependencies
|
||||
- **WPF**: `System.Windows.Controls`, `System.ComponentModel`, `System.Windows.Input`, `System.Windows.Visibility`.
|
||||
- **DTS Libraries**:
|
||||
- `DTS.Common.Interface.ExportData` (`IExportHeader`)
|
||||
- `DTS.Common.Interface.DownloadEvent` (`IDownloadEvent`)
|
||||
- `DTS.Common.Interface.RegionOfInterest` (`IRegionOfInterest`)
|
||||
- `DTS.Common.Interface.TestSetups.TestSetupsList` (`ITestSetup`)
|
||||
- `DTS.Common.Enums` (`RecordingModes`)
|
||||
- `DTS.Common.SharedResource.Strings` (`StringResources`)
|
||||
- **C1.WPF** (`C1.WPF.PropertyChangedEventArgs<double>`) for `numericBoxSubSample_ValueChanged` handlers.
|
||||
- **System.Windows.Forms** (`FolderBrowserDialog`) in `DataCSVExportOptions` for folder browsing.
|
||||
|
||||
### Dependencies on This Module
|
||||
- Export configuration UI pages consume these controls.
|
||||
- Export logic (not shown) likely reads properties from these controls to generate output files.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`DataDiademExportOptions`**: The `DataDiademExportOption` nested class is declared but has no properties defined in the source—likely incomplete or placeholder code.
|
||||
- **`DataCSVExportOptions`**: The `ColumnOrderHeight` property always returns `GridLength(0, Auto)` and ignores its setter—likely a binding workaround with no functional effect.
|
||||
- **`DataSimpleTSVExportOptions`**: `MAX_SUPPORTED_SAMPLES` (2,000,000,000) is described as "completely arbitrary" in comments; no justification or documentation of why this limit exists.
|
||||
- **`DataToyotaExportOptions`**: `ChannelDetailsVisibility` depends on `AddROIVisibility` being `Visible`; if `AddROIVisibility` is `Collapsed`, `ChannelDetailsVisibility` is forced to `Collapsed` regardless of input.
|
||||
- **`DataROIAwareBase`**: `ValidateROIEnabled` returns `true` if ROI section is not visible (via `NoROI` helper), which may mask missing ROI selection if UI visibility is misconfigured.
|
||||
- **`DataSimpleCSVExportOptions` and `DataSimpleTSVExportOptions`**: Sub-sampling is exposed as `SubSample` (ushort), but no validation ensures it is ≥1 (though default is 1).
|
||||
- **`DataSimpleChapter10ExportOptions`**: `UseAnalogFormat` and `UsePCMFormat` are mutually exclusive, but the property setters do not auto-toggle the other (e.g., setting `UseAnalogFormat = true` does not set `UsePCMFormat = false`).
|
||||
- **`DataROIAwareBase`**: `ChannelDetailsVisibility` setter is `protected`, so derived classes cannot override its behavior without redefining the property.
|
||||
- **`DataROIAwareBase`**: `SubscribeToROIEvents` and `UnsubscribeToROIEvents` use a volatile `_bSubscribed` flag to prevent duplicate subscriptions, but no cleanup occurs if `EventAggregator` is null at subscription time (though it resolves lazily).
|
||||
- **`DataCSVExportOptions`**: The `DataCSVExportOption` constructor has commented-out code that would populate `IncludedFields`/`IncludedColumns` from enums—suggesting incomplete initialization or legacy behavior.
|
||||
116
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/Downloads.md
Normal file
116
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/Downloads.md
Normal file
@@ -0,0 +1,116 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/Downloads/SimpleDownloadOptions.xaml.cs
|
||||
generated_at: "2026-04-16T04:16:58.151139+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "3bde5e65d5656708"
|
||||
---
|
||||
|
||||
# Downloads
|
||||
|
||||
### **Purpose**
|
||||
The `SimpleDownloadOptions` user control provides the UI and logic for configuring region-of-interest (ROI) and event-based download parameters in the DataPRO application. It enables users to define, validate, and manage one or more ROIs (each with start/end time, channel selection, and suffix), display associated event metadata, and enforce constraints based on the current recording mode, data boundaries, and test setup configuration. It serves as a dedicated page in a multi-step download workflow, integrating with Prism/Unity DI for view model resolution and leveraging shared interfaces (`IRegionOfInterestChannelsViewModel`, `IRegionOfInterest`, `IDownloadEvent`) to decouple UI from domain logic.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
#### **Constructor**
|
||||
- `SimpleDownloadOptions()`
|
||||
Initializes the control, registers `AddROICommand` and `RemoveROICommand` as routed commands bound to `AddROI` and `RemoveROI` handlers, and calls `InitializeComponent()`.
|
||||
|
||||
#### **Properties**
|
||||
- `Visibility RoiVisibility { get; set; }`
|
||||
Controls visibility of the ROI selection UI (bound via `INotifyPropertyChanged`).
|
||||
- `Visibility EventDetailsVisibility { get; set; }`
|
||||
Controls visibility of event details UI.
|
||||
- `Visibility DataDetailsVisibility { get; private set; }`
|
||||
Controls visibility of data summary (start/end, sample rate, etc.); set to `Visible` after `Initialize`.
|
||||
- `Visibility ChannelDetailsVisibility { get; private set; }`
|
||||
Controls visibility of channel-specific ROI details; set to `Visible` only when `RegionsOfInterest.Count > 1`.
|
||||
- `string DownloadPath { get; private set; }`
|
||||
Full path to the default download folder (set in `Initialize`).
|
||||
- `double DataStart { get; private set; }`
|
||||
Start time (in seconds) of the available data window.
|
||||
- `double DataEnd { get; private set; }`
|
||||
End time (in seconds) of the available data window.
|
||||
- `double PreTriggerSeconds { get; private set; }`
|
||||
Pre-trigger buffer duration (negative start offset for circular/active modes).
|
||||
- `double PostTriggerSeconds { get; private set; }`
|
||||
Post-trigger buffer duration (positive end offset for recorder/active modes).
|
||||
- `double SampleRateAggregate { get; private set; }`
|
||||
Aggregate sample rate across DAS units; `NaN` if inconsistent.
|
||||
- `string SPSText { get; }`
|
||||
Human-readable sample rate string (e.g., `"1,000"` or `"Multiple sample rates"` if `NaN`).
|
||||
- `RecordingModes RecordingMode { get; private set; }`
|
||||
Current recording mode (e.g., `CircularBuffer`, `Recorder`).
|
||||
- `BindingList<IRegionOfInterest> RegionsOfInterest { get; private set; }`
|
||||
List of ROI definitions (populated in `Initialize`).
|
||||
- `BindingList<IDownloadEvent> EventsToDownload { get; private set; }`
|
||||
List of events to download (populated in `Initialize`).
|
||||
|
||||
#### **Methods**
|
||||
- `void SetEnabled(bool bEnable)`
|
||||
Enables/disables the control on the UI thread; skips if `CurrentUser` is null. Uses `Dispatcher` for cross-thread safety.
|
||||
- `void SetParent(object o)`
|
||||
Delegates to `_roiChannelsVm.SetParent(o)` (if `_roiChannelsVm` is initialized).
|
||||
- `void StartSearch(string term)`
|
||||
Delegates to `_roiChannelsVm.Filter(term)` (if `_roiChannelsVm` is initialized).
|
||||
- `bool ValidatePage(double PreTriggerSeconds, double PostTriggerSeconds, RecordingModes recordingMode, ref List<string> errors)`
|
||||
Validates ROI and channel configurations. Calls `ValidateROIControl` and `_roiChannelsVm.Validate(ref errors)`. Returns `false` if any validation error is added to `errors`.
|
||||
- `void ClearView()`
|
||||
Resets all UI state: clears `RegionsOfInterest`/`EventsToDownload`, sets `DataStart`/`DataEnd`/`PreTriggerSeconds`/`PostTriggerSeconds` to `0`, resets `RecordingMode` to `CircularBuffer`, and collapses `DataDetailsVisibility`, `ChannelDetailsVisibility`, and `RoiVisibility`.
|
||||
- `void Initialize(double dataStart, double dataEnd, double preTrigger, double postTrigger, RecordingModes recordingMode, BindingList<IRegionOfInterest> regionsOfInterest, BindingList<IDownloadEvent> eventsToDownload, Dictionary<string, IDASHardware> hardwareLookup, TestTemplate testTemplate, IReadOnlyDictionary<int, double> eventLengthByIndex)`
|
||||
Populates control state: sets data boundaries, sample rate, recording mode, and ROI/event lists; resolves and initializes `_roiChannelsVm`; computes `SampleRateAggregate`; sets `DownloadPath`; configures event lengths; and triggers property change notifications.
|
||||
|
||||
#### **Commands**
|
||||
- `RoutedCommand AddROICommand { get; }`
|
||||
Command bound to `AddROI` handler; adds a new ROI with default suffix, start/end offsets, and all channels.
|
||||
- `RoutedCommand RemoveROICommand { get; }`
|
||||
Command bound to `RemoveROI` handler; removes the ROI from `RegionsOfInterest` (extracted from `e.OriginalSource`), resets suffix if only one ROI remains.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
- `RegionsOfInterest` must contain at least one enabled ROI (validated in `ValidateROIControl`).
|
||||
- ROI suffixes must be unique (validated by checking `GroupBy(roi => roi.Suffix).Count() == RegionsOfInterest.Count`).
|
||||
- For enabled ROIs: `Start < End` (errors added if `Start == End` or `Start > End`).
|
||||
- For enabled ROIs in non-hybrid modes:
|
||||
- **Circular buffer modes**: ROI duration (`|End - Start|`) ≤ `PreTriggerSeconds + PostTriggerSeconds`.
|
||||
- **Circular buffer/Active modes**: `roi.Start ≥ -PreTriggerSeconds` (start time not before data window).
|
||||
- **Recorder modes**: `roi.Start ≤ PostTriggerSeconds` (start time within data window).
|
||||
- **Active modes**: `roi.Start ≥ DataStart` (start time not before available data).
|
||||
- For multiple ROIs: Each enabled ROI must include at least one channel (`roi.ChannelIds.Any()` or `roi.ChannelNames.Contains(chanName)`).
|
||||
- All non-blank, non-digital-out channels in `_currentTestSetup` must be included in at least one enabled ROI (validated via channel lookup against ROI channel IDs/names).
|
||||
- `DataDetailsVisibility` is `Visible` only after `Initialize` completes.
|
||||
- `ChannelDetailsVisibility` is `Visible` only when `RegionsOfInterest.Count > 1`.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
- **External Libraries/Namespaces**:
|
||||
- `System`, `System.Windows`, `System.ComponentModel`, `Prism.Ioc`, `Unity` (for DI via `ContainerLocator.Container`).
|
||||
- `DTS.Common.*` (enums: `RecordingModes`, `DASFactory`, `Sensors`; interfaces: `IRegionOfInterestChannelsViewModel`, `IRegionOfInterest`, `IDownloadEvent`; classes: `TestTemplate`, `SensorConstants`, `StringResources`).
|
||||
- **Internal Dependencies**:
|
||||
- `SimpleDownloadOptions.xaml` (XAML file defining UI layout).
|
||||
- `IRegionOfInterestChannelsView`/`IRegionOfInterestChannelsViewModel` (resolved via Unity; manages channel selection UI).
|
||||
- `TestTemplate` (used for channel/ROI validation and hardware lookup).
|
||||
- `IDASHardware` (used to compute sample rate and filter DAS units).
|
||||
- **Consumers**:
|
||||
- Likely consumed by a parent wizard/page (via `SetParent(object o)` and `StartSearch(string term)`).
|
||||
- `ValidatePage` is called by a higher-level validator (e.g., download wizard step).
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
- **Channel ID vs. Channel Name Fallback**: For multiple ROIs, validation checks `ChannelIds` first; if `null`/empty, falls back to `ChannelNames` (legacy DB compatibility). This is explicitly commented (see code comments referencing issues #13914, #14060, #30129).
|
||||
- **Sample Rate Aggregation**: `SampleRateAggregate` is set to `NaN` if *any* DAS unit has a different sample rate (not just "care about sample rate" units). The loop skips units where `!d.CareAboutSampleRate`, but if *all* units are skipped, `SampleRateAggregate` remains the first DAS’s rate (potentially misleading).
|
||||
- **ROI Channel Validation Logic**:
|
||||
- For multiple ROIs, channel validation assumes *all* channels must be covered *across* ROIs (not per-ROI).
|
||||
- Special handling for TSR AIR and voltage insertion channels (e.g., stripping `Assigned by ID` prefix, parent DAS name).
|
||||
- **Event Length Population**: `eventLengthByIndex` uses 0-based indexing (`downloadEvent.EventNumber - 1`), but event numbers are typically 1-based.
|
||||
- **Thread Safety**: `SetEnabled` uses `Dispatcher` for thread safety, but other properties (e.g., `RegionsOfInterest`) are modified directly without thread checks.
|
||||
- **Hardcoded Default**: `RecordingMode` resets to `CircularBuffer` in `ClearView()` (not configurable).
|
||||
- **Expander Height Management**: `GridLengthConverter` is used to set row heights for ROI/event expanders (hardcoded `"4*"`/`"Auto"`), which may conflict with layout changes in XAML.
|
||||
- **No-Op in `SetEnabled`**: If `CurrentUser` is null, `SetEnabled` silently returns without setting `IsEnabled`.
|
||||
@@ -0,0 +1,199 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorCS3ImportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorTDMCSVImportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorToyotaImportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorEQXImportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorTHFDatabaseFileImportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SIFImportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorMODSensorFileImportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorXMLImportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/BoolConditionalEditor.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/DoubleConditionalEditor.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/StringConditionalEditor.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/ModelDataBaseControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/BulkEdit.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/ParseImportFactory.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorCSVImportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/IFilterConditionalEditor.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/ImportSensorModelsControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SampleRateAAFilterLookup.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/TDCSensorDatabaseImportOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/OverdueSensorsTable.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorTestHistoryControl.xaml.cs
|
||||
generated_at: "2026-04-16T04:15:55.731308+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "fe23843a879bcc68"
|
||||
---
|
||||
|
||||
# Sensor Import Options Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides UI controls for configuring import options for various sensor data formats (CSV, TDM, XML, EQX, Toyota, THF database, MOD sensor files, SIF) within the DataPRO application. Each control encapsulates format-specific import settings and exposes them via a `CurrentOptions` property for binding to the underlying import logic. The module also includes supporting UI components for conditional editing of property values (e.g., handling mixed values across multiple sensors) and utility classes for import parsing and sample rate filtering lookups. It serves as the presentation layer for sensor import configuration, bridging user input to the `DTS.Common.Import` infrastructure.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Sensor Import Option Controls (All implement `INotifyPropertyChanged`)
|
||||
|
||||
All controls share the same pattern: they instantiate a private `ImportOptions` object and expose it via a `CurrentOptions` property. They inherit from `UserControl`.
|
||||
|
||||
- **`SensorCSVImportOptions`** (`DataPROWin7.Controls`)
|
||||
- `public ImportSensorsOptionsControl.CSVImportOptions CurrentOptions { get; set; }`
|
||||
- Exposes CSV-specific import options (e.g., encoding, field separator, included columns). Includes event handlers for `btnInclude_Click`, `btnRemove_Click`, and `btnRemoveAll_Click` to manage included columns via list views (`lvAvailable`, `lvIncluded`).
|
||||
|
||||
- **`SensorTDMCSVImportOptions`** (`DataPROWin7.Controls`)
|
||||
- `public ImportSensorsOptionsControl.TDMCSVImportOptions CurrentOptions { get; set; }`
|
||||
- Exposes TDM CSV-specific import options.
|
||||
|
||||
- **`SensorToyotaImportOptions`** (`DataPROWin7.Controls`)
|
||||
- `public ImportSensorsOptionsControl.ToyotaImportOptions CurrentOptions { get; set; }`
|
||||
- Exposes Toyota-specific import options.
|
||||
|
||||
- **`SensorEQXImportOptions`** (`DataPROWin7.Controls`)
|
||||
- `public ImportSensorsOptionsControl.EQXImportOptions CurrentOptions { get; set; }`
|
||||
- Exposes EQX-specific import options.
|
||||
|
||||
- **`SensorTHFDatabaseFileImportOptions`** (`DataPROWin7.Controls`)
|
||||
- `public ImportSensorsOptionsControl.THFDatabaseImportOptions CurrentOptions { get; set; }`
|
||||
- Exposes THF database file-specific import options.
|
||||
|
||||
- **`SensorMODSensorFileImportOptions`** (`DataPROWin7.Controls`)
|
||||
- `public ImportSensorsOptionsControl.MODFileImportOptions CurrentOptions { get; set; }`
|
||||
- Exposes MOD sensor file-specific import options.
|
||||
|
||||
- **`SensorXMLImportOptions`** (`DataPROWin7.Controls`)
|
||||
- `public ImportSensorsOptionsControl.XMLImportOptions CurrentOptions { get; set; }`
|
||||
- Exposes XML-specific import options.
|
||||
- `public void Update()`
|
||||
- Updates the `UseSensorFirstUseDate` setting from `Common.SerializedSettings` and toggles the visibility of `PanelSensorFirstUseDate` based on this value.
|
||||
|
||||
- **`TDCSensorDatabaseImportOptions`** (`DataPROWin7.Controls.Sensors_and_models`)
|
||||
- `public ImportSensorsOptionsControl.TDCSensorDatabaseImportOptions CurrentOptions { get; set; }`
|
||||
- Exposes TDC Sensor Database-specific import options.
|
||||
- `public CultureHelper[] AvailableImportCultures { get; }`
|
||||
- Returns an alphabetically sorted array of `CultureHelper` objects representing all available system cultures.
|
||||
- `public bool StripBackslash { get; set; }`
|
||||
- Gets/sets the `TDCSensorImportStripBackSlash` setting from `Properties.Settings.Default`, which controls whether TDC serial numbers are sanitized (removes backslashes). Updates `_ImportOption.StripBackSlash` when set.
|
||||
- `public CultureHelper SelectedImportCulture { get; set; }`
|
||||
- Gets/sets the selected culture for import. Setting updates `_ImportOption.ImportCulture`.
|
||||
|
||||
- **`SIFImportOptions`** (`DataPROWin7.Controls.Sensors_and_models`)
|
||||
- `public ImportSensorsOptionsControl.SIFSensorDatabaseImportOptions CurrentOptions { get; set; }`
|
||||
- Exposes SIF Sensor Database-specific import options.
|
||||
- `public enum Tags { CurrentOptions }`
|
||||
- Used for property name in `SetProperty` call.
|
||||
|
||||
### Conditional Property Editors (Implement `ITypeEditor`)
|
||||
|
||||
- **`BoolConditionalEditor`** (`DataPROWin7.Controls.Sensors_and_models`)
|
||||
- `public bool? Value { get; set; }`
|
||||
- Binds to a nullable boolean property. Shows a button when `Value` is `null` (mixed state), and a checkbox otherwise. Clicking the button sets `Value` to `false` and shows the checkbox.
|
||||
|
||||
- **`DoubleConditionalEditor`** (`DataPROWin7.Controls.Sensors_and_models`)
|
||||
- `public double? Value { get; set; }`
|
||||
- Binds to a nullable double property. Shows a button when `Value` is `null` (mixed state), and a text box otherwise. Clicking the button sets `Value` to `0D` and shows the text box.
|
||||
|
||||
- **`StringConditionalEditor`** (`DataPROWin7.Controls.Sensors_and_models`)
|
||||
- `public string Value { get; set; }`
|
||||
- Binds to a string property. Shows a button when `Value` is `null` (mixed state), and a text box otherwise. Clicking the button sets `Value` to `string.Empty` and shows the text box.
|
||||
|
||||
- **`IFilterConditionalEditor`** (`DataPROWin7.Controls.Sensors_and_models`)
|
||||
- `public IFilterClass Value { get; set; }`
|
||||
- Binds to an `IFilterClass` property. Shows a button when `Value` is `null` (mixed state), and a combo box otherwise. Clicking the button sets `Value` to the first filter class (`FilterClassType.None`) and shows the combo box.
|
||||
- `public IFilterClass[] AllFilterClasses { get; }`
|
||||
- Returns a fixed array of `IFilterClass` instances: `None`, `Unfiltered`, `CFC10`, `CFC60`, `CFC180`, `CFC1000`.
|
||||
|
||||
### Supporting Controls & Utilities
|
||||
|
||||
- **`ImportSensorModelsControl`** (`DataPROWin7.Controls`)
|
||||
- `public ImportSensorModelsControl(DataPROPage parentPage)`
|
||||
- Constructor that initializes a `SensorModelsControl` and sets up a file browser button (`btnBrowse_Click`) to select files (`.e2x`, `.sif`, `Model.SensorDB.xml`, or all files) for sensor model import. Updates the sensor model list after selection.
|
||||
|
||||
- **`ParseImportFactory`** (`DataPROWin7.Controls.Sensors_and_models`)
|
||||
- `public static IParseImport CreateParseImport(ImportSensorsPage.SupportedExportFormats importFormat, IImportNotification importNotification, User currentUser, ImportSensorsOptionsControl.ImportOptions importOptions)`
|
||||
- Factory method that creates an `IParseImport` instance based on the `importFormat`. Currently supports `EQX` and `CSV`/`TDCSensorDatabase` formats. Maps `ImportSensorsOptionsControl.*ImportOptions` to `DTS.Common.Import.*ImportOptions` and instantiates the appropriate parser (`EQXSensorsParser`, `DTSCSVSensorsParser`), setting `ImportCreateDynamicGroups = true`.
|
||||
|
||||
- **`SampleRateAAFilterLookup`**
|
||||
- `public SampleRateAAFilterLookup()`
|
||||
- Constructor that builds a lookup dictionary mapping `SerializableAAF.DAS_TYPE` and sample rate (`uint`) to anti-aliasing filter value (`float`). Throws `Exception` if `Common.SerializedSettings.AvailableSampleRates` is empty.
|
||||
- `public bool ContainsKey(SerializableAAF.DAS_TYPE dasType, uint sr)`
|
||||
- `public bool ContainsKey(IDASCommunication das, uint sr)`
|
||||
- Checks if a sample rate exists for a given DAS type.
|
||||
- `public uint GetClosestKey(SerializableAAF.DAS_TYPE dasType, uint sr)`
|
||||
- `public uint GetClosestKey(IDASCommunication das, uint sr)`
|
||||
- Returns the smallest sample rate in the lookup that is ≥ `sr`, or the maximum available rate if `sr` exceeds all keys.
|
||||
- `public float GetExact(SerializableAAF.DAS_TYPE dasType, uint sr)`
|
||||
- `public float GetExact(IDASCommunication das, uint sr)`
|
||||
- Returns the AA filter value for the exact sample rate. Throws `KeyNotFoundException` if not found.
|
||||
|
||||
- **`OverdueSensorsTable`** (`DataPROWin7.Controls`)
|
||||
- `public enum TableColumns { TestObject, SerialNumber, Description, CalInterval, CalDate, CalDueDate, DataObject, Message }`
|
||||
- `public const string MyTableId = "OverdueSensorsTable"`
|
||||
- `public class OverdueSensorHelper { public SensorData Sensor { get; set; }; public SensorCalibration Calibration { get; set; }; public IGroup Group { get; set; }; public string Excitation { get; set; } }`
|
||||
- `public System.Windows.Visibility UpdateTable(OverdueSensorHelper[] entries)`
|
||||
- Populates the table with overdue sensors based on calibration policy. Sets visibility to `Visible` if rows exist, `Collapsed` otherwise.
|
||||
|
||||
- **`SensorTestHistoryControl`** (`DataPROWin7.Controls`)
|
||||
- `public DTS.Common.Storage.SensorTestHistory[] Histories { get; set; }`
|
||||
- `public void DisplaySensorTestHistory(string serialNumber)`
|
||||
- Fetches test history for a given serial number and updates the `Histories` property.
|
||||
- `public void OnSetActive()`
|
||||
- Dynamically adjusts grid columns based on `Common.SerializedSettings.ISOViewMode` (ISOOnly, ISOAndUserCode, UserCodeOnly, ChannelNameOnly).
|
||||
- `public string ExportFilePath { get; set; }`
|
||||
- Path for exporting test history to XML.
|
||||
- `public void btnExport_Click(...)`
|
||||
- Serializes `Histories` to XML and writes to `ExportFilePath`. Reports errors if path is empty or `Histories` is null/empty.
|
||||
|
||||
### Shared Helper Methods (in all `*ImportOptions` controls)
|
||||
|
||||
- `protected bool SetProperty<T>(ref T storage, T value, String propertyName = null)`
|
||||
- Implements `INotifyPropertyChanged`. Updates `storage` if `value` differs, raises `PropertyChanged`, and returns `true` if changed.
|
||||
- `protected void OnPropertyChanged(string propertyName = null)`
|
||||
- Raises the `PropertyChanged` event.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`CurrentOptions` Initialization**: Each `*ImportOptions` control initializes its private `_*ImportOption` field with a new instance of the corresponding `ImportSensorsOptionsControl.*ImportOptions` type in the field declaration. The `CurrentOptions` property setter uses `SetProperty`, ensuring `INotifyPropertyChanged` is raised only on actual change.
|
||||
- **`INotifyPropertyChanged` Implementation**: All controls implement `INotifyPropertyChanged` with consistent `SetProperty` and `OnPropertyChanged` methods. Property names passed to `SetProperty` are hardcoded strings (e.g., `"CurrentOptions"`, `"SensorAggregate"`).
|
||||
- **Conditional Editor State**: For `*ConditionalEditor` controls, `Value` being `null` (or `null`/`empty` for strings) implies a "mixed" state across multiple sensors, triggering display of a button. A non-null `Value` implies a uniform value, triggering display of the editor control (checkbox, text box, combo box).
|
||||
- **`SampleRateAAFilterLookup` Data Dependency**: The lookup table is built once during construction from `Common.SerializedSettings.AvailableSampleRates` and `Common.SerializedSettings.GetAAFException(...)`. If `AvailableSampleRates` is empty, the constructor throws an exception.
|
||||
- **`StripBackslash` Persistence**: The `StripBackslash` property in `TDCSensorDatabaseImportOptions` directly reads/writes to `Properties.Settings.Default.TDCSensorImportStripBackSlash`, ensuring persistence across sessions.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Dependencies (from imports/includes)
|
||||
- **WPF Framework**: `System.Windows`, `System.Windows.Controls`, `System.Windows.Data`, `System.Windows.Input`, `System.Windows.Media`, `System.Windows.Shapes`, `System.ComponentModel`.
|
||||
- **Xceed WPF Toolkit**: `Xceed.Wpf.Toolkit.PropertyGrid.Editors` (for `ITypeEditor` interface).
|
||||
- **DTS Common Libraries**:
|
||||
- `DTS.Common.Import`, `DTS.Common.Import.Interfaces`, `DTS.Common.Import.ImportOptions`, `DTS.Common.Import.Parsers` (for `IParseImport`, `IParseVariant`, import options, and parsers).
|
||||
- `DTS.Common.Interface.Sensors` (`ISensorAggregate`, `ISensor` implied via `SensorData`, `SensorCalibration`).
|
||||
- `DTS.Common.Classes.Sensors`, `DTS.Common.Enums.Sensors`, `DTS.Common.Interface.Sensors.SoftwareFilters` (`IFilterClass`, `FilterClass`, `FilterClassType`).
|
||||
- `DTS.Slice.Users` (`User`).
|
||||
- `DTS.Common.SharedResource.Strings` (for localized strings like `StringResources.ImportSensors_SelectFile`).
|
||||
- `DTS.SensorDB` (`SensorData`, `SensorCalibration`, `CalibrationPolicy`).
|
||||
- `DTS.Common.Storage` (`SensorTestHistory`).
|
||||
- `DTS.Common.Enums.Hardware`, `DTS.Common.Interface.DASFactory` (`IDASCommunication`, `SerializableAAF.DAS_TYPE`).
|
||||
- `DTS.Common.Utilities.Logging` (`APILogger`).
|
||||
- `DTS.Common.Utilities.DotNetProgrammingConstructs` (used in `BoolConditionalEditor`).
|
||||
- **System Libraries**: `System.IO`, `System.Collections.Generic`, `System.Linq`, `System.Globalization`.
|
||||
|
||||
### Internal Dependencies
|
||||
- **`ImportSensorsOptionsControl` namespace**: All controls depend on types in this namespace (e.g., `CSVImportOptions`, `EQXImportOptions`, `TDCSensorDatabaseImportOptions`). This namespace is not included in the provided source files, so its structure is inferred.
|
||||
- **`Common.SerializedSettings`**: Used by `SensorXMLImportOptions.Update()` and `SampleRateAAFilterLookup` constructor.
|
||||
- **`Properties.Settings.Default`**: Used by `TDCSensorDatabaseImportOptions.StripBackslash`.
|
||||
- **`DataPROPage`**: Passed to constructors of `ImportSensorModelsControl`, `ModelDatabaseControl`, `BulkEdit`, `SensorTestHistoryControl`. Used for error reporting (`_page.ReportErrors`).
|
||||
- **`IPageContent` interface**: Implemented by several controls (`ImportSensorModelsControl`, `ModelDatabaseControl`, `BulkEdit`, `SensorTestHistoryControl`, `OverdueSensorsTable`) to integrate with the application's page management system.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Inconsistent Namespace**: Most controls are in `DataPROWin7.Controls`, but `SIFImportOptions` and conditional editors are in `DataPROWin7.Controls.Sensors_and_models`. This may cause confusion.
|
||||
- **`SIFImportOptions` Property Name**: Uses `Tags.CurrentOptions.ToString()` instead of a hardcoded string `"CurrentOptions"` in `SetProperty`, which is correct but unusual. If `Tags.CurrentOptions` changes, the property name changes.
|
||||
- **`SensorXMLImportOptions.Update()`**: The method name `Update()` is generic and non-descriptive. The comment "try to update the visibility of the first use panel ... nothings worked so far ..." suggests potential UI binding issues or incomplete implementation.
|
||||
- **`TDCSensorDatabaseImportOptions` Constructor**: Calls `OnPropertyChanged` for `"AvailableImportCultures"` and `"SelectedImportCulture"` in the constructor, but these properties are not auto-wired to the UI via binding in the provided code. This may be redundant or indicate missing XAML binding setup.
|
||||
- **`SampleRateAAFilterLookup.GetClosestKey` Behavior**: Returns the *smallest* key ≥ `sr`, not necessarily the closest numerically (e.g., for `sr=1024` and keys `[1000, 2000]`, returns `2000`, not `1000`). The docstring says "next largest", which is correct, but the name `GetClosestKey` is misleading.
|
||||
- **`ParseImportFactory` Limitations**: Only handles `EQX` and `CSV`/`TDCSensorDatabase` formats. Other formats (e.g., `TDM`, `Toyota`, `THF`, `MOD`, `XML`) are not yet connected to the import pipeline, despite having dedicated option controls.
|
||||
- **`BulkEdit` Constructor Overload**: Has two constructors: `internal BulkEdit()` and `public BulkEdit(DataPROPage page)`. The `internal` one is unused in the provided code and does not initialize `_parentPage` (though it's not used in the `IPageContent` methods shown).
|
||||
- **`SensorTestHistoryControl.OnSetActive()` Column Index**: Uses a hardcoded `ISOChannelColumnIndex = 11`. This is fragile if column order changes.
|
||||
- **`ImportSensorModelsControl.btnBrowse_Click`**: Uses `ofd.SafeFileNames` to set `tbName.Text`, but then calls `_sensorModelsControl.UpdateList(DTS.SensorDB.SensorModelCollection.SensorModelList.SensorModels)`, which updates the *entire* sensor model list, not just the imported file(s). This may be unintended behavior.
|
||||
@@ -0,0 +1,191 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/Classes/SensorDatabaseLocking.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/Classes/EQXImporter.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/Classes/CSVImporter.cs
|
||||
generated_at: "2026-04-16T04:18:17.888000+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "7b207c4747848a1f"
|
||||
---
|
||||
|
||||
# Documentation: Sensor Import and Locking Module
|
||||
|
||||
---
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides two core functionalities:
|
||||
- **Sensor import handling** for EQX (XML-based equipment exchange) and CSV (TDC database format) files via concrete subclasses of the abstract base `SensorTestSetupImporter`. These classes parse sensor metadata, calibration data, and test setup configuration from external files into in-memory data models (`SensorData`, `SensorCalibration`, `TestSetupImportData`) for use in DataPRO’s import workflows.
|
||||
- **Lock management coordination** for sensor database operations via `SensorDatabaseLocking`, a helper class that encapsulates interaction with `LockManager` and maintains a local cache of lock records to support thread-safe tracking and lifecycle management (e.g., update, free) of locks held by the current UI session.
|
||||
|
||||
The module exists to decouple import logic and locking concerns from UI controls (`SensorDatabaseControl`) and centralize cross-cutting behavior such as version validation, error reporting, and lock state synchronization.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `SensorDatabaseLocking` (internal class)
|
||||
|
||||
#### `static bool LockItem(string serialNumber, int databaseId, string userName, int userId, out LockRecord lockRecord, out LockError lockError)`
|
||||
Attempts to acquire a lock on a sensor item via `LockManager.LockItem`. Returns `true` on success, `false` otherwise. Populates `lockRecord` and `lockError` on return.
|
||||
|
||||
#### `void SetLockedItems(LockRecord[] locks)`
|
||||
Atomically replaces the internal `_existingLocks` array with the provided array. Thread-safe via `MyLock`.
|
||||
|
||||
#### `static bool IsExpiredLock(LockRecord lockRecord, string userName, string machineName)`
|
||||
Returns `true` if the lock is expired (based on `StrandedLockTimeoutMinutes` setting) **or** if the lock is owned by the current user and machine. Otherwise `false`.
|
||||
|
||||
#### `bool HasAnyLocks()`
|
||||
Returns `true` if `_existingLocks` is non-null and contains at least one record. Thread-safe.
|
||||
|
||||
#### `bool UpdateLocks(string userName, int userId, out LockError[] lockErrors, out LockRecord[] failingLocks)`
|
||||
Copies `_existingLocks`, then attempts to update each lock via `LockManager.UpdateLock`. Returns `true` only if *all* updates succeed. On failure, `lockErrors` and `failingLocks` contain corresponding error and record arrays.
|
||||
|
||||
#### `bool IsLocked(LockRecord lockRecord)`
|
||||
Returns `true` if `_existingLocks` contains a record with matching `ItemId` and `ItemCategory`. Thread-safe.
|
||||
|
||||
#### `void FreeLocks(string userName, int userId)`
|
||||
Copies and clears `_existingLocks`, then calls `LockManager.FreeLock` for each record. Exceptions during freeing are logged via `APILogger.Log`. Thread-safe.
|
||||
|
||||
#### `LockRecord[] GetLockRecords()`
|
||||
Returns a **copy** of `_existingLocks` (never `null`). Thread-safe.
|
||||
|
||||
---
|
||||
|
||||
### `EQXImporter` (internal class, inherits `SensorTestSetupImporter`)
|
||||
|
||||
#### Constructor overloads
|
||||
Two public constructors accept varying parameter sets (dictionary vs list-based lookups, custom channel/group templates, etc.), delegating to `base(...)`.
|
||||
|
||||
#### `protected override ImportSensorsOptionsControl.ImportOptions Options { get; set; }`
|
||||
Returns/sets an `EQXImportOptions` instance. Defaults to `new EQXImportOptions()` if unset.
|
||||
|
||||
#### `protected override TestSetupImportData ParseTestSetup(string filename)`
|
||||
Returns a `TestSetupImportData` populated with default settings (`DefaultPreTriggerSeconds`, `DefaultPostTriggerSeconds`, etc.). Does **not** parse file content—intended for future extension.
|
||||
|
||||
#### `protected override SensorImportData ParseSensor(string filename)`
|
||||
Parses an EQX XML file:
|
||||
- Validates `DataFormatEdition` ≤ `MAX_EQX_VERSION_SUPPORT` (1.5F).
|
||||
- Instantiates `EquipmentExchange.EQXSensorDatabase`, reads file, and retrieves sensors/calibrations.
|
||||
- Handles `IDModuleString` null case (preserves existing EID).
|
||||
- Populates `_sensorLookup`, `_calibrationLookup`, `_sensorList`, `_sensorChannelCodeDictionary`, `_calibrationList` for `ImportPageType.ImportTestSetup`.
|
||||
- For `ImportPageType.ImportSensor`, creates models via `FactorySensorModel.CreateModelFromSensor`.
|
||||
- Reports excitation errors via `GetExcitationErrors()` and publishes `PageErrorEvent`.
|
||||
- Returns `SensorImportData` (populated only for test setup import).
|
||||
|
||||
#### `private List<string> GetExcitationErrors()`
|
||||
Scans imported sensors for calibration/excitation mismatches. Skips digital/squib sensors. Returns list of user-friendly error strings.
|
||||
|
||||
---
|
||||
|
||||
### `CSVImporter` (public class, inherits `SensorTestSetupImporter`)
|
||||
|
||||
#### Constructor overloads
|
||||
Two public constructors initialize `_calibrationImport` and `_importNotification`. Delegates to `base(...)`.
|
||||
|
||||
#### `protected override ImportSensorsOptionsControl.ImportOptions Options { get; set; }`
|
||||
Returns/sets a `TDCSensorDatabaseImportOptions` instance. Defaults to `new TDCSensorDatabaseImportOptions()`.
|
||||
|
||||
#### `protected override TestSetupImportData ParseTestSetup(string filename)`
|
||||
Parses CSV header to extract version and test setup metadata (sample rate, recording mode, etc.) using `CSVTestParserFactory` and version-specific parsers.
|
||||
|
||||
#### `protected override SensorImportData ParseSensor(string filename)`
|
||||
Parses CSV file line-by-line:
|
||||
- Detects version (6 or older) and skips header rows appropriately.
|
||||
- Maps columns to `CSVImportTags.Tags` and uses `CSVSensorParserFactory` to populate `SensorData`/`SensorCalibration`.
|
||||
- Fixes sensitivity units (`mVperVperEU` → `mVperEU`) for non-proportional calibrations.
|
||||
- Updates `_sensorLookup`, `_calibrationLookup`, `_sensorList`, etc., based on import type.
|
||||
- Validates sensitivity, capacity, and excitation; adds warnings/errors to `_allErrors`.
|
||||
- Returns `SensorImportData` with lookup dictionaries (group names, ISO codes, DAS mappings).
|
||||
|
||||
#### `private void Parse(CSVImportTags.Tags tag, string sValue, ParseParameters pp, IReadOnlyDictionary<int, IParseCSVSensor> parsers)`
|
||||
Dispatches parsing to version-specific parser.
|
||||
|
||||
#### `private void PreParse(ParseParameters pp)`
|
||||
Initializes sensor defaults (squib, digital out) via `SensorData.Initialize(...)`.
|
||||
|
||||
#### `private void PostParse(ParseParameters pp)`
|
||||
Finalizes calibration:
|
||||
- Sets sensitivity, excitation, nonlinearity (IRTracc-specific logic).
|
||||
- Applies zero method, initial offset.
|
||||
- Validates sensitivity ≠ 0, capacity ≥ 1, and excitation ≠ `Undefined` for analog bridges.
|
||||
- Clears errors for ISO-only channels.
|
||||
|
||||
#### `private bool PopulateSensor(IReadOnlyList<CSVImportTags.Tags> columns, string[] tokens, DateTime fileDateTime, ParseParameters pp)`
|
||||
Drives parsing: calls `PreParse`, loops over columns calling `Parse`, then `PostParse`. Returns `true` only if no errors occurred.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`SensorDatabaseLocking`**
|
||||
- `_existingLocks` is always `null` or a non-null array. `HasAnyLocks()` and `IsLocked(...)` rely on this.
|
||||
- All access to `_existingLocks` is guarded by `MyLock` (a `private static readonly object`).
|
||||
- `IsExpiredLock` uses `DateTime.Now` and `StrandedLockTimeoutMinutes` setting; no external state mutates this logic.
|
||||
- `FreeLocks` clears `_existingLocks` *before* calling `LockManager.FreeLock`, ensuring no reentrancy issues.
|
||||
|
||||
- **`EQXImporter`**
|
||||
- `_db` is initialized only once per `ParseSensor` call.
|
||||
- `MAX_EQX_VERSION_SUPPORT` is fixed at `1.5F`; version > 1.5 aborts import.
|
||||
- Sensor EID is preserved only if `SensorHasNullIDModule` returns `true` *and* a matching sensor exists in `SensorsCollection.SensorsList`.
|
||||
- Excitation error reporting is unconditional if `_db` is non-null and sensors exist.
|
||||
|
||||
- **`CSVImporter`**
|
||||
- Sensitivity unit correction (`mVperVperEU` → `mVperEU`) applies only to non-proportional calibrations.
|
||||
- Version 6 CSVs skip header rows until a recognized tag with version ≤ 4 is found.
|
||||
- `PopulateSensor` returns `false` if any exception occurs during parsing.
|
||||
- ISO-only channels (`ISO_CH_ONLY_PREFIX`) bypass sensitivity/capacity/excitation validation.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### `SensorDatabaseLocking`
|
||||
- **Depends on**:
|
||||
- `DTS.Common.Classes.Locking.LockManager` (for `LockItem`, `UpdateLock`, `FreeLock`).
|
||||
- `DTS.Common.Storage.LockRecord`, `LockError` types.
|
||||
- `DTS.Common.Utilities.Logging.APILogger` (indirectly via `SensorDatabaseControl` usage).
|
||||
- **Used by**: `SensorDatabaseControl` (per comments in source).
|
||||
|
||||
### `EQXImporter`
|
||||
- **Depends on**:
|
||||
- `DTS.SensorDB.EquipmentExchange.EQXSensorDatabase` (for reading EQX files).
|
||||
- `DTS.SensorDB.SensorData`, `SensorCalibration`.
|
||||
- `DTS.Common.Enums.Sensors.SensorConstants`, `BridgeType`, `ExcitationVoltageOptions`.
|
||||
- `DTS.Common.SharedResource.Strings.StringResources` (for error messages).
|
||||
- `Prism.Ioc.IContainerLocator`, `Prism.Events.IEventAggregator`, `PageErrorEvent`.
|
||||
- `DataPROWin7.DataModel.SensorsCollection`, `TestTemplate`, `TestObject`, `FactorySensorModel`.
|
||||
- `Properties.Settings.Default` (for `UsemVOverVForPolys`, `EQXUseSerialNumberFieldForSN`, etc.).
|
||||
- **Used by**: Import pipeline (via `SensorTestSetupImporter` base class).
|
||||
|
||||
### `CSVImporter`
|
||||
- **Depends on**:
|
||||
- `DTS.Common.Import.Factories.CSVTestParserFactory`, `CSVSensorParserFactory`.
|
||||
- `DTS.Common.Import.Interfaces.IParseCSVSensor`, `IParseCSVTSetup`.
|
||||
- `DTS.Common.Import.ImportOptions.CalibrationImport`, `ImportNotification`.
|
||||
- `DTS.Common.Classes.Sensors.CsvUtil`, `CSVImportTags`.
|
||||
- `DTS.Common.DataModel.TestObjectTemplate`, `MME*` types (for test setup compatibility).
|
||||
- `DTS.Common.Enums.Sensors.SensorConstants`, `ISO_CH_ONLY_PREFIX`.
|
||||
- `Properties.Settings.Default.UseZeroForUnfiltered`.
|
||||
- **Used by**: Import pipeline (via `SensorTestSetupImporter` base class).
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`SensorDatabaseLocking`**
|
||||
- `IsExpiredLock` uses *local* `userName`/`machineName` to determine ownership; assumes caller provides correct values.
|
||||
- `FreeLocks` swallows exceptions (logs only); no retry or rollback on partial failure.
|
||||
- `GetLockRecords()` returns a copy (`ToArray()`), but callers must avoid mutating the returned array.
|
||||
|
||||
- **`EQXImporter`**
|
||||
- `ParseTestSetup` does **not** parse file content—returns defaults only. This may be incomplete or misleading.
|
||||
- Excitation error reporting uses `sd.SupportedExcitation.Contains(cal.Records.Records[0].Excitation)`; if `SupportedExcitation` is empty, calibration is treated as invalid.
|
||||
- `MAX_EQX_VERSION_SUPPORT` is hardcoded; no runtime extensibility.
|
||||
|
||||
- **`CSVImporter`**
|
||||
- Sensitivity unit correction (`mVperVperEU` → `mVperEU`) is applied *after* parsing but *before* adding to lookup dictionaries; this may cause inconsistency if callers expect original units.
|
||||
- Version 6 CSV parsing skips rows until a tag with `version ≤ 4` is found; malformed headers may cause silent data loss.
|
||||
- `PopulateSensor` catches exceptions during `Parse(...)` and returns `false`, but does not log the exception (only via `APILogger.Log` in `Parse`’s catch block).
|
||||
- ISO-only channels bypass validation, but `ISO_CH_ONLY_PREFIX` is not defined in this file (likely a static field in base class or elsewhere).
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/Interfaces/ISensorTestSetupImporter.cs
|
||||
generated_at: "2026-04-16T04:18:32.630254+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "237bcb4976683c27"
|
||||
---
|
||||
|
||||
# Interfaces
|
||||
|
||||
### 1. **Purpose**
|
||||
This module defines the `ISensorTestSetupImporter` interface, which standardizes the contract for importing sensor and model data from external test setup files (e.g., CSV, XML) into the DataPRO application. It enables decoupled, pluggable importers—each implementing the `Process` method—to handle file parsing, validation, and population of the UI’s sensor and model collections, while supporting progress reporting, status updates, error aggregation, and file-locking coordination.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `ISensorTestSetupImporter.Process`
|
||||
```csharp
|
||||
void Process(
|
||||
SetStatusTextDelegate SetStatus,
|
||||
SetProgressValueDelegate SetProgressValue,
|
||||
AddSensorDelegate AddSensor,
|
||||
AddModelDelegate AddModel,
|
||||
Action<List<string>> ReportErrors,
|
||||
ImportDoneDelegate MarkDone,
|
||||
ref Tuple<bool, string> fileInUse);
|
||||
```
|
||||
**Behavior**: Executes the import logic for a sensor/model test setup file. The method is *not* responsible for file selection or I/O—it receives delegates for all required UI and data operations. It must:
|
||||
- Use `SetStatus` to update status messages (e.g., "Parsing file...", "Validating entries...").
|
||||
- Use `SetProgressValue` to report progress (presumably as a percentage or step count).
|
||||
- Use `AddSensor` and `AddModel` to register parsed sensor/model entries.
|
||||
- Use `ReportErrors` to report a list of non-fatal validation or parsing errors.
|
||||
- Use `MarkDone` to signal completion (success or failure).
|
||||
- Check and update the `fileInUse` tuple to coordinate exclusive file access (e.g., if the file is locked by another process).
|
||||
|
||||
> **Note**: The `fileInUse` parameter is passed by reference and is a `Tuple<bool, string>` where:
|
||||
> - `Item1` (`bool`) indicates whether the file is currently in use (`true`) or available (`false`).
|
||||
> - `Item2` (`string`) provides a human-readable explanation (e.g., "File is open in Excel").
|
||||
> Implementations must set `fileInUse.Item1 = true` if they detect the file is locked, and populate `Item2` accordingly.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
- The `Process` method **must not throw unhandled exceptions**; errors must be reported via `ReportErrors` or by setting `fileInUse.Item1 = true` where applicable.
|
||||
- `MarkDone` **must be called exactly once** per successful invocation of `Process`, regardless of outcome (success, partial failure, or cancellation).
|
||||
- `ReportErrors` may be called zero or more times with a non-null `List<string>`; implementations should accumulate errors and invoke it once (or multiple times) with all relevant messages.
|
||||
- `fileInUse` must be checked *before* attempting file I/O and updated *during* processing if the lock status changes.
|
||||
- All delegate calls (`SetStatus`, `SetProgressValue`, `AddSensor`, `AddModel`, `ReportErrors`, `MarkDone`) are invoked on the UI thread (implied by `SetStatusTextDelegate`/`SetProgressValueDelegate` naming and typical WinForms patterns).
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
**Depends on**:
|
||||
- `System` (core types).
|
||||
- `DataPROWin7.Controls.ImportSensorsPreviewControl` (for delegate types: `SetStatusTextDelegate`, `SetProgressValueDelegate`, `AddSensorDelegate`, `AddModelDelegate`, `ImportDoneDelegate`).
|
||||
- *Note*: The actual delegate signatures are not provided in this file; they must be resolved in `ImportSensorsPreviewControl.cs`.
|
||||
|
||||
**Is depended upon by**:
|
||||
- Any UI component or service that orchestrates sensor/model import (e.g., a dialog or command handler that instantiates and invokes an `ISensorTestSetupImporter` implementation).
|
||||
- Likely used by `ImportSensorsPreviewControl` or similar (inferred from namespace and delegate usage).
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
- **Delegate ownership**: The interface does not specify *who* owns the delegates (e.g., whether `AddSensor`/`AddModel` are thread-safe or require UI-thread marshaling). Since they are named with `Delegate` suffix and used in a WinForms context, they likely marshal to the UI thread internally—but implementations should assume they are *not* thread-safe unless confirmed.
|
||||
- **`fileInUse` semantics**: The `ref Tuple<bool, string>` pattern is unusual for modern C# (tuples are typically value types, but `Tuple<T1,T2>` is a reference type). Implementations must mutate the *same instance* of the tuple (not reassign the variable), as the caller expects the original tuple to be updated.
|
||||
- **No cancellation support**: There is no `CancellationToken` parameter; long-running imports cannot be gracefully interrupted.
|
||||
- **No return value**: The interface provides no way to programmatically determine success/failure beyond `MarkDone` semantics (which are not defined here). Implementations must rely on convention (e.g., `MarkDone(true)` vs `MarkDone(false)`), but the signature of `ImportDoneDelegate` is unknown.
|
||||
- **Historical quirks**: The interface name `ISensorTestSetupImporter` and the comment `//FB 30357 Interface with one template method Process` suggest legacy or framework-specific naming (possibly tied to a bug/feature tracker). The "template method" reference is misleading—this is a *callback-based* interface, not a template method pattern in the GoF sense.
|
||||
|
||||
> **None identified from source alone** regarding delegate signatures or `ImportDoneDelegate` behavior—these require inspection of `ImportSensorsPreviewControl.cs`.
|
||||
@@ -0,0 +1,162 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorInputControls/EditStreamInputControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorInputControls/SupportedExcitationControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorInputControls/EditDigitalOutputControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorInputControls/InitialOffsetControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Sensors and models/SensorInputControls/EditUartSettingsControl.xaml.cs
|
||||
generated_at: "2026-04-16T04:18:17.150077+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "fdef92daa65ab4ff"
|
||||
---
|
||||
|
||||
# SensorInputControls
|
||||
|
||||
**Documentation Page: Sensor Input Control Modules**
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
These modules (`EditStreamInputControl`, `SupportedExcitationControl`, `EditDigitalOutputControl`, `InitialOffsetControl`, `EditUartSettingsControl`) are WPF `UserControl` implementations that provide UI editing interfaces for various sensor input/output configuration properties. Each control binds to a backing data model (`SensorData` or `SensorBase`) and exposes properties for editing specific sensor attributes (e.g., UDP address, excitation voltages, digital output modes, UART settings, initial offsets). They implement `INotifyPropertyChanged` to support two-way data binding and automatically mark the parent `DataPROPage` as modified when user-editable properties change—except during initialization. They serve as the primary UI layer for configuring sensor input/output behavior in the DataPRO application.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `EditStreamInputControl`
|
||||
- **`string UDPAddress { get; set; }`**
|
||||
Gets/sets the UDP address from `_setting.StreamInUDPAddress`. Raises `PropertyChanged` for `Tags.UDPAddress` on set.
|
||||
- **`string SettingName { get; set; }`**
|
||||
Gets/sets `_setting.SerialNumber`. Raises `PropertyChanged` for `Tags.SettingName` on set.
|
||||
- **`string UserTags { get; set; }`**
|
||||
Gets comma-separated tags from `_setting.GetTagsArray(DbOperations.TagsGet)`; sets tags via `_setting.SetTags(...)`. Text change in UI triggers `MarkPageModified()` via `tbTags_TextChanged`.
|
||||
- **`bool Validate(ref List<string> errors, bool displayWindow) : bool`**
|
||||
Validates `SettingName` (non-empty) and `UDPAddress` (via `Utils.ValidateUDPAddress`). Marks UI controls as valid/invalid using `PageMainContentControl.MarkInvalid/MarkValid`. Returns `false` if validation fails.
|
||||
|
||||
#### `SupportedExcitationControl`
|
||||
- **`DTS.SensorDB.SensorBase Model { set; }`**
|
||||
Sets `_model`, initializes `_supportedExcitations` from `value.SupportedExcitation.ToList()`, and populates derived properties (`SupportedExcitation_2V`, etc.).
|
||||
- **`List<ExcitationVoltageOptions.ExcitationVoltageOption> SupportedExcitations { get; set; }`**
|
||||
Gets/sets the list of supported excitation voltages. Setting triggers updates to `SupportedExcitation_2V/5V/10V`.
|
||||
- **`bool SupportedExcitation_2V { get; set; }`**
|
||||
Gets/sets presence of 2V excitation in `_supportedExcitations`. On set, calls `UpdateList(...)`, raises `PropertyChanged`, and `NotifyExcitationChange()`.
|
||||
- **`bool SupportedExcitation_5V { get; set; }`**
|
||||
Same as above for 5V.
|
||||
- **`bool SupportedExcitation_10V { get; set; }`**
|
||||
Same as above for 10V.
|
||||
- **`private void NotifyExcitationChange()`**
|
||||
Publishes `DTS.Common.Events.Sensors.SensorsList.SensorChangedEvent` via `IEventAggregator` when any excitation option changes.
|
||||
|
||||
#### `EditDigitalOutputControl`
|
||||
- **`ModeHelper[] AvailableModes { get; }`**
|
||||
Returns array of `ModeHelper` instances for all `DigitalOutputModes` except `NONE`. `ModeHelper.ToString()` returns localized string via `StringResources`.
|
||||
- **`string SettingName { get; set; }`**
|
||||
Gets/sets `_setting.SerialNumber`. Raises `PropertyChanged` for `Tags.SettingName`.
|
||||
- **`string UserTags { get; set; }`**
|
||||
Same semantics as in `EditStreamInputControl`.
|
||||
- **`bool LimitDuration { get; set; }`**
|
||||
Gets/sets `_setting.DigitalOutputLimitDuration`. Raises `PropertyChanged` for `LimitDuration` and `DurationVisibility`.
|
||||
- **`Visibility DurationVisibility { get; }`**
|
||||
Returns `Visibility.Visible` if `LimitDuration` is `true`, else `Collapsed`.
|
||||
- **`ModeHelper SelectedMode { get; set; }`**
|
||||
Gets/sets the `ModeHelper` matching `_setting.DigitalOutputMode`. Setting updates `_setting.DigitalOutputMode`.
|
||||
- **`bool Validate(ref List<string> errors, bool displayWindow) : bool`**
|
||||
Validates only `SettingName` (non-empty). Returns `false` if invalid.
|
||||
|
||||
#### `InitialOffsetControl`
|
||||
- **`InitialOffsets InitialOffsets { get; set; }`**
|
||||
Sets `_initialOffsets`, populates `_InitialOffsetCollection` from `value.Offsets`, calls `UpdateInitialOffsetTypes()`, and raises `InitialOffsetCollection` and `CanAddInitialOffset` notifications.
|
||||
- **`InitialOffset[] InitialOffsetCollection { get; set; }`**
|
||||
Gets/sets the collection of `InitialOffset` objects. Setting clears and repopulates `_InitialOffsetCollection`.
|
||||
- **`List<InitialOffsetTypes> AvailableOffsetTypes { get; }`**
|
||||
List of offset types *not* already present in `_InitialOffsetCollection`. Updated by `UpdateInitialOffsetTypes()`.
|
||||
- **`InitialOffsetTypes SelectedOffset { get; set; }`**
|
||||
Gets/sets the currently selected offset type for adding new entries.
|
||||
- **`bool CanAddInitialOffset { get; }`**
|
||||
Returns `true` if `AvailableOffsetTypes.Any()`.
|
||||
- **`bool Validate(bool HasLinearComponent, ref List<string> warnings, ref List<string> errors, bool Valid, bool DisplayErrors) : bool`**
|
||||
Checks for duplicate offset types (adds warning) and validates `EUAtMV` only allowed when `HasLinearComponent` is `true`. Updates `InitialOffsets.Offsets` from `_InitialOffsetCollection`. If `DisplayErrors && Valid`, publishes `PageErrorEvent`; otherwise appends to `warnings`/`errors`. Always returns `true`.
|
||||
|
||||
#### `EditUartSettingsControl`
|
||||
- **`uint BaudRate { get; set; }`**
|
||||
Gets `_setting.UartBaudRate` or `BAUD_RATE_DEFAULT` if `_setting` is null. Sets only if `value <= BAUD_RATE_MAX`.
|
||||
- **`uint DataBits { get; set; }`**
|
||||
Gets `_setting.UartDataBits` or `8` if `_setting` is null. Sets `_setting.UartDataBits`.
|
||||
- **`ParityHelper SelectedParity { get; set; }`**
|
||||
Gets/sets parity matching `_setting.UartParity`. `ParityHelper.ToString()` returns localized parity name.
|
||||
- **`StopBitsHelper SelectedStopBits { get; set; }`**
|
||||
Same as `SelectedParity`, for `_setting.UartStopBits`.
|
||||
- **`HandshakeHelper SelectedFlowControl { get; set; }`**
|
||||
Always returns/sets `Handshake.None` (hardcoded in constructor).
|
||||
- **`UartDataFormatHelper SelectedUartDataFormat { get; set; }`**
|
||||
Gets/sets `_setting.UartDataFormat`. `UartDataFormatHelper.ToString()` returns localized format name.
|
||||
- **`string SettingName { get; set; }`**
|
||||
Gets/sets `_setting.SerialNumber`.
|
||||
- **`string UserTags { get; set; }`**
|
||||
Same semantics as in other controls.
|
||||
- **`bool Validate(ref List<string> errors, bool displayWindow) : bool`**
|
||||
Validates `SettingName` (non-empty) and `BaudRate` via `BaudValidator`. Adds error message if invalid.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **`Setting`/`Model` must be non-null for property getters/setters to have effect.**
|
||||
All controls guard against null `_setting`/`_model` in property accessors and validation.
|
||||
- **`Page` must be assigned before modification tracking works.**
|
||||
`MarkPageModified()` silently no-ops if `_page` is null.
|
||||
- **Initialization flag prevents spurious modification notifications.**
|
||||
`_bInit` (or `_bInitModel`) is set `true` during bulk property updates (e.g., `Setting` setter, constructor initialization), suppressing `MarkPageModified()` calls.
|
||||
- **`SupportedExcitationControl` hardcodes `FlowControl` to `Handshake.None`.**
|
||||
`AvailableFlowControls` list contains only `None`.
|
||||
- **`InitialOffsetControl` enforces uniqueness of `InitialOffset.Form`.**
|
||||
`UpdateInitialOffsetTypes()` removes types already present in `_InitialOffsetCollection` from `AvailableOffsetTypes`.
|
||||
- **`InitialOffsetTypes.EUAtMV` requires linear component.**
|
||||
`Validate(...)` issues a warning if `EUAtMV` is present and `HasLinearComponent` is `false`.
|
||||
- **`SettingName` must be non-empty for validation to pass.**
|
||||
All controls that expose `SettingName` validate it in `Validate(...)`.
|
||||
- **`UDPAddress` must be valid per `Utils.ValidateUDPAddress`.**
|
||||
Validation error string is `StringResources.EditStreamInputOrOutputControl_InvalidUDPAddress`.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
- **Internal Dependencies (from imports):**
|
||||
- `DTS.Common.*`: `Utils`, `Enums`, `Storage`, `SharedResource.Strings`, `Constant.EmbeddedSensors`, `Classes.Sensors`, `Events`, `Converters`, `DAS.Concepts`.
|
||||
- `Prism.*`: `IEventAggregator`, `ContainerLocator`, `Events` (for `SensorChangedEvent`, `PageErrorEvent`).
|
||||
- `System.ComponentModel`, `System.Windows.Controls`, `System.Windows`, `System.IO.Ports`.
|
||||
- `DTS.SensorDB.SensorData`, `DTS.SensorDB.SensorBase`.
|
||||
- `PageHeaderRibbon.ModifyStates`, `PageMainContentControl`, `DbOperations`.
|
||||
|
||||
- **External Dependencies:**
|
||||
- `BaudValidator` (used in `EditUartSettingsControl.Validate`).
|
||||
- `StringResources` (localized strings).
|
||||
- `PageErrorEvent`, `SensorChangedEvent` (Prism event aggregation).
|
||||
|
||||
- **Depended-on by:**
|
||||
- Likely consumed by `DataPROPage` and higher-level sensor configuration UIs (e.g., `SensorDatabaseControl`).
|
||||
- `SensorChangedEvent` publishing implies integration with a sensor list or model update system.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **`SettingName` maps to `_setting.SerialNumber`**, not a dedicated `SettingName` field. This may be non-intuitive.
|
||||
- **`SupportedExcitationControl.Model` setter is *write-only*.**
|
||||
There is no public getter; the control only accepts assignment of `SensorBase` to initialize its state.
|
||||
- **`InitialOffsetControl.Validate(...)` does not return `false` on warnings or errors** — it always returns `true`. Validation failure logic is delegated to the caller (`SensorDatabaseControl`) based on `Valid` and `DisplayErrors` flags.
|
||||
- **`EditUartSettingsControl` hardcodes `FlowControl` to `Handshake.None`.**
|
||||
This may be intentional (per comment `//FB 30486`) but is not obvious from the property API.
|
||||
- **`InitialOffsetCollection` setter clears and replaces the internal list**, but `InitialOffsets` property setter does not call it directly — it sets `_InitialOffsetCollection` via `value.Offsets`. This could cause confusion if setters are used inconsistently.
|
||||
- **`UserTags` setter splits on `,` but does not trim whitespace.**
|
||||
Tags like `" tag1 , tag2 "` may be stored as `" tag1 "` and `" tag2 "` (leading/trailing spaces preserved).
|
||||
- **`Validate(...)` methods do not clear `errors`/`warnings` before appending.**
|
||||
Callers must ensure `errors`/`warnings` lists are cleared before each validation pass.
|
||||
- **`SupportedExcitationControl.NotifyExcitationChange()` publishes `SensorChangedEvent` even during initialization (`_bInitModel == true`).**
|
||||
This may cause unnecessary reprocessing if subscribers do not check `SensorChangedArgs.IsInitializing`.
|
||||
- **`InitialOffsetControl` reorders `InitialOffsetTypes.None` to the front of `_InitialOffsetCollection`** in `UpdateInitialOffsetTypes()`. This ordering is not documented or guaranteed elsewhere.
|
||||
|
||||
None identified beyond these.
|
||||
261
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/Settings.md
Normal file
261
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/Settings.md
Normal file
@@ -0,0 +1,261 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/Settings/ISettingsControl.cs
|
||||
- DataPRO/DataPRO/Controls/Settings/EditAdvancedSettings.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Settings/EditRealtimeSettings.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Settings/TestHistorySettings.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Settings/EditUISettings.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Settings/ImportDB.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Settings/SoftwareFilters.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Settings/EditISOSettings.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Settings/DBImport.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Settings/DatabaseSettings.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Settings/PowerAndBattery.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/Settings/EditTables.xaml.cs
|
||||
generated_at: "2026-04-16T04:15:26.402494+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "90f6d98d170275b8"
|
||||
---
|
||||
|
||||
# Documentation: Settings Controls Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides UI controls for configuring various application settings within the DataPROWin7 application. Each control implements the `ISettingsControl` interface and integrates with the application’s page navigation and permission system via `IPageContent`. These controls expose settings through property grids or dedicated views, support permission-based UI enablement, and provide mechanisms for restoring default values, validating user input, and managing lifecycle events (activation/deactivation). The module serves as the presentation layer for persistent configuration data, bridging user interactions with underlying settings models and database-backed state.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes implement the following interfaces:
|
||||
- `IPageContent` (explicitly implemented)
|
||||
- `INotifyPropertyChanged`
|
||||
- `ISettingsControl`
|
||||
|
||||
### `ISettingsControl`
|
||||
|
||||
```csharp
|
||||
void RestoreOriginalSettings();
|
||||
```
|
||||
- Restores settings to their original/default values (e.g., from database or defaults). Must trigger UI refresh (e.g., via `OnPropertyChanged`).
|
||||
|
||||
### `IPageContent` (Explicit Implementations)
|
||||
|
||||
All controls implement these methods, though most are no-ops or minimal stubs:
|
||||
|
||||
```csharp
|
||||
void SetPermissions(UserPermissionLevels actualPermission, UserPermissionLevels requiredPermission);
|
||||
bool KeyDown(object sender, KeyEventArgs arg);
|
||||
void StartSearch(string term);
|
||||
bool OnButtonPress(PageButton button);
|
||||
object GetPageContent();
|
||||
```
|
||||
|
||||
- `SetPermissions(...)`: Enables/disables the control UI based on permission level (`actualPermission >= requiredPermission`).
|
||||
- `GetPageContent()`: Returns `this` (the control instance).
|
||||
- Others are typically no-ops or return `false`.
|
||||
|
||||
### `INotifyPropertyChanged`
|
||||
|
||||
All controls expose:
|
||||
```csharp
|
||||
event PropertyChangedEventHandler PropertyChanged;
|
||||
protected bool SetProperty<T>(ref T storage, T value, string propertyName = null);
|
||||
protected void OnPropertyChanged(string propertyName = null);
|
||||
```
|
||||
- Standard MVVM property change infrastructure.
|
||||
|
||||
### Concrete Controls
|
||||
|
||||
#### `EditAdvancedSettings`
|
||||
|
||||
```csharp
|
||||
public AdvancedSettings AdvancedSettings { get; set; }
|
||||
public bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow);
|
||||
public void OnSetActive();
|
||||
public void UnSet(Action OnComplete = null);
|
||||
public void Reset();
|
||||
```
|
||||
- `OnSetActive()`: Refreshes `_advancedSettings`, then rebinds `propertyGrid.SelectedObject` to force UI update (workaround for `PropertyGrid` not observing `INotifyPropertyChanged`).
|
||||
- `RestoreOriginalSettings()`: Calls `_advancedSettings.Restore()` and raises `PropertyChanged("AdvancedSettings")`.
|
||||
|
||||
#### `EditRealtimeSettings`
|
||||
|
||||
```csharp
|
||||
public RealtimeSettings RealtimeSettings { get; set; }
|
||||
public bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow);
|
||||
public void OnSetActive();
|
||||
public void UnSet(Action OnComplete = null);
|
||||
public void Reset();
|
||||
```
|
||||
- Identical pattern to `EditAdvancedSettings`, but operates on `RealtimeSettings`.
|
||||
- `RestoreOriginalSettings()` calls `_realtimeSettings.Restore()` and raises `PropertyChanged("RealtimeSettings")`.
|
||||
|
||||
#### `TestHistorySettings`
|
||||
|
||||
```csharp
|
||||
public TestHistoryDefaults TestHistoryDefaults { get; set; }
|
||||
public bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow);
|
||||
public void OnSetActive();
|
||||
public void UnSet(Action OnComplete = null);
|
||||
```
|
||||
- `OnSetActive()`: Instantiates new `TestHistoryDefaults`.
|
||||
- `RestoreOriginalSettings()`: Calls `Settings.TestHistoryDefaults.RestoreOriginalSettings()`, then creates new `TestHistoryDefaults` instance and raises `PropertyChanged("TestHistoryDefaults")`.
|
||||
|
||||
#### `EditUISettings`
|
||||
|
||||
```csharp
|
||||
public void OnSetActive();
|
||||
public void Reset();
|
||||
public void UnSet(Action OnComplete = null);
|
||||
```
|
||||
- `OnSetActive()`: Instantiates new `UIProperties`, subscribes to its `PropertyChanged`, binds to `gridUIProperties`.
|
||||
- `_uiProperties_PropertyChanged`: Handles `"ShowGroups"` (calls `MainWindow.SetGroupsVisible()`) and `"UICulture"` (calls `App.SetCulture(true)`).
|
||||
- `RestoreOriginalSettings()`: Instantiates `UIProperties(true)` (likely constructor overload for defaults), re-subscribes, rebinds.
|
||||
|
||||
#### `ImportDB`
|
||||
|
||||
```csharp
|
||||
public object DBImportView { get; set; }
|
||||
public bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow);
|
||||
public void OnSetActive();
|
||||
public void UnSet(Action OnComplete = null);
|
||||
public void RestoreOriginalSettings(); // no-op
|
||||
```
|
||||
- Delegates to Prism/IoC-resolved `IDBImportView` and `IDBViewModel`.
|
||||
- `OnSetActive()`: Resolves and initializes viewmodel/view; sets `DBImportView` and `ImportDBViewContainer.Content`.
|
||||
- `RestoreOriginalSettings()` is empty.
|
||||
|
||||
#### `SoftwareFilters`
|
||||
|
||||
```csharp
|
||||
public object SoftwareFiltersView { get; set; }
|
||||
public bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow);
|
||||
public void OnSetActive();
|
||||
public void UnSet(Action OnComplete = null);
|
||||
public void RestoreOriginalSettings(); // no-op
|
||||
public bool CheckChangeStep(); // custom method
|
||||
```
|
||||
- Delegates to Prism/IoC-resolved `ISoftwareFiltersView` and `ISoftwareFiltersViewModel`.
|
||||
- `UnSet(...)`: Sets `_vm.CurrentUser` and calls `_vm.Unset()`.
|
||||
- `CheckChangeStep()`: Sets `_vm.CurrentUser` and calls `_vm.ValidateAndSave()`.
|
||||
- `RestoreOriginalSettings()` is empty.
|
||||
|
||||
#### `EditISOSettings`
|
||||
|
||||
```csharp
|
||||
public object IsoSettingsView { get; set; }
|
||||
public bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow);
|
||||
public void OnSetActive();
|
||||
public void UnSet(Action OnComplete = null);
|
||||
public void Reset();
|
||||
public void RestoreOriginalSettings();
|
||||
```
|
||||
- `UnSet(...)`: Saves `_vm.ISOData` via `_vm.Model.SaveData`, updates `SerializedSettings` properties (e.g., `ISOViewMode`, `ShowISOStringBuilder`, etc.), and calls `App.ResetISOSupport()`.
|
||||
- `RestoreOriginalSettings()`: Resets `SerializedSettings.*Default` properties to defaults, then reloads `_vm.ISOData` via `_vm.Model.LoadData()`.
|
||||
|
||||
#### `DBImport`
|
||||
|
||||
```csharp
|
||||
public object DBImportView { get; set; }
|
||||
public bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow);
|
||||
public void OnSetActive();
|
||||
public void UnSet(Action OnComplete = null);
|
||||
public void RestoreOriginalSettings(); // no-op
|
||||
public void Import(); // public method
|
||||
public void ImportXML(object o);
|
||||
```
|
||||
- `Import()`: Validates import file exists; queues `ImportXML` on thread pool.
|
||||
- `ImportXML(...)`: Constructs `DatabaseImport.DbImporter` and calls `ImportXML(...)`.
|
||||
- `RestoreOriginalSettings()` is empty.
|
||||
|
||||
#### `DatabaseSettings`
|
||||
|
||||
```csharp
|
||||
public bool DatabaseCopyEnabled { get; }
|
||||
public bool DatabaseControlEnabled { get; }
|
||||
public bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow);
|
||||
public void OnSetActive();
|
||||
public void UnSet(Action OnComplete = null);
|
||||
public void RestoreOriginalSettings(); // no-op
|
||||
```
|
||||
- `DatabaseCopyEnabled`/`DatabaseControlEnabled`: Return `true` only if `DBType == 2` (Hybrid) or `DBType == 2` respectively.
|
||||
- `OnSetActive()`: Initializes viewmodels (`IDatabaseCopyViewModel`, `IDatabaseSwitchViewModel`) via IoC.
|
||||
- `RestoreOriginalSettings()` is empty.
|
||||
|
||||
#### `PowerAndBattery`
|
||||
|
||||
```csharp
|
||||
public bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow);
|
||||
public void OnSetActive();
|
||||
public void UnSet(Action OnComplete = null);
|
||||
public void RestoreOriginalSettings();
|
||||
```
|
||||
- Constructor populates `InputAndBatterySetting` controls for all `HardwareTypes`.
|
||||
- `RestoreOriginalSettings()`: Calls `Restore()` on each `InputAndBatterySetting` per hardware type.
|
||||
- `Reset()`: Calls `Reset()` on each `InputAndBatterySetting`.
|
||||
|
||||
#### `EditTables`
|
||||
|
||||
```csharp
|
||||
public TableHelper[] AllTables { get; set; }
|
||||
public bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow);
|
||||
public void OnSetActive();
|
||||
public void UnSet(Action OnComplete = null);
|
||||
public void Reset();
|
||||
```
|
||||
- `TableHelper`: Wraps `GenericTableColumnOrderTable`, exposes data via `DataTable` bound to `TableOptionsTable`.
|
||||
- `RestoreOriginalSettings()`: Calls `GenericTableDictionary.Dictionary.ResetTable(...)` for each table, then repopulates.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`ISettingsControl.RestoreOriginalSettings()` must refresh UI**: All implementations must ensure UI reflects restored state (e.g., via `OnPropertyChanged`, reassignment of bound properties, or rebinding property grids).
|
||||
- **Permission-based UI enablement**: `IPageContent.SetPermissions(...)` must set `IsEnabled` (or equivalent) based on `actualPermission >= requiredPermission`.
|
||||
- **`OnSetActive()` must initialize viewmodels**: For controls using Prism/IoC (`ImportDB`, `SoftwareFilters`, `EditISOSettings`, `DatabaseSettings`, `DBImport`), `OnSetActive()` must resolve and initialize viewmodel/view if not already done.
|
||||
- **`Validate(...)` always returns `true`**: All controls’ `Validate(...)` methods currently return `true` unconditionally. No validation logic is present in the source.
|
||||
- **`UnSet(...)` and `Reset()` are no-ops in most controls**: Only `EditUISettings`, `EditISOSettings`, `SoftwareFilters`, and `PowerAndBattery` have non-trivial logic in these methods.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies (from source):
|
||||
- **Core interfaces**:
|
||||
- `IPageContent` (namespace `DataPROWin7.Controls.Settings`)
|
||||
- `ISettingsControl` (defined in same file)
|
||||
- **Settings models**:
|
||||
- `AdvancedSettings`, `RealtimeSettings`, `TestHistoryDefaults`, `UIProperties`, `SerializedSettings`, `TableHelper`, `TableOptionsTable`
|
||||
- **User/Permission system**:
|
||||
- `DTS.Slice.Users.User.UserPermissionLevels`
|
||||
- **UI frameworks**:
|
||||
- `System.ComponentModel` (`INotifyPropertyChanged`)
|
||||
- `System.Windows.Controls`, `System.Windows.Input`, `Xceed.Wpf.Toolkit.PropertyGrid`
|
||||
- **Prism/IoC**:
|
||||
- `Prism.Events.IEventAggregator`, `Prism.Regions.IRegionManager`, `Prism.Ioc.IContainerLocator`, `Unity.IUnityContainer`
|
||||
- **Database/Import**:
|
||||
- `DTS.Common.Interface.IDBViewModel`, `DTS.Common.Interface.IDBImportView`, `DatabaseImport.DbImporter`
|
||||
- **Hardware types**:
|
||||
- `DTS.Common.Enums.Hardware.HardwareTypes`
|
||||
|
||||
### External Dependencies (inferred):
|
||||
- `DTS.*` assemblies (e.g., `DTS.Slice`, `DTS.Common`)
|
||||
- `Prism.*` assemblies (Prism Framework)
|
||||
- `Unity` container
|
||||
- `Xceed.Wpf.Toolkit` (PropertyGrid)
|
||||
- `System.Windows.Forms` (used in `PowerAndBattery.xaml.cs`)
|
||||
|
||||
### Depended Upon:
|
||||
- No other modules depend on this module *directly* in the source, but it is consumed by the broader settings UI system (e.g., via `IPageContent` integration in `DataPROPage`/`HomePage`).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **PropertyGrid INotifyPropertyChanged limitation**: `EditAdvancedSettings` and `EditRealtimeSettings` explicitly rebind `propertyGrid.SelectedObject` in `OnSetActive()` to force UI updates, as noted in comments referencing a known `PropertyGrid` limitation ([StackOverflow link](https://stackoverflow.com/questions/10092162/propertygrid-doesnt-notice-properties-changed-in-code)).
|
||||
- **`RestoreOriginalSettings()` semantics vary**:
|
||||
- `EditAdvancedSettings`/`EditRealtimeSettings`: Restore via `_settings.Restore()`.
|
||||
- `TestHistorySettings`: Calls static `Settings.TestHistoryDefaults.RestoreOriginalSettings()`.
|
||||
- `EditISOSettings`: Resets `SerializedSettings.*Default` fields and reloads viewmodel data.
|
||||
- Others (`ImportDB`, `SoftwareFilters`, `DatabaseSettings`, `DBImport`): No-op.
|
||||
- **`EditTables.TableHelper` mutates underlying data on `DataTable.ColumnChanged`**: Changes to `DisplayOrder`, `Visible`, or `Width` columns directly update `GenericTableColumnOrderColumn` and persist via `GenericTableDictionary.Dictionary.SaveColumns(...)`.
|
||||
- **`PowerAndBattery` constructor hardcodes hardware types**: The list of `HardwareTypes` is hardcoded in the constructor; missing types will result in `GetSettingCtrl(...)` returning `null`.
|
||||
- **`EditISOSettings.UnSet(...)` saves state even if not modified**: It unconditionally updates `SerializedSettings.*` fields and calls `App.ResetISOSupport()` on deactivation, regardless of whether changes occurred.
|
||||
- **`DatabaseSettings.OnDbError(...)` does not handle all `DbStatusArg.EventTypes`**: The `switch` statement includes a `default` that throws `ArgumentOutOfRangeException`, but some cases (e.g., `FailedToRestoreLocal`, `Complete`, `LegacyStatus`) are silent.
|
||||
- **`ImportDB.ImportXML(...)` runs on thread pool without cancellation**: No mechanism to cancel or track import progress beyond `SetStatus(...)` callback.
|
||||
- **`SoftwareFilters.CheckChangeStep()` is not part of `ISettingsControl`**: It is a custom method used elsewhere (likely for step validation), but not exposed via interface.
|
||||
- **`EditTables.UnSet(...)` clears `AllTables`**: Sets `AllTables = new TableHelper[0]`, which may cause UI issues if not handled by consuming code.
|
||||
177
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/TestObject.md
Normal file
177
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/TestObject.md
Normal file
@@ -0,0 +1,177 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestObject/IEditObjectSensorsControlPage.cs
|
||||
- DataPRO/DataPRO/Controls/TestObject/TableOptionsTable.cs
|
||||
- DataPRO/DataPRO/Controls/TestObject/ImportObjectImport.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestObject/ImportObjectOptions.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestObject/EditObjectInfoControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestObject/ImportObjectPreview.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestObject/SensorLockAndContend.cs
|
||||
- DataPRO/DataPRO/Controls/TestObject/EditObjectHardwareControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestObject/ExportGroup.xaml.cs
|
||||
generated_at: "2026-04-16T04:17:01.479504+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "d08bce9ece7691a5"
|
||||
---
|
||||
|
||||
# TestObject
|
||||
|
||||
**Documentation Page: Test Object Edit Control Module**
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
This module provides UI controls and supporting logic for editing *test objects* (e.g., test setups, groups) in the DataPRO application. It enables users to configure sensors, hardware, import/export settings, and validate object state before saving. The controls implement the `IPageContent` interface to integrate with the application’s page navigation and permission system, and they coordinate with backend services (e.g., locking, hardware/channel management, import/export pipelines) via view models and domain interfaces. The module is part of the `DataPROWin7.Controls.TestObject` namespace and serves as the primary UI layer for test object editing workflows.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### Interfaces
|
||||
- **`IEditObjectSensorsControlPage`**
|
||||
- `void SetOnlineSensors(DTS.SensorDB.SensorData[] sensors)`
|
||||
Sets the list of online sensors to display or process in the sensors control page. Used to populate sensor selection UI.
|
||||
|
||||
#### Classes
|
||||
- **`TableOptionsTable`**
|
||||
- Inherits from `GenericTable2`.
|
||||
- `enum TableColumns { ColumnName, ColumnHeader, Visible, DisplayOrder, Width, UserData }`
|
||||
- Constructor: `TableOptionsTable(ContentControl container, DataPROPage page)`
|
||||
Initializes a data grid with columns for table configuration (e.g., visibility, order, width).
|
||||
- Overrides `CreateColumns(string resourcePrefix, Type enumType)`
|
||||
Dynamically creates grid columns based on `TableColumns` enum values. Special handling for `Visible`, `DisplayOrder`, and `Width` (numeric/checkbox columns); `UserData` is skipped.
|
||||
|
||||
- **`ImportObjectImport`**
|
||||
- `IGroupImportImportView ImportView { get; set; }`
|
||||
Gets/sets the view model for import configuration. Setting it assigns the view to `Content`.
|
||||
- `bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`
|
||||
Always returns `true`; no validation logic implemented (placeholder).
|
||||
- `void OnSetActive()`
|
||||
No-op stub.
|
||||
|
||||
- **`ImportObjectOptions`**
|
||||
- `IGroupImportOptionsView OptionsView { get; set; }`
|
||||
Gets/sets the view model for import options. Setting it assigns the view to `Content`.
|
||||
- `bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`
|
||||
Delegates validation to `OptionsView.Validate(...)`. Aggregates errors/warnings into output parameters. If errors exist, reports them via `page.ReportErrors(...)` using the active page from `MainWindow`.
|
||||
- `void OnSetActive()`
|
||||
No-op stub.
|
||||
|
||||
- **`ImportObjectPreview`**
|
||||
- `IGroupImportPreviewView PreviewView { get; set; }`
|
||||
Gets/sets the view model for import preview. Setting it assigns the view to `Content`.
|
||||
- `bool DontValidate { get; set; }`
|
||||
Bypasses validation when `true`.
|
||||
- `bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`
|
||||
Calls `PreviewView.Validate(isAdmin, out errors, out warnings)`. If errors exist, reports them and returns `false`. If warnings exist, displays them via `ThreadPool.QueueUserWorkItem(DoWarning, ...)` and returns `false`.
|
||||
- `static void DoWarning(object o)`
|
||||
Shows a modal message box with warnings (using `App.DoMessageBox`) and OK/Cancel buttons.
|
||||
- `void OnSetActive()`
|
||||
No-op stub.
|
||||
|
||||
- **`SensorLockAndContend`**
|
||||
- Constructor: `SensorLockAndContend(DataPROPage page)`
|
||||
- `bool HasLockedSensors { get; }`
|
||||
Returns `true` if any sensors are currently locked.
|
||||
- `LockRecord[] GetLockRecords()`
|
||||
Returns all currently locked sensor records.
|
||||
- `void LockSensors(SensorData[] sensorsToLock)`
|
||||
Attempts to lock each sensor. Handles lock contention:
|
||||
- If lock is stale (timeout exceeded) or held by same user/machine, steals it.
|
||||
- Otherwise, records as contentious and calls `ContendLocks(...)`.
|
||||
- `void FreeSensors()`
|
||||
Frees all locked sensors and clears contentious locks. Clears `_sensorsContentiousLocks` unconditionally.
|
||||
- `private void ContendLocks(User user)`
|
||||
For non-admin users: reports errors via `_page.ReportErrors(...)`. For admins: prompts to steal locks via `StealLocks()`.
|
||||
- `private void StealLocks()`
|
||||
Frees and re-locks contentious sensors.
|
||||
|
||||
- **`EditObjectHardwareControl`**
|
||||
- Constructor: `EditObjectHardwareControl(DataPROPage page)`
|
||||
- `string HardwareInfo { get; }`
|
||||
Returns formatted string (e.g., `"X channels required. Y channels included."`) based on `ChannelsRequired` and hardware channel counts.
|
||||
- `int ChannelsRequired { get; set; }`
|
||||
Tracks required channel count (updated via `OnGroupChannelsChanged`).
|
||||
- `void AddHardware(DASHardware hardware, IGroup group, Dictionary<string, DASHardware> lookup, DASHardware[] allHardware)`
|
||||
Adds hardware to group’s `IncludedHardware` list. Special handling for TSRAIR (creates embedded channels) and SLICETC.
|
||||
- `void OnSetActive()`
|
||||
Initializes hardware view model, subscribes to events, sets compact view mode, and populates hardware list.
|
||||
- `void UnSet(Action OnComplete = null)`
|
||||
Unsubscribes from events and unsets hardware view model.
|
||||
- `bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`
|
||||
Delegates to `ValidateTestObjectHardware(...)`, which currently always returns `true`.
|
||||
- `private void OnIncludedChanged(HardwareListHardwareIncludedEventArgs args)`
|
||||
Adds/removes hardware from group when included state changes. Handles pseudo-rack and TSRAIR module dependencies.
|
||||
- `private void OnGroupChannelsChanged(GroupChannelsChangedEventArgs obj)`
|
||||
Updates `ChannelsRequired` when group channel count changes.
|
||||
|
||||
- **`ExportGroup`**
|
||||
- Constructor: `ExportGroup(DataPROPage page)`
|
||||
- `string ExportFile { get; set; }`
|
||||
Target export file path.
|
||||
- `string TCFFile { get; set; }`
|
||||
TCF file path (unused in source).
|
||||
- `bool UseFirstUseDate { get; set; } = true`
|
||||
Flag for sensor first-use date inclusion (UI visibility controlled by `SerializedSettings.UseSensorFirstUseDate`).
|
||||
- `bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`
|
||||
Checks `ExportFile` is non-empty and at least one group is selected. Marks invalid controls via `PageMainContentControl.MarkInvalid(...)`.
|
||||
- `void OnSetActive()`
|
||||
Populates `_dt` (DataTable) with groups from `IGroupListViewModel`, sorted by `LastModified`.
|
||||
- `void Export()`
|
||||
Starts export asynchronously via `Task.Run(ExportGroupFunc)`. If file exists, prompts for overwrite.
|
||||
- `private void ExportGroupFunc()`
|
||||
Calls `ExportTestSetup.ExportToFile(...)` with selected groups. Handles errors and updates status via delegates.
|
||||
- `private void FileOverwriteWarning(object o)`
|
||||
Shows overwrite warning modal; if OK, invokes `Export()` on dispatcher thread.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- **Permissions**: All `IPageContent` implementations enforce permission checks via `SetPermissions(...)`. `IsEnabled` is set only if `actualPermission >= requiredPermission`.
|
||||
- **Validation**:
|
||||
- `Validate(...)` methods must populate `errors`/`warnings` lists; returning `false` indicates failure.
|
||||
- `ImportObjectOptions.Validate` and `ImportObjectPreview.Validate` report errors via `page.ReportErrors(...)` on failure.
|
||||
- `ExportGroup.Validate` requires a non-empty `ExportFile` and at least one selected group.
|
||||
- **Locking**:
|
||||
- `SensorLockAndContend.LockSensors` may steal locks only for admins (after user confirmation) or stale/self-held locks.
|
||||
- `FreeSensors` clears `_sensorsContentiousLocks` unconditionally before freeing locks.
|
||||
- **Hardware/Channel Consistency**:
|
||||
- `EditObjectHardwareControl.OnIncludedChanged` ensures hardware inclusion/exclusion updates `group.IncludedHardware` and channels.
|
||||
- TSRAIR and SLICETC hardware trigger special channel creation/removal logic.
|
||||
- **Event Subscription**:
|
||||
- `EditObjectHardwareControl` subscribes to `GroupChannelsChangedEvent`, `HardwareListHardwareIncludedEvent`, and `HardwareListShowCompactEvent` in `OnSetActive`.
|
||||
- Unsubscribes in `UnSet` to prevent leaks.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
**Imports/References (from source):**
|
||||
- `DTS.*` namespaces:
|
||||
- `DTS.SensorDB` (e.g., `SensorData`, `SensorsCollection`)
|
||||
- `DTS.Slice.Users` (e.g., `User`, `UserPermissionLevels`)
|
||||
- `DTS.Common.*` (e.g., `IGroup`, `IGroupImportImportView`, `LockManager`, `IEventAggregator`, `IUnityContainer`)
|
||||
- `Prism.*` (e.g., `IEventAggregator`, `ContainerLocator`)
|
||||
- `System.*` (e.g., `Data`, `Windows.Controls`, `Threading`)
|
||||
- `DataPROWin7.*` (e.g., `DataModel`, `Common`, `Controls`)
|
||||
- `C1.WPF.DataGrid` (for `ExportGroup` grid columns)
|
||||
- `App`, `MainWindow`, `HomePage`, `DataPROPage`, `EditObjectPage`, `GenericTable2` (internal types).
|
||||
|
||||
**Depended on by:**
|
||||
- `EditObjectPage` (inferred from `EditObjectHardwareControl`, `EditObjectInfoControl`, `ImportObject*`, `ExportGroup` constructors).
|
||||
- `DataPROPage` and `App` (via `DoMessageBox`, `CurrentUser`, `DoWarning`).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
- **`ExportGroup.Export` does not block**: It starts export in a background `Task.Run`, but `FileOverwriteWarning` uses `ManualResetEvent.WaitOne()` to block the dispatcher thread during overwrite confirmation. This risks deadlocks if not handled carefully.
|
||||
- **`EditObjectHardwareControl.ValidateTestObjectHardware` is a stub**: Always returns `true`; no actual hardware/channel validation occurs.
|
||||
- **`ImportObjectImport.Validate` is a stub**: Always returns `true`; no validation logic implemented.
|
||||
- **`SensorLockAndContend.FreeSensors` clears `_sensorsContentiousLocks` before freeing**: If `FreeSensors` is called mid-contention, the contentious records are lost before resolution.
|
||||
- **`EditObjectHardwareControl.OnSetActive` sets column widths to `0`**: Hardcoded column widths (`TestSampleRateColumnWidth = 0`, etc.) hide columns; may conflict with tile-specific settings (e.g., "Test Setups tile" comment).
|
||||
- **`EditObjectInfoControl.TextBoxSourceUpdated` publishes `PageModifiedEvent` on data binding updates**: This may fire frequently (e.g., on every keystroke), potentially causing performance issues or race conditions.
|
||||
- **`ImportObjectPreview.Validate` always returns `false` if warnings exist**: Even if `bValid` is `true`, warnings trigger a modal and return `false`. This may block progression despite valid data.
|
||||
- **`ExportGroup.Export` uses `ExportTestSetup.PossibleStatus`**: Status enum is defined in `ExportTestSetup` (not in this module), implying tight coupling.
|
||||
- **`TableOptionsTable` skips `TableColumns.UserData` in `CreateColumns`**: Intentional, but may confuse developers expecting a column.
|
||||
- **`EditObjectHardwareControl` uses `DASHardware.GetChildrenDAS` and `GetEmbeddedModules`**: Logic for pseudo-rack/module dependencies is embedded in `AddHardware`/`RemoveFromChannels`; not centralized.
|
||||
- **`SensorLockAndContend` uses `Properties.Settings.Default.StrandedLockTimeoutMinutes`**: Hardcoded timeout setting; no runtime configuration visible in source.
|
||||
183
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/TestSetups.md
Normal file
183
enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/TestSetups.md
Normal file
@@ -0,0 +1,183 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/AvailableRecordingMode.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/EditTestSetupROIChannelsControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/EditTestSetupChannels.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/EditTestSetupParameters.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/EditTestSetupSysBuiltObjectsControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/EditTestSetupGraphControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/EditTestSetupSysBuiltObjectsTypeControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/TimedTriggersTable.cs
|
||||
generated_at: "2026-04-16T04:17:43.596855+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "b7f7104b314b4c10"
|
||||
---
|
||||
|
||||
# Documentation: Test Setup Controls Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a suite of WPF user controls and supporting classes for editing and validating test setup configurations in the DataPRO application. It enables users to configure hardware assignments, sensor mappings, regions of interest (ROI), graph definitions, timed triggers, and system-built test objects within a test setup. The controls integrate with Prism-based MVVM patterns, dependency injection via Unity, and external domain interfaces (e.g., `DTS.Common.Interface.*`) to manage test setup lifecycle, validation, and UI state.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `AvailableRecordingMode`
|
||||
- **`RecordingMode`**: `DFConstantsAndEnums.RecordingMode` — Gets or sets the recording mode enumeration value.
|
||||
- **`DisplayString`**: `string` — Gets or sets the human-readable string representation of the recording mode.
|
||||
- **`ToString()`**: `override string` — Returns the value of `DisplayString`.
|
||||
|
||||
### `EditTestSetupROIChannelsControl`
|
||||
- **`SetData(TestTemplate test)`**: `void` — Initializes the ROI channels view model with the provided test setup, populating groups and hardware lookup, then sets the ROI list. Logs and rethrows exceptions.
|
||||
- **`ShowROIGrid(TestTemplate test)`**: `void` — Calls `SetData(test)` and sets `_roiChannelsVm.View` as the content of `ContentContainer`.
|
||||
- **`ClearGrid()`**: `void` — Resets the ROI list in `_roiChannelsVm` to an empty `BindingList<IRegionOfInterest>`.
|
||||
- **`Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`**: `bool` — Invokes `_roiChannelsVm.Validate(ref warnings)` (no errors added). Always returns `true`.
|
||||
- **Constructors**:
|
||||
- `EditTestSetupROIChannelsControl()` — Initializes component; `_page` remains null.
|
||||
- `EditTestSetupROIChannelsControl(DataPROPage page)` — Initializes component and stores `_page`.
|
||||
|
||||
### `EditTestSetupChannels`
|
||||
- **`GetTestChannelsGroup()`**: `IGroup` — Delegates to `_editObjectSensorsControl.GetTestChannelsGroup()`.
|
||||
- **`GetMaxDisplayOrder()`**: `int` — Delegates to `_editObjectSensorsControl.GetMaxDisplayOrder()`.
|
||||
- **`AddChannels(IGroupChannel[] groupChannels)`**: `void` — Delegates to `_editObjectSensorsControl.AddChannels(groupChannels)`.
|
||||
- **`ClearFilters()`**: `void` — Clears all filters in `_editObjectSensorsControl`.
|
||||
- **`CurrentTest`**: `DataModel.TestTemplate` — Property that, when set, calls `_editObjectSensorsControl.UpdateTestSetup(CurrentTest)`.
|
||||
- **Filter methods** (e.g., `FilterAnalog()`, `FilterDigitalIn()`, etc.): `void` — Set corresponding button `IsChecked` state on `_editObjectSensorsControl`.
|
||||
- **`Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`**: `bool` — Delegates to `Validate(ref errors, null)` and always returns `true`.
|
||||
- **`Validate(ref List<string> errors, DataModel.DASHardware[] hardware)`**: `bool` — Always returns `true`.
|
||||
- **`OnSetActive()`**: `void` — Delegates to `_editObjectSensorsControl.OnSetActive()`.
|
||||
- **Constructors**:
|
||||
- `EditTestSetupChannels(DataPROPage page)` — Initializes component, creates `_editObjectSensorsControl`, and sets it as `editObjectSensorsContainer.Content`.
|
||||
- `EditTestSetupChannels()` — Private, only initializes component.
|
||||
|
||||
### `EditTestSetupParameters`
|
||||
- **`SetGroupChannelListViewModel(IGroupChannelListViewModel vm)`**: `void` — Assigns `_vm`, sets `CapacityFormat`, and sets `_vm.SettingsView` as `dgSensorsContainer.Content`.
|
||||
- **`CurrentTest`**: `DataModel.TestTemplate` — Property with `SetProperty` change notification.
|
||||
- **`Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`**: `bool` — Validates `_vm.SettingChannels`:
|
||||
- Adds warning if `AllowSensorPushAndPull` is enabled and channel parameters differ from sensor defaults.
|
||||
- Adds warning if any channel has no `SquibDelay` value.
|
||||
- Always returns `true`.
|
||||
- **`OnSetActive()`**: `void` — Refreshes `dgSensorsContainer.Content`, configures `_vm` with test setup, sensors, hardware, channel defaults, and user/admin flags, then calls `_vm.OnSetActive()` and applies filters.
|
||||
- **`UnSet(Action OnComplete = null)`**: `void` — Calls `_vm.Unset()`.
|
||||
- **Constructors**:
|
||||
- `EditTestSetupParameters(DataPROPage page)` — Stores `_page` and initializes component.
|
||||
- `EditTestSetupParameters()` — Private, only initializes component.
|
||||
|
||||
### `EditTestSetupSysBuiltObjectsControl`
|
||||
- **`CurrentTest`**: `DataModel.TestTemplate` — DP property.
|
||||
- **`UpdateChannelIndex(string sysBuiltTestObjectSerialNumberConverted, int channelTypesIndex)`**: `void` — Updates `ChannelTypesIndex` on matching `TestTestObject` in `CurrentTest.AddedGroups`.
|
||||
- **`UpdateObjectTemplate(string sysBuiltTestObjectSerialNumberConverted, DataModel.TestObjectTemplate objectTemplate)`**: `void` — Updates `Template` on matching `TestTestObject` in `CurrentTest.AddedGroups`.
|
||||
- **`Validate(ref List<string> errors, bool displayWindow)`**: `bool` — Always returns `true`.
|
||||
- **`OnSetActive()`**: `void` — No-op.
|
||||
- **`ISOItemVisibility`**: `Visibility` — Returns `Collapsed` if `ISOViewMode` is `NO_ISO`, else `Visible`.
|
||||
- **`ChangedSysBuiltTestObjectType`**: `string` — Stores last changed object serial number.
|
||||
- **`ChangedTemplate`**: `DataModel.TestObjectTemplate` — Stores last changed template.
|
||||
- **`TestSetupNameValid`**: `bool` — Stores validity flag.
|
||||
- **Event handlers**:
|
||||
- `ChannelType_Changed(...)`: Updates template, sets `ChangedSysBuiltTestObjectType`/`ChangedTemplate`, updates channel display orders, and notifies parent `EditTestSetupPage` via `ChannelTypeChanged(...)`.
|
||||
- `Position_Changed(...)`: Updates `NewPosition`/`GroupName`, calls `tto.SetSensors(CurrentTest)`.
|
||||
- `TestObjectChangePosition_Click(...)`: Resets position to defaults, updates `NewPosition`/`GroupName`, calls `tto.SetSensors(CurrentTest)`.
|
||||
|
||||
### `EditTestSetupSysBuiltObjectsTypeControl`
|
||||
- **`CurrentTest`**: `DataModel.TestTemplate` — Property with `SetProperty`.
|
||||
- **`ISOItemVisibility`**: `Visibility` — Same logic as `EditTestSetupSysBuiltObjectsControl`.
|
||||
- **`TestSetupNameValid`**: `bool` — Stores validity flag.
|
||||
- **`ChangedSysBuiltTestObjectType`**: `string` — Stores last changed object type.
|
||||
- **`OnSetActive()`**: `void` — Raises `PropertyChanged` for `ISOItemVisibility`.
|
||||
- **`Validate(ref List<string> errors, bool displayWindow)`**: `bool` — Always returns `true`.
|
||||
- **`ThreadData`**: Nested class with `AffectedGraphs` list property (used for async confirmation).
|
||||
- **Event handlers** (commented out in source):
|
||||
- `TestObjectTypeRemove_Click(...)`: Initiates async removal confirmation via `ThreadPool.QueueUserWorkItem`.
|
||||
- `GroupRemovalConfirmation(...)`: Displays message box with affected graphs.
|
||||
|
||||
### `EditTestSetupGraphControl`
|
||||
- **`AvailableChannels`**: `GroupChannel[]` — Property with `SetProperty`; populated in `PopulateAvailableChannels()`.
|
||||
- **`SelectedGraph`**: `TestGraph` — Property with `SetProperty`.
|
||||
- **`CurrentTest`**: `TestTemplate` — Property with `SetProperty`.
|
||||
- **`AvailableGraphChannelsAdd_Click(...)`**: Adds selected channel to `SelectedGraph`, clears `AvailableChannels` if ≥8 channels, notifies page of modification.
|
||||
- **`GraphChannelsRemove_Click(...)`**: Removes channel from `SelectedGraph`, repopulates `AvailableChannels`, notifies page.
|
||||
- **`btnAddGraph_Click(...)`**: Creates new `TestGraph`, adds to `CurrentTest.TestGraphs`, selects it, sets visibility, and notifies page.
|
||||
- **`btnGraphRemove_Click(...)`**: Removes selected graph from `CurrentTest.TestGraphs`, hides details, notifies page.
|
||||
- **`PopulateAvailableChannels()`**: Filters `CurrentTest.GetChannels()` to exclude blank, disabled, invalid-sensor, digital-out, and already-added channels; caps at 8 channels.
|
||||
- **`Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`**: `bool` — Always returns `true`.
|
||||
- **`OnSetActive()`**: Selects first graph if any exist.
|
||||
|
||||
### `TimedTriggersTable`
|
||||
- **Inherits from `GenericTable2`**.
|
||||
- **`Clear()`**: Clears `DataTable`.
|
||||
- **`UpdateList(TestTemplate test, DASHardware[] hardwares = null)`**: Populates `DataTable` rows with test schedule info and hardware serial numbers.
|
||||
- **`UpdateTable()`**: Ensures UI update on dispatcher thread; calls `AcceptChanges()`.
|
||||
- **`IsPassed(ref List<string> errors)`**: Returns `false` if any row has `StatusEnum == Status.Fail`; adds error message.
|
||||
- **`UnSet()`**: Clears `DataTable.Rows`.
|
||||
- **Nested `Status` enum**: `NA`, `Pass`, `Fail`.
|
||||
- **Nested `Locations` enum**: `BasicInfo`, `ArmCheckList`.
|
||||
- **Nested `Fields` enum**: `SerialNumber`, `Duration`, `StartDateTime`, `TimedTriggerText`, `Status`, `StatusEnum`.
|
||||
- **`TimedTriggersTable_LoadedCellPresenter(...)`**: Sets background color based on `StatusEnum` (`NA` → idle, `Pass` → complete, `Fail` → failed) for `ArmCheckList` location.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`AvailableRecordingMode`**: `ToString()` always returns `DisplayString`; `RecordingMode` must be a valid `DFConstantsAndEnums.RecordingMode`.
|
||||
- **`EditTestSetupROIChannelsControl`**:
|
||||
- `_roiChannelsVm` must be initialized before calling `SetData`, `ShowROIGrid`, or `ClearGrid`.
|
||||
- `SetData` must be called before `ShowROIGrid`.
|
||||
- `RegionsOfInterest` list is replaced entirely on each `SetData` call (no incremental updates).
|
||||
- **`EditTestSetupChannels`**:
|
||||
- `_editObjectSensorsControl` is always non-null after public constructor.
|
||||
- `CurrentTest` setter always triggers `UpdateTestSetup` on `_editObjectSensorsControl`.
|
||||
- **`EditTestSetupParameters`**:
|
||||
- `_vm` must be set via `SetGroupChannelListViewModel` before `OnSetActive` or `Validate` to avoid null reference.
|
||||
- `SquibDelay` validation assumes `null` means missing; no other validation of squib delay values.
|
||||
- **`EditTestSetupSysBuiltObjectsControl`**:
|
||||
- `CurrentTest.AddedGroups` is used (not `SysBuiltTestObjects`), per comments.
|
||||
- `ChangedSysBuiltTestObjectType` and `ChangedTemplate` are set only during `ChannelType_Changed`.
|
||||
- **`EditTestSetupGraphControl`**:
|
||||
- `AvailableChannels` is capped at 8 channels (if `SelectedGraph.GroupChannels.Length >= 8`, cleared).
|
||||
- Digital output channels are excluded from available channels.
|
||||
- `SelectedGraph` must be non-null for `PopulateAvailableChannels` to populate.
|
||||
- **`TimedTriggersTable`**:
|
||||
- `StatusEnum` values (`NA`, `Pass`, `Fail`) are stored in `DataTable` and used for visual styling.
|
||||
- `IsPassed` only checks for `Fail` status; `NA` and `Pass` are non-failing.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Dependencies (from imports)
|
||||
- **Prism**: `IEventAggregator`, `IContainer`, `IUnityContainer`, `ContainerLocator`, `Prism.Events`, `Prism.Ioc`.
|
||||
- **DTS Common Libraries**: `DTS.Common.*` (e.g., `Enums`, `Interface.*`, `DataModel`, `SharedResource`, `Utilities.Logging`, `ISO`, `Storage`, `SensorDB`, `Slice.Users`).
|
||||
- **WPF**: `System.Windows.*`, `C1.WPF.DataGrid`.
|
||||
- **DataPRO internal**: `DataPROWin7.DataModel`, `DataPROWin7.Common`, `DataPROWin7.Strings`, `DTS.Common.*`.
|
||||
|
||||
### Internal Dependencies
|
||||
- **Controls**:
|
||||
- `EditTestSetupROIChannelsControl` depends on `IRegionOfInterestChannelsViewModel`, `IRegionOfInterestChannelsView`.
|
||||
- `EditTestSetupParameters` depends on `IGroupChannelListViewModel`.
|
||||
- `EditTestSetupChannels` depends on `EditObjectSensorsControl`.
|
||||
- `TimedTriggersTable` depends on `GenericTable2`.
|
||||
- **DataModel**:
|
||||
- `TestTemplate`, `TestTestObject`, `TestGraph`, `DASHardware`, `GroupChannel`, `TestObjectTemplate`, `SysBuiltObjectType`.
|
||||
- **Services**:
|
||||
- `ContainerLocator.Container` (Unity container).
|
||||
- `SensorsCollection.SensorsList`, `DataModel.Classes.Hardware.DASHardwareList`.
|
||||
- `DbOperations.GetChannelSettingDefaults()`.
|
||||
- `SerializedSettings` (ISO view mode, sensor push/pull, capacity format, etc.).
|
||||
- `StringResources` (localized strings).
|
||||
- `APILogger`, `BrushesAndColors`.
|
||||
|
||||
### Inferred Usage
|
||||
- All controls implement `IPageContent` and are used as page content in `DataPROPage` hierarchy.
|
||||
- `EditTestSetupROIChannelsControl`, `EditTestSetupChannels`, `EditTestSetupParameters`, `EditTestSetupGraphControl`, and `TimedTriggersTable` are likely hosted in an `EditTestSetupPage` or similar parent.
|
||||
- `TimedTriggersTable` is used in both `BasicInfo` and `ArmCheckList` locations.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`EditTestSetupROIChannelsControl.SetData`**: Overwrites `RegionsOfInterest` list entirely; does not merge or diff. If incremental updates are needed, this is a bug.
|
||||
- **`EditTestSetupParameters.OnSetActive`**: Explicitly clears and reassigns `dgSensorsContainer.Content` to force reload (see comment on FB 14506). This may cause flicker or performance issues.
|
||||
- **`EditTestSetupSysBuiltObjectsControl.ChannelType_Changed`**: Creates a *new* `TestObjectTemplate` and commits it to `TemplateCollection`. This may have side effects if templates are shared or cached.
|
||||
- **`EditTestSetupGraphControl.PopulateAvailableChannels`**: Digital outputs are excluded, but digital inputs, analog, etc., are included. No explicit filtering for channel type beyond `IsDigitalOut`.
|
||||
- **`TimedTriggersTable.IsPassed`**: Only checks for `Fail`; `NA` is treated as non-failing (e.g., untested). Ensure this aligns with business rules.
|
||||
- **`EditTestSetupSysBuiltObjectsControl.UpdateChannelIndex` / `UpdateObjectTemplate`**: Iterates over `CurrentTest.AddedGroups`, *not* `SysBuiltTestObjects`, per comments. This may be intentional or a legacy inconsistency.
|
||||
- **`EditTestSetupSysBuiltObjectsTypeControl`**: Many methods and event handlers are commented out (e.g., `TestObjectTypeRemove_Click`, `RemoveSysBuiltTestObjectType`). Functionality may be incomplete or deferred.
|
||||
- **`EditTestSetupChannels.Filter*` methods**: Only set button `IsChecked`; no validation that the filter is applied or that `_editObjectSensorsControl` supports the filter.
|
||||
- **`AvailableRecordingMode`**: No validation or constraints on `DisplayString`; could be empty or null.
|
||||
- **`EditTestSetupROIChannelsControl.Validate`**: Only populates warnings; never adds errors. May be insufficient for strict validation scenarios.
|
||||
- **`EditTestSetupParameters.Validate`**: Assumes `_vm.SettingChannels` is populated; no null check beyond `_vm != null`.
|
||||
- **`TimedTriggersTable`**: Uses `IntervalTriggersTable.Status` in `IsPassed` (note: `IntervalTriggersTable.Status`, not `TimedTriggersTable.Status`), but `StatusEnum` column is `TimedTriggersTable.Status`. This mismatch could cause runtime errors if `IntervalTriggersTable.Status` is not assignable to `TimedTriggersTable.Status`.
|
||||
@@ -0,0 +1,287 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Classes/IValidatorImportingTestSetupTemplate.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Classes/HardwareScanThreadData.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Classes/ISFSensorList.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Classes/ReadFileThreadData.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Classes/ISFSensor.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Classes/LevelTriggerAxes.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Classes/ImportingTestSetupTemplate.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Classes/DataExportsTemplate.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Classes/LevelTriggerCapableChannel.cs
|
||||
generated_at: "2026-04-16T04:19:23.019632+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "15a4b3dd27a5fe0d"
|
||||
---
|
||||
|
||||
# Documentation: Test Setup Controls Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides data models and interfaces for managing test setup configurations in the DataPRO application, specifically supporting import operations, level-trigger configuration, and data export settings. It enables UI-bound view models for importing test setups (including duplicate detection and overwrite validation), configuring level-trigger thresholds on hardware channels (with hardware-specific constraints), and defining export format and data type permissions. The module serves as the data layer for the `ImportTestSetup` and `EditTestSetupInfoControl` UI pages, bridging user interactions with the underlying `DataModel` and ISO-level test setup structures.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Interfaces
|
||||
|
||||
- **`IValidatorImportingTestSetupTemplate`**
|
||||
- `void ValidateList()`
|
||||
Validates the entire list of importing test setups (e.g., checks for duplicates, validity of names, overwrite state).
|
||||
- `void SetProcessFailedStatus()`
|
||||
Sets a process failure status flag, likely used to disable the Save button or indicate an error state.
|
||||
- `int CheckForDuplicatesInImport(string importingTestSetupName)`
|
||||
Returns the count of test setups in the import list with the same `ImportingTestSetupName` (including the current one). Used to detect duplicates during import.
|
||||
|
||||
### Classes
|
||||
|
||||
- **`HardwareScanThreadData`**
|
||||
- `ManualResetEvent DoneEvent { get; }`
|
||||
Event signaled when the hardware scan thread completes.
|
||||
- Constructor: `HardwareScanThreadData(ManualResetEvent doneEvent)`
|
||||
Wraps a `ManualResetEvent` for thread coordination during hardware scanning.
|
||||
|
||||
- **`ISFSensorList`**
|
||||
- `string Status { get; set; }`
|
||||
Status string (e.g., "Found", "Missing", "Extra").
|
||||
- `int Sort { get; set; }`
|
||||
Sort order for UI display.
|
||||
- `bool Error { get; set; }`
|
||||
Indicates if this list has an error condition.
|
||||
- `List<ISFSensor> Sensors { get; set; }`
|
||||
Collection of sensors in this category.
|
||||
|
||||
- **`ReadFileThreadData`**
|
||||
- `string File { get; }`
|
||||
Path to the file being read.
|
||||
- `ManualResetEvent DoneEvent { get; }`
|
||||
Signaled when file reading completes.
|
||||
- `ManualResetEvent CancelEvent { get; }`
|
||||
Signaled to request cancellation of the read operation.
|
||||
- Constructor: `ReadFileThreadData(string file, ManualResetEvent doneEvent, ManualResetEvent cancelEvent)`
|
||||
Encapsulates parameters for a file-reading background thread.
|
||||
|
||||
- **`ISFSensor`**
|
||||
- Inherits from `DTS.Common.Base.BasePropertyChanged`.
|
||||
- Properties: `EID`, `SerialNumber`, `Type`, `Number`, `Description`, `Location`
|
||||
All are `string` properties with `SetProperty`-based change notification.
|
||||
|
||||
- **`LevelTriggerAxes`**
|
||||
- Inherits from `DTS.Common.Base.BasePropertyChanged`.
|
||||
- `static event EventHandler<Tuple<string, string>> OutsideValueTextChanged`
|
||||
Raised when `OutsideValueText` changes; payload is `(DasSerial, value)`.
|
||||
- `string DasSerial { get; set; }`
|
||||
Serial number of the DAS unit.
|
||||
- `string Units { get; set; }`
|
||||
Engineering units for the channel.
|
||||
- `string OutsideValueText { get; set; }`
|
||||
Text representation of the absolute outside value; setter parses and updates internal `_dOutsideValue`, then raises `OutsideValueTextChanged`.
|
||||
- `string ZeroMethodText { get; set; }`, `string MaximumRangeText { get; set; }`
|
||||
UI display strings.
|
||||
- `string ChannelName { get; }`
|
||||
Computed as `"{DasSerial}-{Acceleration}"`.
|
||||
- `bool IsCheckBoxAxis1Checked`, `IsCheckBoxAxis2Checked`, `IsCheckBoxAxis3Checked { get; set; }`
|
||||
Checkbox states for axes.
|
||||
|
||||
- **`ImportingTestSetupTemplate`**
|
||||
- Inherits from `BasePropertyChanged`.
|
||||
- `IEventAggregator _eventAggregator { get; set; }` *(private)*
|
||||
Used for Prism event aggregation (not exposed publicly).
|
||||
- `ImportTestSetup Parent { get; set; }`
|
||||
Reference to the parent UI control.
|
||||
- `bool IncludedCheckBox { get; set; }`
|
||||
Whether this test setup is included in the import.
|
||||
- `bool OverwriteCheckBox { get; set; }`
|
||||
Whether to overwrite an existing test setup with the same name.
|
||||
- `string OriginalTestSetupName { get; set; }`
|
||||
Name of the test setup before import.
|
||||
- `string ImportingTestSetupName { get; set; }`
|
||||
Proposed name after import.
|
||||
- `bool TestSetupExists { get; set; }`
|
||||
Whether a test setup with `ImportingTestSetupName` already exists in the system.
|
||||
- `bool TestSetupExistsAndIncluded { get; set; }`
|
||||
True if `TestSetupExists && IncludedCheckBox`.
|
||||
- `bool TestSetupImportDuplicate { get; set; }`
|
||||
True if another entry in the import list has the same `ImportingTestSetupName`.
|
||||
- `bool IsValid { get; set; }`
|
||||
Computed validity: `!IncludedCheckBox || !(TestSetupExists || TestSetupImportDuplicate) || OverwriteCheckBox`.
|
||||
- `DelegateCommand<object> ControlChangedCommand { get; }`
|
||||
Prism command bound to UI controls; triggers `ControlChangedMethod`.
|
||||
- `void UpdateImportingTestSetupListElement()`
|
||||
Updates `TestSetupExists`, `TestSetupImportDuplicate`, `TestSetupExistsAndIncluded`, and `IsValid`.
|
||||
- `bool Validate()`
|
||||
Returns `IsValid`.
|
||||
|
||||
- **`DataExportsTemplate`**
|
||||
- Inherits from `BasePropertyChanged`.
|
||||
- `EditTestSetupInfoControl Parent { get; set; }`
|
||||
Reference to the parent UI control.
|
||||
- `string ExportType { get; set; }`
|
||||
Display name of the export type (e.g., "CSV", "XLSX").
|
||||
- `DataModel.SupportedExportFormats ExportFormat { get; set; }`
|
||||
Enum value for the export format.
|
||||
- `bool UnfilteredEUCheckBox { get; set; }`, `UnfilteredEUExportSupported { get; set; }`
|
||||
Checkbox state and export capability flag for unfiltered engineering units.
|
||||
- `bool FilteredEUCheckBox { get; set; }`, `FilteredEUExportSupported { get; set; }`
|
||||
Checkbox state and export capability flag for filtered engineering units.
|
||||
- `bool MVCheckBox { get; set; }`, `MVExportSupported { get; set; }`
|
||||
Checkbox state and export capability flag for millivolt data.
|
||||
- `bool ADCCheckBox { get; set; }`, `ADCExportSupported { get; set; }`
|
||||
Checkbox state and export capability flag for raw ADC data.
|
||||
- `DTS.Slice.Users.User.UserPermissionLevels ActualPermission { get; set; }`
|
||||
Current user’s permission level.
|
||||
- `DTS.Slice.Users.User.UserPermissionLevels RequiredPermission { get; set; }`
|
||||
Minimum permission required to use this export type.
|
||||
- `bool Permitted { get; }`
|
||||
`ActualPermission >= RequiredPermission`.
|
||||
- `bool PermittedAndUnfilteredEUExportSupported`, `PermittedAndFilteredEUExportSupported`, `PermittedAndMVExportSupported`, `PermittedAndADCExportSupported { get; }`
|
||||
Computed flags combining permission and export support.
|
||||
- `DelegateCommand<object> ControlChangedCommand { get; }`
|
||||
Prism command bound to checkboxes; triggers `ControlChangedMethod`.
|
||||
- `void ControlChangedMethod(object o)`
|
||||
Updates corresponding `Parent.Export*` properties based on `ExportFormat` and checkbox tag (`ExportChoices`).
|
||||
|
||||
- **`LevelTriggerCapableChannel`**
|
||||
- Inherits from `BasePropertyChanged`, implements `IComparable<LevelTriggerCapableChannel>`.
|
||||
- `DataModel.HardwareChannel HardwareChannel { get; }`
|
||||
Underlying hardware channel.
|
||||
- `string DASOrModuleSerialNumber { get; }`
|
||||
Returns `HardwareChannel.ModuleSerialNumber` for rack-type DAS; otherwise `HardwareChannel.Hardware.SerialNumber`.
|
||||
- `string MaximumRangeText { get; }`
|
||||
Computed from sensor capacity and units (special handling for TSR AIR).
|
||||
- `string ZeroMethodText { get; }`
|
||||
Displays the first zero method from calibration records.
|
||||
- `string GroupName { get; }`, `string ChannelName { get; }`
|
||||
Display names from group and channel objects.
|
||||
- `string DeviceChannel { get; }`, `string SensorInformation { get; }`, `string DisplayUnits { get; }`
|
||||
UI display strings.
|
||||
- `bool Selected { get; set; }`
|
||||
Selection state; triggers `BackgroundColor`/`ForegroundColor` updates.
|
||||
- `bool TriggerBetweenBounds { get; set; }`, `bool TriggerOutsideBounds { get; set; }`
|
||||
Trigger mode flags; update `_testSetupLevelTrigger` and mark page as modified.
|
||||
- `bool IsLessThanThresholdEnabled { get; set; }`, `bool IsGreatherThanThresholdEnabled { get; set; }`
|
||||
Threshold enable flags.
|
||||
- `double LessThanValue { get; }`, `double GreaterThanValue { get; }`
|
||||
Threshold values (read-only; set via `LessThanText`/`GreaterThanText`).
|
||||
- `string LessThanText { get; set; }`, `string GreaterThanText { get; set; }`
|
||||
Text representations; setters parse, validate via `RangeCheck`, and update `_testSetupLevelTrigger`.
|
||||
- `double InsideUpperBoundValue { get; }`, `double InsideLowerBoundValue { get; }`, `double OutsideUpperBoundValue { get; }`, `double OutsideLowerBoundValue { get; }`
|
||||
Bound values (read-only; set via corresponding `*Text` properties).
|
||||
- `string OutsideValueText { get; set; }`
|
||||
Special setter: sets symmetric inside/outside bounds and threshold values (for symmetric triggering).
|
||||
- `string Units { get; set; }`
|
||||
Engineering units from calibration.
|
||||
- `string UpperUnits`, `LowerUnits { get; }`
|
||||
Formatted unit strings.
|
||||
- `bool RangeCheck(double d, double absMaxCapacity, double absMinCapacity, bool displayError, out string err)`
|
||||
Validates value against sensor capacity limits; reports errors via `_page.ReportErrors`. Special handling for TSR AIR devices to avoid duplicate error messages.
|
||||
- `static Dictionary<string, string> errorInDevice`
|
||||
Stores per-DAS error messages to deduplicate UI errors.
|
||||
- `Visibility TriggerOutsideBoundsVisibility`, `TriggerBetweenBoundsVisibility { get; }`
|
||||
Hardware-specific visibility rules (e.g., collapsed for rack types).
|
||||
- `bool IsTriggerBetweenBoundsAllowed`, `IsTriggerOutsideBoundsAllowed`, `IsLessThanThresholdAllowed`, `IsGreaterThanThresholdAllowed { get; }`
|
||||
Computed constraints based on active trigger modes and hardware type.
|
||||
- `Visibility LevelTriggerGreaterThanVisibility`, `LevelTriggerLessThanVisibility { get; }`
|
||||
Hardware-specific visibility (hidden for DIR, DKR, TSR_AIR).
|
||||
- `string LevelTriggerText { get; }`
|
||||
Display text from `_testSetupLevelTrigger` or `"N/A"`.
|
||||
- `enum Tags`
|
||||
Used for property change notifications: `IsLessThanThresholdEnabled`, `IsGreatherThanThresholdEnabled`, `LessThanText`, `GreaterThanText`, etc.
|
||||
- **Methods:**
|
||||
- `ToISOLevelTriggerChannel()`
|
||||
Constructs a `DTS.Common.ISO.LevelTriggerChannel` from current state.
|
||||
- `FromISOLevelTriggerChannel(DTS.Common.ISO.LevelTriggerChannel channel)`
|
||||
Initializes state from an ISO channel; updates all bound properties.
|
||||
- `SetTestSetupLevelTriggerChannel(DTS.Common.ISO.LevelTriggerChannel channel)`
|
||||
Assigns `_testSetupLevelTrigger` and calls `FromISOLevelTriggerChannel`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`ImportingTestSetupTemplate.IsValid`** is computed as:
|
||||
`!IncludedCheckBox || !(TestSetupExists || TestSetupImportDuplicate) || OverwriteCheckBox`.
|
||||
This means a test setup is valid if it is not included, or if it is included but either does not exist, is not duplicated, or has overwrite enabled.
|
||||
|
||||
- **`LevelTriggerCapableChannel.RangeCheck`** enforces:
|
||||
- Values must not exceed `absMaxCapacity` (defined as `|SensorCapacity| * LevelTriggerMaxPercentage`).
|
||||
- Values must not be below `absMinCapacity` (defined as `|SensorCapacity| * LevelTriggerMinPercentage`) in magnitude if positive/negative near zero.
|
||||
- For TSR AIR channels, `absMinCapacity` is clamped to `|LowG64| * LevelTriggerMinPercentage`.
|
||||
- Duplicate error messages for the same DAS serial are suppressed.
|
||||
|
||||
- **Hardware-specific visibility constraints**:
|
||||
- `TriggerOutsideBoundsVisibility` is `Collapsed` for `TDAS_Pro_Rack`/`TDAS_LabRack`.
|
||||
- `TriggerBetweenBoundsVisibility` is `Visible` only for `G5VDS`/`G5INDUMMY`.
|
||||
- `LevelTriggerGreaterThanVisibility`/`LessThanVisibility` are `Hidden` for `DIR`, `DKR`, `TSR_AIR`, `TSR_AIR_RevB`.
|
||||
|
||||
- **`ISFSensor`** inherits `BasePropertyChanged`, so all property setters must use `SetProperty` for change notification.
|
||||
|
||||
- **`LevelTriggerAxes.OutsideValueTextChanged`** is only raised when `value` is non-empty and successfully parsed.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports/References
|
||||
- **Core Framework**: `System`, `System.Collections.Generic`, `System.Threading`, `System.Windows`, `System.Windows.Media`.
|
||||
- **Common Libraries**:
|
||||
- `DTS.Common.Base` (`BasePropertyChanged`, `SerializedSettings`).
|
||||
- `DTS.Common.Enums` (`HardwareTypes`, `Tags`, `ExportChoices`, `SupportedExportFormats`).
|
||||
- `DTS.Common.Interface` (`Groups.IGroup`, `Channels.IGroupChannel`).
|
||||
- `DTS.Common.ISO` (`LevelTriggerChannel`).
|
||||
- `DTS.Common.SharedResource.Strings` (`StringResources`).
|
||||
- `DTS.SensorDB` (`SensorData`, `SensorCalibration`).
|
||||
- `DTS.Slice.Users.User` (`UserPermissionLevels`).
|
||||
- **Prism Framework**: `Prism.Events.IEventAggregator`, `Prism.Commands.DelegateCommand`.
|
||||
- **Internal Models**:
|
||||
- `DataModel.HardwareChannel`, `DataModel.TestTemplateList.TestTemplatesList`.
|
||||
- `DataPROWin7.Common.BrushesAndColors`, `DataPROWin7.Common.SerializedSettings`.
|
||||
- `DTS.Common.SensorConstants`.
|
||||
|
||||
### Dependencies
|
||||
- **Consumed by**: UI controls `ImportTestSetup` and `EditTestSetupInfoControl` (via `Parent` references).
|
||||
- **Consumes**:
|
||||
- `DataModel.TestTemplateList.TestTemplatesList.GetTemplate` (for `TestSetupExists` check).
|
||||
- `DataModel.SupportedExportFormats` enum (for export format handling).
|
||||
- `DTS.Common.ISO.LevelTriggerChannel` (for ISO-level test setup serialization).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **TSR AIR Special Cases**:
|
||||
- `IsLessThanThresholdEnabled` and `IsGreaterThanThresholdEnabled` are *always false* for TSR AIR channels (hardcoded in `FromISOLevelTriggerChannel` and `ToISOLevelTriggerChannel`).
|
||||
- `TriggerOutsideBounds` is *always true* for TSR AIR channels.
|
||||
- `RangeCheck` uses `LowG64` instead of sensor capacity for min threshold calculation.
|
||||
- Error deduplication via `errorInDevice` dictionary avoids duplicate error popups for the same DAS serial.
|
||||
|
||||
- **`OutsideValueText` Setter Behavior**:
|
||||
- Setting `OutsideValueText` *implicitly sets* `OutsideLowerBoundValue`, `OutsideUpperBoundValue`, `GreaterThanValue`, and `LessThanValue` to symmetric values (±`d`). This is non-obvious and couples multiple properties.
|
||||
|
||||
- **`TestSetupExistsAndIncluded` Side Effect**:
|
||||
- Setting `TestSetupExistsAndIncluded` to `false` *unchecks* `OverwriteCheckBox` (via `SetProperty` callback).
|
||||
|
||||
- **Export Checkbox Logic**:
|
||||
- `ExportChoices.ADCCheckBox` for `ExportFormat.asc` does *not* update any `Parent.Export*` property (intentional, per comment: "per KM ASC should always be unfiltered").
|
||||
- `ExportChoices.FilteredEUCheckBox` for `ExportFormat.asc` is ignored (no case in switch).
|
||||
|
||||
- **`LevelTriggerAxes.OutsideValueText`**:
|
||||
- Getter returns `Math.Abs(_dOutsideValue).ToString("N2")`, but setter accepts signed values and converts to absolute value internally.
|
||||
|
||||
- **`ISFSensorList.Status` and `Sort`**:
|
||||
- No validation or constraints documented for these fields; behavior depends on UI usage.
|
||||
|
||||
- **`LevelTriggerCapableChannel.CompareTo`**:
|
||||
- Delegates comparison to `_groupChannel.CompareTo(rhs._groupChannel)`, which may rely on internal channel ordering semantics.
|
||||
|
||||
- **`LevelTriggerCapableChannel.ToISOLevelTriggerChannel`**:
|
||||
- Uses `SensorConstants.IsTSRAirHighGChannel` to override threshold enable flags and `TriggerOutsideBounds` behavior.
|
||||
|
||||
- **`DataExportsTemplate.ActualPermission`/`RequiredPermission`**:
|
||||
- Changing either triggers multiple dependent property changes (`Permitted*` flags) via `OnPropertyChanged`, but no validation ensures `RequiredPermission` ≤ `ActualPermission`.
|
||||
|
||||
- **`ReadFileThreadData.CancelEvent`**:
|
||||
- The `CancelEvent` is passed to the thread but not used in the class itself; its handling is external.
|
||||
|
||||
- **`HardwareScanThreadData.DoneEvent`**:
|
||||
- Only wraps a `ManualResetEvent`; no additional state or lifecycle management.
|
||||
|
||||
- **`ImportingTestSetupTemplate.ControlChangedMethod`**:
|
||||
- For `IncludeOverwriteName.ImportingTestSetupName`, it calls `Parent.ValidateList()` to revalidate *all* entries, which may be expensive for large lists.
|
||||
|
||||
- **`LevelTriggerCapableChannel.RangeCheck`**:
|
||||
- `errorInDevice` is a *static* dictionary; errors from one channel instance can affect another if they share the same DAS serial.
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Enums/Enums.cs
|
||||
generated_at: "2026-04-16T04:19:05.938652+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "6fd0a0189a898722"
|
||||
---
|
||||
|
||||
# Enums
|
||||
|
||||
## 1. Purpose
|
||||
This module defines a centralized location for enumerations used within the `DataPROWin7.Controls` namespace, specifically to consolidate enum definitions into a single class (`Enums`) as indicated by the inline comment. Its role is to provide strongly-typed constants for sensor detection states in the ISF (presumably *In-Situ Flow* or similar) testing context, enabling consistent representation of sensor presence/absence conditions across the codebase.
|
||||
|
||||
## 2. Public Interface
|
||||
The module exposes one nested enumeration:
|
||||
|
||||
- **`ISFSensors`**
|
||||
```csharp
|
||||
public enum ISFSensors
|
||||
{
|
||||
Found = 2,
|
||||
Missing = 0,
|
||||
Extra = 1,
|
||||
}
|
||||
```
|
||||
Represents the possible states of an ISF sensor during a test setup. Values map to:
|
||||
- `Missing` (0): Sensor not detected.
|
||||
- `Extra` (1): An unexpected (additional) sensor was detected.
|
||||
- `Found` (2): The expected sensor was successfully detected.
|
||||
|
||||
## 3. Invariants
|
||||
- The underlying integer values are fixed and explicitly assigned (`0`, `1`, `2`).
|
||||
- No validation or runtime enforcement is present in this file for usage of these values; correctness relies on callers adhering to the documented semantics.
|
||||
- The enum is defined *inside* the `Enums` class (not as a top-level type), so its fully qualified name is `DataPROWin7.Controls.Enums.ISFSensors`.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Dependencies *of* this module**:
|
||||
- Standard .NET libraries: `System`, `System.Collections.Generic`, `System.Linq`, `System.Text`, `System.Threading.Tasks` (all implicitly referenced via `using` directives, but not actively used in this file).
|
||||
- **Dependencies *on* this module**:
|
||||
- Not inferable from this file alone. Other files in the `DataPROWin7.Controls` namespace (e.g., test setup logic, sensor validation components) are expected to reference `Enums.ISFSensors`, but their usage is not visible here.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Non-sequential ordering**: The enum values are ordered `Missing=0`, `Extra=1`, `Found=2`, but semantically `Found` (the desired state) has the highest value. Callers may incorrectly assume ordering implies priority or severity (e.g., `Missing < Extra < Found`), though the values are not intended for comparison beyond equality.
|
||||
- **Naming ambiguity**: `ISFSensors` does not clarify whether it represents *sensor presence* or *test result status*; context from other modules is required to interpret usage correctly.
|
||||
- **Single enum scope**: As the comment notes, this is a "first attempt" to centralize enums. Future enums may be added here, but currently only one is defined—suggesting possible incomplete refactoring or future expansion.
|
||||
- **No XML documentation on individual values**: While the class has a summary comment, the enum members lack `<summary>` tags, reducing discoverability of semantics in IDE tooling.
|
||||
- **None identified from source alone.**
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/ISFImpotTables/ISFSensorsTable.cs
|
||||
generated_at: "2026-04-16T04:19:20.838551+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "b0ca9be502d965bb"
|
||||
---
|
||||
|
||||
# ISFImpotTables
|
||||
|
||||
## Documentation: `ISFSensorsTable<T>` Class
|
||||
|
||||
---
|
||||
|
||||
### **1. Purpose**
|
||||
|
||||
`ISFSensorsTable<T>` is a specialized WPF data grid control used to render sensor-related test data in a read-only, styled table format within the DataPRO application. It extends `GenericTable` and dynamically configures its header appearance (background/foreground colors) based on the `tableName` parameter, which is parsed as an `Enums.ISFSensors` value (`Extra`, `Found`, or `Missing`). Its role is to provide a consistent, visually distinct UI representation of sensor test results—e.g., highlighting "Extra" or "Found" sensors with status-specific colors—while preventing user interaction (editing, filtering, reordering, etc.).
|
||||
|
||||
---
|
||||
|
||||
### **2. Public Interface**
|
||||
|
||||
#### **Constructor**
|
||||
```csharp
|
||||
public ISFSensorsTable(DataPROPage page, StackPanel parent, string id, string name, List<T> tableData)
|
||||
```
|
||||
- **Behavior**: Instantiates the control by calling the private `CrateTable` method (note the typo in method name), passing all constructor arguments. Initializes the grid with `tableData` as `ItemsSource`, applies styling and behavior constraints, and appends a header `Label` and the grid itself to the provided `parent` `StackPanel`.
|
||||
|
||||
#### **Inherited Members (from `GenericTable`)**
|
||||
- The source file does not define `GenericTable`, but `ISFSensorsTable<T>` inherits from it. Presumably, `GenericTable` provides base grid functionality (e.g., `Columns`, `ItemsSource`, `Style`, etc.). No further details are available from this file.
|
||||
|
||||
---
|
||||
|
||||
### **3. Invariants**
|
||||
|
||||
- **Header Color Logic**:
|
||||
- If `tableName` parses to `Enums.ISFSensors.Extra`, `HeaderBackground` is set to `BrushesAndColors.Brush_ApplicationStatus_Busy`, and `HeaderForeground` to `BrushesAndColors.Brushes.Black`.
|
||||
- If `tableName` parses to `Enums.ISFSensors.Found`, `HeaderBackground` is set to `BrushesAndColors.Brush_ApplicationStatus_Complete`, and `HeaderForeground` to `BrushesAndColors.Brushes.Black`.
|
||||
- If `tableName` parses to `Enums.ISFSensors.Missing`, no header color changes are applied (defaults remain).
|
||||
- If `Enum.TryParse` fails (e.g., `tableName` is not a valid `ISFSensors` enum name), **no header styling is applied**—the grid retains default header colors.
|
||||
- **Grid Behavior**:
|
||||
- `ReadOnly = true`, `CanUserAddRows = false`, `CanUserFilter = false`, `CanUserRemoveRows = false`, `CanUserReorderColumns = false`, `CanUserResizeColumns = false`, `CanUserResizeRows = false`, `SelectionMode = None`.
|
||||
- All columns (`Columns`) are explicitly set to `IsReadOnly = true`.
|
||||
- `VerticalScrollBarVisibility = Auto`.
|
||||
- `Style` is set to the `"FlatDataGrid"` resource.
|
||||
- `HeadersVisibility = Column` (row headers hidden).
|
||||
- **UI Layout**:
|
||||
- A `Label` with `Style = "SimpleHeader"`, `Content = tableName`, `Width = 500`, and `HorizontalAlignment = Left` is prepended to the `parent` `StackPanel`.
|
||||
- `parentControl.Visibility` is set to `Visibility.Visible` unconditionally.
|
||||
|
||||
---
|
||||
|
||||
### **4. Dependencies**
|
||||
|
||||
#### **Internal Dependencies**
|
||||
- `DataPROWin7.Controls.GenericTable`: Base class (not shown in source).
|
||||
- `C1.WPF.DataGrid`: Used for `C1DataGrid` features (`Columns`, `ItemsSource`, `Style`, `HeadersVisibility`, etc.).
|
||||
- `DTS.Common`: Contains `Enums.ISFSensors` and `BrushesAndColors` types.
|
||||
- WPF resources: `"FlatDataGrid"` (grid style) and `"SimpleHeader"` (label style) must be defined in application/resource scope.
|
||||
|
||||
#### **External Dependencies**
|
||||
- `System.Windows`, `System.Windows.Controls`, `System.ComponentModel`: Standard WPF and .NET types.
|
||||
|
||||
#### **Dependents**
|
||||
- Not visible in this file. Presumably instantiated by higher-level UI logic (e.g., test result rendering pages) that passes `DataPROPage`, `StackPanel`, and sensor data.
|
||||
|
||||
---
|
||||
|
||||
### **5. Gotchas**
|
||||
|
||||
- **Typo in Method Name**: The private method is named `CrateTable` instead of `CreateTable`. This is likely a historical typo and should be corrected if refactoring.
|
||||
- **Generic Type Parameter Shadowing**: The constructor uses `T`, but `CrateTable` redeclares a new generic type `TT`. While functionally harmless here (since `T` is unused after construction), it is confusing and could mislead maintainers.
|
||||
- **Enum Parsing Side Effects**: If `tableName` does not match a valid `Enums.ISFSensors` value, the grid proceeds without header styling—no error or warning is raised. This silent failure could mask misconfiguration.
|
||||
- **Hardcoded UI Constraints**: All interaction features are disabled unconditionally. If future requirements allow user interaction for specific sensor types, this class would need refactoring.
|
||||
- **No Null/Empty Checks**: The constructor and `CrateTable` do not validate `tableData`, `parent`, `id`, or `name` for null/empty values. Passing `null` could cause `NullReferenceException`.
|
||||
- **Assumes Resource Availability**: Relies on `"FlatDataGrid"` and `"SimpleHeader"` styles being defined. Missing resources will cause runtime XAML exceptions.
|
||||
- **No Support for Dynamic Updates**: Once constructed, the grid is static (`ReadOnly`, no `ItemsSource` rebinding logic). Changes to `tableData` after construction will not update the UI unless `ItemsSource` is reassigned externally (not done here).
|
||||
|
||||
None identified beyond those above.
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/WizardHelper.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/StatusUpdater.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/ParseImportFactory.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/ImportFunctions.cs
|
||||
generated_at: "2026-04-16T04:19:52.935779+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "d9ba66f7bdf0c48a"
|
||||
---
|
||||
|
||||
# Import
|
||||
|
||||
### **Purpose**
|
||||
This module provides core infrastructure for the test setup import wizard in the DataPROWin7 application. It handles file-type-specific import parsing (CSV, E2X, XML), status and progress reporting to the UI, error notification, and hardware discovery/validation logic required before and during import operations. Its role is to decouple import orchestration from UI and business logic, enabling robust, user-informed import workflows while enforcing hardware safety constraints (e.g., checking for armed DAS units and TOM switches).
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
#### `WizardHelper.ReportErrors(List<string> errors)`
|
||||
- **Signature**: `public static void ReportErrors(List<string> errors)`
|
||||
- **Behavior**: Deduplicates the input `errors` list, joins the unique messages with newline separators, and displays them via a modal message box using `App.DoMessageBox` with an OK button.
|
||||
- **Note**: The method mutates the input list by reassigning it to the deduplicated version, but this has no effect on the caller since `List<T>` is passed by reference *value* (i.e., the reference itself isn’t reassigned externally).
|
||||
|
||||
#### `StatusUpdater` class
|
||||
- **Constructor**: `public StatusUpdater(StatusAndProgressBarViewModel statusAndProgressBarViewModel)`
|
||||
Initializes the updater with a bound ViewModel for UI state.
|
||||
|
||||
- **`SetProgress(double progressValue)`**
|
||||
- **Behavior**: Normalizes `progressValue` to [0, 100] range. If ≤1, multiplies by 100 (to support both decimal and percentage inputs). Clamps to [0, 100], then sets `_statusAndProgressBarViewModel.ProgressBarValue` to the integer result.
|
||||
- **Gotcha**: The comment indicates inconsistent callers pass decimals (0–1) vs. percentages (0–100), necessitating the normalization logic.
|
||||
|
||||
- **`SetStatus(PossibleStatus status, ImportExtraStatus importExtraStatus, string error)`**
|
||||
- **Behavior**: Sets the aggregate status text, color, progress visibility, and optional error text in the ViewModel.
|
||||
- `status` (e.g., `Waiting`, `Working`, `Failed`) determines color and progress visibility.
|
||||
- `importExtraStatus` (e.g., `ReadingChannels`, `NormalizingIds`) appends a localized sub-status to the main status text via `GetStatusString`.
|
||||
- `error` is appended to the status text with a `" - "` separator if non-null/whitespace.
|
||||
- **Note**: Uses `GetStatusString` to fetch localized strings from `StringResources.ResourceManager`.
|
||||
|
||||
- **`GetStatusString(PossibleStatus status, ImportExtraStatus importExtraStatus)` (static)**
|
||||
- **Signature**: `public static string GetStatusString(PossibleStatus status, ImportExtraStatus importExtraStatus)`
|
||||
- **Behavior**: Retrieves a base status string (e.g., `"ExportTestSetup_Importing"` → `"Importing..."`) and appends a sub-status string (e.g., `"ReadingChannels"`) if `importExtraStatus` is non-`None`. Sub-status strings are fetched via `StringResources.ResourceManager.GetString($"IMPORT_{importExtraStatus}")`.
|
||||
|
||||
#### `ParseImportFactory` class
|
||||
- **Constructor**: `public ParseImportFactory(IImportNotification importNotification, User user, Func<bool> isCancelled)`
|
||||
Stores dependencies for import parsing.
|
||||
|
||||
- **Properties**:
|
||||
- `CsvImportOptions { get; set; }`
|
||||
- `EqxImportOptions { get; set; }`
|
||||
- Hold import-specific options for CSV and E2X formats.
|
||||
|
||||
- **`CreateParseImport(string fileName)`**
|
||||
- **Signature**: `public IParseImport CreateParseImport(string fileName)`
|
||||
- **Behavior**:
|
||||
1. Validates `fileName` is non-null/empty and exists.
|
||||
2. Extracts file extension (lowercase, no dot).
|
||||
3. **Blocks ISF imports** if `SerializedSettings.UniqueISOCodesRequired && SerializedSettings.ShowISOCodes` is true (throws `NotSupportedImportFileException`).
|
||||
4. Returns a parser instance based on extension:
|
||||
- `"csv"` → `CreateCSVParseImport()`
|
||||
- `"e2x"` → `CreateE2XParseImport()`
|
||||
- `"xml"` → `CreateXMLParseImport()`
|
||||
- Else → `NotSupportedImportFileException`.
|
||||
|
||||
- **Private Helpers**:
|
||||
- `CreateCSVParseImport()`: Builds a `DefaultParseImport` with `DTSCSVSensorsParser` and `DTSCSVTestSetupParser`. Uses `GetTestSetupImportDefaults()` to populate `TestSetupImportData` from user settings.
|
||||
- `CreateE2XParseImport()`: Builds a `DefaultParseImport` with `EQXSensorsParser` and `EQXTestSetupParser`. Uses `EQXGroupImport` and `EquipmentExchange.EQXSensorDatabase`.
|
||||
- `CreateXMLParseImport()`: Returns a `DTSXMLParseImport` with `UIItems` populated from `App.GetAllIUIItems()`.
|
||||
- `GetTestSetupImportDefaults()`: Fetches user-specific defaults (pretrigger/posttrigger seconds, sample rate, etc.) from `TestSetupDefaults.GetUserSettings`. Logs exceptions via `APILogger`.
|
||||
|
||||
#### `NotSupportedImportFileException` class
|
||||
- **Signature**: `[Serializable] public class NotSupportedImportFileException : Exception`
|
||||
- **Behavior**: Thrown when an unsupported file extension (e.g., ISF in strict ISO mode) is encountered. Constructor accepts the extension for the message.
|
||||
|
||||
#### `ImportFunctions` abstract class
|
||||
- **Static Properties**:
|
||||
- `DasSerialToConfigurationData { get; }`: Maps DAS serial numbers to `ConfigurationData`.
|
||||
- `Hardware { get; }`: List of `DASHardware` objects collected during hardware scan.
|
||||
|
||||
- **`HardwareScanRun(...)`**
|
||||
- **Signature**: `public static void HardwareScanRun(...)`
|
||||
- **Behavior**: Orchestrates hardware discovery and validation:
|
||||
1. Runs `PingSweep` to discover connected DAS units.
|
||||
2. Checks for armed DAS/TOM switches via `CheckForArmedAndSafe`.
|
||||
3. Validates G5 units have docking stations via `AnyDASMissingDockingStation`.
|
||||
4. Populates `Hardware`, `DasSerialToConfigurationData`, and voltage status metadata.
|
||||
- **Parameters**: Delegates for progress/status updates, cancellation checks, and UI interaction (e.g., `setProgress`, `setStatus`, `cancelCheck`).
|
||||
|
||||
- **`PingSweep(...)`**
|
||||
- **Behavior**: Performs network/USB ping sweep to discover DAS units. Initializes `HardwareDiscoveryTable` instances and invokes `HardwareDiscoveryControl.PingAndConnect`. Sets app busy state; clears `hardwareList` first.
|
||||
|
||||
- **`CheckForArmedAndSafe(...)`**
|
||||
- **Behavior**:
|
||||
- If any connected DAS is armed, shows warning, refreshes voltage status, and returns `true`.
|
||||
- Otherwise, prompts user to ensure TOM switches are in SAFE position (blocks until safe). Returns `false`.
|
||||
|
||||
- **`GetStatusColor(string color)`**
|
||||
- **Behavior**: Maps voltage status color strings (`"Red"`, `"Yellow"`, `"Green"`) to `SolidColorBrush` instances (e.g., `BrushApplicationStatusPowerRed`).
|
||||
|
||||
- **Other Private Helpers**:
|
||||
- `AnySwitchedToArm(...)`, `AnyDASMissingDockingStation(...)`, `PopulateSerialToDAS(...)`, `FindSensorsFromIncludedDAS(...)`, `ManageNeededDAS(...)`, `CountEIDAndSetVoltageStatus(...)`, `PopulateDasSerialToConfigurationData(...)`: Internal logic for hardware discovery, validation, and metadata collection.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
1. **Progress Values**: `StatusUpdater.SetProgress` ensures `ProgressBarValue` is always an integer in [0, 100].
|
||||
2. **Import File Validation**: `ParseImportFactory.CreateParseImport` rejects non-existent files and unsupported extensions (including ISF in strict ISO mode).
|
||||
3. **Hardware Safety**: `ImportFunctions.HardwareScanRun` blocks import if any DAS is armed or TOM switches are not SAFE.
|
||||
4. **G5 Docking Station**: Import fails if a connected G5 DAS reports a missing docking station.
|
||||
5. **Status Text Composition**: `StatusUpdater.SetStatus` appends error text to status text *only* if non-null/whitespace, with `" - "` separator.
|
||||
6. **UI Thread Safety**: All `App.DoMessageBox` and `Application.Current.Dispatcher.BeginInvoke` calls ensure UI operations occur on the UI thread.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
- **Imports/References**:
|
||||
- `DTS.Common.*` (e.g., `DTS.Common.Import`, `DTS.Common.DataModel`, `DTS.Common.BrushesAndColors`)
|
||||
- `DataPROWin7.Common`, `DataPROWin7.DataModel`
|
||||
- WPF namespaces (`System.Windows`, `System.Windows.Media`)
|
||||
- `DTS.Slice.Users` (for `User` and settings)
|
||||
- `DTS.Common.Settings` (e.g., `Properties.Settings.Default`)
|
||||
- **Key External Services**:
|
||||
- `App.DoMessageBox`, `App.SetAppBusy`, `App.SetAppAvailable`
|
||||
- `ConfigurationService.CheckArmSwitch`
|
||||
- `HardwareDiscoveryControl.PingAndConnect`, `HardwareDiscoveryControl.RefreshVoltageStatus`
|
||||
- `TestSetupDefaults.GetUserSettings`
|
||||
- `StringResources.ResourceManager`
|
||||
- **Consumed Interfaces**: `IParseImport`, `IParseVariant`, `IImportNotification`, `IDASCommunication`, `IDASHardware`
|
||||
- **Depended Upon**:
|
||||
- `StatusAndProgressBarViewModel` (via `StatusUpdater`)
|
||||
- `DataPROPage` (for `AnyArmed` check)
|
||||
- `DASFactory` (via `((App)Application.Current).DASFactory`)
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
1. **Progress Value Ambiguity**: `StatusUpdater.SetProgress` normalizes inputs ≤1 to percentages, but callers may inconsistently pass decimals (0–1) or percentages (0–100). This is explicitly noted in the source comment.
|
||||
2. **ISF Import Block**: ISF imports are disabled *only* when `UniqueISOCodesRequired && ShowISOCodes` are both true. Otherwise, ISF may be allowed.
|
||||
3. **`ReportErrors` Mutation**: Reassigning `errors = distinct` has no effect outside the method (C# passes reference *by value*). Callers must use the returned deduplicated list if needed (but none is returned).
|
||||
4. **`AnySwitchedToArm` Safety**: Returns `true` on any exception to avoid false negatives (i.e., proceeding when a DAS *might* be armed).
|
||||
5. **Hardware Discovery State**: `DasSerialToConfigurationData` and `Hardware` are static and shared across calls—state must be cleared/refreshed between import sessions.
|
||||
6. **`GetTestSetupImportDefaults` Fallback**: If user settings fail to load, defaults are returned as empty (no explicit fallback values), potentially causing import misconfiguration.
|
||||
7. **`CountEIDAndSetVoltageStatus` Logic**: EIDs (sensor IDs) are counted per module, but squib channels on odd indices are skipped. This may be non-intuitive.
|
||||
8. **`PingSweep` Synchronization**: Uses `ManualResetEvent` to ensure `includedTable`/`availableTable` initialization completes before proceeding. Blocking on UI thread could cause deadlocks if misused.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,139 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Classes/UserISOUtility.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Classes/DigitalInputPopulateChannels.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Classes/SquibPopulateChannels.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Classes/AnalogPopulateChannels.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Classes/DASPopulateChannels.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Classes/DigitalOutputPopulateChannels.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Classes/SensorsPopulateChannels.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Classes/SummaryRowHelper.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Classes/GroupChannelHelper.cs
|
||||
generated_at: "2026-04-16T04:20:26.330131+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "8f0536e102b7ae08"
|
||||
---
|
||||
|
||||
# Documentation: Test Setup Import Channel Population Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module handles the population and synchronization of channel models between hardware (DAS), sensors, and test setup group channels during test setup import. It bridges the gap between raw hardware channel data (`IDASHardware`, `IHardwareChannel`), sensor definitions (`SensorData`), and logical groupings in the test template (`TestTemplate.ChannelsForGroup`). The module ensures that hardware channels are correctly mapped to sensors and that channel-specific properties (e.g., ISO/user codes, squib/fire settings, digital output modes) are propagated to the appropriate logical channel representations. It supports multiple channel types—Analog, Digital Input, Digital Output, and Squib—via dedicated populate classes implementing shared interfaces.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Static Classes
|
||||
|
||||
#### `UserCodeISOUtility`
|
||||
- **`ShowUserCode()`** (`bool`)
|
||||
Returns `true` if the current `ISOViewMode` setting is `ISOAndUserCode` or `UserCodeOnly`. Controls visibility of user-defined channel names/codes in UI.
|
||||
- **`ShowISOCode()`** (`bool`)
|
||||
Returns `true` if the current `ISOViewMode` setting is `ISOAndUserCode` or `ISOOnly`. Controls visibility of ISO-standard channel names/codes in UI.
|
||||
|
||||
### Classes Implementing `ISensorsPopulateChannels` and/or `IDASPopulateChannels`
|
||||
|
||||
#### `DigitalInputPopulateChannels`
|
||||
- **Constructor**: Not exposed (no public constructor defined; relies on dependency injection or external instantiation).
|
||||
- **`PopulateDASChannels(...)`** (`IEnumerable<DASChannelModel>`)
|
||||
Filters hardware channels to those where `IsDigitalIn == true`, then delegates to `DASPopulateChannels`.
|
||||
- **`PopulateSensorsChannels(...)`** (`IEnumerable<ChannelModel>`)
|
||||
Filters sensors to those where `IsDigitalInput() == true`, then delegates to `SensorsPopulateChannels`.
|
||||
|
||||
#### `SquibPopulateChannels`
|
||||
- **`PopulateDASChannels(...)`** (`IEnumerable<DASChannelModel>`)
|
||||
Filters hardware channels to those where `IsSquib == true`, *excluding odd-numbered channels* (per `ch.IsSquib && 1 == ch.ChannelNumber % 2` check in `DASPopulateChannels`). Delegates to `DASPopulateChannels`.
|
||||
- **`PopulateSensorsChannels(...)`** (`IEnumerable<ChannelModel>`)
|
||||
Filters sensors to those where `IsSquib() == true`, then delegates to `SensorsPopulateChannels`.
|
||||
|
||||
#### `AnalogPopulateChannels`
|
||||
- **Constructor**: `AnalogPopulateChannels(Dictionary<string, string> hardwareChannelIdToSensorId)`
|
||||
Initializes with a mapping from hardware channel IDs to sensor EIDs.
|
||||
- **`PopulateDASChannels(...)`** (`IEnumerable<DASChannelModel>`)
|
||||
Filters hardware channels to those where `IsAnalog == true`, then delegates to `DASPopulateChannels`.
|
||||
- **`PopulateSensorsChannels(...)`** (`IEnumerable<ChannelModel>`)
|
||||
Filters sensors to those where `IsAnalog() == true`, then delegates to `SensorsPopulateChannels`.
|
||||
|
||||
#### `DigitalOutputPopulateChannels`
|
||||
- **Constructor**: `DigitalOutputPopulateChannels(Dictionary<string, string> hardwareChannelIdToSensorId)`
|
||||
Initializes with a mapping from hardware channel IDs to sensor EIDs.
|
||||
- **`PopulateDASChannels(...)`** (`IEnumerable<DASChannelModel>`)
|
||||
Filters hardware channels to those where `IsDigitalOut == true`. For each channel:
|
||||
- If a mapping exists (`HardwareChannelIdToSensorId`), assigns `EID`.
|
||||
- If a corresponding `IGroupChannel` exists (via `channelIdToGroupChannel`), copies digital output settings (`DigitalOutputMode`, `DigitalOutputDurationMs`, etc.) and creates/updates `ChannelModel`.
|
||||
- Otherwise, creates a new `ChannelModel` with default digital output settings.
|
||||
|
||||
#### `DASPopulateChannels`
|
||||
- **Constructor**: `DASPopulateChannels(Dictionary<string, string> hardwareChannelIdToSensorId, Predicate<IHardwareChannel> hardwareChannelFilter)`
|
||||
Stores hardware channel filter and EID mapping.
|
||||
- **`PopulateDASChannels(...)`** (`IEnumerable<DASChannelModel>`)
|
||||
Iterates over DAS hardware (skipping SLICE Ethernet controllers), applies filter, and:
|
||||
- Skips squib channels on odd channel numbers (`ch.IsSquib && 1 == ch.ChannelNumber % 2`).
|
||||
- Creates `DASChannelModel` for each qualifying hardware channel.
|
||||
- If `HardwareChannelIdToSensorId` contains the channel ID, assigns `EID`, then attempts to link to `IGroupChannel` via sensor lookup.
|
||||
- Populates `channelIdToDASChannel` dictionary.
|
||||
|
||||
#### `SensorsPopulateChannels`
|
||||
- **Constructor**: `SensorsPopulateChannels(Predicate<SensorData> channelTypeFilter)`
|
||||
Stores sensor type filter.
|
||||
- **`GetSensorToChannels(...)`** (`Dictionary<int, List<IGroupChannel>>`)
|
||||
Returns group channels grouped by `SensorId`, removing channels with `SensorId == 0`.
|
||||
- **`BuildHardwareLookup(...)`** (`void`)
|
||||
Links `IGroupChannel.HardwareChannel` by matching `DASId` and `DASChannelIndex` to hardware.
|
||||
- **`PopulateSensorsChannels(...)`** (`IEnumerable<ChannelModel>`)
|
||||
Filters sensors using `_channelTypeFilter`, then builds assigned `ChannelModel`s for sensors with hardware channels, or unassigned models otherwise. Calls `SetPropertiesFromGroupChannel` to copy settings.
|
||||
|
||||
### Helper Classes
|
||||
|
||||
#### `SummaryRowHelper`
|
||||
- **`GetSummaries(...)`** (`void`)
|
||||
Populates `found`, `missing`, and `extra` lists based on comparison between test setup sensors and DAS hardware channels. Uses `GetFoundEids`, `GetSummaryRowFound`, `GetSummaryRowMissing`, and `GetSummaryRowExtraEids` internally. Includes logic to exclude TOM squib odd channels and handle missing sensor descriptions.
|
||||
|
||||
#### `GroupChannelHelper`
|
||||
- **`UpdateGroupChannelsInTestTemplate(...)`** (`void`)
|
||||
Synchronizes `IGroupChannel` instances in `TestTemplate.ChannelsForGroup` with `DASChannelModel`s from all channel types. Handles:
|
||||
- Updating existing group channels with new sensor assignments.
|
||||
- Removing group channels with no sensor.
|
||||
- Creating new group channels for newly assigned sensors.
|
||||
- Preserving hardware channel assignments from previous runs (FB 31874).
|
||||
- Copying channel-specific properties (squib, digital output, analog, etc.) via `AssignProperties`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Hardware Channel Filtering**: Each `Populate*Channels` class enforces a specific filter on hardware channels (e.g., `IsAnalog`, `IsDigitalIn`, `IsSquib`, `IsDigitalOut`). Filters are applied in `DASPopulateChannels` and `DigitalOutputPopulateChannels`.
|
||||
- **Squib Channel Exclusion**: For squib channels, odd-numbered channels (`ChannelNumber % 2 == 1`) are *always skipped* during DAS population (FB 43723).
|
||||
- **EID Mapping**: `HardwareChannelIdToSensorId` is used to map hardware channels to sensor EIDs. If absent, no sensor assignment occurs.
|
||||
- **Hardware Channel Uniqueness**: Each hardware channel ID maps to at most one `DASChannelModel` in `channelIdToDASChannel`.
|
||||
- **Group Channel Consistency**: `GroupChannelHelper.UpdateGroupChannelsInTestTemplate` ensures that:
|
||||
- Group channels with no hardware channel are removed *unless* they were pre-assigned (FB 31874).
|
||||
- Sensor assignments are updated only if a valid `SerialNumber` exists in the `DASChannelModel`.
|
||||
- Channel properties (e.g., `Range`, `Polarity`, `SquibFireMode`, `DigitalOutputMode`) are copied from `DASChannelModel` to `IGroupChannel`.
|
||||
- **ISO/User Code Visibility**: `ShowUserCode()` and `ShowISOCode()` depend solely on `Common.SerializedSettings.ISOViewMode`, which must be set before calling.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports/Usings (External)
|
||||
- `DTS.Common.*`: Core enums (`IsoViewMode`, `Sensors.SensorConstants`), interfaces (`IDASHardware`, `IHardwareChannel`, `IGroupChannel`, `ISensorData`, `IDASCommunication`), classes (`ChannelRepresentation`, `DASHardware`, `GroupChannel`, `SummaryRow`), and utilities (`Logging.APILogger`, `SharedResource.Strings.StringResources`).
|
||||
- `DTS.SensorDB`: `SensorData`, `DbOperations`.
|
||||
- `DataPROWin7.DataModel`: `TestTemplate`, `ChannelModel`, `DASChannelModel`, `DASHardware`.
|
||||
- `System.*`: LINQ, collections, predicates.
|
||||
|
||||
### Module Dependencies
|
||||
- **Consumers**: Likely invoked during test setup import (e.g., `ImportObject`, `TestSetupImporter`).
|
||||
- **Depends on**:
|
||||
- `Common.SerializedSettings.ISOViewMode` (for `UserCodeISOUtility`).
|
||||
- `TestTemplate.ChannelsForGroup` (for `GroupChannelHelper`).
|
||||
- `Sensors()` and `TestSetups()` from `ImportObject` (for `SummaryRowHelper`).
|
||||
- Hardware configuration (`IDASHardware`, `IDASCommunication`) from DAS devices.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Squib Odd-Channel Exclusion**: The `DASPopulateChannels.PopulateDASChannels` method *unconditionally skips* squib channels on odd channel numbers (`1 == ch.ChannelNumber % 2`). This is hardcoded and applies to all callers, not just `SquibPopulateChannels`. Ensure hardware configuration accounts for this.
|
||||
- **SLICE Ethernet Controller Skipping**: `DASPopulateChannels` skips any DAS where `IsSLICEEthernetController == true`. This may cause channels on such devices to be silently ignored.
|
||||
- **`HardwareChannelIdToSensorId` Requirement**: If this dictionary is empty or missing keys, `DASChannelModel.EID` will not be assigned, and sensor linking will fail.
|
||||
- **`CleanSerialNumber` Logic**: `GroupChannelHelper.CleanSerialNumber` replaces test-specific serial numbers (e.g., `"TEST_SPECIFIC_ANALOG_SERIAL"`) with the constant string, but only if the input matches *exactly* the resource string value. This may cause mismatches if the constant is updated.
|
||||
- **Digital Output Channel Assignment**: `DigitalOutputPopulateChannels` relies on `IGroupChannel.HardwareChannel` being pre-assigned (via `DASChannelIndex` and `DASId`) to link to existing group channels. If hardware channel assignment is missing, new group channels are created.
|
||||
- **FB References**: Comments like `//FB 41819` refer to internal bug/feature numbers. These may be useful for historical context but are not self-documenting.
|
||||
- **No Public Constructors**: `DigitalInputPopulateChannels`, `SquibPopulateChannels`, and `AnalogPopulateChannels` lack public constructors, implying instantiation is handled externally (e.g., via DI or factory). This is not explicit in the source.
|
||||
- **Event Subscription**: `DigitalOutputPopulateChannels` subscribes to `DigitalOutputChannelChanged` on `DASChannelModel`. Ensure event handlers are cleaned up to avoid memory leaks if instances are reused.
|
||||
- **`GetSummaries` Side Effects**: `GetSummaries` modifies `ref` lists (`found`, `missing`, `extra`) and uses `importObject.TestSetups().First()`—assumes at least one test setup exists.
|
||||
@@ -0,0 +1,114 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Events/DisableNavStepsEventArgs.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Events/DigitalOutputChannelEventArgs.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Events/ImportTestSetupEventArgs.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Events/ImportProcessStatusEventArgs.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Events/ReadFileStatusEventArgs.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Events/HardwareScanEventArgs.cs
|
||||
generated_at: "2026-04-16T04:20:44.151483+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "c6dc961ccabaff2e"
|
||||
---
|
||||
|
||||
# Events
|
||||
|
||||
## Documentation: Test Setup Import Event Argument Classes
|
||||
|
||||
### 1. Purpose
|
||||
This module defines a set of custom `EventArgs` subclasses used to carry state and metadata during asynchronous or event-driven operations in the test setup import workflow. These classes facilitate communication between UI components (e.g., import dialogs, progress indicators) and background import logic—such as file reading, hardware scanning, and process status updates—by encapsulating operation outcomes, associated data (e.g., imported objects, hardware lists), and error details. They serve as the standardized payload type for events raised during import operations within the `DataPROWin7.Controls.TestSetups.Import` and `DataPROWin7.Controls.TestSetups` namespaces.
|
||||
|
||||
### 2. Public Interface
|
||||
All classes are `public` and inherit from `System.EventArgs`. None expose methods beyond the default constructor and property accessors.
|
||||
|
||||
- **`DisableNavStepsEventArgs`**
|
||||
```csharp
|
||||
public class DisableNavStepsEventArgs : EventArgs
|
||||
{
|
||||
public bool Status { get; set; }
|
||||
}
|
||||
```
|
||||
Carries a boolean flag indicating whether navigation steps (e.g., Next/Back buttons in a wizard) should be disabled (`Status == true`) or enabled (`Status == false`) during an import operation.
|
||||
|
||||
- **`DigitalOutputChannelEventArgs`**
|
||||
```csharp
|
||||
public class DigitalOutputChannelEventArgs : EventArgs
|
||||
{
|
||||
public bool Removed { get; set; }
|
||||
public bool Added { get; set; }
|
||||
}
|
||||
```
|
||||
Indicates changes to digital output channel configuration. `Removed` and `Added` are mutually exclusive flags (though not enforced by this class); one or both may be `true` depending on the operation (e.g., removal only, addition only, or replacement).
|
||||
|
||||
- **`ImportTestSetupEventArgs`**
|
||||
```csharp
|
||||
public class ImportTestSetupEventArgs : EventArgs
|
||||
{
|
||||
public ImportTestSetupEventArgs(string testSetupName);
|
||||
public string TestSetupName { get; set; }
|
||||
}
|
||||
```
|
||||
Signals that a specific test setup has been imported or is being processed. `TestSetupName` holds the name of the imported test setup.
|
||||
|
||||
- **`ImportProcessStatusEventArgs`**
|
||||
```csharp
|
||||
public class ImportProcessStatusEventArgs : EventArgs
|
||||
{
|
||||
public ImportProcessStatusEventArgs(bool status, string errorMessage = null);
|
||||
public bool Status { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
}
|
||||
```
|
||||
Reports the overall status of the import process. `Status == true` indicates success; `false` indicates failure, with `ErrorMessage` providing optional diagnostic details.
|
||||
|
||||
- **`ReadFileStatusEventArgs`**
|
||||
```csharp
|
||||
public class ReadFileStatusEventArgs : EventArgs
|
||||
{
|
||||
public ReadFileStatusEventArgs(bool status, ImportObject importObject = null, string errorMessage = null);
|
||||
public bool Status { get; set; }
|
||||
public ImportObject ImportObject { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
}
|
||||
```
|
||||
Reports the result of reading an import file. `Status` indicates success/failure; `ImportObject` contains the parsed data if successful; `ErrorMessage` provides failure details.
|
||||
|
||||
- **`HardwareScanEventArgs`**
|
||||
```csharp
|
||||
public class HardwareScanEventArgs : EventArgs
|
||||
{
|
||||
public HardwareScanEventArgs(bool status, List<DASHardware> hardware, ImportObject importObject = null, string erroeMessage = null);
|
||||
public bool Status { get; set; }
|
||||
public List<DASHardware> Hardware { get; set; }
|
||||
public ImportObject ImportObject { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
}
|
||||
```
|
||||
Reports the result of a hardware scan performed during import. `Status` indicates success/failure; `Hardware` contains the discovered hardware list if successful; `ImportObject` may reference the source file’s import context; `ErrorMessage` provides failure details.
|
||||
⚠️ **Note**: Constructor parameter `erroeMessage` is misspelled (should be `errorMessage`); this typo is preserved in the source.
|
||||
|
||||
### 3. Invariants
|
||||
- All `Status` properties are boolean and intended to be interpreted as: `true` = success, `false` = failure.
|
||||
- In `HardwareScanEventArgs`, `ErrorMessage` is misspelled as `erroeMessage` in the constructor parameter (but the property is correctly named `ErrorMessage`).
|
||||
- `DigitalOutputChannelEventArgs.Removed` and `Added` are *not* enforced as mutually exclusive by the class—consumers must handle cases where both are `true` or both `false`.
|
||||
- `ImportTestSetupEventArgs` requires `testSetupName` in its constructor; `TestSetupName` is non-null after construction.
|
||||
- `ImportProcessStatusEventArgs` and `ReadFileStatusEventArgs` allow `errorMessage` to be `null` (default), indicating no error details.
|
||||
- `HardwareScanEventArgs.Hardware` may be `null` on failure (not guaranteed non-null on success).
|
||||
|
||||
### 4. Dependencies
|
||||
- **Internal dependencies**:
|
||||
- `DTS.Common.Import.ImportObject` (used in `ReadFileStatusEventArgs`, `HardwareScanEventArgs`)
|
||||
- `DataPROWin7.DataModel.DASHardware` (used in `HardwareScanEventArgs`)
|
||||
- **External dependencies**:
|
||||
- `System` (standard .NET Framework types: `EventArgs`, `List<T>`, `string`, `bool`)
|
||||
- **Consumers**:
|
||||
- Likely used by event handlers in UI controls (e.g., import wizard, progress forms) and background import services within `DataPROWin7.Controls.TestSetups.*`.
|
||||
- No direct usage is visible in the provided source; inferred from namespace structure and naming conventions.
|
||||
|
||||
### 5. Gotchas
|
||||
- **Typo in `HardwareScanEventArgs`**: Constructor parameter `erroeMessage` (instead of `errorMessage`) is a clear typo and could cause confusion or misalignment with documentation. This may have been introduced historically and is not self-correcting.
|
||||
- **Ambiguity in `DigitalOutputChannelEventArgs`**: The class does not enforce that exactly one of `Removed` or `Added` is `true`. Callers must ensure logical consistency (e.g., via validation or documentation).
|
||||
- **`ImportObject` nullability**: In `ReadFileStatusEventArgs` and `HardwareScanEventArgs`, `ImportObject` is optional and may be `null` even on success (e.g., if parsing succeeds but no import context is available).
|
||||
- **No validation on `TestSetupName`**: `ImportTestSetupEventArgs` accepts any non-null string; no sanitization or format checks are performed.
|
||||
- **No inheritance hierarchy**: All classes are standalone; no shared base or interface is defined for uniform error handling (e.g., `IHasErrorMessage`).
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Interfaces/ITestSetupValidation.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Interfaces/ISensorsPopulateChannels.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Interfaces/IDASPopulateChannels.cs
|
||||
generated_at: "2026-04-16T04:21:31.781073+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "02423d24ad303aec"
|
||||
---
|
||||
|
||||
# Interfaces
|
||||
|
||||
### **Purpose**
|
||||
This module defines a set of interfaces that govern the validation and channel-population logic for importing test setups within the DataPRO system. It serves as a contract layer between the import workflow and concrete implementations responsible for ensuring data integrity (via validation) and correctly mapping hardware, sensors, and channels into the target `TestTemplate` model. Its existence enables decoupled, testable, and pluggable import behavior—specifically supporting scenarios where imported test setups must be checked for duplicates, marked with failure status, and populated with sensor and DAS (Data Acquisition System) channel data.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
#### `ITestSetupValidation`
|
||||
- **`void ValidateList()`**
|
||||
Performs validation on the list of test setups pending import. Expected to detect issues such as missing required fields, invalid configurations, or other business rule violations. Does not return a result; side effects (e.g., updating internal state or UI) are implied.
|
||||
|
||||
- **`void SetProcessFailedStatus()`**
|
||||
Marks the current import process as failed. Likely updates internal state (e.g., a flag or status property) used elsewhere to abort or rollback the import.
|
||||
|
||||
- **`int CheckForDuplicatesInImport(string importingTestSetupName)`**
|
||||
Checks whether a test setup with the given `importingTestSetupName` already exists in the current import batch or target dataset. Returns the count of duplicate occurrences (e.g., `0` if unique, `>0` if duplicates exist). *Note: The exact scope of “duplicate” (e.g., name-only vs. full identity) is not specified in the interface.*
|
||||
|
||||
#### `ISensorsPopulateChannels`
|
||||
- **`IEnumerable<ChannelModel> PopulateSensorsChannels(TestTemplate testTemplate, IEnumerable<DASHardware> hardware, IEnumerable<SensorData> sensors, ref Dictionary<string, DASChannelModel> channelIdToDASChannel)`**
|
||||
Populates sensor-derived channel data into the `testTemplate`, using provided hardware and sensor metadata. Returns an `IEnumerable<ChannelModel>` representing the newly created or updated channels. The `channelIdToDASChannel` dictionary is passed by reference and likely used to track or link DAS channel mappings during population.
|
||||
|
||||
#### `IDASPopulateChannels`
|
||||
- **`Dictionary<string, string> HardwareChannelIdToSensorId { get; set; }`**
|
||||
A bidirectional or unidirectional mapping (implementation-defined) from hardware channel identifiers to sensor identifiers. Used to correlate physical channels with logical sensor definitions.
|
||||
|
||||
- **`TestTemplate TestSetup { get; set; }`**
|
||||
The target test setup model being populated. Set prior to calling `PopulateDASChannels`.
|
||||
|
||||
- **`IEnumerable<SensorData> Sensors { get; set; }`**
|
||||
The collection of sensor metadata to be applied during channel population.
|
||||
|
||||
- **`IEnumerable<DASChannelModel> PopulateDASChannels(TestTemplate testTemplate, IEnumerable<SensorData> sensors, List<DTS.Common.Interface.DataRecorders.IDASHardware> hardware, ref Dictionary<string, DASChannelModel> channelIdToDASChannel)`**
|
||||
Populates DAS-specific channel models into the `testTemplate`, using sensor and hardware data. Returns an `IEnumerable<DASChannelModel>` of the created channels. The `channelIdToDASChannel` dictionary is updated by reference and likely used to maintain a live index of channel IDs to `DASChannelModel` instances.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
- **`ITestSetupValidation`**
|
||||
- `ValidateList()` must be called before `SetProcessFailedStatus()` in a typical import flow, though the interface does not enforce ordering.
|
||||
- `CheckForDuplicatesInImport()` must be deterministic for the same `importingTestSetupName` within a single import session (i.e., no side effects altering its own behavior mid-session).
|
||||
- No invariant on whether `ValidateList()` clears prior validation state; behavior depends on implementation.
|
||||
|
||||
- **`ISensorsPopulateChannels` and `IDASPopulateChannels`**
|
||||
- The `channelIdToDASChannel` dictionary must be initialized by the caller before invocation and may be mutated during population.
|
||||
- The `TestTemplate` passed to `PopulateSensorsChannels`/`PopulateDASChannels` must be non-null and mutable (i.e., modifiable in-place).
|
||||
- For `IDASPopulateChannels`, the `HardwareChannelIdToSensorId` dictionary must be set before calling `PopulateDASChannels`; otherwise, behavior is undefined.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
- **Imports/References**
|
||||
- `DataPROWin7.Controls.TestSetups.Import.Models` (for `ChannelModel`, `TestTemplate`, `DASChannelModel`)
|
||||
- `DataPROWin7.DataModel` (likely contains core domain types like `TestTemplate`)
|
||||
- `DTS.SensorDB` (for `SensorData`, `DASHardware`)
|
||||
- `DTS.Common.Import` (for `DASChannelModel` in `IDASPopulateChannels`)
|
||||
- `DTS.Common.Interface.DataRecorders.IDASHardware` (for hardware abstraction in `IDASPopulateChannels`)
|
||||
- `System.Collections.Generic` (for `IEnumerable<T>`, `Dictionary<TKey, TValue>`, `List<T>`)
|
||||
|
||||
- **Depended upon by**
|
||||
- Concrete import service classes (e.g., `TestSetupImportService`) that implement `ITestSetupValidation`, `ISensorsPopulateChannels`, and `IDASPopulateChannels`.
|
||||
- UI or orchestration layers that drive the import workflow and require pluggable validation or channel-population strategies.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
- **Ambiguity in `CheckForDuplicatesInImport` scope**: The interface does not clarify whether duplicates are checked against the *current import batch*, *existing database records*, or both. Implementation must be verified.
|
||||
- **`ref` parameter semantics**: The `channelIdToDASChannel` dictionary is passed by reference in both `ISensorsPopulateChannels` and `IDASPopulateChannels`. Callers must ensure it is initialized before invocation, and implementations may clear, add, or replace entries—behavior not constrained by the interface.
|
||||
- **`IDASPopulateChannels` property naming**: The property `HardwareChannelIdToSensorId` suggests a mapping *from* hardware channels *to* sensors, but the interface does not specify directionality or whether it supports reverse lookups.
|
||||
- **No error handling contract**: None of the interfaces declare exceptions or return error codes. Callers must assume failures may occur silently or via side effects (e.g., `SetProcessFailedStatus()`).
|
||||
- **`DASHardware` vs `IDASHardware`**: `ISensorsPopulateChannels` uses `DASHardware` (likely a concrete type), while `IDASPopulateChannels` uses `IDASHardware` (an interface). This inconsistency may indicate legacy or platform-specific divergence.
|
||||
@@ -0,0 +1,311 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Models/TestSetupModel.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Models/SummaryChannelModel.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Models/ChannelSummaryRow.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Models/SummaryRow.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Models/DASRow.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Models/DASSummaryRow.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Models/ChannelModel.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Models/DASChannelModel.cs
|
||||
generated_at: "2026-04-16T04:21:17.003966+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "c6d2c56784c09efc"
|
||||
---
|
||||
|
||||
# Documentation: Test Setup Import Models
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides data models for representing and manipulating test setup channel configurations during import operations in the DataPRO application. It serves as the data layer for UI components that display, validate, and allow editing of channel assignments between physical DAS hardware channels and logical sensor records. The models bridge the gap between low-level hardware interfaces (`IHardwareChannel`, `IDASCommunication`) and high-level UI requirements (e.g., summary tables, validation indicators), supporting operations such as sensor assignment, configuration synchronization, and status reporting (e.g., EID counts, voltage status, channel type summaries).
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `TestSetupModel`
|
||||
- **`List<ChannelModel> Channels { get; set; }`**
|
||||
Collection of logical `ChannelModel` instances representing sensor/channel assignments.
|
||||
- **`ObservableCollection<DASChannelModel> DASChannels { get; set; }`**
|
||||
Collection of `DASChannelModel` instances representing physical DAS hardware channels.
|
||||
|
||||
### `SummaryChannelModel`
|
||||
- **`string ChannelType { get; set; }`**
|
||||
Type of channel (e.g., "Analog", "Squib").
|
||||
- **`int Assigned { get; set; }`**
|
||||
Number of channels of this type that are assigned to sensors.
|
||||
- **`string Unassigned { get; set; }`**
|
||||
String representation of unassigned channel count (likely for display formatting).
|
||||
|
||||
### `ChannelSummaryRow`
|
||||
- **`ChannelSummaryRow(string channelType, int requested, int assigned, int unassigned)`**
|
||||
Constructor initializing summary statistics for a channel type.
|
||||
- **`string ChannelType { get; }`**
|
||||
Channel type identifier.
|
||||
- **`int Requested { get; }`**
|
||||
Total requested channels of this type.
|
||||
- **`int Assigned { get; }`**
|
||||
Number of assigned channels.
|
||||
- **`int Unassigned { get; }`**
|
||||
Number of unassigned channels.
|
||||
- **`void AddCount(bool assigned)`**
|
||||
Increments `Requested` and either `Assigned` or `Unassigned` based on `assigned`.
|
||||
- **`SolidColorBrush UnassignedColor { get; }`**
|
||||
Returns `Brush_ApplicationStatus_Failed` if any unassigned channels exist, otherwise `Brush_ApplicationStatus_Complete`.
|
||||
|
||||
### `SummaryRow`
|
||||
- **`SummaryRow(int number, string description, string serialNumber, string sensorTag, string eid, string location)`**
|
||||
Constructor for rows in "Extra/Found/Missing" tables in sensor import summary.
|
||||
- **`int Number { get; set; }`**
|
||||
Channel number (not index), if available.
|
||||
- **`string Description { get; set; }`**
|
||||
Channel description.
|
||||
- **`string SerialNumber { get; set; }`**
|
||||
Sensor serial number.
|
||||
- **`string SensorTag { get; set; }`**
|
||||
Sensor tag (e.g., "CF", "P4").
|
||||
- **`string EID { get; set; }`**
|
||||
Electronic ID on the sensor.
|
||||
- **`string Location { get; set; }`**
|
||||
Physical location of the sensor.
|
||||
|
||||
### `DASRow`
|
||||
- **`DASRow(IDASCommunication das)`**
|
||||
Constructor that initializes DAS hardware metadata and counts valid EIDs from configuration.
|
||||
- **`string SerialNumberFamily { get; }`**
|
||||
Serial number of the DAS hardware.
|
||||
- **`int EIDFound { get; }`**
|
||||
Count of valid EIDs found in DAS configuration (only for non-Ethernet distributors).
|
||||
- **`string InputVoltageStatus { get; }`**
|
||||
Voltage status string for input voltage.
|
||||
- **`SolidColorBrush InputVoltageColor { get; }`**
|
||||
Color brush corresponding to input voltage status.
|
||||
- **`string BatteryVoltageStatus { get; }`**
|
||||
Voltage status string for battery voltage.
|
||||
- **`SolidColorBrush BatteryVoltageColor { get; }`**
|
||||
Color brush corresponding to battery voltage status.
|
||||
|
||||
### `DASSummaryRow`
|
||||
- **`void AddDAS(DataModel.DASHardware das)`**
|
||||
Adds a DAS hardware instance to the summary and updates channel type counts.
|
||||
- **`HardwareTypes[] GetRelevantDAS()`**
|
||||
Returns array of hardware types present (non-empty).
|
||||
- **`int GetHardwareTypeOrder(HardwareTypes a)`**
|
||||
Returns display order integer for a given `HardwareTypes` enum value (custom ordering defined in `_hardwareDisplayOrder`).
|
||||
- **`int GetDASCount(HardwareTypes dasType)`**
|
||||
Returns count of DAS units of specified type.
|
||||
- **`void Clear()`**
|
||||
Resets all internal state (DAS list and channel counts).
|
||||
- **Properties (all `int`):**
|
||||
`Analog`, `Squib`, `DigitalIn`, `DigitalOut`, `StreamOut`, `UART`, `StreamIn`, `CAN`
|
||||
Represent counts of each channel type across all added DAS units.
|
||||
|
||||
### `ChannelModel`
|
||||
- **`ChannelModel()`**
|
||||
Default constructor initializing default values.
|
||||
- **`ChannelModel(SensorData sd)`**
|
||||
Constructor initializing from `SensorData`.
|
||||
- **`void InitializeFromGroupChannel(IGroupChannel groupChannel)`**
|
||||
Updates properties from a group channel (e.g., user overrides).
|
||||
- **`SensorData Sensor { get; set; }`**
|
||||
Underlying sensor data record.
|
||||
- **`IHardwareChannel HardwareChannel { get; set; }`**
|
||||
Associated hardware channel.
|
||||
- **`bool IsModified { get; set; }`**
|
||||
Flag indicating whether the record has been modified.
|
||||
- **`bool IsEmptyRecord { get; }`**
|
||||
Returns `true` if `ChannelCode == "None"` and `SensorSerialNumber` is null/empty.
|
||||
- **`bool IsChannelCodeValid { get; set; }`**
|
||||
Indicates whether `ChannelCode` is non-empty and not "None".
|
||||
- **`bool RemoveOffset { get; set; }`**
|
||||
Whether offset removal is enabled.
|
||||
- **`bool ProportionalToExcitation { get; set; }`**
|
||||
Whether sensor output is proportional to excitation.
|
||||
- **`double InitialOffsetVoltage { get; set; }`**
|
||||
Initial offset voltage.
|
||||
- **`double InitialOffsetVoltageTolerance { get; set; }`**
|
||||
Tolerance for initial offset voltage.
|
||||
- **`string SensorEU { get; set; }`**
|
||||
Engineering units of the sensor.
|
||||
- **`double BridgeResistance { get; set; }`**
|
||||
Bridge resistance.
|
||||
- **`string ChannelRangeString { get; set; }`**
|
||||
String representation of `ChannelRange` (formatted with `SYSTEMSETTING` format).
|
||||
- **`string ISOCode { get; set; }`**
|
||||
ISO standard code.
|
||||
- **`string ISODescription { get; set; }`**
|
||||
ISO channel description.
|
||||
- **`string ISOPolarity { get; set; }`**
|
||||
ISO polarity ("+" or "-").
|
||||
- **`bool IsSquib { get; set; }`**
|
||||
Whether channel is a squib.
|
||||
- **`bool IsDigitalInput { get; set; }`**
|
||||
Whether channel is digital input.
|
||||
- **`bool IsDigitalOutput { get; set; }`**
|
||||
Whether channel is digital output.
|
||||
- **`double InitialEUInMV { get; set; }`**
|
||||
Initial EU in millivolts.
|
||||
- **`double InitialEUInEU { get; set; }`**
|
||||
Initial EU in engineering units.
|
||||
- **`double IRTraccExponent { get; set; }`**
|
||||
IR Tracc linearization exponent.
|
||||
- **`string DASChannelString { get; }`**
|
||||
String representation of `HardwareChannel`.
|
||||
- **`string ChannelCode { get; set; }`**
|
||||
User-defined channel code.
|
||||
- **`string CustomCodeDescription { get; set; }`**
|
||||
Custom code description.
|
||||
- **`string SensorSerialNumber { get; set; }`**
|
||||
Sensor serial number.
|
||||
- **`string ChannelEID { get; set; }`**
|
||||
EID on the channel.
|
||||
- **`string SensorEID { get; }`**
|
||||
EID from `Sensor.EID` or backing field.
|
||||
- **`double SensorSensitivity { get; set; }`**
|
||||
Sensor sensitivity.
|
||||
- **`double SensorCapacity { get; set; }`**
|
||||
Sensor capacity.
|
||||
- **`bool SensorPolarity { get; set; }`**
|
||||
Sensor polarity (`true` = positive).
|
||||
- **`double ChannelRange { get; set; }`**
|
||||
Channel range.
|
||||
- **`IFilterClass FilterClass { get; set; }`**
|
||||
Software filter class.
|
||||
- **`bool IsRangeValid { get; set; }`**
|
||||
Whether `ChannelRange` is valid (>0 and not NaN).
|
||||
- **`double CableMultiplier { get; set; }`**
|
||||
Cable multiplier factor.
|
||||
- **`bool Disabled { get; set; }`**
|
||||
Whether channel is disabled.
|
||||
- **`double SensorExcitationVolts { get; }`**
|
||||
Excitation voltage magnitude from `Sensor.SupportedExcitation`.
|
||||
- **`SquibFireMode SquibFireMode { get; set; }`**
|
||||
Squib fire mode (`CAP` or `CONSTANT`).
|
||||
- **`double SquibFireDelayMs { get; set; }`**
|
||||
Delay between trigger and squib fire.
|
||||
- **`double SquibFireCurrent { get; set; }`**
|
||||
Squib fire current limit (amps).
|
||||
- **`bool LimitDuration { get; set; }`**
|
||||
Whether squib fire duration is limited.
|
||||
- **`double SquibFireDurationMs { get; set; }`**
|
||||
Squib fire duration (clamped to `DEFAULT_MIN_FIRE_DURATION_MS`/`DEFAULT_MAX_FIRE_DURATION_MS`).
|
||||
- **`double SquibFireResistanceLowOhm { get; set; }`**
|
||||
Squib resistance tolerance low (ohms).
|
||||
- **`double SquibFireResistanceHighOhm { get; set; }`**
|
||||
Squib resistance tolerance high (ohms).
|
||||
- **`DigitalInputModes DigitalInputMode { get; set; }`**
|
||||
Digital input mode.
|
||||
- **`DigitalOutputModes DigitalOutputMode { get; set; }`**
|
||||
Digital output mode.
|
||||
- **`double DigitalOutputDelay { get; set; }`**
|
||||
Digital output delay (ms).
|
||||
- **`double DigitalOutputDuration { get; set; }`**
|
||||
Digital output duration (ms).
|
||||
|
||||
### `DASChannelModel`
|
||||
- **`DASChannelModel(IHardwareChannel channel)`**
|
||||
Constructor wrapping a hardware channel.
|
||||
- **`void SetChannelModel(ChannelModel channel)`**
|
||||
Assigns/removes a `ChannelModel` to/from this hardware channel, updating bidirectional references and raising property change notifications.
|
||||
- **`DigitalOutputModes DigitalOutputMode { get; set; }`**
|
||||
Gets/sets digital output mode; raises `DigitalOutputChannelChanged` event on mode transitions.
|
||||
- **`double DigitalOutputDelayMs { get; set; }`**
|
||||
Digital output delay (ms).
|
||||
- **`double DigitalOutputDurationMs { get; set; }`**
|
||||
Digital output duration (ms).
|
||||
- **`string Polarity { get; set; }`**
|
||||
Sensor polarity ("+" or "-").
|
||||
- **`SquibFireMode SquibFireMode { get; set; }`**
|
||||
Squib fire mode.
|
||||
- **`bool Disabled { get; set; }`**
|
||||
Whether channel is disabled (via `DependencyProperty`).
|
||||
- **`ChannelModel Channel { get; private set; }`**
|
||||
Associated `ChannelModel` (sensor record).
|
||||
- **`string DASChannelString { get; }`**
|
||||
String representation of `HardwareChannel`.
|
||||
- **`string CustomCode { get; set; }`**
|
||||
Custom code description.
|
||||
- **`string EID { get; set; }`**
|
||||
Electronic ID on the channel.
|
||||
- **`string UserChannelName { get; set; }`**
|
||||
Channel code (user name).
|
||||
- **`string ISOCode { get; set; }`**
|
||||
ISO code.
|
||||
- **`string ISOChannelName { get; set; }`**
|
||||
ISO channel name.
|
||||
- **`string SerialNumber { get; }`**
|
||||
Sensor serial number (with special handling for test-specific serials).
|
||||
- **`double Sensitivity { get; }`**
|
||||
Sensor sensitivity.
|
||||
- **`string SensitivityString { get; }`**
|
||||
`Sensitivity` formatted to 12 decimal places.
|
||||
- **`bool IsActive { get; }`**
|
||||
`true` if channel has a record and is not a disabled digital output.
|
||||
- **`double Capacity { get; }`**
|
||||
Sensor capacity.
|
||||
- **`double Range { get; set; }`**
|
||||
Channel range.
|
||||
- **`IFilterClass FilterClass { get; set; }`**
|
||||
Filter class.
|
||||
- **`double CableMultiplier { get; set; }`**
|
||||
Cable multiplier.
|
||||
- **`double SquibFireDelayMs { get; set; }`**
|
||||
Squib fire delay.
|
||||
- **`double SquibFireCurrent { get; set; }`**
|
||||
Squib fire current limit.
|
||||
- **`bool LimitDuration { get; set; }`**
|
||||
Whether squib duration is limited.
|
||||
- **`double SquibFireDurationMs { get; set; }`**
|
||||
Squib fire duration.
|
||||
- **`double SquibFireResistanceLowOhm { get; set; }`**
|
||||
Squib resistance low tolerance.
|
||||
- **`double SquibFireResistanceHighOhm { get; set; }`**
|
||||
Squib resistance high tolerance.
|
||||
- **`IHardwareChannel HardwareChannel { get; }`**
|
||||
Wrapped hardware channel.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`ChannelModel.ChannelCode`** must not be `"None"` for a record to be considered non-empty (`IsEmptyRecord == false`).
|
||||
- **`ChannelModel.SquibFireDurationMs`** is always clamped to `[DEFAULT_MIN_FIRE_DURATION_MS, DEFAULT_MAX_FIRE_FIRE_DURATION_MS]` (enforced in setter).
|
||||
- **`ChannelSummaryRow.UnassignedColor`** is determined solely by `Unassigned > 0`.
|
||||
- **`DASSummaryRow._hardwareDisplayOrder`** defines explicit ordering for known hardware types; unknown types fall back to `_hardwareDisplayOrder.Count + (int)HardwareTypes`.
|
||||
- **`DASRow.EIDFound`** counts only valid EIDs from non-Ethernet-distributor DAS units (excludes `IsEthernetDistributor()` units).
|
||||
- **`DASChannelModel.Channel`** and `ChannelModel.HardwareChannel` are kept in sync: assigning a `ChannelModel` to a `DASChannelModel` sets `Channel.HardwareChannel = HardwareChannel`, and vice versa.
|
||||
- **`DASChannelModel.IsActive`** for digital outputs is `false` only if `DigitalOutputMode == DigitalOutputModes.NONE`.
|
||||
- **`DASChannelModel.SerialNumber`** returns a localized string for `TEST_SPECIFIC_ANALOG_SERIAL`; otherwise returns `Channel.SensorSerialNumber`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **`DTS.Common.*`**
|
||||
Core infrastructure: `BasePropertyChanged`, `HardwareTypes`, `DigitalInputModes`, `DigitalOutputModes`, `SquibFireMode`, `IFilterClass`, `IHardwareChannel`, `IGroupChannel`, `ExcitationVoltageOptions`, `SensorConstants`, `Logging.APILogger`, `SharedResource.Strings.StringResources`, `DAS.Concepts.Test.Module.Channel.Sensor`, `DASLib.Service.OutputSquibChannel`, `Enums.Hardware.HardwareConstants`.
|
||||
- **`DTS.SensorDB`**
|
||||
`SensorData` type.
|
||||
- **`DTS.Common.Interface.Channels`**
|
||||
`ChannelModel` uses `DASChannelModel` and `IGroupChannel`.
|
||||
- **`DTS.Common.Interface.DASFactory`**
|
||||
`IDASCommunication`.
|
||||
- **`DTS.DASLib.Service`**
|
||||
`OutputSquibChannel`, `HardwareConstants`.
|
||||
- **`System.Windows.Media`**
|
||||
`SolidColorBrush`, `BrushesAndColors` (via `ChannelSummaryRow.UnassignedColor`).
|
||||
- **`System.Collections.ObjectModel`**
|
||||
`ObservableCollection<T>`.
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- **UI Controls** (inferred from namespace `DataPROWin7.Controls.TestSetups.Import.Models`)
|
||||
Likely consumed by XAML views and view models for test setup import workflows (e.g., channel assignment grids, summary tables).
|
||||
- **Import Logic**
|
||||
Code in `DataPROWin7.Controls.TestSetups.Import.*` (e.g., view models, services) that populates and manipulates these models during import.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`ChannelModel.SquibFireDurationMs` setter silently clamps values** to min/max constants (`DEFAULT_MIN_FIRE_DURATION_MS`, `DEFAULT_MAX_FIRE_DURATION_MS`). No exception or warning is raised for out-of-range assignments.
|
||||
- **`DASRow.EIDFound` excludes Ethernet distributors** (`das.IsEthernetDistributor()`), but does not exclude SLICE Ethernet controllers (which are counted in `DASSummaryRow.AddChannelCountForDAS` only if not `IsSLICEEthernetController`).
|
||||
- **`DASSummaryRow.AddChannelCountForDAS` skips SLICE Ethernet controllers entirely** (`if (das.IsSLICEEthernetController) { return; }`), meaning no channel counts are accumulated for them.
|
||||
- **`DASChannelModel.Polarity` and `ChannelModel.SensorPolarity` use inverse semantics**: `SensorPolarity = true` means *positive* polarity (no inversion), while `Polarity` string is `"+"` for positive.
|
||||
- **`DASChannelModel.SerialNumber` has special handling for `TEST_SPECIFIC_ANALOG_SERIAL`**, returning a localized string via `StringResources`; other values are returned as-is.
|
||||
- **`ChannelModel.ChannelRangeString` setter parses and updates `ChannelRange`**, but also sets `IsRangeValid = true` on success — this may overwrite prior validation state.
|
||||
- **`DASSummaryRow.GetHardwareTypeOrder` for unknown hardware types uses `_hardwareDisplayOrder.Count + (int)HardwareTypes`**, which may cause ordering instability if new hardware types are added without updating `_hardwareDisplayOrder`.
|
||||
- **`ChannelModel.InitializeFromGroupChannel` logs exceptions via `APILogger.Log(ex)` but does not propagate them**, potentially masking configuration errors.
|
||||
- **`DASChannelModel.SetChannelModel` raises many `OnPropertyChanged` notifications** (e.g., for `IsActive`, `SerialNumber`, `SquibFireDelayMs`) — callers should be aware of
|
||||
@@ -0,0 +1,242 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/ViewModels/HardwareScanViewModel.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/ViewModels/StatusAndProgressBarViewModel.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/ViewModels/DigitalOutputChannelsViewModel.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/ViewModels/ChannelDetailViewModel.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/ViewModels/ImportTestSetupTemplate.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/ViewModels/ReadFileViewModel.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/ViewModels/HardwareViewModel.cs
|
||||
generated_at: "2026-04-16T04:20:25.203305+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f18294d885fecf32"
|
||||
---
|
||||
|
||||
# ViewModels
|
||||
|
||||
**Documentation Page: Import ViewModels Module**
|
||||
|
||||
---
|
||||
|
||||
### **1. Purpose**
|
||||
|
||||
This module provides the view model layer for the *Test Setup Import* wizard flow in the DataPRO application. It orchestrates the UI state, data parsing, hardware scanning, channel assignment, and validation logic required to import test setup data from external files (CSV, XML, E2X). The view models coordinate with underlying import infrastructure (e.g., `ParseImportFactory`, `ImportObject`, DAS hardware discovery), manage UI-bound properties for WPF data binding, and expose events to signal completion or status changes. It serves as the glue between the UI (Views) and the core import/data model layers.
|
||||
|
||||
---
|
||||
|
||||
### **2. Public Interface**
|
||||
|
||||
#### **`HardwareScanViewModel`**
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.ViewModels`
|
||||
- **Inherits**: `DTS.Common.Base.BasePropertyChanged`
|
||||
- **Status**: Empty class; no properties or methods defined in source. Likely a placeholder or stub for future functionality.
|
||||
|
||||
#### **`StatusAndProgressBarViewModel`**
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.ViewModels`
|
||||
- **Implements**: `INotifyPropertyChanged`
|
||||
- **Purpose**: Binds status text, progress bar visibility/value, alert visibility, and status color to the UI.
|
||||
- **Properties**:
|
||||
- `Visibility AlertVisibility`: Controls visibility of an alert UI element. Default: `Hidden`.
|
||||
- `string AggregateStatusText`: Status message (e.g., "Scanning...", "Done"). Default: `"---"`.
|
||||
- `Color AggregateStatusColor`: Foreground color for status text (e.g., green for success). Default: `Colors.AliceBlue`.
|
||||
- `Visibility ProgressBarVisibility`: Toggles progress bar visibility. Default: `Hidden`.
|
||||
- `int ProgressBarValue`: Current progress value (0–100). Default: `0`.
|
||||
- **Methods**:
|
||||
- `bool SetProperty<T>(ref T storage, T value, string propertyName = null)`: Updates property if changed, raises `PropertyChanged`, returns `true` if changed.
|
||||
- `protected void OnPropertyChanged(string propertyName = null)`: Raises `PropertyChanged` event.
|
||||
|
||||
#### **`DigitalOutputChannelsViewModel`**
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.ViewModels`
|
||||
- **Inherits**: `DTS.Common.Base.BasePropertyChanged`
|
||||
- **Purpose**: Manages digital output channel assignment and DAS channel population after hardware scan.
|
||||
- **Constructor**:
|
||||
- `DigitalOutputChannelsViewModel(HardwareViewModel hardwareViewModel, IDASPopulateChannels dasPopulateChannels)`
|
||||
Subscribes to `HardwareScanFinished` event on `hardwareViewModel`.
|
||||
- **Properties**:
|
||||
- `ObservableCollection<DASChannelModel> DASChannels`: List of DAS channels populated after scan.
|
||||
- `DASChannelModel SelectedDASChannel`: Currently selected channel.
|
||||
- `string EnableOrDisableText`: Dynamically returns `"Enable"` or `"Disable"` based on `SelectedDASChannel.Channel.Disabled`.
|
||||
- **Events**:
|
||||
- `HardwareScanFinished` handler (`HardwareViewModel_HardwareScanFinished`) triggers `OnHardwareScanComplete()` and `OnAssignedChannelsChangedEvent()`.
|
||||
- **Methods**:
|
||||
- `private void OnAssignedChannelsChangedEvent()`:
|
||||
- Marshals to UI thread if needed.
|
||||
- Uses `_dasPopulateChannels.PopulateDASChannels(...)` to populate `DASChannels`.
|
||||
- Raises `OnPropertyChanged` for `LimitDuration`, `DigitalOutputDelayMs`, `DigitalOutputDurationMs`, `DigitalOutputMode`, and `DASChannels`.
|
||||
- Refreshes `ICollectionView` for `DASChannels`.
|
||||
|
||||
#### **`ChannelDetailViewModel`**
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.ViewModels`
|
||||
- **Inherits**: `DTS.Common.Base.BasePropertyChanged`
|
||||
- **Purpose**: Displays summary of DAS channel assignments: *Found*, *Missing*, and *Extra* channels.
|
||||
- **Properties**:
|
||||
- `bool ExtraSummaryVisible`: Controls visibility of extra-summary section.
|
||||
- `bool ShowSummaryDetails`: Controls visibility of found/missing summary section.
|
||||
- `SummaryRow[] ExtraSummaries`, `FoundSummaries`, `MissingSummaries`: Read-only arrays of summary rows.
|
||||
- `GridLength ExtraHeight`, `SummaryDetailHeight`: Grid row heights for UI layout.
|
||||
- **Methods**:
|
||||
- `void GetSummaries(List<IDASCommunication> das, ImportObject importObject)`:
|
||||
- Validates preconditions (single test setup, non-empty DAS list, non-null import object).
|
||||
- Calls `SummaryRowHelper.GetSummaries(...)` to populate lists.
|
||||
- Invokes `SetSummaries(...)` to update properties.
|
||||
- `private void SetSummaries(SummaryRow[] found, SummaryRow[] missing, SummaryRow[] extra)`:
|
||||
- Updates all summary arrays.
|
||||
- Sets `ExtraSummaryVisible` and `ShowSummaryDetails` based on content.
|
||||
|
||||
#### **`ImportTestSetupTemplate`**
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.ViewModels`
|
||||
- **Inherits**: `BasePropertyChanged`
|
||||
- **Purpose**: Represents a single test setup entry in the import list; handles name, overwrite, inclusion, and validation state.
|
||||
- **Properties**:
|
||||
- `ImportFileFormat TestSetupImportFileFormat`: Format of the imported file.
|
||||
- `ITestSetupValidation TestSetupValidation`: Validator instance (used for list-wide validation).
|
||||
- `bool IncludedCheckBox`: Whether the test setup is included for import.
|
||||
- `bool OverwriteCheckBox`: Whether to overwrite existing test setup.
|
||||
- `string OriginalTestSetupName`: Original name from file.
|
||||
- `string ImportingTestSetupName`: User-modified name for import.
|
||||
- `bool TestSetupExists`: Whether a test setup with this name exists in the database.
|
||||
- `bool TestSetupExistsAndIncluded`: `TestSetupExists && IncludedCheckBox`.
|
||||
- `bool TestSetupImportDuplicate`: Whether the name is duplicated *within the import list*.
|
||||
- `bool IsValid`: Whether the entry is valid for import (depends on inclusion, existence, duplicates, overwrite).
|
||||
- **Events**:
|
||||
- `event EventHandler<ImportTestSetupEventArgs> TestSetupNameChanged`: Raised when `ImportingTestSetupName` changes.
|
||||
- **Commands**:
|
||||
- `ICommand ControlChangedCommand`: Bound to checkbox changes; invokes `ControlChangedMethod(...)`.
|
||||
- **Methods**:
|
||||
- `void UpdateImportTestSetupListElement()`:
|
||||
- Checks for existence/duplicates.
|
||||
- Updates `TestSetupExists`, `TestSetupImportDuplicate`, `TestSetupExistsAndIncluded`, and `IsValid`.
|
||||
- `bool Validate()`: Returns `IsValid`.
|
||||
|
||||
#### **`ReadFileViewModel`**
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.ViewModels`
|
||||
- **Implements**: `INotifyPropertyChanged`
|
||||
- **Purpose**: Handles file browsing, parsing, and error reporting for import files.
|
||||
- **Constructor**:
|
||||
- `ReadFileViewModel(DataPROPage page, StatusAndProgressBarControl statusAndProgressBarView, StatusAndProgressBarViewModel statusAndProgressBarViewModel)`
|
||||
Initializes status UI and `StatusUpdater`.
|
||||
- **Properties**:
|
||||
- `string ImportFile`: Path to selected file.
|
||||
- `bool BrowseEnabled`: Controls browse button availability.
|
||||
- `StatusAndProgressBarControl StatusAndProgressBarView`: Reference to status UI control.
|
||||
- `bool AutoConnectToHardware`: Gets/sets `SerializedSettings.AutoConnectHardwareScan`.
|
||||
- **Events**:
|
||||
- `event EventHandler<ReadFileStatusEventArgs> ReadFileFinished`: Raised on parse completion.
|
||||
- `event EventHandler<DisableNavStepsEventArgs> DisableNavSteps`: Raised during parsing to disable navigation.
|
||||
- **Commands**:
|
||||
- `ICommand BrowseClicked`: Opens `OpenFileDialog`, triggers `Parse(...)`.
|
||||
- **Methods**:
|
||||
- `void BrowseMethod(object obj)`:
|
||||
- Clears state, opens file dialog, sets `ImportFile`.
|
||||
- Configures `CsvImportOptions`/`EqxImportOptions` from UI controls.
|
||||
- Launches `Parse(...)` on background thread.
|
||||
- `void Parse(...)` (overload):
|
||||
- Sets status to `Working`, enables cancel, disables navigation.
|
||||
- Creates `ParseImportFactory`, handles exceptions, checks for file-in-use/invalid CSV.
|
||||
- Calls `HandleErrors(...)` on completion.
|
||||
- `void HandleErrors(ImportObject importObj)`:
|
||||
- Determines success/failure based on error severity.
|
||||
- Warns on level triggers if UI disabled (`WarnOnLevelTriggerPresentWithNoUI(...)`).
|
||||
- Invokes `ReadFileFinished` with success/failure status and import object.
|
||||
- `void SetImportStatus(ImportStatus importStatus)`, `void SetStatus(PossibleStatus status)`: Updates status via `StatusUpdater`.
|
||||
|
||||
#### **`HardwareViewModel`**
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.ViewModels`
|
||||
- **Inherits**: `DTS.Common.Base.BasePropertyChanged`
|
||||
- **Purpose**: Manages hardware discovery, scanning, and summary reporting.
|
||||
- **Events**:
|
||||
- `event EventHandler<HardwareScanEventArgs> HardwareScanFinished`: Raised after scan completes.
|
||||
- **Properties**:
|
||||
- `ChannelDetailViewModel ChannelDetailViewContext`: Summary view model for channel assignments.
|
||||
- `StatusAndProgressBarControl StatusAndProgressBarView`: Status UI control.
|
||||
- `HardwareDiscoveryTable IncludedTable`, `_availableTable`: Tables for hardware discovery UI.
|
||||
- **Constructor**:
|
||||
- `HardwareViewModel(DataPROPage page, StatusAndProgressBarControl, StatusAndProgressBarViewModel, ReadFileViewModel, ChannelDetailViewModel)`
|
||||
Initializes tables, subscribes to `ReadFileViewModel.ReadFileFinished`.
|
||||
- **Methods**:
|
||||
- `void Scan(bool bConnect)`:
|
||||
- Clears tables, populates `_includedTable` from `_hardwareInImportFile`, optionally starts `HardwareScan()`.
|
||||
- `void HardwareScan()`: Calls `ImportFunctions.HardwareScanRun(...)` with callbacks (e.g., `SetProgressValue`, `SetStatusText`).
|
||||
- `void PopulateTables()`: Updates `_setupHardware` (from import file) and `_connectedHardware` (from active DAS devices).
|
||||
- `ChannelSummaryRow[] GetChannelSummary()`: Returns counts for analog, squib, digital in/out channels.
|
||||
- `DASSummaryRow GetTestSummary()`, `GetConnectedSummary()`: Returns hardware summaries.
|
||||
- `HardwareTypes[] GetRelevantHardwareTypes()`: Merges hardware types from setup and connected hardware.
|
||||
- `void ClearTables()`: Resets tables and summary view model layout.
|
||||
- `void ClearHardwareTables()`: Clears `_setupHardware` and `_connectedHardware`.
|
||||
- `private void AddAnyMissingDAS()`: Adds DAS devices detected during scan but not in import file to `_importObject`.
|
||||
- `private void SetDone()`, `SetProgressValue(...)`, `SetStatusText(...)`, `SetProgressVisibility(...)`, `SetStatusColor(...)`: Internal helpers to update `StatusAndProgressBarViewModel`.
|
||||
|
||||
---
|
||||
|
||||
### **3. Invariants**
|
||||
|
||||
- **`StatusAndProgressBarViewModel`**:
|
||||
- `SetProperty` only raises `PropertyChanged` if the value actually changes.
|
||||
- All property setters call `OnPropertyChanged` with the exact property name string (e.g., `"AggregateStatusText"`).
|
||||
- **`DigitalOutputChannelsViewModel`**:
|
||||
- `OnAssignedChannelsChangedEvent()` is always marshaled to the UI thread before executing logic.
|
||||
- `_hardware` and `_importObject` are only set after `HardwareScanFinished` event.
|
||||
- **`ImportTestSetupTemplate`**:
|
||||
- `IsValid` is `false` if `IncludedCheckBox` is `true` and `ImportingTestSetupName` is empty/whitespace.
|
||||
- Setting `TestSetupExistsAndIncluded = false` unchecks `OverwriteCheckBox`.
|
||||
- **`ReadFileViewModel`**:
|
||||
- `BrowseMethod` disables the browse button during parsing (`BrowseEnabled = false`).
|
||||
- `Parse(...)` cancels early if `CancelCheck()` returns `true` (e.g., user cancelled).
|
||||
- `HandleErrors(...)` clears errors after successful import with warnings to avoid duplicate display.
|
||||
- **`HardwareViewModel`**:
|
||||
- `HardwareScan()` is only invoked if `bConnect = true` and import file has ≤1 test setup.
|
||||
- `AddAnyMissingDAS()` assigns negative `DASId`s to new hardware to avoid conflicts with DB IDs.
|
||||
- `PopulateTables()` is called after scan to refresh UI-bound hardware summaries.
|
||||
|
||||
---
|
||||
|
||||
### **4. Dependencies**
|
||||
|
||||
#### **Internal Dependencies**
|
||||
- **Core Libraries**:
|
||||
- `DTS.Common.*` (e.g., `BasePropertyChanged`, `Import`, `Interface.*`, `Enums.*`, `Classes.Viewer.Commands`, `SharedResource.Strings`)
|
||||
- `DataPROWin7.Controls.TestSetups.Import.Models` (`DASChannelModel`, `SummaryRow`, etc.)
|
||||
- `DataPROWin7.DataModel` (`DataModel`, `TestTemplateList`)
|
||||
- `DataPROWin7.Common`, `DataPROWin7.Controls.DAS.HardwareDiscovery`
|
||||
- **WPF & UI**:
|
||||
- `System.Windows`, `System.Windows.Media`, `System.Windows.Input`, `System.Windows.Threading`
|
||||
- `System.Windows.Forms` (for `OpenFileDialog`)
|
||||
- **Prism Framework**:
|
||||
- `Prism.Events.IEventAggregator`, `Prism.Ioc.IContainerLocator`
|
||||
|
||||
#### **External Dependencies**
|
||||
- **Hardware**:
|
||||
- `DASFactory` (via `((App)Application.Current).DASFactory`)
|
||||
- `IDASHardware`, `IDASCommunication`, `IGroupChannel`, `ISensorData`
|
||||
- **Import Infrastructure**:
|
||||
- `ParseImportFactory`, `IParseImport`, `ImportObject`, `ImportFunctions.HardwareScanRun`
|
||||
- `CSVFile`, `ImportSensorsOptionsControl`
|
||||
- **Settings**:
|
||||
- `Common.SerializedSettings`, `Properties.Settings.Default`
|
||||
|
||||
#### **Consumers**
|
||||
- **Views**:
|
||||
- `DataPROPage` (via `DataPROPage` parameter in constructors)
|
||||
- `StatusAndProgressBarControl`, `HardwareDiscoveryTable`
|
||||
- **ViewModels**:
|
||||
- `HardwareScanViewModel` (empty; likely consumed by XAML)
|
||||
- `DigitalOutputChannelsViewModel`, `ChannelDetailViewModel`, `ImportTestSetupTemplate`, `ReadFileViewModel` are instantiated and bound to views.
|
||||
|
||||
---
|
||||
|
||||
### **5. Gotchas**
|
||||
|
||||
- **`HardwareScanViewModel` is empty**: No functionality is implemented; likely a placeholder or future extension point. Do not assume behavior.
|
||||
- **Thread Marshaling**: All `StatusAndProgressBarViewModel` and `HardwareViewModel` property updates that modify UI-bound properties are *not* automatically thread-safe. Internal methods (e.g., `SetProgressValue`) check `Dispatcher.CheckAccess()` and re-invoke on UI thread.
|
||||
- **Hardware ID Conflicts**: `AddAnyMissingDAS()` assigns negative `DASId`s to new hardware. This assumes negative IDs are safe for in-memory use but not persisted to DB.
|
||||
- **Duplicate Sensor Counting**: `ParseImportObject` uses `sensorCounter` to avoid double-counting duplicate sensors in channel summaries (FB 39430/44011). Ensure `SensorConstants.TEST_SPECIFIC_*_SERIAL` values are correct.
|
||||
- **CSV Validation**: `ReadFileViewModel.Parse(...)` checks for file-in-use (`CSVFile.IsInUse`) and test-setup-specific CSV format (`CSVFile.IsCSVFileForTestSetupImport`) *before* parsing. Skipping these checks may cause cryptic errors.
|
||||
- **Level Trigger Warning**: `WarnOnLevelTriggerPresentWithNoUI` warns if level triggers exist in imported test setups *and* `AllowLevelTriggerUI` is disabled. This warning is only issued on *successful* import.
|
||||
- **Overwrite Checkbox Logic**: In `ImportTestSetupTemplate`, unchecking `IncludedCheckBox` does *not* automatically uncheck `OverwriteCheckBox`. However, setting `TestSetupExistsAndIncluded = false` *does* uncheck it (via property setter).
|
||||
- **Hardware Scan Skipping**: `HardwareViewModel.Scan(...)` skips scanning if the import file has multiple test setups or no test setups (`NoTestSetup` format). Ensure callers understand this behavior.
|
||||
- **`ImportFile` Property Side Effects**: Setting `ImportFile` in `ReadFileViewModel` raises `OnPropertyChanged("BrowseEnabled")` (via `ImportFile` setter), which may re-enable the browse button prematurely if not handled carefully.
|
||||
|
||||
---
|
||||
|
||||
*Documentation generated from provided source files. No behavior inferred beyond explicit code.*
|
||||
@@ -0,0 +1,155 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Views/StatusAndProgressBarControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Views/SummaryControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Views/ReadFileControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Views/SquibChannelsControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Views/AnalogChannelsControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Views/DigitalInputChannelsControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Views/DigitalOutputChannelsControl.xaml.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/Import/Views/HardwareScanControl.xaml.cs
|
||||
generated_at: "2026-04-16T04:21:13.395069+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f791b8eabda60a09"
|
||||
---
|
||||
|
||||
# Documentation: Import View Controls Module
|
||||
|
||||
## 1. Purpose
|
||||
This module provides WPF `UserControl` implementations for the various pages/steps in a test setup import workflow. Each control corresponds to a specific configuration phase (e.g., reading input files, configuring analog/digital channels, hardware scanning, summary review) and adheres to a common `IPageContent` interface to integrate with a higher-level page navigation and validation system. The controls are purely UI-layer components—they bind to dedicated view models, handle permission-based enabling/disabling, and participate in page lifecycle events (activation, validation, deactivation), but contain no business logic beyond UI-specific data population and rendering.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All controls implement the `IPageContent` interface (defined externally, inferred from usage). Each control exposes a single public constructor accepting a strongly-typed view model.
|
||||
|
||||
### `StatusAndProgressBarControl`
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.Views`
|
||||
- **Type**: `public partial class StatusAndProgressBarControl : UserControl`
|
||||
- **Constructor**: `StatusAndProgressBarControl()`
|
||||
Initializes the control via `InitializeComponent()`. No view model binding or custom logic is present in the provided source.
|
||||
|
||||
### `SummaryControl`
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.Views`
|
||||
- **Type**: `public partial class SummaryControl : UserControl, IPageContent`
|
||||
- **Constructor**: `SummaryControl(SummaryViewModel summaryViewModel)`
|
||||
Sets `DataContext` to `summaryViewModel` and calls `InitializeComponent()`.
|
||||
- **`IPageContent` Members**:
|
||||
- `void SetPermissions(User.UserPermissionLevels actualPermission, User.UserPermissionLevels requiredPermission)`
|
||||
Enables/disables the control based on permission level comparison.
|
||||
- `bool KeyDown(object sender, KeyEventArgs arg)` → `false`
|
||||
No key handling.
|
||||
- `void StartSearch(string term)` → *no-op*
|
||||
Search functionality not implemented.
|
||||
- `bool OnButtonPress(PageButton button)` → `false`
|
||||
No button press handling.
|
||||
- `bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)` → `true`
|
||||
Always returns `true`; no validation logic.
|
||||
- `void OnSetActive()`
|
||||
Invokes `Validate(...)` silently to flag invalid fields (e.g., for visual indicators).
|
||||
- `void UnSet(Action OnComplete = null)` → *no-op*
|
||||
Cleanup hook not implemented.
|
||||
- `object GetPageContent()` → `this`
|
||||
Returns the control instance.
|
||||
|
||||
### `ReadFileControl`
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.Views`
|
||||
- **Type**: `public partial class ReadFileControl : UserControl, IPageContent`
|
||||
- **Constructor**: `ReadFileControl(ReadFileViewModel readFileViewModel)`
|
||||
Sets `DataContext` to `readFileViewModel` and calls `InitializeComponent()`.
|
||||
- **`IPageContent` Members**: Identical implementation to `SummaryControl`.
|
||||
|
||||
### `SquibChannelsControl`
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.Views`
|
||||
- **Type**: `public partial class SquibChannelsControl : UserControl, IPageContent`
|
||||
- **Constructor**: `SquibChannelsControl(SquibChannelsViewModel squibChannelsViewModel)`
|
||||
Sets `DataContext` to `squibChannelsViewModel` and calls `InitializeComponent()`.
|
||||
- **`IPageContent` Members**: Identical implementation to `SummaryControl`.
|
||||
|
||||
### `AnalogChannelsControl`
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.Views`
|
||||
- **Type**: `public partial class AnalogChannelsControl : UserControl, IPageContent`
|
||||
- **Constructor**: `AnalogChannelsControl(AnalogChannelsViewModel analogChannelsViewModel)`
|
||||
Sets `DataContext` to `analogChannelsViewModel` and calls `InitializeComponent()`.
|
||||
- **`IPageContent` Members**: Identical implementation to `SummaryControl`.
|
||||
|
||||
### `DigitalInputChannelsControl`
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.Views`
|
||||
- **Type**: `public partial class DigitalInputChannelsControl : UserControl, IPageContent`
|
||||
- **Constructor**: `DigitalInputChannelsControl(DigitalInputChannelsViewModel digitalInputChannelsViewModel)`
|
||||
Sets `DataContext` to `digitalInputChannelsViewModel` and calls `InitializeComponent()`.
|
||||
- **`IPageContent` Members**: Identical implementation to `SummaryControl`.
|
||||
|
||||
### `DigitalOutputChannelsControl`
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.Views`
|
||||
- **Type**: `public partial class DigitalOutputChannelsControl : UserControl, IPageContent`
|
||||
- **Constructor**: `DigitalOutputChannelsControl(DigitalOutputChannelsViewModel digitalOutputChannelsViewModel)`
|
||||
Sets `DataContext` to `digitalOutputChannelsViewModel` and calls `InitializeComponent()`.
|
||||
- **`IPageContent` Members**: Identical implementation to `SummaryControl`.
|
||||
|
||||
### `HardwareScanControl`
|
||||
- **Namespace**: `DataPROWin7.Controls.TestSetups.Import.Views`
|
||||
- **Type**: `public partial class HardwareScanControl : UserControl, IPageContent`
|
||||
- **Constructors**:
|
||||
- `protected HardwareScanControl()`
|
||||
Protected parameterless constructor; only calls `InitializeComponent()`.
|
||||
- `public HardwareScanControl(HardwareViewModel model, DataPROPage page)`
|
||||
Sets `DataContext` to `model`, stores `_page` and `_hardwareViewModel`, and registers `_hardwareViewModel.OnDone = ViewModelDone` and `_hardwareViewModel.OnClear = ViewModelClear`.
|
||||
- **`IPageContent` Members**:
|
||||
- `void SetPermissions(...)` → same as others.
|
||||
- `bool KeyDown(...)` → `false`.
|
||||
- `void StartSearch(string term)` → *no-op*.
|
||||
- `bool OnButtonPress(...)` → `false`.
|
||||
- `bool Validate(...)` → `true`.
|
||||
- `void OnSetActive()` → invokes `Validate(...)` silently.
|
||||
- `void UnSet(...)` → *no-op*.
|
||||
- `object GetPageContent()` → `this`.
|
||||
- **Additional Public Methods**:
|
||||
- `void Scan()`
|
||||
Triggers `_hardwareViewModel.Scan(true)` to initiate hardware scanning.
|
||||
- **Internal Helpers** (not part of public interface but relevant for behavior):
|
||||
- `ViewModelClear()` → clears `ItemsSource` bindings for `lvChannelSummary`, `lvDASSummary`, `dgDASCount`.
|
||||
- `ViewModelDone()` → populates UI via `CreateDataTable()`, `PopulateListView()`, `CreateChannelsSummary()`.
|
||||
- `CreateDataTable()` → builds a `DataTable` for `dgDASCount` with columns for DAS types and channel counts (Analog, Squib, DIn, etc.).
|
||||
- `GetChannelSummary()` → calls `_hardwareViewModel.GetChannelSummary()` to populate `lvChannelSummary`.
|
||||
- `PopulateListView()` → retrieves active DAS devices via `((App)Application.Current).DASFactory.GetActiveDevices()` and populates `lvDASSummary`.
|
||||
|
||||
## 3. Invariants
|
||||
- **All controls implement `IPageContent`** with identical behavior for permission handling, validation, and lifecycle hooks (except `HardwareScanControl`, which adds a `Scan()` method).
|
||||
- **Permission enforcement**: `IsEnabled` is set to `true` iff `(int)actualPermission >= (int)requiredPermission`.
|
||||
- **Validation is a no-op**: All `Validate(...)` methods return `true` unconditionally and do not populate `errors` or `warnings`.
|
||||
- **`OnSetActive()` always runs validation silently**: It instantiates empty `errors`/`warnings` lists and calls `Validate(..., displayWindow: false)` to allow UI feedback (e.g., highlighting invalid fields) without user interaction.
|
||||
- **`StartSearch()` and `OnButtonPress()` are stubbed**: No search or button handling logic is implemented.
|
||||
- **`UnSet()` is a no-op** across all controls.
|
||||
- **`GetPageContent()` always returns `this`**.
|
||||
|
||||
## 4. Dependencies
|
||||
### Internal Dependencies (from imports):
|
||||
- **View Models** (namespace inferred from `using`):
|
||||
- `DataPROWin7.Controls.TestSetups.Import.ViewModels.*` (e.g., `SummaryViewModel`, `HardwareViewModel`, etc.)
|
||||
- **User Permissions**:
|
||||
- `DTS.Slice.Users` → `User.UserPermissionLevels`
|
||||
- **Hardware Types** (only in `HardwareScanControl`):
|
||||
- `DTS.Common.Enums.Hardware.HardwareTypes`
|
||||
- **Shared Resources** (only in `HardwareScanControl`):
|
||||
- `DTS.Common.SharedResource.Strings.StringResources` (e.g., `Analog`, `Squib`, `DIn`, `PPRO`, `S15`, etc.)
|
||||
- **WPF & .NET Base Types**:
|
||||
- `System.Windows.Controls`, `System.Windows.Input`, `System.Collections.Generic`, `System.Data`, `System.Threading.Tasks`, `System.Windows.Application`
|
||||
|
||||
### External Dependencies:
|
||||
- **`DataPROPage`**: Passed to `HardwareScanControl` constructor; likely a page container or host interface (not defined in provided sources).
|
||||
- **`App.DASFactory`**: Global singleton (`((App)Application.Current).DASFactory`) used to retrieve active DAS devices.
|
||||
|
||||
### What depends on this module?
|
||||
- A higher-level page navigation system (e.g., `DataPROPage`) that consumes `IPageContent` implementations to manage import workflow steps.
|
||||
|
||||
## 5. Gotchas
|
||||
- **`StatusAndProgressBarControl` has no logic**: Its source file contains no custom logic beyond `InitializeComponent()`. Its purpose is unclear without the corresponding XAML or usage context.
|
||||
- **All `Validate()` methods are stubs**: They never report errors or warnings, despite being called in `OnSetActive()`. This may indicate incomplete validation logic or deferred validation to the view models.
|
||||
- **`HardwareScanControl` has two constructors**: The protected parameterless constructor is unused in the provided source and may be for designer support only. The public constructor is the only functional one.
|
||||
- **Dispatcher marshaling in `ViewModelClear()`/`ViewModelDone()`**: UI updates are dispatched via `Dispatcher.BeginInvoke(...)` if not on the UI thread, but the recursive call pattern (`return; ... BeginInvoke(...)`) is redundant and could be simplified.
|
||||
- **`_hardwareTypeToDisplayString` dictionary is hardcoded**: Mapping from `HardwareTypes` to display strings is fixed at compile time; no localization or runtime customization is evident.
|
||||
- **`HardwareScanControl` mutates shared state (`_dt`)**: The private `DataTable _dt` is disposed and recreated on each scan, but its lifecycle is not guarded against concurrent access (no locking or async safety noted).
|
||||
- **No error handling in `HardwareScanControl`**: Methods like `ViewModelDone()` assume `_hardwareViewModel` and its data (e.g., `GetChannelSummary()`, `GetConnectedSummary()`) are always valid; exceptions would crash the UI thread callback.
|
||||
|
||||
None identified from source alone for other controls.
|
||||
@@ -0,0 +1,104 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Controls/TestSetups/ImportTTSHelpers/TestSetupHelper.cs
|
||||
- DataPRO/DataPRO/Controls/TestSetups/ImportTTSHelpers/SensorGroupHelper.cs
|
||||
generated_at: "2026-04-16T04:19:40.075645+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "dd34d74e093fd21a"
|
||||
---
|
||||
|
||||
# ImportTTSHelpers
|
||||
|
||||
## Documentation: `DataPROWin7.Controls.TestSetups.ImportTTSHelpers`
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module provides lightweight view-model helper classes (`TestSetupHelper` and `SensorGroupHelper`) to support UI presentation and user interaction for test setup selection during TTS (likely *Test Template System*) import workflows. `TestSetupHelper` wraps a `DataModel.TestTemplate` to expose its name and inclusion state, while `SensorGroupHelper` groups available DAS (Data Acquisition System) hardware by `TestObject` and exposes per-DAS inclusion flags—both classes derive from `BasePropertyChanged` to support two-way data binding in WPF/XAML UIs.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `TestSetupHelper`
|
||||
- **`public TestSetupHelper(DataModel.TestTemplate setup)`**
|
||||
Constructor. Initializes the helper with the given `TestTemplate` instance.
|
||||
|
||||
- **`public DataModel.TestTemplate TestSetup { get; set; }`**
|
||||
Read-write property holding the underlying `TestTemplate` object.
|
||||
|
||||
- **`public string TestSetupName => TestSetup.Name;`**
|
||||
Read-only computed property exposing the `Name` of the wrapped `TestSetup`.
|
||||
|
||||
- **`public bool IsIncluded { get; set; }`**
|
||||
Read-write boolean flag indicating whether this test setup is included in the current operation. Defaults to `true`. Implements `INotifyPropertyChanged` via `SetProperty`.
|
||||
|
||||
#### `SensorGroupHelper`
|
||||
- **`public SensorGroupHelper(DataModel.TestObject to)`**
|
||||
Constructor. Initializes the helper for the given `TestObject`. Automatically populates `_das` with all non-module hardware from `DASHardwareList.GetAllHardware()`.
|
||||
|
||||
- **`public DataModel.TestObject TestObject { get; set; }`**
|
||||
Read-write property holding the `TestObject` this group represents.
|
||||
|
||||
- **`public string GroupName => TestObject.SerialNumber;`**
|
||||
Read-only computed property exposing the serial number of the `TestObject`.
|
||||
|
||||
- **`public bool IsIncluded { get; set; }`**
|
||||
Read-write boolean flag indicating whether the entire sensor group (i.e., all DAS units in this group) is included. Defaults to `true`. Implements `INotifyPropertyChanged`.
|
||||
|
||||
- **`public DASHelper[] AvailableDAS { get; set; }`**
|
||||
Read-write array of `DASHelper` instances representing DAS hardware associated with this group. Initialized on construction and updated via `SetProperty` (which raises `PropertyChanged`).
|
||||
|
||||
##### Nested class `SensorGroupHelper.DASHelper`
|
||||
- **`public DASHelper(DataModel.DASHardware h)`**
|
||||
Constructor. Wraps a `DASHardware` instance. Sets `IsIncluded` to `false` by default.
|
||||
|
||||
- **`public DataModel.DASHardware Hardware { get; set; }`**
|
||||
Read-write property holding the wrapped DAS hardware.
|
||||
|
||||
- **`public string SerialNumber => Hardware.SerialNumber;`**
|
||||
Read-only property exposing the hardware’s serial number.
|
||||
|
||||
- **`public string DASDescription => SerialNumber;`**
|
||||
Read-only property (currently identical to `SerialNumber`), likely intended for display.
|
||||
|
||||
- **`public bool IsIncluded { get; set; }`**
|
||||
Read-write flag indicating whether this DAS unit is included. Defaults to `true` (note: overridden to `false` in constructor).
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- `TestSetupHelper.TestSetup` must not be `null` after construction; otherwise, `TestSetupName` will throw a `NullReferenceException`.
|
||||
- `SensorGroupHelper.TestObject` must not be `null` after construction; otherwise, `GroupName` will throw a `NullReferenceException`.
|
||||
- `SensorGroupHelper.DASHelper` instances are only created for hardware where `h.IsModule()` returns `false` (i.e., non-module hardware is included in `AvailableDAS`).
|
||||
- `IsIncluded` properties on both `TestSetupHelper` and `SensorGroupHelper` default to `true`; `DASHelper.IsIncluded` defaults to `false` (explicitly set in constructor).
|
||||
- All `*Helper` classes derive from `BasePropertyChanged`, implying they support property change notifications for data binding.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### Dependencies *of* this module:
|
||||
- `DTS.Common.Base` → Provides `BasePropertyChanged`, the base class for all helpers.
|
||||
- `DataPROWin7.DataModel.Classes.Hardware` → Provides `DASHardware`, `DASHardwareList`, and extension method `IsModule()`.
|
||||
- `DataPROWin7.DataModel` (implicit) → Provides `TestTemplate` and `TestObject`.
|
||||
|
||||
#### Dependencies *on* this module:
|
||||
- UI layers (e.g., `ImportTTSHelpers` namespace usage suggests consumption by `ImportTTSHelpers` controls or views, likely `ImportSensorsPreviewControl` as hinted by the comment in `SensorGroupHelper`).
|
||||
- Any WPF/XAML views or view models that bind to `IsIncluded`, `TestSetupName`, `GroupName`, or `AvailableDAS`.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **`DASHelper.IsIncluded` default is `false`**, but `SensorGroupHelper.IsIncluded` and `TestSetupHelper.IsIncluded` default to `true`. This asymmetry may cause confusion if UI logic assumes uniform defaults.
|
||||
- **`AvailableDAS` is exposed as an array**, but internally stored as a `List<DASHelper>`. The setter reconstructs a new list from the incoming array, which may cause performance issues if set frequently.
|
||||
- **Comment in `SensorGroupHelper`**: `/////////////duplicate of ImportSensorsPreviewControl` suggests potential code duplication or refactoring debt—no indication of whether this is intentional or technical debt.
|
||||
- **No validation on `TestSetup` or `TestObject`**: Constructors assume non-null inputs; no defensive checks are present.
|
||||
- **`DASDescription` is redundant** (same as `SerialNumber`)—no indication of future extensibility or localization support.
|
||||
- **`SetProperty` uses string-based property names** (e.g., `"IsIncluded"`), which are not refactor-safe and risk runtime errors if property names change.
|
||||
|
||||
> *None of the above are explicitly documented in source; inferred from code structure and conventions.*
|
||||
151
enriched-qwen3-coder-next/DataPRO/DataPRO/DataModel.md
Normal file
151
enriched-qwen3-coder-next/DataPRO/DataPRO/DataModel.md
Normal file
@@ -0,0 +1,151 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/DataModel/VisibilityConverter.cs
|
||||
- DataPRO/DataPRO/DataModel/SysBuiltObjectType.cs
|
||||
- DataPRO/DataPRO/DataModel/UIProperties.cs
|
||||
generated_at: "2026-04-16T04:07:34.040858+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "6399197e4c47078a"
|
||||
---
|
||||
|
||||
# DataModel
|
||||
|
||||
## Documentation: DataModel Module
|
||||
|
||||
### 1. Purpose
|
||||
This module provides core data modeling and UI configuration abstractions for the DataPROWin7 application. It includes a WPF value converter for binding integer values to `Visibility` states, a wrapper class (`SysBuiltObjectType`) for accessing ISO-defined test object metadata, and a centralized settings class (`UIProperties`) that exposes user-configurable UI preferences backed by a serialized settings store (`Common.SerializedSettings`). Its role is to decouple UI presentation logic (e.g., visibility toggling, display formatting) from business logic and to provide a consistent interface for managing persistent UI state.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `VisibilityConverter`
|
||||
- **Namespace**: `DataPROWin7.DataModel`
|
||||
- **Inherits**: `object`
|
||||
- **Implements**: `IValueConverter`
|
||||
- **Attributes**: `[ValueConversion(typeof(int), typeof(Visibility))]`
|
||||
|
||||
##### `Convert`
|
||||
```csharp
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
```
|
||||
- **Behavior**: Converts an `int` value to a `Visibility` enum value by casting the integer directly.
|
||||
- *Example*: `0` → `Visibility.Collapsed`, `1` → `Visibility.Visible`, `2` → `Visibility.Hidden` (assuming standard WPF `Visibility` mapping).
|
||||
- **Note**: Does not validate input; invalid integers may cause runtime exceptions.
|
||||
|
||||
##### `ConvertBack`
|
||||
```csharp
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
```
|
||||
- **Behavior**: Always returns `null`. One-way conversion only.
|
||||
|
||||
---
|
||||
|
||||
#### `SysBuiltObjectType`
|
||||
- **Namespace**: `DataPROWin7.DataModel`
|
||||
- **Inherits**: `object`
|
||||
|
||||
##### Constructor
|
||||
```csharp
|
||||
public SysBuiltObjectType(string testObjectType)
|
||||
```
|
||||
- **Behavior**: Initializes the instance with a test object type string (e.g., `"Vehicle 1"`). Stores the raw string in `_testObject`.
|
||||
|
||||
##### Properties
|
||||
- **`TestObject`** (`ISODll.MMETestObjects`)
|
||||
- **Getter**: Retrieves the `MMETestObject` instance corresponding to `_testObject` via `(App.Current as App).IsoDb.GetTestObjectByIso(_testObject)`.
|
||||
- **Setter**: Updates `_testObject` to `value.Test_Object` *only if* `value` is non-null.
|
||||
|
||||
- **`ISOTestObjectType`** (`string`)
|
||||
- **Getter**: Returns `TestObject.Text_L1` (localized display name).
|
||||
|
||||
##### `ToString()`
|
||||
```csharp
|
||||
public override string ToString()
|
||||
```
|
||||
- **Behavior**: Returns `TestObject.Text_L1` (same as `ISOTestObjectType`).
|
||||
|
||||
---
|
||||
|
||||
#### `UIProperties`
|
||||
- **Namespace**: `DataPROWin7.DataModel`
|
||||
- **Inherits**: `DTS.Common.Base.BasePropertyChanged`
|
||||
- **Attributes**: `[DisplayAttributeEx("UIProperties")]`
|
||||
- **Implements**: `INotifyPropertyChanged` (via base class)
|
||||
|
||||
##### Constructor
|
||||
```csharp
|
||||
public UIProperties(bool bReset = false)
|
||||
```
|
||||
- **Behavior**:
|
||||
- If `bReset` is `true`, initializes all properties to their default values from `Common.SerializedSettings` (e.g., `SHOW_GRAPHS_SETUP_STEP_DEFAULT`).
|
||||
- If `bReset` is `false` (default), leaves settings unchanged.
|
||||
|
||||
##### Properties
|
||||
All properties delegate to `Common.SerializedSettings` and raise `OnPropertyChanged` *except* where noted.
|
||||
|
||||
| Property | Type | Description | Key Notes |
|
||||
|----------|------|-------------|-----------|
|
||||
| `ShowGraphsSetupStep` | `bool` | Controls visibility of the Graphs step in test setup. | Default: `true`. Raises `OnPropertyChanged("ShowGraphsSetupStep")`. |
|
||||
| `NonLinearDisplayFormat` | `string` | Display format for non-linear sensor data. | Raises `OnPropertyChanged("NonLinearDisplayExample")` (likely typo; should be `"NonLinearDisplayFormat"`). |
|
||||
| `SensitivityDisplayFormat` | `string` | Display format for sensitivity values. | Raises `OnPropertyChanged("SensitivityDisplayExample")` (likely typo). |
|
||||
| `TriggerSecondsDisplayFormat` | `string` | Display format for trigger time values. | Raises `OnPropertyChanged("TriggerSecondsDisplayExample")` (likely typo). |
|
||||
| `CapacityRangeDisplayFormat` | `string` | Display format for capacity range values. | Raises `OnPropertyChanged("CapacityRangeDisplayExample")` (likely typo). |
|
||||
| `DisplayEUOffset` | `bool` | If `true`, show diagnostic offsets in engineering units (EU) for sensors. | Default: `false` (inferred from usage). |
|
||||
| `RememberTestIdAffixes` | `bool` | If `true`, persist test ID suffix state in dropdowns. | Does *not* raise `OnPropertyChanged` (no UI binding support). |
|
||||
| `ShowADCUnsigned` | `bool` | If `true`, display ADC values as unsigned (0–65535); else signed (-32768–32767). | Default: `false`. |
|
||||
| `AlwaysShowTSRAirSettings` | `bool` | If `true`, show TSR Air Settings in Edit Test Setup regardless of context. | Default: `false`. |
|
||||
| `DoNotShowExpiredLicense` | `bool` | Suppress license expiration warnings. | Default: `false`. |
|
||||
| `DoNotShowUnlicensed` | `bool` | Suppress unlicensed feature warnings. | Default: `false`. |
|
||||
| `ShowISOExport` | `bool` | If `true`, show ISO export in navigation and format list. | Default: `true`. |
|
||||
| `ShowGroups` | `bool` | If `true`, show Groups step in Edit Test Setup and related UI. | Default: `true`. Raises `OnPropertyChanged("ShowGroups")`. |
|
||||
| `DoNotShowInvalidProductVersion` | `bool` | Suppress invalid product version warnings. | Default: `false`. |
|
||||
| `UICulture` | `DTS.Common.Enums.UICultures` | Overrides system culture for UI localization. | Default: `en_US`. Raises `OnPropertyChanged("UICulture")`. |
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- **`VisibilityConverter.Convert`**:
|
||||
- Input `value` must be an `int` (or convertible to `int` via `System.Convert.ToInt32`).
|
||||
- Output is a `Visibility` enum value; invalid integers (e.g., `3`) will cause an `InvalidCastException` at runtime.
|
||||
- **`SysBuiltObjectType.TestObject`**:
|
||||
- `_testObject` is initialized to `"?"` but updated to a valid ISO test object string via the setter or constructor.
|
||||
- `TestObject` getter may throw if `IsoDb.GetTestObjectByIso(_testObject)` returns `null` (no validation in source).
|
||||
- **`UIProperties`**:
|
||||
- All properties are backed by `Common.SerializedSettings` (assumed to be a singleton).
|
||||
- Properties with `OnPropertyChanged` calls are intended for data binding; those without (e.g., `RememberTestIdAffixes`) are not.
|
||||
- Constructor `bReset=true` *only* initializes defaults; it does not persist changes.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
#### This module depends on:
|
||||
- **WPF**: `System.Windows`, `System.Windows.Data` (for `VisibilityConverter`).
|
||||
- **ISODll**: `ISODll.MMETestObjects` (for `SysBuiltObjectType`).
|
||||
- **Application Framework**: `App.Current` (to access `IsoDb`).
|
||||
- **DTS Libraries**:
|
||||
- `DTS.Slice.Users.UserSettings` (for `Common.SerializedSettings`).
|
||||
- `DTS.Common.Base.BasePropertyChanged` (for `UIProperties` base class).
|
||||
- `DTS.Common.Enums.UICultures` (for `UICulture` property).
|
||||
- **System**: `System.ComponentModel` (for `INotifyPropertyChanged`).
|
||||
|
||||
#### This module is depended on by:
|
||||
- **UI Layer**: `VisibilityConverter` is likely used in XAML bindings (e.g., `Visibility="{Binding SomeInt, Converter={StaticResource VisibilityConverter}}"`).
|
||||
- **Settings UI**: `UIProperties` is consumed by UI components to drive visibility/formatting of test setup steps, channels, and diagnostics.
|
||||
- **ISO Integration**: `SysBuiltObjectType` bridges ISO metadata to UI components (e.g., dropdowns listing test object types).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
- **`VisibilityConverter.ConvertBack`**: Always returns `null`, making two-way binding impossible. This is intentional but may confuse developers expecting reverse conversion.
|
||||
- **`SysBuiltObjectType.TestObject` setter**: Does *not* update `_testObject` if `value` is `null`, but the getter may throw if `_testObject` is invalid. No null-check on `TestObject.Text_L1` in `ToString()` or `ISOTestObjectType`.
|
||||
- **`UIProperties` property naming inconsistencies**:
|
||||
- `NonLinearDisplayFormat`, `SensitivityDisplayFormat`, etc., raise `OnPropertyChanged` with *example* names (e.g., `"NonLinearDisplayExample"`), not the property name itself. This breaks WPF binding updates.
|
||||
- `RememberTestIdAffixes` does not raise `OnPropertyChanged`, so UI will not refresh when changed programmatically.
|
||||
- **`UIProperties` constructor**: `bReset=true` initializes defaults but does *not* persist them (no call to a save method). Settings are only persisted via property setters.
|
||||
- **`ShowADCUnsigned`**: Default behavior (signed ADC) is non-intuitive for some hardware; the flag was added to address case #32992.
|
||||
- **`DisplayEUOffset`**: Only applies to "14700 Diagnostic offsets" (per comment); other offsets may not respect this setting.
|
||||
- **`UICulture`**: Overrides system culture *only* for UI resources (per comment referencing case #30281). Does not affect data parsing/culture-sensitive operations.
|
||||
|
||||
None identified beyond these.
|
||||
@@ -0,0 +1,150 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/DataModel/Classes/Hardware/ATDArmStatus.cs
|
||||
generated_at: "2026-04-16T04:21:53.763389+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "6a714462e0ec79a3"
|
||||
---
|
||||
|
||||
# Hardware
|
||||
|
||||
## Documentation: `ATDArmStatus.cs`
|
||||
|
||||
### 1. Purpose
|
||||
This module provides data structures and logic to model the arm status hierarchy of ATD (Arm Test Device) hardware in the DTS system, aggregating status information from individual devices, distributors (e.g., SLICE Ethernet Controllers), and ATD groups. It enables tracking of connection, arming, and diagnostic states across the hardware tree, updating aggregate statuses based on child states, and populating the model from live hardware data (`IDASHardware[]`) or QATS UDP entries (`IUDPQATSEntry`). The class `AllATDStatus` serves as the top-level container, organizing hardware into `ATDStatus` instances (one per logical ATD group), each containing `DistributorArmStatus` entries, each in turn containing `DeviceArmStatus` entries.
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `AllATDStatus`
|
||||
- **`AllATDStatuses OverallStatus { get; }`**
|
||||
Read-only aggregate status of all ATD groups managed by this instance. Derived from `ATDs` statuses via `ATDStatus.UpdateAggregateStatus()`.
|
||||
- **`IATDStatus[] ATDs { get; }`**
|
||||
Read-only array of all `ATDStatus` instances managed by this object.
|
||||
- **`void PopulateFromHardware(IDASHardware[] hardware)`**
|
||||
Populates the internal `ATDs` list by processing the input hardware array. SLICE Ethernet Controllers (distributors) are processed first; child devices are associated with their parent distributor via `DbOperations.DASChildrenGet`. Non-controller devices are added under their parent distributor or a default distributor if no parent is found.
|
||||
- **`void AddDevice(IDeviceArmStatus device, string parent = null)`**
|
||||
Adds a device to the appropriate `ATDStatus` and `DistributorArmStatus`. If no matching `ATDStatus` or `DistributorArmStatus` exists, new ones are created. Distributors (SLICE Ethernet Controllers) are added as top-level distributors; devices are added to a distributor.
|
||||
|
||||
#### `ATDStatus`
|
||||
- **`AllATDStatuses Status { get; }`**
|
||||
Read-only aggregate status of this ATD group (derived from its `Distributors`).
|
||||
- **`IDistributorArmStatus[] Distributors { get; }`**
|
||||
Read-only array of distributors in this ATD group.
|
||||
- **`IPAddress IP { get; }`**
|
||||
IP address associated with this ATD group (set via `SetIP`).
|
||||
- **`void AddDistributor(IDistributorArmStatus distributor)`**
|
||||
Adds a distributor to this ATD group (no-op if already present).
|
||||
- **`void SetIP(IPAddress ip)`**
|
||||
Sets the `IP` property.
|
||||
- **`void UpdateAggregateStatus()`**
|
||||
Recalculates `Status` based on `Distributors.AggregateStatus`. Priority: `AllArmed` > `AllConnected`/`Connecting` > `Errors`. `AllArmed` is only set if *all* distributors report `AllArmed`; otherwise, `Connecting` if any distributor is connecting, else `AllConnected`. Errors override if any distributor reports `Errors`.
|
||||
|
||||
#### `DistributorArmStatus`
|
||||
- **`bool EmptyDistributor { get; }`**
|
||||
`true` if `SerialNumber` is null or empty (used for orphaned devices).
|
||||
- **`DateTime? LastSeen { get; set; }`**
|
||||
Timestamp of last QATS update.
|
||||
- **`float? InputVoltage { get; set; }`**
|
||||
Input voltage from QATS.
|
||||
- **`float? BackupVoltage { get; set; }`**
|
||||
Backup voltage from QATS.
|
||||
- **`AllATDStatuses AggregateStatus { get; set; }`**
|
||||
Aggregate status of this distributor (derived from its `Devices`).
|
||||
- **`IDeviceArmStatus Distributor { get; }`**
|
||||
Reference to the hardware object representing this distributor (e.g., SLICE controller), if applicable.
|
||||
- **`DistributorStatuses DistributorStatus { get; }`**
|
||||
Status of the distributor itself (derived from QATS `ArmState` and fault flags).
|
||||
- **`IDeviceArmStatus[] Devices { get; }`**
|
||||
Read-only array of devices under this distributor.
|
||||
- **`void UpdateStatusFromQATS(IUDPQATSEntry qats)`**
|
||||
Updates `InputVoltage`, `BackupVoltage`, `LastSeen`, and `DistributorStatus` based on QATS data.
|
||||
- **`void UpdateAggregateStatus()`**
|
||||
Recalculates `AggregateStatus` based on `Devices.DASStatus`. Sets `DistributorStatus.NotConnected` if `LastSeen` is >30s old. Checks for missing devices (no update within `QATSMaxExpectedTimeMS`) and marks them `DASStatuses.MissingNotBooted`.
|
||||
- **`void AddDevice(IDeviceArmStatus device)`**
|
||||
Adds a device to this distributor (no-op if already present).
|
||||
- **`void SetDistributor(IDeviceArmStatus distributor)`**
|
||||
Sets the `Distributor` property.
|
||||
- **`void SetSerialNumber(string serial)`**
|
||||
Sets the `SerialNumber` property (used for empty distributors).
|
||||
- **`void SetDistributorStatus(DistributorStatuses status)`**
|
||||
Sets `DistributorStatus` directly.
|
||||
|
||||
#### `DeviceArmStatus`
|
||||
- **`string IPAddress { get; }`**
|
||||
IP address of the device (from `Hardware.Connection` if available).
|
||||
- **`string SerialNumber { get; }`**
|
||||
Serial number (from `DASCommunication.SerialNumber`, `Hardware.SerialNumber`, or internal `_serialNumber`).
|
||||
- **`DASStatuses DASStatus { get; }`**
|
||||
Current DAS status of the device (e.g., `BootedNotArmedYet`, `ArmedReady`, `MissingNotBooted`).
|
||||
- **`bool HasArmed { get; }`**
|
||||
`true` if the device has ever reached `ArmedReady` or `ArmedButFailedDiag`.
|
||||
- **`DiagStatuses DiagStatus { get; }`**
|
||||
Diagnostic status (e.g., `Passed`, `FailedOffset`, `FailedShunt`, `NoResults`).
|
||||
- **`IDistributorArmStatus Distributor { get; }`**
|
||||
Reference to the parent distributor.
|
||||
- **`IDASHardware Hardware { get; }`**
|
||||
Hardware object used to initialize the device.
|
||||
- **`IDASCommunication DASCommunication { get; }`**
|
||||
Communication object (if available).
|
||||
- **`DateTime? LastSeen { get; set; }`**
|
||||
Timestamp of last QATS update.
|
||||
- **`float? InputVoltage { get; set; }`**
|
||||
Input voltage from QATS.
|
||||
- **`float? BackupVoltage { get; set; }`**
|
||||
Backup voltage from QATS.
|
||||
- **`bool Triggered { get; set; }`**
|
||||
`true` if QATS `Triggered` and `Started` flags are non-zero.
|
||||
- **`string ShuntResults { get; set; }`**
|
||||
Human-readable shunt test results (e.g., "Passed" or list of failed channels).
|
||||
- **`string OffsetResults { get; set; }`**
|
||||
Human-readable offset test results.
|
||||
- **`double? TiltX/Y/Z { get; set; }`**
|
||||
Calculated tilt angles (from QATS tilt channels and calibration data).
|
||||
- **`void SetHardware(IDASHardware hardware)`**
|
||||
Sets `Hardware` and loads monitor info from `{SerialNumber}_MonitorInfo.txt`.
|
||||
- **`void SetDASCommunication(IDASCommunication das)`**
|
||||
Sets `DASCommunication`.
|
||||
- **`void SetDASStatus(DASStatuses status)`**
|
||||
Sets `DASStatus`, updating `HasArmed` and `_bootTime` as needed. Transitions `BootedNotArmedYet` to `BootedNeverArmed` if elapsed time exceeds `ExpectedMaxArmTimeSeconds`.
|
||||
- **`void SetDiagStatus(DiagStatuses status)`**
|
||||
Sets `DiagStatus` directly.
|
||||
- **`void SetDistributor(IDistributorArmStatus distributor)`**
|
||||
Sets `Distributor`.
|
||||
- **`void UpdateStatusFromQATS(IUDPQATSEntry qats)`**
|
||||
Updates `LastSeen`, `InputVoltage`, `BackupVoltage`, `Triggered`, and `DiagStatus` based on QATS data. Runs `CheckOffsets`, `CheckShunts`, and `CheckTilts`.
|
||||
- **`void SetSerialNumber(string serial)`**
|
||||
Sets internal `_serialNumber` (used when no hardware/communication is available).
|
||||
|
||||
### 3. Invariants
|
||||
- **Hierarchy Integrity**: Every `DeviceArmStatus` must belong to exactly one `DistributorArmStatus`, and every `DistributorArmStatus` must belong to exactly one `ATDStatus`. `AllATDStatus` is the root container.
|
||||
- **Distributor Detection**: A device is considered a distributor if `IDASHardware.IsSLICEEthernetController` is `true` *or* `IDASCommunication.IsEthernetDistributor()` returns `true`.
|
||||
- **Status Aggregation Rules**:
|
||||
- `ATDStatus.Status` is derived solely from `Distributors.AggregateStatus`.
|
||||
- `DistributorArmStatus.AggregateStatus` is derived solely from `Devices.DASStatus`.
|
||||
- `DeviceArmStatus.DASStatus` is set explicitly via `SetDASStatus` and reflects boot/arming state.
|
||||
- **Diagnostic Status**: `DiagStatus` is a bitmask. `NoResults` is cleared on any QATS update; `Passed` is set only if *all* checks (`CheckOffsets`, `CheckShunts`, `CheckTilts`) pass. Individual failures (`FailedOffset`, `FailedShunt`, `FailedTilt`) are OR’d in.
|
||||
- **Empty Distributor Handling**: A distributor with `SerialNumber == string.Empty` is treated as a fallback for devices without a known parent. Only one such distributor is created per `ATDStatus` (via `GetDistributor`/`CreateATD`).
|
||||
|
||||
### 4. Dependencies
|
||||
- **Imports/Usings**:
|
||||
- `DTS.Common.*`: Core types (`IDASHardware`, `IDASCommunication`, `IUDPQATSEntry`, `DASStatuses`, `DiagStatuses`, `DistributorStatuses`, `AllATDStatuses`, `Constants`, `DFConstantsAndEnums`, `Properties.Settings`, `StringResources`, `Test.Module`, `DbOperations`, `DASMonitorInfo`).
|
||||
- `System.*`: Standard .NET types (collections, IO, networking, data).
|
||||
- **External Services**:
|
||||
- `DbOperations.DASChildrenGet`: Used to resolve parent-child relationships between DAS units.
|
||||
- `Constants.DAS_CONFIGS`: Path to configuration directory for monitor info files.
|
||||
- `Properties.Settings.Default`: Settings for thresholds (`QATSMaxExpectedTimeMS`, `AllowedShuntErrorPercent`, `ExpectedMaxArmTimeSeconds`).
|
||||
- `Test.Module.GetTiltDegreesEU`: Converts raw tilt ADC values to degrees.
|
||||
- **Depended Upon By**:
|
||||
- UI layers (via `IAllATDStatus`, `IATDStatus`, etc.) to display hardware status.
|
||||
- Test orchestration logic that drives `PopulateFromHardware` and `UpdateStatusFromQATS`.
|
||||
|
||||
### 5. Gotchas
|
||||
- **`SerialNumber` Resolution Order**: `DeviceArmStatus.SerialNumber` prioritizes `DASCommunication.SerialNumber` > `Hardware.SerialNumber` > `_serialNumber`. If `DASCommunication` or `Hardware` is null, `_serialNumber` is used, but `_serialNumber` is only set via `SetSerialNumber` (not auto-populated).
|
||||
- **`DistributorStatus` vs `AggregateStatus`**: `DistributorArmStatus.DistributorStatus` reflects the distributor’s *own* state (from QATS `ArmState`), while `AggregateStatus` reflects the state of its *child devices*. They may differ (e.g., distributor armed but devices not).
|
||||
- **`BootedNeverArmed` Transition**: A device in `BootedNotArmedYet` may be downgraded to `BootedNeverArmed` if `DateTime.Now - _bootTime > ExpectedMaxArmTimeSeconds`. This is checked *only* in `SetDASStatus`, not during `UpdateAggregateStatus`.
|
||||
- **Tilt Diagnostics**: `CheckTilts` does *not* fail diagnostics (returns `passed = true` unconditionally). It only computes and stores tilt values. Diag failure for tilt is never set.
|
||||
- **`EmptyDistributor` Behavior**: Devices without a known parent are added to a distributor with `SerialNumber == string.Empty`. `GetDistributor` prioritizes matching `parent` serial over the empty distributor, but if no match is found, the empty distributor is reused. This may cause unrelated devices to be grouped if no parent is specified.
|
||||
- **`Triggered` Logic**: `Triggered = true` only if *both* `qats.Triggered != 0` and `qats.Started != 0`. If either is zero, `Triggered` remains `false`.
|
||||
- **`IP` Property**: `ATDStatus.IP` is set only via `SetIP`; it is never populated from hardware/QATS data.
|
||||
- **`ShuntResults`/`OffsetResults` Format**: Results are comma- and newline-separated strings (e.g., `"Ch1 [1234.5] > 500.0,\r\nCh2 [1234.5] < 100.0"`). This is for UI display and not machine-readable.
|
||||
@@ -0,0 +1,192 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/DataModel/Classes/TabPage/TabPageCommon.cs
|
||||
- DataPRO/DataPRO/DataModel/Classes/TabPage/TabPage.cs
|
||||
generated_at: "2026-04-16T04:22:06.174801+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "b38601ae7a2157be"
|
||||
---
|
||||
|
||||
# TabPage Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a foundational data model for UI tab pages in the DataPRO application, enabling structured representation of tabbed interface elements with support for permissions, visibility, grouping, and dynamic content loading. It defines abstract and concrete classes (`TabPageCommon`, `TabPageItem`, `TabPageItemGroup`, `TabPageSource`) that model tab pages as navigable UI components with associated metadata (title, description, image), permission requirements, and content (e.g., `UserControl`, sub-pages). The module centralizes UI item management, including tile-based navigation, role-based access control, and dynamic content instantiation, serving as the backbone for the application’s tabbed UI structure.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `TabPageCommon` (abstract class)
|
||||
- **`long GetID()` / `void SetID(long id)`**
|
||||
Gets/sets the internal numeric ID (`_id`) for the tab page instance.
|
||||
|
||||
- **`virtual DTS.Slice.Users.User.UserPermissionLevels GetDefaultRolePermission(DTS.Slice.Users.User.DefaultRoles role)`**
|
||||
Returns the default permission level required for a given user role (e.g., `Guest` → `Read`, `Administrator` → `Admin`). Overrideable by subclasses.
|
||||
|
||||
- **`bool IsEnabled { get; set; }`**
|
||||
Gets/sets whether the tab page is enabled (UI-interactable). Bound to UI via `SetProperty`.
|
||||
|
||||
- **`void SetEnabled(bool bEnable)`**
|
||||
Enables/disables the tab page based on current user permissions. If `bEnable` is `true`, compares `_requiredPermission` against the current user’s permission for this instance; disables if insufficient. Does nothing if `CurrentUser` is null.
|
||||
|
||||
- **`virtual bool GetDefaultRoleVisibility(DTS.Slice.Users.User.DefaultRoles role)`**
|
||||
Determines visibility for a given role based on `_requiredPermission`. Returns `false` if role lacks sufficient permission (e.g., `Guest` cannot see pages requiring `Edit` or higher). Overrideable.
|
||||
|
||||
- **`virtual string GetName()`**
|
||||
Returns `UniqueId`. Overrideable.
|
||||
|
||||
- **`Visibility Visibility { get; set; }`**
|
||||
Gets/sets WPF `Visibility` state. Setter triggers `OnPropertyChanged("Visibility")`.
|
||||
|
||||
- **`void SetVisible(bool bShow)`**
|
||||
Sets `Visibility` based on `bShow` and user’s tab flag (`IsShowTabFlagSet`). If `bShow` is `true`, checks user’s flag; otherwise sets `Collapsed`. Falls back to `Visible` if `CurrentUser` is null.
|
||||
|
||||
- **`DTS.Slice.Users.User.UserPermissionLevels GetRequiredPermission()`**
|
||||
Returns `_requiredPermission`.
|
||||
|
||||
- **`string UniqueId { get; set; }`**
|
||||
Unique identifier for the tab page (e.g., `"Homepage_SensorModels"`).
|
||||
|
||||
- **`string Title { get; set; }`**
|
||||
Localized title string. Getter looks up `_title` via `StringResources.ResourceManager`; returns `"#stringnotfound# " + _title` if missing.
|
||||
|
||||
- **`string SubTitle { get; set; }`**
|
||||
Non-localized subtitle string.
|
||||
|
||||
- **`string Description { get; set; }`**
|
||||
Non-localized description string.
|
||||
|
||||
- **`ImageSource Image { get; set; }`**
|
||||
Lazy-loaded image from `_imagePath` using `_baseUri` (`pack://application:,,,/ResourceFile.xaml`). Setter clears `_imagePath`.
|
||||
|
||||
- **`void SetImage(string path)`**
|
||||
Sets `_imagePath`, clears `_image`, and raises `OnPropertyChanged("Image")`.
|
||||
|
||||
- **Constructor**
|
||||
`TabPageCommon(string uniqueId, string title, string subtitle, string imagePath, string description, UserPermissionLevels requiredPermission)`
|
||||
Initializes all fields; `_id` defaults to `-1`.
|
||||
|
||||
### `TabPageItem` (concrete class, inherits `TabPageCommon`)
|
||||
- **`double TileHeight { get; set; }`**
|
||||
Tile height (WPF binding). Raises `OnPropertyChanged` twice (redundant, per FIXME comment).
|
||||
|
||||
- **`double TileWidth { get; set; }`**
|
||||
Tile width (WPF binding). Raises `OnPropertyChanged` twice.
|
||||
|
||||
- **`double TileFontSize { get; set; }`**
|
||||
Font size for tile text. Defaults to `12.0`.
|
||||
|
||||
- **`double FontSize { get; set; }`**
|
||||
Alias for `TileFontSize` (to resolve binding errors). Sets `TileFontSize`.
|
||||
|
||||
- **`UserControl Content { get; set; }`**
|
||||
UI content (`UserControl`) for the tab page.
|
||||
|
||||
- **`DataPROPage[] SubPages { get; set; }`**
|
||||
Array of sub-pages (`DataPROPage[]`) associated with this item.
|
||||
|
||||
- **`DataPROPage GetSubPage(string id)`**
|
||||
Returns the first `DataPROPage` in `SubPages` with matching `UniqueId`. Throws `NullReferenceException` if not found.
|
||||
|
||||
- **`TabPageItemGroup Group { get; set; }`**
|
||||
Parent group containing this item.
|
||||
|
||||
- **`virtual void SetCurrentItem(object o)`**
|
||||
No-op by default. Overrideable (e.g., `SensorsItem` calls `(Content as HardwareSensorsAndSquibs).SetCurrentItem(o)`).
|
||||
|
||||
- **`virtual void SetContent()`**
|
||||
Re-initializes `Content` and `SubPages`. Overrideable (e.g., `DASItem`, `SensorsItem`).
|
||||
|
||||
- **Constructor**
|
||||
`TabPageItem(string uniqueid, string title, string subtitle, string imagepath, string description, UserControl content, TabPageItemGroup group, UserPermissionLevels requiredPermission)`
|
||||
Calls base constructor and initializes `_content`, `_group`.
|
||||
|
||||
### `TabPageItemGroup` (concrete class, inherits `TabPageCommon`)
|
||||
- **`ObservableCollection<TabPageItem> Items { get; }`**
|
||||
Read-only collection of child `TabPageItem`s.
|
||||
|
||||
- **`IEnumerable<TabPageItem> TopItems { get; }`**
|
||||
Returns all items in `Items` (currently `_items.Take(_items.Count)`).
|
||||
|
||||
- **`void UpdateTopItems()`**
|
||||
Raises `OnPropertyChanged("TopItems")`.
|
||||
|
||||
- **`Color SelectedColor { get; set; }`**
|
||||
Background color when the group’s tile is selected.
|
||||
|
||||
- **`Color HoverColor { get; set; }`**
|
||||
Background color on hover.
|
||||
|
||||
- **Constructor**
|
||||
`TabPageItemGroup(string uniqueid, string title, string subtitle, string imagepath, string description, Color selectedColor, Color hoverColor, UserPermissionLevels requiredPermission)`
|
||||
Initializes base fields and color properties.
|
||||
|
||||
### `TabPageSource` (static-like singleton)
|
||||
- **`static ObservableCollection<TabPageItemGroup> AllGroups { get; }`**
|
||||
Global collection of all `TabPageItemGroup`s.
|
||||
|
||||
- **`static IEnumerable<TabPageItemGroup> GetGroups(string uniqueid)`**
|
||||
Returns `AllGroups` if `uniqueid == "AllGroups"`; otherwise throws `ArgumentException`.
|
||||
|
||||
- **`static void TurnOffISOTiles()`**
|
||||
Calls `_source._prepareGroup.UpdateTopItems()`.
|
||||
|
||||
- **`static void TurnOnISOTiles()`**
|
||||
Calls `_source.AddAllPrepareTileGroups()` and `_source._prepareGroup.UpdateTopItems()`.
|
||||
|
||||
- **`static TabPageItemGroup GetGroup(string uniqueid)`**
|
||||
Returns the single matching group from `AllGroups`; `null` if 0 or >1 matches.
|
||||
|
||||
- **`static TabPageItem GetItem(string uniqueid)`**
|
||||
Returns the single matching item across all groups; `null` if 0 or >1 matches.
|
||||
|
||||
- **`enum TileUniqueIDs`**
|
||||
Defines string constants for tile IDs (e.g., `Hardware_SensorModels`, `Prepare_TestSetups`).
|
||||
|
||||
- **`enum TileGroupUniqueIDs`**
|
||||
Defines group IDs: `Hardware`, `Prepare`, `Diagnostics`, `Record`, `Review`, `Admin`.
|
||||
|
||||
- **`void TabPageItemClick(object o)`**
|
||||
No-op stub.
|
||||
|
||||
- **Nested item classes** (e.g., `SensorModelsItem`, `DASItem`, `SensorsItem`, etc.)
|
||||
Predefined `TabPageItem` subclasses with hardcoded `Content`, `SubPages`, and permissions. Each implements `SetContent()` to re-initialize content.
|
||||
|
||||
- **Constructor**
|
||||
Instantiates all groups and items, populating `AllGroups`. Initializes `_prepareGroup`, `_testObjectItem`, `_testSetupsItem`, `_additionalDetailsItem`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`UniqueId` uniqueness**: Each `TabPageItem` and `TabPageItemGroup` must have a unique `UniqueId` within the system (enforced by `GetGroup`/`GetItem` expecting exactly one match).
|
||||
- **`_id` initialization**: `_id` defaults to `-1`; must be explicitly set via `SetID` before use in ID-based lookups.
|
||||
- **Permission hierarchy**: `_requiredPermission` determines visibility/enablement. Higher enum values (`Admin > Edit > ReadAndExecute > Read > Deny`) imply broader access.
|
||||
- **Image loading**: `_image` is lazily loaded from `_imagePath` using `_baseUri`. Setting `Image` directly clears `_imagePath`.
|
||||
- **Content initialization**: `Content` and `SubPages` are set in constructors and must be re-initialized via `SetContent()` if dynamic reloading is needed.
|
||||
- **User context dependency**: `SetEnabled` and `SetVisible` require `((App)Application.Current).CurrentUser` to be non-null for permission/flag checks; otherwise, they fall back to defaults (`IsEnabled = bEnable`, `Visibility = Visible`).
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **WPF**: Uses `System.Windows`, `System.Windows.Media`, `System.Windows.Controls`, `System.Windows.Media.Imaging`, `System.Windows.Application`.
|
||||
- **DTS libraries**: `DTS.Common`, `DTS.Slice.Users`, `DTS.Common.Base` (for `BasePropertyChanged`), `DTS.Common.SharedResource.Strings` (for `StringResources`).
|
||||
- **Application context**: Relies on `((App)Application.Current).CurrentUser` for permission/visibility checks.
|
||||
- **Settings**: Uses `Common.SerializedSettings` (in `StatusLineItem` constructor) and `Properties.Settings.Default.ShowTestSetupWizard`.
|
||||
- **Page types**: Depends on concrete `DataPROPage` subclasses (e.g., `EditSensorModelDetailsPage`, `HardwareSensorsAndSquibs`) and `UserControl` implementations (e.g., `HardwareSensorModels`, `UsersPage`).
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- **UI layer**: WPF views bind to `IsEnabled`, `Visibility`, `Image`, `Title`, etc.
|
||||
- **Navigation system**: `TabPageSource` is used to populate and manage tab groups/items.
|
||||
- **Permission system**: Integrates with `DTS.Slice.Users.User` for role-based access control.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Redundant property change notifications**: `TileHeight`/`TileWidth`/`TileFontSize` setters call `OnPropertyChanged` twice (see `FIXME` comment in source). May cause performance issues or unexpected UI updates.
|
||||
- **`FontSize` alias**: `FontSize` is a direct alias to `TileFontSize` to resolve binding errors, but this may mask underlying binding issues (e.g., if consumers expect `FontSize` to be independent).
|
||||
- **`GetSubPage` throws `NullReferenceException`**: Non-existent `id` throws `NullReferenceException` (not `KeyNotFoundException` or custom exception), which is misleading.
|
||||
- **`_baseUri` hardcoded**: Image paths use `pack://application:,,,/ResourceFile.xaml` as base URI. If `ResourceFile.xaml` is renamed or moved, images break silently (returns `null`).
|
||||
- **`GetGroups` restriction**: Only supports `"AllGroups"` as `uniqueid`; other values throw `ArgumentException`.
|
||||
- **`TopItems` implementation**: Returns `_items.Take(_items.Count)` (i.e., all items). The name `TopItems` and `UpdateTopItems()` suggest partial/top-N behavior, but no filtering is implemented.
|
||||
- **`SetEnabled` logic**: Disables page if `permission < _requiredPermission`, but does *not* re-enable if permission improves dynamically (e.g., user role change). Requires manual re-invocation.
|
||||
- **`SetVisible` behavior**: Visibility depends on `CurrentUser.IsShowTabFlagSet(this)`, but no documentation clarifies how this flag is managed or persisted.
|
||||
- **Hardcoded permissions**: Item permissions (e.g., `SensorsItem` requires `Edit`) are hardcoded in constructors. Changing permissions requires code changes, not configuration.
|
||||
- **`TileFontSize` default**: Initialized to `12.0` to avoid binding errors, but this value may conflict with theme defaults or designer expectations.
|
||||
59
enriched-qwen3-coder-next/DataPRO/DataPRO/HelpStrings.md
Normal file
59
enriched-qwen3-coder-next/DataPRO/DataPRO/HelpStrings.md
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/HelpStrings/HelpStringResources.Designer.cs
|
||||
generated_at: "2026-04-16T04:04:41.534416+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "963019add4c5fb12"
|
||||
---
|
||||
|
||||
# HelpStrings
|
||||
|
||||
## Documentation Page: `HelpStringResources` Class
|
||||
|
||||
### 1. Purpose
|
||||
The `HelpStringResources` class serves as a strongly-typed, auto-generated wrapper for accessing localized help strings used throughout the DataPRO application. It enables type-safe retrieval of UI help text (e.g., tooltips, help dialog content) from embedded resources, supporting localization via culture-specific resource files (`.resx`). This class centralizes help text management and ensures consistent, localized messaging for UI elements such as combo boxes and error states.
|
||||
|
||||
### 2. Public Interface
|
||||
All members are `internal` (not public), per the `internal` access modifier in the source. No public API is exposed.
|
||||
|
||||
- **`HelpStringResources()`**
|
||||
*Constructor.* Private/`internal` parameterless constructor. Used internally by the resource infrastructure. Not intended for direct instantiation.
|
||||
|
||||
- **`ResourceManager` (static property)**
|
||||
*Signature:* `internal static System.Resources.ResourceManager ResourceManager { get; }`
|
||||
Returns a cached `ResourceManager` instance initialized for the `"DataPROWin7.HelpStrings.HelpStringResources"` base name. Lazily initializes on first access.
|
||||
|
||||
- **`Culture` (static property)**
|
||||
*Signature:* `internal static System.Globalization.CultureInfo Culture { get; set; }`
|
||||
Gets or sets the UI culture used for resource lookups. Overrides the current thread’s `CurrentUICulture` for this class only.
|
||||
|
||||
- **`HelpTextNotFound` (static property)**
|
||||
*Signature:* `internal static string HelpTextNotFound { get; }`
|
||||
Returns the localized string for the resource key `"HelpTextNotFound"`. Used as a fallback when help text is missing.
|
||||
|
||||
- **`SensorDatabaseModelComboBox` (static property)**
|
||||
*Signature:* `internal static string SensorDatabaseModelComboBox { get; }`
|
||||
Returns the localized string for the resource key `"SensorDatabaseModelComboBox"`. Intended for help text associated with the sensor model combo box in the UI.
|
||||
|
||||
### 3. Invariants
|
||||
- The class is **thread-safe for read-only access** to static properties (due to `ResourceManager`’s thread-safe caching and immutable string returns), but `Culture` assignment is not synchronized—concurrent writes may cause race conditions.
|
||||
- Resource keys (`"HelpTextNotFound"`, `"SensorDatabaseModelComboBox"`) must exist in the corresponding `.resx` file; otherwise, `ResourceManager.GetString()` returns `null`.
|
||||
- The class is **not extensible**—new keys require editing the `.resx` file and regenerating this file (via Visual Studio or `ResGen`).
|
||||
|
||||
### 4. Dependencies
|
||||
- **Depends on:**
|
||||
- `System.Resources.ResourceManager`
|
||||
- `System.Globalization.CultureInfo`
|
||||
- Embedded resource file `DataPROWin7.HelpStrings.HelpStringResources.resources` (compiled from `HelpStringResources.resx`)
|
||||
- `System.CodeDom.Compiler`, `System.Diagnostics`, `System.ComponentModel`, `System.Runtime.CompilerServices` (for attributes)
|
||||
- **Used by:**
|
||||
- Other modules in `DataPROWin7.HelpStrings` namespace (inferred from namespace and naming convention). Likely consumed by UI components (e.g., form controls, help providers) that need localized help text.
|
||||
- *Not directly visible* in this file—consumers must reference the `DataPROWin7.HelpStrings` namespace.
|
||||
|
||||
### 5. Gotchas
|
||||
- **Auto-generated file:** Manual edits will be overwritten. Changes must be made in the source `.resx` file.
|
||||
- **No null-safety:** `HelpTextNotFound` and `SensorDatabaseModelComboBox` may return `null` if the corresponding resource key is missing or empty in the `.resx` file. Callers must handle `null` gracefully.
|
||||
- **Culture override scope:** Setting `Culture` affects only lookups via this class—not global thread culture. Other resource classes require separate `Culture` assignment.
|
||||
- **No documentation for missing keys:** The class does not validate key existence at compile time or runtime—missing keys silently yield `null`.
|
||||
- **None identified from source alone** for additional quirks (e.g., performance, threading beyond `Culture`), but the auto-generated nature and minimal logic imply low complexity.
|
||||
136
enriched-qwen3-coder-next/DataPRO/DataPRO/Licensing.md
Normal file
136
enriched-qwen3-coder-next/DataPRO/DataPRO/Licensing.md
Normal file
@@ -0,0 +1,136 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Licensing/LicenseProperty.cs
|
||||
- DataPRO/DataPRO/Licensing/ClientLicense.cs
|
||||
generated_at: "2026-04-16T04:07:06.063338+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f6b16e33719f7ff4"
|
||||
---
|
||||
|
||||
# Licensing
|
||||
|
||||
## Documentation: Licensing Module (`DataPROWin7.Licensing`)
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module provides core licensing validation logic for the DataPRO application. It enables verification of license files against system hardware and product version constraints, distinguishing between different license types (e.g., standard, enterprise, site licenses), and determining validity based on expiration, product version compatibility, and machine binding. It serves as the central authority for license validation within the application, leveraging the `Portable.Licensing` library and custom extensions for DataPRO-specific attributes.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
All types and members are `internal`, meaning they are only accessible within the `DataPROWin7` assembly.
|
||||
|
||||
#### `class LicenseProperty`
|
||||
A static class exposing read-only properties for *default* (placeholder) license metadata values. These are **not** runtime-computed values and appear to be fallbacks for unlicensed or debug builds.
|
||||
|
||||
- `public static string PublicKey { get; private set; }`
|
||||
Default placeholder public key: `"00000000-0000-0000-0000-000000000000"`.
|
||||
|
||||
- `public static string KeyGuid { get; private set; }`
|
||||
Default placeholder key GUID: `"00000000-0000-0000-0000-000000000000"`.
|
||||
|
||||
- `public static string BuildMode { get; private set; }`
|
||||
Default build mode: `"Debug"`.
|
||||
|
||||
> ⚠️ **Note**: These properties are auto-generated and should not be manually modified.
|
||||
|
||||
#### `class ClientLicense`
|
||||
A static class containing license validation and helper methods.
|
||||
|
||||
- `public static bool IsSiteLicense(DataProLicensingEnums.LicenseType licenseType)`
|
||||
Returns `true` if `licenseType` is `EnterpriseSite`, `StandardSite`, or `TSRAir`. These license types bypass machine hardware validation.
|
||||
|
||||
- `public static bool IsStandardSiteLicense(DataProLicensingEnums.LicenseType licenseType)`
|
||||
Returns `true` if `licenseType == StandardSite`.
|
||||
|
||||
- `public static bool IsEnterpriseSiteLicense(DataProLicensingEnums.LicenseType licenseType)`
|
||||
Returns `true` if `licenseType == EnterpriseSite`.
|
||||
|
||||
- `public static bool IsEnterpriseLicense(DataProLicensingEnums.LicenseType licenseType)`
|
||||
Returns `true` if `licenseType == Enterprise`.
|
||||
|
||||
- `public static bool IsStandardLicense(DataProLicensingEnums.LicenseType licenseType)`
|
||||
Returns `true` if `licenseType == Standard`.
|
||||
|
||||
- `public static bool IsTSRAIRLicense(DataProLicensingEnums.LicenseType licenseType)`
|
||||
Returns `true` if `licenseType == TSRAir`.
|
||||
|
||||
- `public static Tuple<bool, string> ValidateVersion(ValidationResult validationResult, Version dataProVersion)`
|
||||
Compares the product version in `validationResult` against the current `dataProVersion`.
|
||||
- Returns `(true, null)` if `validationResult.ProductVersion >= dataProVersion` (ignoring build number).
|
||||
- Returns `(false, errorMessage)` if version is incompatible or license version is invalid.
|
||||
- Special handling: if `validationResult.ProductVersion.Minor == 999`, displays `"x"` in error message (e.g., `"2.x"`).
|
||||
- Uses `StringResources.License_LicenseVersionIsNotSupported` / `StringResources.License_ProductVersionIsWrong` for messages.
|
||||
|
||||
- `public static ValidationResult Validate(StreamReader licenseContent, string decryptedPublicKey)`
|
||||
Validates a license file (`licenseContent`) using `decryptedPublicKey`.
|
||||
- Loads and parses the license using `Portable.Licensing`.
|
||||
- Validates signature using `decryptedPublicKey`.
|
||||
- For **non-site licenses**, validates that the `SystemIdentifier` attribute matches the current machine’s hardware ID (`processorID_mainBoardSerialNumber_systemID`).
|
||||
- For **site licenses** (`IsSiteLicense`), skips hardware validation.
|
||||
- Parses `LicenseVersion`, `ProductVersion`, `LicenseNeverExpires`, and `Expiration` attributes.
|
||||
- Sets `ValidationResult` fields:
|
||||
- `IsValid`, `IsLicenseVersionValid`, `IsLicenseExpired`
|
||||
- `ProductVersion`, `LicenseVersion`, `LicenseExpiration`
|
||||
- `LicensedTo`, `LicenseId`, `LicenseType`
|
||||
- `ValidationFailures` (list of `ValidationFailure` objects with `Message` and `HowToResolve`)
|
||||
- Returns a `ValidationResult` with full validation state.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **Hardware binding**: Non-site licenses *must* have a `SystemIdentifier` attribute matching the current machine’s hardware ID (`processorID_{mainBoardSerialNumber}_{systemID}`), otherwise validation fails.
|
||||
- **Site license exemption**: Licenses of type `EnterpriseSite`, `StandardSite`, or `TSRAir` are exempt from hardware binding.
|
||||
- **Version comparison**: Product version comparison ignores the build number (only `Major.Minor` is used).
|
||||
- **License version handling**:
|
||||
- Licenses with `LicenseVersion > "1.0.0"` support `ProductVersion`, `LicenseNeverExpires`, and `Expiration` attributes.
|
||||
- Licenses with `LicenseVersion <= "1.0.0"` are considered invalid (`IsLicenseVersionValid = false`).
|
||||
- **Expiration logic**:
|
||||
- Expiration is checked *only if* `LicenseNeverExpires` is not `true`.
|
||||
- If `LicenseNeverExpires` is absent or `false`, and `license.Expiration < DateTime.Now`, then `IsLicenseExpired = true`.
|
||||
- **No build number in version**: `dataProVersion` passed to `ValidateVersion` is truncated to `Major.Minor` before comparison.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### External Dependencies (via imports):
|
||||
- `System` (`System`, `System.IO`, `System.Linq`, `System.Collections.Generic`)
|
||||
- `DTS.Common.Licensing` (custom licensing infrastructure)
|
||||
- `DTS.Common.Licensing.SystemInformation` (provides `ProcessorInfo`, `MainBoardInfo`, `ComputerSystemInfo`, `MachineInfo`)
|
||||
- `Portable.Licensing` (core license parsing/validation: `License.Load`, `.Validate()`, `.Signature()`, `.AssertValidLicense()`)
|
||||
- `Portable.Licensing.Validation` (`ValidationResult`, `ValidationFailure`, `IValidationFailure`)
|
||||
- `DTS.Common.Licensing.Messages` (likely contains `ValidationFailure` type used)
|
||||
- `DTS.Common.SharedResource.Strings` (`StringResources` for localized error messages)
|
||||
|
||||
#### Internal Dependencies:
|
||||
- `DataProLicensingEnums` (assumed to define `LicenseType` enum: `Standard`, `Enterprise`, `StandardSite`, `EnterpriseSite`, `TSRAir`)
|
||||
- `LicenseProperty` (provides placeholder values; used only for defaults, not runtime validation logic)
|
||||
|
||||
#### Depends on:
|
||||
- Hardware info providers (`ProcessorInfo`, `MainBoardInfo`, `ComputerSystemInfo`, `MachineInfo`) to generate system identifiers.
|
||||
- `StringResources` for user-facing error messages.
|
||||
|
||||
#### Used by:
|
||||
- Unknown from source alone — likely invoked by UI or startup logic to validate license before application launch.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **Placeholder values in `LicenseProperty`**: The default values (e.g., all-zero GUIDs) are *not* real keys and should not be used in production. They are likely for debug builds or unlicensed scenarios.
|
||||
- **`maxMinor = 999` magic constant**: Used to represent wildcard minor versions (e.g., `"2.x"`). This is non-standard and may confuse developers expecting semantic versioning.
|
||||
- **`LicenseVersion` parsing is strict**: Licenses with `LicenseVersion <= "1.0.0"` are *rejected entirely* (`IsLicenseVersionValid = false`), even if other attributes are present.
|
||||
- **`ProductVersion` parsing quirk**: If `"ProductVersion"` contains `"x"` (e.g., `"2.x"`), minor is set to `999`. This is only used for comparison and display — not standard version handling.
|
||||
- **`IsSiteLicense` includes `TSRAir`**: A comment references bug fixes (FB 37931, 30629) for `TSRAir` being treated as a site license to bypass hardware checks. This may be unexpected for new developers.
|
||||
- **`ValidationResult.IsValid` vs `IsLicenseVersionValid`**: `IsValid` is only `true` if *all* checks pass (signature, hardware, version, expiration). `IsLicenseVersionValid` is a *subset* check (only for license file version compatibility).
|
||||
- **`LicenseNeverExpires` is nullable**: Logic checks `!licenseNeverExpires.HasValue` *and* `licenseNeverExpires.Value == false` to decide whether to check expiration. This suggests the attribute may be missing, `true`, or `false`.
|
||||
- **`ValidationResult.LicenseExpiration` may be unset**: If `LicenseNeverExpires` is `true`, `LicenseExpiration` is *not* set (remains default `DateTime`), which callers must handle.
|
||||
- **No exception handling visible**: If `License.Load`, `ProcessorInfo`, or `Convert.ToBoolean` fails (e.g., malformed license), behavior is undefined from source — likely throws or returns partial result.
|
||||
|
||||
> ✅ **No other obvious tech debt or quirks identified from source alone.**
|
||||
71
enriched-qwen3-coder-next/DataPRO/DataPRO/ModuleCatalog.md
Normal file
71
enriched-qwen3-coder-next/DataPRO/DataPRO/ModuleCatalog.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/ModuleCatalog/AggregateModuleCatalog.cs
|
||||
generated_at: "2026-04-16T04:05:38.214804+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "aeeddd16140af69e"
|
||||
---
|
||||
|
||||
# ModuleCatalog
|
||||
|
||||
### **Purpose**
|
||||
The `AggregateModuleCatalog` class serves as a composite implementation of `IModuleCatalog` that aggregates multiple underlying module catalogs into a unified interface for Prism’s module loading system. It enables the application to manage modules across different catalog sources (e.g., configuration-based, code-defined, or external catalogs) while maintaining a single point of access for module discovery, dependency resolution, and initialization. Its primary role is to delegate operations to the appropriate underlying catalog(s) based on where a given `ModuleInfo` resides, ensuring modularity and extensibility in module registration and loading.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
- **`AggregateModuleCatalog()`**
|
||||
*Constructor.* Initializes a new instance with a default `ModuleCatalog` (from `Microsoft.Practices.Prism.Modularity`) added to the internal `_catalogs` list as the first catalog. This default catalog is used for modules added via `AddModule`.
|
||||
|
||||
- **`void AddCatalog(IModuleCatalog catalog)`**
|
||||
Adds a new catalog to the internal list of catalogs. Throws `ArgumentNullException` if `catalog` is `null`. The added catalog becomes part of the aggregation and is consulted during enumeration and lookups.
|
||||
|
||||
- **`IEnumerable<ModuleInfo> Modules { get; }`**
|
||||
Returns a flattened enumeration of all `ModuleInfo` instances across all aggregated catalogs, in the order of the catalogs in `_catalogs`.
|
||||
|
||||
- **`IEnumerable<ModuleInfo> GetDependentModules(ModuleInfo moduleInfo)`**
|
||||
Returns the list of modules that `moduleInfo` depends on. Delegates to the *single* catalog that contains `moduleInfo` (throws `InvalidOperationException` if `moduleInfo` is not found in exactly one catalog).
|
||||
|
||||
- **`IEnumerable<ModuleInfo> CompleteListWithDependencies(IEnumerable<ModuleInfo> modules)`**
|
||||
Given a set of modules, returns those modules plus all transitive dependencies. Groups the input modules by the catalog that contains each, then delegates `CompleteListWithDependencies` per catalog and flattens the results.
|
||||
|
||||
- **`void Initialize()`**
|
||||
Calls `Initialize()` on each catalog in `_catalogs`, in order.
|
||||
|
||||
- **`void AddModule(ModuleInfo moduleInfo)`**
|
||||
Adds `moduleInfo` to the *first* catalog in `_catalogs` (i.e., the default `ModuleCatalog` created in the constructor). Does *not* consult or add to other catalogs.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
|
||||
- `_catalogs` is never `null`; it is initialized with one element (a `ModuleCatalog`) in the constructor.
|
||||
- `AddCatalog` may only be called with non-null `IModuleCatalog` instances.
|
||||
- `GetDependentModules` and `CompleteListWithDependencies` assume that each `ModuleInfo` belongs to **exactly one** catalog in `_catalogs`. If a `ModuleInfo` appears in multiple catalogs (e.g., due to duplicate registration), behavior is undefined (likely throws `InvalidOperationException` from `Single()`).
|
||||
- `AddModule` *always* targets the first catalog (`_catalogs[0]`), regardless of where other modules reside.
|
||||
- The `Modules` property returns modules in catalog order (i.e., order of insertion into `_catalogs`), with all modules from catalog *i* appearing before those from catalog *i+1*.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
|
||||
- **Depends on:**
|
||||
- `Microsoft.Practices.Prism.Modularity` (specifically `IModuleCatalog`, `ModuleInfo`, and `ModuleCatalog`).
|
||||
- Standard .NET types: `System`, `System.Collections.Generic`, `System.Linq`.
|
||||
|
||||
- **Depended on by (inferred):**
|
||||
- The application’s bootstrapper or composition root (likely `DataPROWin7.App` or similar), which would instantiate and configure `AggregateModuleCatalog` as the Prism module catalog.
|
||||
- No other types in the provided source depend on it, but its usage is implied by Prism’s module loading pipeline.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
|
||||
- **`Single()` usage is fragile:** Both `GetDependentModules` and `CompleteListWithDependencies` use `_catalogs.Single(x => x.Modules.Contains(moduleInfo))`. If a `ModuleInfo` appears in multiple catalogs (e.g., added via `AddModule` *and* manually added to another catalog), this will throw `InvalidOperationException`.
|
||||
- **`AddModule` is not distributed:** Modules added via `AddModule` go *only* to the first catalog (`_catalogs[0]`). If that catalog is replaced or reconfigured, modules may be lost or misrouted.
|
||||
- **No deduplication:** The `Modules` property may yield duplicate `ModuleInfo` instances if the same module is registered in multiple catalogs (e.g., via `AddCatalog` and `AddModule`).
|
||||
- **Order sensitivity:** Behavior of `CompleteListWithDependencies` may depend on catalog order if dependencies span catalogs (though dependencies themselves are resolved per-catalog, so cross-catalog dependencies are not explicitly supported).
|
||||
- **No validation of cross-catalog dependencies:** If a module in catalog *A* depends on a module in catalog *B*, the dependency resolution may succeed only if catalog *A*’s `GetDependentModules`/`CompleteListWithDependencies` correctly references the module in catalog *B*—but `AggregateModuleCatalog` does not enforce or validate this.
|
||||
- **No thread-safety:** The class is not documented as thread-safe; concurrent modifications (e.g., `AddCatalog` during enumeration) may cause exceptions.
|
||||
280
enriched-qwen3-coder-next/DataPRO/DataPRO/Pages.md
Normal file
280
enriched-qwen3-coder-next/DataPRO/DataPRO/Pages.md
Normal file
@@ -0,0 +1,280 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Pages/ATDMonitorStatusPage.cs
|
||||
- DataPRO/DataPRO/Pages/CopyAndTrimPage.cs
|
||||
- DataPRO/DataPRO/Pages/RenameTestPage.cs
|
||||
- DataPRO/DataPRO/Pages/DownloadAndView.cs
|
||||
- DataPRO/DataPRO/Pages/TimedWaitControl.xaml.cs
|
||||
- DataPRO/DataPRO/Pages/ModalPage.xaml.cs
|
||||
- DataPRO/DataPRO/Pages/SplashScreen.xaml.cs
|
||||
- DataPRO/DataPRO/Pages/AddGraphPage.cs
|
||||
- DataPRO/DataPRO/Pages/StatusLinePage.cs
|
||||
- DataPRO/DataPRO/Pages/EditGraphPage.cs
|
||||
- DataPRO/DataPRO/Pages/RealtimePage.cs
|
||||
- DataPRO/DataPRO/Pages/DownloadDataPage.cs
|
||||
- DataPRO/DataPRO/Pages/ChangeView.xaml.cs
|
||||
- DataPRO/DataPRO/Pages/EditUserDetailsPage.cs
|
||||
- DataPRO/DataPRO/Pages/LoginControl2.xaml.cs
|
||||
- DataPRO/DataPRO/Pages/UsersPage.cs
|
||||
generated_at: "2026-04-16T04:07:55.599898+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "0cf7084f6b7d3cb6"
|
||||
---
|
||||
|
||||
# Pages
|
||||
|
||||
**Documentation Page: DataPROWin7 Page Implementations**
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module defines concrete implementations of `DataPROPage`—the base class for all UI pages in the DataPROWin7 application—each representing a distinct functional area such as test setup monitoring, data export, user administration, graph editing, and real-time diagnostics. These pages coordinate UI controls, navigation, permissions, and business logic to support user workflows including test selection, data download, user management, and graph configuration. They integrate with controls (e.g., `TestSetupsControl`, `CopyAndTrim`, `RenameTestControl`, `UserListControl`) and leverage infrastructure services (e.g., Prism event aggregation, licensing, user management) to provide a consistent, role-based UI experience.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
All classes inherit from `DataPROPage`. Only public members explicitly declared or overridden in the source are listed.
|
||||
|
||||
#### `ATDMonitorStatusPage`
|
||||
- **Constructor**: `ATDMonitorStatusPage(DataModel.TabPageItem item)`
|
||||
Initializes `_statusControl`, sets `UsesNAVControl = false`, `UsesSearchControl = true`, `ContentBackgroundColor = Transparent`, and assigns `_statusControl` as `MainContent`.
|
||||
- **Property**: `CurrentTest` (setter only)
|
||||
Sets `_statusControl.CurrentTest`.
|
||||
- **Override**: `UniqueId` → `MyId` (`"TestSetups_ATDMonitorStatusPage"`)
|
||||
- **Override**: `UnSet()`
|
||||
Calls `base.UnSet()`; no additional logic.
|
||||
|
||||
#### `CopyAndTrimPage`
|
||||
- **Constructor**: `CopyAndTrimPage(DataModel.TabPageItem item)`
|
||||
Configures page metadata: `UsesNAVControl = false`, `IsAdd = true`, `PageName = StringResources.Homepage_ExportData`, `UsesSearchControl = false`, `UsesSelectControl = false`, `UsesModifyEnhancements = true`, `HasSaveButton = false`, `HasNextButton = false`. Instantiates `_copyAndTrim = new Controls.CopyAndTrim(this)` and sets `MainContent`.
|
||||
- **Properties**:
|
||||
- `DownloadFolder` (`string`, default `""`)
|
||||
- `IsROI` (`bool`, default `false`)
|
||||
- `TestItem` (`string`, default `""`)
|
||||
- `AvailableTestIds` (`List<string>`)
|
||||
- `DTSFilePath` (`string`, default `""`)
|
||||
- **Override**: `UniqueId` → `"Review_ExportData_CopyAndTrim"`
|
||||
|
||||
#### `RenameTestPage`
|
||||
- **Constructor**: `RenameTestPage(DataModel.TabPageItem item)`
|
||||
Same configuration as `CopyAndTrimPage`, but instantiates `_renameTestControl = new Controls.RenameTestControl(this)`.
|
||||
- **Properties**:
|
||||
- `DownloadFolder`, `IsROI`, `TestItem`, `AvailableTestIds`, `AvailableTestNames` (`List<string>`), `DTSFilePath`
|
||||
(All with same defaults as `CopyAndTrimPage`.)
|
||||
- **Override**: `UniqueId` → `"Review_ExportData_Rename"`
|
||||
|
||||
#### `DownloadAndView`
|
||||
- **Constructor**: `DownloadAndView(DataModel.TabPageItem item)` and `DownloadAndView(DataModel.TabPageItem item, int possibleSteps)`
|
||||
Inherits from `RunTestBase`; initializes `_item`.
|
||||
- **Override**: `OnSetActive()`
|
||||
Resets `ROINext_OK` and `ALLNext_OK`; subscribes to `AutomaticModeStatusEvent` once via `IEventAggregator`; sets `PageName`.
|
||||
- **Override**: `UnSet()`
|
||||
Clears search term; if `_downloadROIControl` exists, calls `StartSearch(string.Empty)` on it.
|
||||
- **Override**: `UniqueId` → `MyId` (`"Record_DownloadAndView"`)
|
||||
- **Method**: `NavigateToROIDownload()`
|
||||
Calls `SetCurrentStep(_downloadROIControlNavStep, false)`.
|
||||
|
||||
#### `TimedWaitControl`
|
||||
- **Constructor**: `TimedWaitControl()` and `TimedWaitControl(MainWindow MainWindow)`
|
||||
- **Property**: `ManualResetEvent` (`System.Threading.ManualResetEvent`)
|
||||
- **Method**: `MarkDone()`
|
||||
Sets and nullifies `ManualResetEvent`.
|
||||
- **Method**: `SetValuePercent(double d)`
|
||||
Calls `ctrlStatusRibbon.SetProgressValue(int)`.
|
||||
- **Method**: `SetStatusMessage(string msg)`
|
||||
Calls `ctrlStatusRibbon.SetStatusTextNoTranslate(msg)`.
|
||||
- **Property**: `CancelButtonVisibility` (`Visibility`, implements `INotifyPropertyChanged`)
|
||||
- **Event**: `btnCancel_Click` handler sets `ManualResetEvent` if non-null.
|
||||
|
||||
#### `ModalPage`
|
||||
- **Constructor**: `ModalPage()` and `ModalPage(MainWindow MainWindow)`
|
||||
- **Interface**: Implements `IModalContent` (see below).
|
||||
- **Method**: `SetContent(IModalContent content)`
|
||||
Calls `content.OnSetActive()`, assigns `content.CloseFunction = ModalContentClosed`, and sets `modalContent.Content`.
|
||||
- **Private**: `ModalContentClosed()`
|
||||
Calls `_MainWindow.CloseModalDialog()`.
|
||||
|
||||
##### `IModalContent` interface (defined in `ModalPage.xaml.cs`)
|
||||
- `DialogResult DialogResult { get; }`
|
||||
- `ModalPage.OnCloseDelegate CloseFunction { get; set; }`
|
||||
- `void OnSetActive()`
|
||||
- `string PromptString { get; set; }`
|
||||
- `bool ReusableMessageBox { get; set; }`
|
||||
- `void SetButtons(PageButton[] buttons)`
|
||||
- `PageButton DefaultButton { get; set; }`
|
||||
|
||||
#### `SplashScreen`
|
||||
- **Constructor**: `SplashScreen()`
|
||||
Sets WPF Toolkit license key; configures window properties (`ShowInTaskbar = false`, `Topmost = false`, `ResizeMode = NoResize`).
|
||||
- **Properties**:
|
||||
- `Version`, `DbVersion`, `LicensedTo`, `Copyright` (all setters assign to respective `TextBlock`s)
|
||||
- `LicenseType` (`DataProLicensingEnums.LicenseType`)
|
||||
Triggers `SetBackgroundImage()` on change.
|
||||
- **Method**: `SetBackgroundImage()`
|
||||
Sets `BannerImage.ImageSource` based on `RunTestVariables.IsTSRAIRGo` and `LicenseType`.
|
||||
|
||||
#### `AddGraphPage`
|
||||
- **Constructor**: `AddGraphPage(DataModel.TabPageItem item)`
|
||||
Sets `PageName`, disables `UsesSearchControl`, `UsesSelectControl`, `HasNextButton`, `HasBackButton`.
|
||||
- **Override**: `UniqueId` → `"Review_ViewData_AddGraph"`
|
||||
- **Fields**: `saveButton`, `saveAsButton`, `saveAndAddAnotherButton` (`Controls.PageButton`)
|
||||
- **Override**: `AddPageButtons()`
|
||||
Adds buttons: Cancel, Save, SaveAs, SaveAndAddAnother, View.
|
||||
- **Override**: `OnButtonPress(PageButton button)`
|
||||
Handles button presses for Save/SaveAs/SaveAndAddAnother (calls `Validate`), View/Cancel (navigates back).
|
||||
|
||||
#### `StatusLinePage`
|
||||
- **Constructor**: `StatusLinePage(DataModel.TabPageItem item)`
|
||||
Initializes `_selectControl = new Controls.TestSetupsControl(...)`, sets `UsesNAVControl = false`, `UsesSearchControl = true`, `ContentBackgroundColor = Transparent`, `MainContent = _selectControl`.
|
||||
- **Override**: `UniqueId` → `MyId` (`"Diagnostics_StatusLineCheck"`)
|
||||
- **Override**: `OnSetActive()`
|
||||
Calls `SetRunButtonEnabled()`.
|
||||
- **Override**: `AddPageButtons()`
|
||||
Adds `runButton` (`Record_StatusLineCheckRunButton`).
|
||||
- **Override**: `OnButtonPress(PageButton button)`
|
||||
On `Record_StatusLineCheckRunButton`, calls `SetNewTest()`.
|
||||
- **Methods**:
|
||||
- `SetRunButtonEnabled()`
|
||||
Enables `runButton` only if a test is selected *and* its name differs from `PersistentTestSetupName`.
|
||||
- `SetNewTest()`
|
||||
Calls `MainWindow.SetNewTest(_selectControl.SelectedTest)`.
|
||||
|
||||
#### `RealtimePage`
|
||||
- **Constructor**: `RealtimePage(DataModel.TabPageItem item)`
|
||||
Same initialization as `StatusLinePage`.
|
||||
- **Override**: `UniqueId` → `MyId` (`"Diagnostics_Realtime"`)
|
||||
- **Override**: `OnButtonPress(PageButton button)`
|
||||
Logs user action via `APILogger.Log`, then calls `SetNewTest()` on `Record_RealtimeRunButton`.
|
||||
- **Methods**: Same as `StatusLinePage` (`SetRunButtonEnabled`, `SetNewTest`).
|
||||
|
||||
#### `DownloadDataPage`
|
||||
- **Constructor**: `DownloadDataPage(DataModel.TabPageItem item)`
|
||||
Same initialization as `StatusLinePage`, but uses `BrushesAndColors.Color_ApplicationTileCollectData`.
|
||||
- **Override**: `UniqueId` → `MyId` (`"Record_DownloadAndView"`)
|
||||
- **Override**: `OnButtonPress(PageButton button)`
|
||||
Logs user action, then calls `SetNewTest()` on `Record_DownloadData_RunButton`.
|
||||
- **Methods**: Same as `StatusLinePage`.
|
||||
|
||||
#### `ChangeView`
|
||||
- **Constructor**: `ChangeView()`
|
||||
Registers `Activated`/`Deactivated` handlers to enforce topmost behavior.
|
||||
- **Properties**:
|
||||
- `AvailableUsers` (`User[]`)
|
||||
Triggers `FilteredUsers` update.
|
||||
- `FilteredUsers` (`User[]`)
|
||||
Filters `AvailableUsers` by case-insensitive match on `UserName` or `Name`.
|
||||
- **Methods**:
|
||||
- `OK_Click`: Calls `App.ChangeView(_selectedUser)` and `MainWindow.CloseChangeView()`.
|
||||
- `Cancel_Click`: Calls `MainWindow.CloseChangeView()`.
|
||||
- `Selected_Clicked`: Sets `_selectedUser` from `RadioButton.DataContext`.
|
||||
- **Override**: `Window_Closing`
|
||||
Cancels close and calls `CloseChangeView()`.
|
||||
|
||||
#### `EditUserDetailsPage`
|
||||
- **Constructor**: `EditUserDetailsPage(DataModel.TabPageItem item)`
|
||||
Sets `UsesNAVControl = true`, `IsAddPage = true`, `PageName`, `HasSaveButton = true`, `UsesModifyEnhancements = true`. Configures `NavStep`s for Info, Permissions, Visibility.
|
||||
- **Override**: `UniqueId` → `"Admin_Users_EditUserDetails_Page"`
|
||||
- **Properties**:
|
||||
- `IsAddPage` (`bool`)
|
||||
Syncs `_userInfoControl.IsAdd`.
|
||||
- `CurrentUser` (`DTS.Slice.Users.User`)
|
||||
Subscribes to `PropertyChanged`, updates `ModifiedObjectName`, propagates to controls.
|
||||
- **Override**: `OnSetActive()`
|
||||
Sets `NavControl` to first step (`_pageOne`), marks unmodified.
|
||||
- **Override**: `Validate(...)`
|
||||
Aggregates validation from `_userInfoControl`, `_userVisibilityControl`, `_userPermissionsControl`.
|
||||
- **Overrides**: `SaveAndExitButtonPress()`, `SaveButtonPress()`
|
||||
Validate → `UserCollection.UsersList.Commit(...)` → navigate or stay.
|
||||
|
||||
#### `LoginControl2`
|
||||
- **Constructor**: `LoginControl2()` and `LoginControl2(MainWindow MainWindow)`
|
||||
Sets version text from assembly version.
|
||||
- **Properties**:
|
||||
- `Users` (`UserData[]`)
|
||||
Filters and sorts users via `App.FilterUsers`.
|
||||
- `RememberPassword` (`bool`)
|
||||
- **Methods**:
|
||||
- `button_Click`: Attempts login, writes password if `RememberPassword`, shows license prompts on success.
|
||||
- `tbPassword_KeyDown`: Invokes login button on Enter.
|
||||
- `SetActive()`: Navigates to home if default user re-logged in.
|
||||
- `UpdateUsers()`: Raises `PropertyChanged("Users")`.
|
||||
|
||||
#### `UsersPage`
|
||||
- **Constructor**: `UsersPage(DataModel.TabPageItem item)`
|
||||
Initializes `_usersControl = new Controls.UserListControl(...)`, wires events.
|
||||
- **Override**: `UniqueId` → `"Admin_Users"`
|
||||
- **Override**: `SetPagePermissions()`
|
||||
Enables/disables `_editButton`, `_addButton`, `_deleteButton` based on admin status and license type.
|
||||
- **Override**: `OnSetActive()`
|
||||
Calls `_usersControl.UpdateList()`, publishes `ProgressBarEvent`.
|
||||
- **Override**: `AddPageButtons()`
|
||||
Adds `_addButton`, `_editButton`, `_deleteButton` (admin-only).
|
||||
- **Override**: `OnButtonPress(PageButton button)`
|
||||
Handles Add (creates new `User`, navigates), Edit (loads selected user), Delete (prompts, then deletes).
|
||||
- **Methods**:
|
||||
- `UpdateButtons()`: Controls visibility of Edit/Delete based on selection and user properties (default user, duplicate, ID).
|
||||
- `ChallengeUserDelete(User[])`: Displays confirmation dialog; on OK, deletes users asynchronously.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **Page Navigation & State**:
|
||||
- `UsesNAVControl`, `UsesSearchControl`, `UsesSelectControl`, `HasSaveButton`, `HasNextButton`, `HasBackButton`, `UsesModifyEnhancements`, `IsAdd`, and `ContentBackgroundColor` are set in constructors and must remain consistent for correct UI layout.
|
||||
- `MainContent` is always assigned to a control instance in the constructor.
|
||||
- `UniqueId` is constant per page type and used for subpage lookup (e.g., `EditUserDetailsPageId` in `UsersPage`).
|
||||
- **User Interaction**:
|
||||
- `runButton` in `StatusLinePage`, `RealtimePage`, and `DownloadDataPage` is enabled only when a test is selected *and* differs from `PersistentTestSetupName`.
|
||||
- `CancelButtonVisibility` in `TimedWaitControl` is a bindable property; visibility changes must be handled by XAML.
|
||||
- **User Management**:
|
||||
- `EditUserDetailsPage` requires `CurrentUser` to be non-null before `Validate()` or `Save*` methods are called.
|
||||
- `UsersPage.Delete` is blocked for default users (Admin, PowerUser, User, Guest) unless they are duplicates and not default-ID users.
|
||||
- **Modal Pages**:
|
||||
- `IModalContent.CloseFunction` must be assigned before `ModalPage.SetContent()` is called; otherwise, closing may not propagate correctly.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### Internal Dependencies
|
||||
- **Controls**:
|
||||
- `Controls.TestSetupsControl`, `Controls.CopyAndTrim`, `Controls.RenameTestControl`, `Controls.UserListControl`, `Controls.EditUserInfoControl`, `Controls.EditUserPermissionsControl`, `Controls.EditUserVisibilityControl`, `Controls.PageButton`, `Controls.TestSetups.ATDMonitorStatus`.
|
||||
- **Models**:
|
||||
- `DataModel.TabPageItem`, `DataModel.TestTemplate`, `DTS.Slice.Users.User`, `DTS.Slice.Users.UserCollection`.
|
||||
- **Infrastructure**:
|
||||
- `Prism.Ioc.IContainerLocator`, `Prism.Events.IEventAggregator`, `DTS.Common.Events.AutomaticModeStatusEvent`, `DTS.Common.Events.ProgressBarEvent`.
|
||||
- `DTS.Common.Licensing.DataProLicensingEnums`, `DTS.Common.SharedResource.Strings.StringResources`, `DTS.Common.Utilities.Logging.APILogger`.
|
||||
- `MainWindow`, `App`, `BrushesAndColors`.
|
||||
|
||||
#### External Dependencies
|
||||
- WPF Toolkit (`Xceed.Wpf.Toolkit.Licenser`)
|
||||
- .NET Framework (WPF, WinForms interop in `SplashScreen`)
|
||||
- Prism Library (event aggregation, container)
|
||||
|
||||
#### Inferred Usage
|
||||
- `ATDMonitorStatusPage`, `RealtimePage`, `StatusLinePage`, `DownloadDataPage` are likely used in diagnostics/record workflows.
|
||||
- `CopyAndTrimPage`, `RenameTestPage`, `DownloadAndView` are part of export/download workflows.
|
||||
- `AddGraphPage`, `EditGraphPage` are part of review/view workflows.
|
||||
- `UsersPage`, `EditUserDetailsPage`, `LoginControl2`, `ChangeView` are part of admin/user management workflows.
|
||||
- `SplashScreen` is used at application startup.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **`DownloadAndView` and `DownloadDataPage` share `UniqueId`**: Both use `"Record_DownloadAndView"` for `UniqueId`. This may cause ambiguity if subpage lookup or navigation relies solely on `UniqueId`.
|
||||
- **`TimedWaitControl.CancelButtonVisibility`**: The property is bindable, but its usage in XAML is not shown. Ensure binding is set up correctly.
|
||||
- **`LoginControl2.RememberPassword`**: Setting `RememberPassword = true` writes the password to settings; setting it to `false` clears `DefaultUserName`. This may conflict with security policies.
|
||||
- **`UsersPage.Delete` Logic**: The logic for enabling the Delete button is complex (checks `IsADefaultUser`, `IsADefaultID`, `IsADuplicate`). Misunderstanding these flags may lead to unexpected button visibility.
|
||||
- **`EditUserDetailsPage.IsAddPage`**: Changing `IsAddPage` updates `IsAdd` and `_userInfoControl.IsAdd`, but the `IsAdd` property is not defined in this class—likely inherited from `DataPROPage`.
|
||||
- **`SplashScreen.SetBackgroundImage()`**: Uses hardcoded asset paths (`pack://application:,,,/ResourceFile.xaml`) and assumes assets exist; missing assets may cause silent failures.
|
||||
- **`ModalPage` and `IModalContent`**: `ReusableMessageBox` flag (commented with issue #15378) suggests reuse of modal content may require special handling—verify if this is enforced elsewhere.
|
||||
- **`RealtimePage.OnButtonPress` logs user action**; ensure logging infrastructure is configured to avoid runtime exceptions.
|
||||
- **`StatusLinePage`, `RealtimePage`, `DownloadDataPage`**: All use `SetNewTest()` which calls `MainWindow.SetNewTest(...)`. If `SelectedTest` is null, this may cause a `NullReferenceException`—no null check is present in the source.
|
||||
|
||||
---
|
||||
|
||||
*No other significant gotchas were identified from the source alone.*
|
||||
169
enriched-qwen3-coder-next/DataPRO/DataPRO/Pages/DAS.md
Normal file
169
enriched-qwen3-coder-next/DataPRO/DataPRO/Pages/DAS.md
Normal file
@@ -0,0 +1,169 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Pages/DAS/ImportDASRecordPage.cs
|
||||
- DataPRO/DataPRO/Pages/DAS/EditDASRecordPage.cs
|
||||
- DataPRO/DataPRO/Pages/DAS/ExportDASRecordPage.cs
|
||||
- DataPRO/DataPRO/Pages/DAS/DASUsageReportPage.cs
|
||||
- DataPRO/DataPRO/Pages/DAS/AutoDetectDASPage.cs
|
||||
- DataPRO/DataPRO/Pages/DAS/ReplaceHardwarePage.cs
|
||||
- DataPRO/DataPRO/Pages/DAS/DataRecordersPage.cs
|
||||
- DataPRO/DataPRO/Pages/DAS/HardwareDiscovery.cs
|
||||
generated_at: "2026-04-16T04:23:11.961521+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "806fea6e6a55261e"
|
||||
---
|
||||
|
||||
# DAS Record Pages Documentation
|
||||
|
||||
## 1. Purpose
|
||||
This module provides UI pages for managing Data Acquisition System (DAS) hardware records within the DataPRO application. It supports core operations including viewing, adding, editing, importing, exporting, auto-detecting, generating usage reports, and replacing DAS hardware. The pages are part of a larger page navigation framework (`DataPROPage`) and integrate with hardware data models (`DataModel.DASHardware`, `DASHardwareList`), user permissions, and event-driven workflows (e.g., hardware replacement events). Each page is responsible for rendering a specific DAS management task via dedicated control classes and enforces consistent navigation, save, and validation behavior.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `ImportDASRecordPage`
|
||||
- **Constructor**: `ImportDASRecordPage(DataModel.TabPageItem item)`
|
||||
Initializes the page with an `ImportDASRecordControl`, disables navigation/search controls, enables save button, and sets `UsesModifyEnhancements = true`.
|
||||
- **`UniqueId`**: Returns `DataRecordersPage.ImportDASPageId`.
|
||||
- **`OnSetActive()`**: Resets page modification state to `Unmodified`.
|
||||
- **`SaveAndExitButtonPress()` / `SaveButtonPress()`**: Calls `Import()` then invokes base class methods.
|
||||
- **`Import()` (private)**: Invokes `_importDASControl.Import()` and sets state to `Saved`.
|
||||
|
||||
### `EditDASRecordPage`
|
||||
- **Constructor**: `EditDASRecordPage(DataModel.TabPageItem item)`
|
||||
Initializes with `EditDASRecordControl`, disables navigation/search controls, enables save button, sets `UsesModifyEnhancements = true`, and defines title strings.
|
||||
- **`UniqueId`**: Returns `DataRecordersPage.EditDASDetailsPageId`.
|
||||
- **`SetHardware(DataModel.DASHardware hardware, bool isAdd)`**: Delegates to `_editDASControl.SetHardware(hardware, isAdd)`.
|
||||
- **`OnSetActive()`**: Calls base implementation.
|
||||
- **`AddPageButtons()`**: Overrides to set empty button list (no custom buttons added).
|
||||
- **`SaveAndExitButtonPress()` / `SaveButtonPress()`**: Validates via `Validate()`; if valid, calls `_editDASControl.Save()`. `SaveAndExitButtonPress()` navigates back after saving.
|
||||
- **`Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`**: Delegates to `_editDASControl.Validate(...)`.
|
||||
- **`_requiredPermission`**: Returns `UserPermissionLevels.Edit`.
|
||||
|
||||
### `ExportDASRecordPage`
|
||||
- **Constructor**: `ExportDASRecordPage(DataModel.TabPageItem item)`
|
||||
Initializes with `ExportDASRecordControl`, disables navigation/search controls, disables save button, sets `UsesModifyEnhancements = false`.
|
||||
- **`UniqueId`**: Returns `DataRecordersPage.ExportDASPageId`.
|
||||
- **`OnSetActive()`**: Calls base and `_exportDASControl.OnSetActive()`.
|
||||
- **`AddPageButtons()`**: Adds a single `PageButton` for export action with `Edit` permission.
|
||||
- **`OnButtonPress(PageButton button)`**: Handles `ExportDASRecordPage_ExportButton` press: validates, reports errors if invalid, otherwise calls `_exportDASControl.Export()`.
|
||||
|
||||
### `DASUsageReportPage`
|
||||
- **Constructor**: `DASUsageReportPage(DataModel.TabPageItem item)`
|
||||
Initializes with `DASUsageReportControl`, disables navigation/search controls, disables save button, sets `UsesModifyEnhancements = false`.
|
||||
- **`UniqueId`**: Returns `DataRecordersPage.DASUsageReportPageId`.
|
||||
- **`OnSetActive()`**: Calls base and `_dasUsageReportControl.OnSetActive()`.
|
||||
- **`AddPageButtons()`**: Adds a single `PageButton` for run action with `Edit` permission.
|
||||
- **`OnButtonPress(PageButton button)`**: Handles `DASUsageReportRecordPage_RunButton` press: validates, reports errors if invalid, otherwise calls `_dasUsageReportControl.Run()`.
|
||||
|
||||
### `AutoDetectDASPage`
|
||||
- **Constructor**: `AutoDetectDASPage(DataModel.TabPageItem item)`
|
||||
Initializes with `AutoDetectDASControl`, sets page name from resources, disables navigation/search/select controls, enables back/save buttons, sets `UsesModifyEnhancements = true`.
|
||||
- **`Hardware` property**: Gets/sets `_hardware` via `SetProperty`.
|
||||
- **`AutoMode` property**: Gets/sets `_autoDetectControl.AutoMode`.
|
||||
- **`RequeryConfig()`**: Delegates to `_autoDetectControl.RequeryConfig()`.
|
||||
- **`SaveAndExitButtonPress()`**: Calls `_autoDetectControl.Save()` and navigates back.
|
||||
- **`SaveButtonPress()`**: Calls `_autoDetectControl.Save()` and sets state to `Saved`.
|
||||
- **`UniqueId`**: Returns `DataRecordersPage.AutoDetectDASPageId`.
|
||||
- **`OnSetActive()`**: Sets state to `Unmodified`; does *not* call `_autoDetectControl.OnSetActive()` (commented out).
|
||||
|
||||
### `ReplaceHardwarePage`
|
||||
- **Constructor**: `ReplaceHardwarePage(DataModel.TabPageItem item)`
|
||||
Initializes with Prism DI (`IUnityContainer`, `IEventAggregator`), disables navigation/search controls, disables save button, sets tile color.
|
||||
- **`UniqueId`**: Returns `"Prepare_TestSetups_EditTestSetup_Page_ReplaceHardware"`.
|
||||
- **`TestTemplate` property**: Publicly settable `DataModel.TestTemplate`.
|
||||
- **`OnSetActive()`**: Initializes viewmodels, subscribes to `HardwareReplaceEvent`, sets `MainContent` to `_vm.ReplaceView`, and triggers hardware list load.
|
||||
- **`DoneButtonPress()`**: Restores referring page’s modification state based on whether modifications were made.
|
||||
- **`UnSet()`**: Unsubscribes from events and calls base.
|
||||
- **`Validate(...)`**: Always returns `true` (validation stub).
|
||||
- **`_requiredPermission`**: Returns `UserPermissionLevels.Edit`.
|
||||
- **`OnReplaceEvent(Tuple<IHardware, IHardware>)`**: Handles hardware replacement event: updates `TestTemplate`, reinitializes viewmodel, marks referring page as modified.
|
||||
|
||||
### `DataRecordersPage`
|
||||
- **Constructor**: `DataRecordersPage(DataModel.TabPageItem item)`
|
||||
Initializes with `DataRecodersTileControl`, sets content background transparent, enables refresh button.
|
||||
- **`UniqueId`**: Returns `"Hardware_DataRecorders"`.
|
||||
- **Constants**: Defines page IDs for subpages (`EditDASDetailsPageId`, `ExportDASPageId`, etc.).
|
||||
- **`RefreshButtonPressed()`**: Reloads `DASHardwareList` and updates tile control.
|
||||
- **`OnButtonPress(PageButton button)`**: Handles all DAS management buttons (Add, Edit, Delete, Export, Import, AutoDetect, UsageReport, DeleteAll). For Add/Edit, sets up and navigates to `EditDASRecordPage`. For Delete, opens modal confirmation.
|
||||
- **`GetNewHardware()`**: Returns a new `DASHardware` instance with type `SLICE_NANO_Base`.
|
||||
- **`EditSelectedHardware()`**: Loads selected hardware into `EditDASRecordPage` and navigates.
|
||||
- **`DeleteConfirmationWindow()`**: Shows modal delete confirmation dialog.
|
||||
- **`OnSetActive()`**: Async reload of tile list; publishes progress bar event.
|
||||
- **`ChangeButtons()`**: Dynamically sets visibility of Edit/Delete/DeleteAll buttons based on hardware list and selection state.
|
||||
- **`GetAnySLICEBridges(ref List<DASHardware>)` / `GetAnyEmbeddedSensorICs(ref List<DASHardware>)`**: Augments deletion list with associated bridge/IEPE or embedded sensor hardware.
|
||||
- **`UnSet()`**: Calls base and unsets tile control.
|
||||
|
||||
### `HardwareDiscovery`
|
||||
- **Constructors**:
|
||||
- `HardwareDiscovery(DataModel.TabPageItem item, Location location)`
|
||||
- `HardwareDiscovery(Location location)`
|
||||
Both initialize control and build test setup control; set tile color based on `Location`.
|
||||
- **`UniqueId`**: Returns `"Hardware_DataRecorders_HardwareDiscovery"`.
|
||||
- **`Location` enum**: Values: `RunTest`, `EditTestSetup`, `EditObject`, `DataRecorders`, `CheckHardware`, `TestSetups`.
|
||||
- **`ExistingSelections` property**: Sets `_control.ExistingSelections`.
|
||||
- **`TestSetup` property**: Gets/sets `_testSetup`.
|
||||
- **`SetChannelAssignments(IGroup[], Dictionary<IGroup, IGroupChannel[]>)`**: Delegates to `_control.SetAssignments(...)`.
|
||||
- **`OnButtonPress(PageButton button)`**: Handles build/run buttons, conflicting EID modal buttons, and delegates others to `_control.OnButtonPress(...)`.
|
||||
- **`BuildAndOrRun(bool runTestAfterBuild)`**: Saves hardware, hides build/run buttons, switches `MainContent` to `_buildTestSetupControl`.
|
||||
- **`SaveButtonPress()` / `SaveAndExitButtonPress()`**: Save hardware, call `SetHardwareIfNeeded()`/`SetSensorsIfNeeded()`, update referring page state, and navigate.
|
||||
- **`DoneButtonPress()`**: For `TestSetups` location, updates referring page with quick build results. Restores modification state based on save status.
|
||||
- **`UnSet()`**: Clears `_testSetup`.
|
||||
- **`ShowBusy(bool busy)`**: Sets mouse cursor to wait or arrow.
|
||||
- **`SetName()`**: Sets page title, icon, and header color based on `Location`.
|
||||
- **`SetHardwareFunc` property**: Delegate used to propagate selected hardware to caller.
|
||||
- **`SetHardwareIfNeeded()` / `SetSensorsIfNeeded()`**: Helper methods to apply hardware/sensor changes to caller context.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Page navigation**: All pages derive from `DataPROPage`, use `GetSubPage(pageId)` to retrieve subpages, and navigate via `MainWindow.GoToNewPage(...)` or `GoToPreviousPage()`.
|
||||
- **Save semantics**:
|
||||
- `HasSaveButton = true` implies `SaveButtonPress()` and `SaveAndExitButtonPress()` are overridden to perform save logic.
|
||||
- `HasNextButton = false` for all DAS record pages.
|
||||
- `UsesModifyEnhancements = true` for `ImportDASRecordPage`, `EditDASRecordPage`, and `AutoDetectDASPage`; `false` for `ExportDASRecordPage`, `DASUsageReportPage`, and `ReplaceHardwarePage`.
|
||||
- **Permission enforcement**:
|
||||
- `EditDASRecordPage`, `ReplaceHardwarePage` require `UserPermissionLevels.Edit`.
|
||||
- Export, Import, AutoDetect, UsageReport, and Delete buttons require `Edit` permission.
|
||||
- **Hardware consistency**:
|
||||
- `DataRecordersPage.Delete` operations include associated SLICE bridges/IEPE and embedded sensor ICs via `GetAnySLICEBridges`/`GetAnyEmbeddedSensorICs`.
|
||||
- `HardwareDiscovery.SaveButtonPress()` and `SaveAndExitButtonPress()` propagate hardware and sensor changes to caller via delegates.
|
||||
- **State management**:
|
||||
- `OnSetActive()` resets page state to `Unmodified` in `ImportDASRecordPage` and `AutoDetectDASPage`.
|
||||
- `ReplaceHardwarePage` and `HardwareDiscovery` restore referring page modification state in `DoneButtonPress()`/`Save*ButtonPress()`.
|
||||
- **Event lifecycle**: `ReplaceHardwarePage` subscribes to `HardwareReplaceEvent` in `OnSetActive()` and unsubscribes in `UnSet()`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies
|
||||
- **Controls**:
|
||||
- `Controls.ImportDASRecordControl`, `Controls.EditDASRecordControl`, `Controls.ExportDASRecordControl`, `Controls.DASUsageReportControl`, `Controls.AutoDetectDASControl`, `Controls.HardwareDiscoveryControl`, `Controls.BuildTestSetupControl`, `Controls.ModalUserPrompt`, `Controls.PageButton`, `Controls.DAS.DataRecodersTileControl`.
|
||||
- **Data Models**:
|
||||
- `DataModel.TabPageItem`, `DataModel.DASHardware`, `DataModel.DASHardwareList`, `DataModel.TestTemplate`, `DataModel.TestObject`.
|
||||
- **Enums/Constants**:
|
||||
- `DTS.Common.Enums.Hardware.HardwareTypes`, `DTS.Slice.Users.User.UserPermissionLevels`, `PageHeaderRibbon.ModifyStates`, `DataRecordersPage.ButtonIDs`, `HardwareDiscovery.Location`.
|
||||
- **Prism Framework**: `IUnityContainer`, `IEventAggregator`, `Prism.Events.*` (e.g., `HardwareReplaceEvent`, `ProgressBarEvent`, `PageModifiedEvent`).
|
||||
- **Logging**: `DTS.Common.Utilities.Logging.APILogger`.
|
||||
|
||||
### External Dependencies
|
||||
- **WPF**: `System.Windows`, `System.Windows.Input`, `System.Windows.Media.*`.
|
||||
- **System**: `System.Collections.Generic`, `System.Threading.Tasks`, `System.Linq`.
|
||||
- **DTS Libraries**: `DTS.Slice.Users`, `DTS.Common.Interface.DASFactory.Diagnostics.HardwareList`, `DTS.Common.Interface.Channels`, `DTS.Common.Interface.Groups.GroupList`, `DTS.Common.Events.*`, `DTS.Common.SharedResource.Strings`, `DTS.Common`.
|
||||
|
||||
### Inferred Callers
|
||||
- `DataRecordersPage` is the primary caller for `ImportDASRecordPage`, `ExportDASRecordPage`, `DASUsageReportPage`, `AutoDetectDASPage`, and `EditDASRecordPage`.
|
||||
- `HardwareDiscovery` is called from multiple contexts (`RunTest`, `EditTestSetup`, `EditObject`, `DataRecorders`, `TestSetups`) via `MainWindow.GoToNewPage(...)`.
|
||||
- `ReplaceHardwarePage` is used in test setup editing context (inferred from `TestTemplate.ReplaceDAS(...)` and `_referringPage`).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`AutoDetectDASPage.OnSetActive()` does not call `_autoDetectControl.OnSetActive()`** — the call is commented out in the source. This may be intentional (e.g., to avoid redundant initialization), but could lead to inconsistent control state if the control expects this call.
|
||||
- **`ReplaceHardwarePage.Validate(...)` always returns `true`** — the actual validation logic is commented out. If validation is required, this is a potential bug.
|
||||
- **`HardwareDiscovery.DoneButtonPress()` and `Save*ButtonPress()` restore modification state inconsistently**:
|
||||
- `DoneButtonPress()` uses `_entryState` captured in `OnSetActive()`.
|
||||
- `SaveButtonPress()`/`SaveAndExitButtonPress()` publish `PageModifiedEvent` to signal saving, but also manually set `_referringPage` state. This dual mechanism may cause race conditions or redundant state updates.
|
||||
- **`DataRecordersPage.ChangeButtons()` hides Edit/Delete buttons when no hardware exists** — but `DeleteAllButton` visibility is toggled separately. If hardware is added/removed dynamically, this could cause UI inconsistency until `ChangeButtons()` is reinvoked.
|
||||
- **`HardwareDiscovery` uses `SetHardwareFunc` delegate to propagate hardware to callers** — this pattern is fragile; if the caller does not assign the delegate, hardware changes are silently lost.
|
||||
- **`HardwareDiscovery` sets `HasCancelButton = true` and `SetCancelEnabled(false)`** — the cancel button is present but disabled by default. Its behavior is implemented in `CancelButtonPress()` → `_control.CancelRequest()`, but callers must ensure `_control` supports cancellation.
|
||||
- **`DataRecordersPage.Delete` operations include associated hardware** — while this ensures referential integrity, it may surprise users who expect only explicitly selected items to be deleted.
|
||||
- **`ImportDASRecordPage` and `ExportDASRecordPage` disable `UsesSearchControl = true` but do not use it** — likely legacy configuration; may indicate technical debt.
|
||||
- **`HardwareDiscovery` uses `Task.Run(...).Wait(-1)` in `OnSetActive()`** — blocking the dispatcher thread may cause UI freezes during hardware discovery initialization.
|
||||
@@ -0,0 +1,234 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Pages/Sensors And Models/DiagnosticsTrackingPage.cs
|
||||
- DataPRO/DataPRO/Pages/Sensors And Models/TestHistoryPage.cs
|
||||
- DataPRO/DataPRO/Pages/Sensors And Models/SensorUsageReportPage.cs
|
||||
- DataPRO/DataPRO/Pages/Sensors And Models/ImportSensorModelsPage.cs
|
||||
- DataPRO/DataPRO/Pages/Sensors And Models/ExportSensorsPage.cs
|
||||
- DataPRO/DataPRO/Pages/Sensors And Models/BulkEditPage.cs
|
||||
- DataPRO/DataPRO/Pages/Sensors And Models/MeasureBridgeReadIDPage.cs
|
||||
- DataPRO/DataPRO/Pages/Sensors And Models/HardwareSensorsAndSquibs.cs
|
||||
- DataPRO/DataPRO/Pages/Sensors And Models/EditSensorModelDetailsPage.cs
|
||||
- DataPRO/DataPRO/Pages/Sensors And Models/ImportSensorsPage.cs
|
||||
- DataPRO/DataPRO/Pages/Sensors And Models/HardwareSensorModels.cs
|
||||
generated_at: "2026-04-16T04:22:53.973997+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "9ce33bd375b5f4d4"
|
||||
---
|
||||
|
||||
# Documentation: Sensors & Models Page Module
|
||||
|
||||
## 1. Purpose
|
||||
This module implements the UI layer for managing sensors and sensor models within the DataPRO application. It provides a suite of dedicated page classes—each inheriting from `DataPROPage`—that handle specific workflows such as viewing/editing sensor details, importing/exporting sensor data, running usage reports, tracking diagnostics, and managing sensor models. These pages integrate with underlying data models (`DTS.SensorDB.SensorData`, `DTS.SensorDB.SensorModel`, etc.) and controls (e.g., `SensorsDatabaseControl`, `ModelDatabaseControl`) to support CRUD operations, bulk editing, and navigation-driven multi-step processes like sensor import. The module serves as the central interface for hardware sensor and model administration.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `DiagnosticsTrackingPage`
|
||||
- **Constructor**: `public DiagnosticsTrackingPage(DataModel.TabPageItem item)`
|
||||
Initializes the page with `UsesNAVControl = false`, `UsesSearchControl = false`, `UsesSelectControl = false`, `HasNextButton = false`, and sets `PageName` to `StringResources.Hardware_Sensors_Page_DiagnosticsTrackingButton`. Instantiates `_diagnosticsTracking` control and configures page buttons from it.
|
||||
- **`public override string UniqueId`** → `"Hardware_Sensors_DiagnosticsTracking"`
|
||||
- **`public override bool OnButtonPress(PageButton button)`**
|
||||
Delegates button press to `_diagnosticsTracking.OnButtonPress(button)`; returns `true` if handled.
|
||||
|
||||
### `TestHistoryPage`
|
||||
- **Constructor**: `internal TestHistoryPage(DataModel.TabPageItem item)`
|
||||
Initializes `_control` (`SensorTestHistoryControl`), disables NAV/search/select controls, sets `PageName` to `StringResources.SensorTestHistoryPage`.
|
||||
- **`public void DisplaySensorHistory(string serialNumber)`**
|
||||
Invokes `_control.DisplaySensorTestHistory(serialNumber)`.
|
||||
- **`public override string UniqueId`** → `"Hardware_Sensors_TestHistory"`
|
||||
- **`public override void OnSetActive()`**
|
||||
Calls base and `_control.OnSetActive()`.
|
||||
|
||||
### `SensorUsageReportPage`
|
||||
- **Constructor**: `public SensorUsageReportPage(DataModel.TabPageItem item)`
|
||||
Enables `UsesSearchControl = true`, disables others; instantiates `_sensorUsageReportControl`.
|
||||
- **`public override string UniqueId`** → `"Hardware_Sensors_UsageReport"`
|
||||
- **`public void Run()`**
|
||||
Marshals to UI thread if needed; validates via `Validate(ref errors, ref warnings, true)`; if valid, calls `_sensorUsageReportControl.Run()`.
|
||||
- **`protected override void AddPageButtons()`**
|
||||
Adds a `PageButton` with permission `ReadAndExecute` and name `"Hardware_Sensors_UsageReport_Page_Run"`.
|
||||
- **`public override bool OnButtonPress(PageButton button)`**
|
||||
Parses button name to `ButtonIds.Hardware_Sensors_UsageReport_Page_Run`; logs and calls `Run()` if matched.
|
||||
|
||||
### `ImportSensorModels`
|
||||
- **Constructor**: `public ImportSensorModels(DataModel.TabPageItem item)`
|
||||
Instantiates `_importControl` (`ImportSensorModelsControl`), disables NAV/search/select, sets `HasBackButton = false`.
|
||||
- **`public override string UniqueId`** → `"Hardware_SensorModels_ImportSensorModels"`
|
||||
- **`public override void OnSetActive()`**
|
||||
Calls base and `_importControl.OnSetActive()`.
|
||||
- **`public override void UnSet()`**
|
||||
Calls `_importControl.UnSet()`.
|
||||
- **`protected override void AddPageButtons()`**
|
||||
Adds a `PageButton` with permission `Edit` and name `"Hardware_SensorModels_ImportSensorModels_Page_CloseButton"`.
|
||||
- **`public override bool OnButtonPress(PageButton button)`**
|
||||
Parses button name to `ButtonIds.Hardware_SensorModels_ImportSensorModels_Page_CloseButton`; logs and navigates to previous page via `MainWindow.GoToPreviousPage()`.
|
||||
|
||||
### `ExportSensorsPage`
|
||||
- **Constructor**: `public ExportSensorsPage(DataModel.TabPageItem item)`
|
||||
Instantiates `_exportControl` (`ExportSensorsControl`), disables NAV/search/select, sets `HasNextButton = false`.
|
||||
- **`public override string UniqueId`** → `"Hardware_Sensors_ExportSensors"`
|
||||
- **`public override void OnSetActive()`**
|
||||
Calls base; if `RunExportOnStartup` is `true`, calls `Export()` after 100ms sleep.
|
||||
- **`public bool RunExportOnStartup { get; set; }`**
|
||||
Property with `SetProperty` backing.
|
||||
- **`public void Export()`**
|
||||
Marshals to UI thread if needed; sets `RunExportOnStartup = false`; validates; if valid, calls `_exportControl.Export()`.
|
||||
- **`public void SetFilename(string fullfilepath)`**
|
||||
Sets `_exportControl.FullFilePath`.
|
||||
- **`public enum SupportedExportFormats { TDCSensorDatabaseCSV }`**
|
||||
- **`public new SupportedExportFormats ExportFormat { get; set; }`**
|
||||
Property with `SetProperty` and `OnPropertyChanged` logic.
|
||||
|
||||
### `BulkEditPage`
|
||||
- **Constructor**: `internal BulkEditPage(DataModel.TabPageItem item)`
|
||||
Instantiates `_control` (`BulkEdit`), disables NAV/search/select, enables `UsesModifyEnhancements = true`, `HasSaveButton = true`, sets `PageName` and ID strings.
|
||||
- **`public override string UniqueId`** → `"Hardware_Sensors_BulkEdit"`
|
||||
- **`public void SetSelectedSensors(SensorData[] sensors)`**
|
||||
Creates/assigns `_sensorAggregate` (`SensorAggregate`), hooks `PropertyChanged`, sets `ModifiedObjectName`.
|
||||
- **`protected override void SaveButtonPress()`**
|
||||
Commits all selected `SensorData` objects via `SensorsCollection.SensorsList.Commit(...)`.
|
||||
- **`protected override void SaveAndExitButtonPress()`**
|
||||
Commits sensors, sets state to `Saved`, then navigates to previous page.
|
||||
|
||||
### `MeasureBridgeReadIDPage`
|
||||
- **Constructor**: `internal MeasureBridgeReadIDPage(DataModel.TabPageItem item)`
|
||||
Instantiates `_measureBridgeControl` (`MeasureBridgeControl`), enables `UsesSearchControl = true`, `UsesModifyEnhancements = true`, `HasSaveButton = true`.
|
||||
- **`public override string UniqueId`** → `"Hardware_Sensors_MeasureBridgeReadID"`
|
||||
- **Modal dialog delegates & methods**:
|
||||
`DuplicateSensorWindow(string)`, `IncompatibleSensorsWindow(string)`, `TooManySensorsWindow(string)`, `ExcessiveResistanceChangeWindow(string)`
|
||||
All marshal to UI thread and invoke `DoModalWindow` with respective `_modal*` prompts.
|
||||
- **`protected override void Init()`**
|
||||
Instantiates modal prompts using `StringResources` and calls `AddModalDialogButtons()`.
|
||||
- **`protected override void SaveButtonPress()` / `SaveAndExitButtonPress()`**
|
||||
Delegates to `_measureBridgeControl.SaveButtonPress(false/true)`.
|
||||
|
||||
### `HardwareSensorsAndSquibs`
|
||||
- **Constructor**: `public HardwareSensorsAndSquibs(DataModel.TabPageItem item)`
|
||||
Instantiates `_sensorsControl` (`SensorsDatabaseControl`), enables `UsesSearchControl = true`, `UsesModifyEnhancements = true`, `HasSaveButton = true`, `HasRefreshButton = true`.
|
||||
- **`public override string UniqueId`** → `"Hardware_Sensors"`
|
||||
- **`public void SetSelection(IGroupChannel channel)` / `SetSelection(ISensorData sensor)`**
|
||||
Filters search and selection to the given sensor/channel.
|
||||
- **`public override void RefreshButtonPressed()`**
|
||||
Reloads `SensorsCollection` and `SensorCalibrationList`, calls `_sensorsControl.PostRefresh()`.
|
||||
- **`public override void UnSet()` / `FormClosing(...)`**
|
||||
Calls `_sensorsControl.UnSet()`.
|
||||
- **`public void ImportSensor()`**
|
||||
Gets `ImportSensorsPage`, sets `SensorsControl`, navigates to it.
|
||||
- **`public void AddSensor()`**
|
||||
Calls `_sensorsControl.AddNewSensor()`.
|
||||
- **`public override bool AdvanceButtonPress(string id)`**
|
||||
Delegates to `Advance(id)` after base handling.
|
||||
- **`private void Advance(string id)`**
|
||||
Parses `id` to `SensorsDatabaseControl.ButtonIds`; dispatches to methods like `AdvanceToReadIdsButtonPress()`, `AdvanceToExportSensorsButtonPress()`, etc.
|
||||
- **`public override void SaveAndProgressButtonPress(string id)`**
|
||||
Stores `id`, calls `_sensorsControl.SaveSensorsButtonPress(SaveAndProgressAction)`, then `Advance(id)`.
|
||||
- **`public override void DontSaveAndProgressButtonPress(string id)`**
|
||||
Calls `Advance(id)`.
|
||||
- **`public override void SaveButtonPress()` / `SaveAndExitButtonPress()`**
|
||||
Delegates to `_sensorsControl.SaveSensorsButtonPress(...)` with appropriate actions.
|
||||
|
||||
### `EditSensorModelDetailsPage`
|
||||
- **Constructor**: `public EditSensorModelDetailsPage(DataModel.TabPageItem item)`
|
||||
Instantiates `_sensorModelInfoControl` (`ModelDatabaseControl`), sets `IsAdd = true`, `HasSaveButton = true`.
|
||||
- **`public override string UniqueId`** → `"Hardware_SensorModels_EditSensorModelDetails"`
|
||||
- **`public DTS.SensorDB.SensorModel CurrentModel { get; set; }`**
|
||||
Gets/sets `_sensorModelInfoControl.EditModelControl.CurrentModel`; hooks `PropertyChanged`.
|
||||
- **`public const string ModelSeparator = "_axis_"`**
|
||||
- **`protected override void SaveButtonPress()` / `SaveAndExitButtonPress()`**
|
||||
Validates; calls `SaveSensorModels()`; resets `CurrentModel` to new instance; reports errors/warnings; navigates on `SaveAndExit`.
|
||||
- **`private void SaveSensorModels()`**
|
||||
Commits master model and derived axis models (e.g., `Model_axis_2`) to `SensorModelList`.
|
||||
|
||||
### `ImportSensorsPage`
|
||||
- **Constructor**: `public ImportSensorsPage(DataModel.TabPageItem item)`
|
||||
Enables `UsesNAVControl = true`, disables others; instantiates `_optionsControl`, `_previewControl`, `_importControl`.
|
||||
- **`public override string UniqueId`** → `"Hardware_Sensors_ImportSensors"`
|
||||
- **`public Controls.SensorsDatabaseControl SensorsControl { get; set; }`**
|
||||
Exposed for lock management during import (see comment).
|
||||
- **`public void MoveToImport()`**
|
||||
Marshals to UI thread; sets nav step to `_importStep`.
|
||||
- **`public void SetFilename(string filename)`**
|
||||
Sets format to `TDCSensorDatabase`, populates `_optionsControl.Files`/`Filename`.
|
||||
- **`public bool ImportPreviewOnStartup { get; set; }`**
|
||||
Controls auto-preview on `OnSetActive`.
|
||||
- **`public enum SupportedExportFormats { CSV, SIF, XML, EQX, TDCSensorDatabase, TDMCSVExport, CS3, DataPROXML, MODSensorFile, THFDatabaseFile }`**
|
||||
- **`public SupportedExportFormats ImportFormat { get; set; }`**
|
||||
Reads/writes to `Properties.Settings.Default.EditSensorsDefaultImportType`.
|
||||
- **`protected override void AddPageButtons()`**
|
||||
Adds `_importAnotherButton` (hidden by default); sets up nav steps: `_optionsStep`, `_previewStep`, `_importStep`.
|
||||
- **`public override bool OnButtonPress(PageButton button)`**
|
||||
Handles `_importAnotherButton` press by returning to options step.
|
||||
|
||||
### `HardwareSensorModels`
|
||||
- **Constructor**: `public HardwareSensorModels(DataModel.TabPageItem item)`
|
||||
Enables `HasRefreshButton = true`; instantiates `_sensorModelsControl` (`SensorModelsControl`).
|
||||
- **`public override string UniqueId`** → `"Hardware_SensorModels"`
|
||||
- **`public override void RefreshButtonPressed()`**
|
||||
Reloads `SensorModelList`, calls `_sensorModelsControl.PostRefresh()`.
|
||||
- **`protected override void Init()`**
|
||||
Instantiates `_modalDeleteConfirmationPage`, adds modal buttons, creates `_sensorModelsControl`.
|
||||
- **`private void EditCurrentSensor()`**
|
||||
Navigates to `EditSensorModelDetailsPage` with selected model.
|
||||
- **`protected override void AddPageButtons()`**
|
||||
Adds `_addButton`, `_editButton`, `_deleteButton` (all `Edit` permission).
|
||||
- **`public override bool OnButtonPress(PageButton button)`**
|
||||
Handles `Add`, `Edit`, `Delete`, and modal `Yes/No` (delete confirmation).
|
||||
- **`public void DeleteConfirmationWindow()`**
|
||||
Marshals to UI thread; invokes `DoModalWindow` for delete confirmation.
|
||||
- **`private void ChangeButtons()`**
|
||||
Toggles `_editButton`/`_deleteButton` visibility based on selection count.
|
||||
|
||||
## 3. Invariants
|
||||
- **`UniqueId` is constant per page class** and matches the naming convention `"Hardware_Sensors_*"` or `"Hardware_SensorModels_*"`.
|
||||
- **`UsesSearchControl` is `true` only for pages requiring search functionality** (`SensorUsageReportPage`, `MeasureBridgeReadIDPage`, `HardwareSensorsAndSquibs`).
|
||||
- **`UsesNAVControl` is `true` only for multi-step workflows** (`ImportSensorsPage`).
|
||||
- **`HasSaveButton` is `true` for pages with direct save capability** (`BulkEditPage`, `MeasureBridgeReadIDPage`, `HardwareSensorsAndSquibs`, `EditSensorModelDetailsPage`).
|
||||
- **`HasNextButton` is `false` for all pages** (navigation is handled via `AdvanceButtonPress` or `NavControl`).
|
||||
- **Permission levels are strictly enforced**:
|
||||
- `Edit` permission required for import/export/sensor/model edits (`ImportSensorModels`, `ExportSensorsPage`, `BulkEditPage`, `HardwareSensorModels`, `EditSensorModelDetailsPage`).
|
||||
- `ReadAndExecute` required for read-only actions (`SensorUsageReportPage`).
|
||||
- **Dispatcher marshaling** is used for UI thread access in modal dialog methods and `Run`/`Export` methods across pages.
|
||||
|
||||
## 4. Dependencies
|
||||
### Internal Dependencies
|
||||
- **Controls**:
|
||||
- `Controls.Sensors_and_models.DiagnosticsTracking`
|
||||
- `Controls.SensorTestHistoryControl`
|
||||
- `Controls.Sensors_and_models.SensorUsageReportControl`
|
||||
- `Controls.ImportSensorModelsControl`
|
||||
- `Controls.Sensors_and_models.ExportSensorsControl`
|
||||
- `Controls.Sensors_and_models.BulkEdit`
|
||||
- `Controls.MeasureBridgeControl`
|
||||
- `Controls.SensorsDatabaseControl`
|
||||
- `Controls.ModelDatabaseControl`
|
||||
- `Controls.ImportSensorsOptionsControl`, `PreviewControl`, `ImportControl`
|
||||
- `Controls.SensorModelsControl`
|
||||
- `Controls.ModalUserPrompt`
|
||||
- **Data Models**:
|
||||
- `DTS.SensorDB.SensorData`, `SensorModel`, `SensorsCollection`, `SensorModelCollection`
|
||||
- `DTS.Slice.Users.User.UserPermissionLevels`
|
||||
- **Utilities**:
|
||||
- `DTS.Common.Utilities.Logging.APILogger`
|
||||
- `DTS.Common.SharedResource.Strings.StringResources`
|
||||
- `Prism.Events.IEventAggregator`, `ProgressBarEvent`
|
||||
- `System.Windows.Application.Current`, `MainWindow`, `Dispatcher`
|
||||
- **Navigation**: `NavStep`, `PageNavControl`, `PageButton`, `PageActionControlsGroup`
|
||||
|
||||
### External Dependencies
|
||||
- `System`, `System.Collections.Generic`, `System.Windows`, `System.Linq`
|
||||
- `DTS.Common.*` (SharedResource, Utilities, Interface)
|
||||
- `DTS.Slice.Users`
|
||||
- `DTS.SensorDB`
|
||||
|
||||
## 5. Gotchas
|
||||
- **`UsesNAVControl = false` is duplicated in `TestHistoryPage` and `MeasureBridgeReadIDPage`** (redundant assignment).
|
||||
- **`UsesNAVControl = false` is set twice in `BulkEditPage` and `MeasureBridgeReadIDPage`** (likely copy-paste artifact).
|
||||
- **`RunExportOnStartup` in `ExportSensorsPage` is reset to `false` inside `Export()`**, but may cause race conditions if called concurrently.
|
||||
- **`ImportFormat` in `ImportSensorsPage` has a hardcoded fallback** (`_importFormat = SupportedExportFormats.DataPROXML;`) inside the getter, overriding settings only on first read.
|
||||
- **`EditSensorModelDetailsPage.ModelSeparator = "_axis_"`** is used to derive axis model names, but multi-axis support is commented out as `TODO`.
|
||||
- **`HardwareSensorModels.DeleteConfirmationWindow()`** uses a single shared modal prompt; if multiple delete confirmations are triggered rapidly, they may interfere.
|
||||
- **`HardwareSensorsAndSquibs.SetSelection(...)`** modifies `PageSearch.searchTextBox.Text` directly, bypassing standard validation or binding.
|
||||
- **`ImportSensorsPage.SensorsControl`** is a mutable property set externally; null-safety is not enforced in `ImportSensorsPage` methods.
|
||||
- **`SensorUsageReportPage.Run()` and `ExportSensorsPage.Export()`** call `Validate(...)` but do not expose the `errors`/`warnings` lists to callers—errors are silently suppressed unless `Validate` returns `false`.
|
||||
- **`BulkEditPage.SaveButtonPress()` and `SaveAndExitButtonPress()`** cast `SensorAggregate.Sensors` to `SensorData[]` via `Where(x => x is SensorData).Cast<SensorData>()`, which may silently drop non-`SensorData` items.
|
||||
122
enriched-qwen3-coder-next/DataPRO/DataPRO/Pages/Settings.md
Normal file
122
enriched-qwen3-coder-next/DataPRO/DataPRO/Pages/Settings.md
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Pages/Settings/ExportSettingsPage.cs
|
||||
- DataPRO/DataPRO/Pages/Settings/ImportSettingsPage.cs
|
||||
- DataPRO/DataPRO/Pages/Settings/SettingsPage.cs
|
||||
generated_at: "2026-04-16T04:22:28.113789+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "5bf386deab8ef180"
|
||||
---
|
||||
|
||||
# Documentation: Settings Page Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module implements the user interface and business logic for the system settings pages in the DataPRO application, specifically handling *Export Settings*, *Import Settings*, and the main *Settings* hub. It enables users with appropriate permissions to configure application behavior, database settings, user preferences, and perform import/export operations for system configuration and database state. The module acts as a coordinator between high-level navigation, permission management, and lower-level settings controls (`ExportSettings`, `ImportSettings`, `EditRealtimeSettings`, etc.), enforcing locking, validation, and state persistence semantics across the settings workflow.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `ExportSettingsPage`
|
||||
- **Constructor**: `ExportSettingsPage(DataModel.TabPageItem item)`
|
||||
Initializes the page with the provided tab item, sets `PageName` to `StringResources.Prepare_Settings_Export_Page_Title`, disables search, select, next, and NAV controls, and assigns `_infoControl` (an `ExportSettings` instance) as `MainContent`.
|
||||
- **`OnSetActive()`**: Overrides base behavior; calls `_infoControl.OnSetActive()` after base.
|
||||
- **`UnSet()`**: Overrides base behavior; calls `_infoControl.UnSet()` after base.
|
||||
- **`UniqueId`**: Property returning `"Prepare_Settings_Export"` (via `MyId` constant).
|
||||
- **`OnButtonPress(PageButton button)`**: Handles button press events. If the button ID matches `Prepare_Settings_Export_Page_ExportButton`, it validates the page and, if valid, calls `_infoControl.Export()`.
|
||||
- **`Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`**: Delegates validation to `_infoControl.Validate(...)`, and if `displayWindow` is true and validation fails, reports errors via `ReportErrors(errors)`.
|
||||
|
||||
### `ImportSettingsPage`
|
||||
- **Constructor**: `ImportSettingsPage(TabPageItem item)`
|
||||
Initializes the page with tab item, sets `PageName` to `StringResources.Prepare_Settings_Import_Page_Title`, enables `UsesModifyEnhancements`, `HasSaveButton`, and `HasCancelButton`, disables search/select/next/NAV controls, assigns `_infoControl` (an `ImportSettings` instance) as `MainContent`, and initializes three `NavStep` instances (`_readFileNavStep`, `_editFileNavStep`, `_summaryNavStep`). The `CheckChangeStepOK` event for `_editFileNavStep` is wired to `CanNavigateFromEditFile`, which currently throws `NotImplementedException`.
|
||||
- **`UniqueId`**: Property returning `"Prepare_Settings_Import"` (via `MyId` constant).
|
||||
- **`StartImport()`**: Public method that marshals to the UI thread (if needed) and, after validation, calls `_infoControl.Import()`.
|
||||
- **`DoneImporting()`**: Public method that, if `_bReturnToHomePage` is true, navigates to the previous page (`MainWindow.GoToPreviousPage()`), marshaling to the UI thread if needed.
|
||||
- **`OnButtonPress(PageButton button)`**: Delegates button press to `_infoControl.OnButtonPress(button)` first; falls back to base implementation.
|
||||
- **`Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`**: Delegates validation to `_infoControl.Validate(...)`, and if `displayWindow` is true and validation fails, reports errors via `ReportErrors(errors)`.
|
||||
- **`SaveAndExitButtonPress()`**: Overrides base; sets `_bReturnToHomePage = true` then calls `Save()`.
|
||||
- **`SaveButtonPress()`**: Overrides base; sets `_bReturnToHomePage = false` then calls `Save()`.
|
||||
- **`Save()`**: Private helper that validates and, if valid, calls `_infoControl.Import()`, then reports errors if any.
|
||||
|
||||
### `SettingsPage`
|
||||
- **Constructor**: `SettingsPage(DataModel.TabPageItem item)`
|
||||
Initializes numerous settings controls (`EditTables`, `EditRealtimeSettings`, `EditISOSettings`, `EditUISettings`, `EditTestSettings`, `QASettings`, `PowerAndBattery`, `EditAdvancedSettings`, `DatabaseSettings`, `DBImport`, `DBExport`, `EditUserSettings`, `SoftwareFilters`, `SensorSettings`, `TestHistorySettings`), sets up multiple `NavStep` instances, wires `CheckChangeStepOK` events for `_sensorSettingsNavStep` and `_softwareFiltersNavStep`, and registers modal buttons for restore confirmation.
|
||||
- **`UniqueId`**: Property returning `"Admin_SystemSettings"` (via `MyId` constant).
|
||||
- **`GetNavSteps()`**: Overrides base; returns a lazily-initialized array of `IUIItems[]` representing the navigation steps (excluding `_tablesNavStep`, which is commented out).
|
||||
- **`SetPagePermissions()`**: Overrides base; sets permissions on navsteps and controls based on current user’s permission level, and enables/disables page-level buttons (`_btnExport`, `_btnImport`, etc.) accordingly.
|
||||
- **`UnSet()`**: Overrides base; unsubscribes from `AppStatusEvent`, ensures `_iso.UnSet()` is called (even if not on its navstep), stops lock update thread, and releases the system settings lock via `LockManager.FreeLock(...)`.
|
||||
- **`OnSetActive()`**: Overrides base; subscribes to `LogoutUserEvent`, attempts to lock the settings page, subscribes to `AppStatusEvent`, refreshes settings, resets `_iso` and `_sensorSettings`, rebuilds `_navstepList` based on `QAMode` and `DBType`, sets navsteps, and publishes a progress bar event.
|
||||
- **`OnButtonPress(PageButton button)`**: Handles page-level button presses:
|
||||
- `Admin_SystemSettings_RestoreOriginalSettings`: Shows restore confirmation modal.
|
||||
- `ConfirmRestore_YesButton`: Calls `RestoreOriginalSettings()` (invokes `ISettingsControl.RestoreOriginalSettings()` on current navstep content).
|
||||
- `ConfirmRestore_NoButton`: Closes modal.
|
||||
- `Admin_SystemSettings_Export`: Calls `_dbExport.Export()`.
|
||||
- `Admin_SystemSettings_Import`: Calls `_dbImport.Import()`.
|
||||
- `Admin_SystemSettings_ExportSettings`: Navigates to `ExportSettingsPage`.
|
||||
- `Admin_SystemSettings_ImportSettings`: Navigates to `ImportSettingsPage`.
|
||||
Also handles OK/Cancel button presses for DB export overwrite warnings.
|
||||
- **`DoneButtonPress()`**: Overrides base; for the Sensor Settings navstep, calls `_sensorSettings.CheckChangeStep()` and only proceeds if it returns `true`.
|
||||
- **`RestoreConfirmationWindow()`**: Public delegate and method to show the restore confirmation modal on the UI thread.
|
||||
- **`RestoreOriginalSettings()`**: Private method that invokes `ISettingsControl.RestoreOriginalSettings()` on the current navstep content.
|
||||
- **`ImportDBFunc()` / `ExportDBFunc()`**: Private helpers that delegate to `_dbImport.Import()` and `_dbExport.Export()` respectively.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Locking**:
|
||||
- The `SettingsPage` attempts to acquire and maintain a lock on `"SystemSettings"` (category `LockManager.ItemCategories.SystemSettings`) upon activation.
|
||||
- The lock is periodically updated every 15 seconds (`UPDATE_INTERVAL_SECONDS`) on a background thread.
|
||||
- If lock update fails (e.g., stolen or lost), the user is navigated to the home page (unless logout is in progress).
|
||||
- `UnSet()` ensures the lock is released and background thread stopped.
|
||||
|
||||
- **Validation & Export/Import**:
|
||||
- `_infoControl.Export()` (in `ExportSettingsPage`) and `_infoControl.Import()` (in `ImportSettingsPage` and `SettingsPage`) are only called after successful validation (`Validate(...)` returns `true`).
|
||||
- Validation errors are reported via `ReportErrors(errors)` only when `displayWindow` is `true`.
|
||||
|
||||
- **Navigation & State Consistency**:
|
||||
- `_iso.UnSet()` is guaranteed to be called during `UnSet()` regardless of current navstep.
|
||||
- `_sensorSettings.CheckChangeStep()` and `_softwareFilters.CheckChangeStep()` are invoked before allowing navigation away from their respective navsteps (via `CheckChangeStepOK` handlers).
|
||||
- `NavControl_PropertyChanged` toggles visibility of `_btnExport`/`_btnImport` based on current navstep (`BackupDB` → export visible, `RestoreDB` → import visible).
|
||||
|
||||
- **Permissions**:
|
||||
- All navsteps and controls require at least `UserPermissionLevels.Edit` to be editable.
|
||||
- Page buttons (`_btnExport`, `_btnImport`, etc.) require `UserPermissionLevels.Admin`.
|
||||
- Modal restore buttons require `Edit` (Yes) and `Read` (No) permissions.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies (from source):
|
||||
- **Controls**:
|
||||
- `Controls.Settings.ExportSettings`, `Controls.Settings.ImportSettings`, `Controls.Settings.QASettings`, `Controls.Settings.PowerAndBattery`, `Controls.Settings.SoftwareFilters`
|
||||
- `Controls.PageButton`, `Controls.ModalUserPrompt`, `Controls.Settings.*` (e.g., `EditRealtimeSettings`, `EditISOSettings`, etc.)
|
||||
- **DataModel**:
|
||||
- `DataModel.TabPageItem`, `DataModel.NavStep`
|
||||
- **Common Libraries**:
|
||||
- `DTS.Common.SharedResource.Strings` (for localized strings like `StringResources.Prepare_Settings_Export_Page_Title`)
|
||||
- `DTS.Slice.Users.User.UserPermissionLevels`
|
||||
- `DTS.Common.Storage.LockManager`, `DTS.Common.Classes.Locking.LockRecord`
|
||||
- `DTS.Common.Events.*` (`AppStatusEvent`, `LogoutUserEvent`, `PageErrorEvent`, `ProgressBarEvent`)
|
||||
- `Prism.Events.IEventAggregator`, `Prism.Ioc.IContainerLocator`
|
||||
- `DTS.Common.Settings.SettingsDB`
|
||||
- `DTS.Common.Utilities.Logging.APILogger`
|
||||
|
||||
### External Dependencies:
|
||||
- `System.Windows` (WPF, for `Dispatcher`, `Application`, `MainWindow`)
|
||||
- `Xceed.Wpf.Toolkit.PropertyGrid` (for property grid UI)
|
||||
|
||||
### Inferred Consumers:
|
||||
- `MainWindow` (navigates to `ExportSettingsPage`/`ImportSettingsPage` via `GoToNewPage(...)` and `GoToPreviousPage()`).
|
||||
- `App` (provides `CurrentView`, `CurrentUser`, `DoMessageBox`, `MainWindow`).
|
||||
- `LockManager` (external lock management system).
|
||||
- `SettingsDB` (settings persistence layer).
|
||||
- `IEventAggregator` (event bus for app lifecycle and errors).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`CanNavigateFromEditFile` and `NavControl_PropertyChanged` are unimplemented**: In `ImportSettingsPage`, `CanNavigateFromEditFile` and `NavControl_PropertyChanged` both throw `NotImplementedException`. This implies incomplete or broken import navigation logic.
|
||||
- **`_tablesNavStep` is commented out**: In `SettingsPage`, the `_tablesNavStep` and its corresponding `NavSteps.Admin_SystemSettings_Page_Tables` are commented out in multiple places (constructor, `GetNavSteps()`, `OnSetActive()`), suggesting the Tables settings page is deprecated or disabled.
|
||||
- **Lock stealing logic may use wrong category**: In `ChallengeForLock`, when stealing the lock, it uses `LockManager.ItemCategories.Sensor` instead of `SystemSettings`. This is likely a bug.
|
||||
- **`UnSet()` calls `_iso.UnSet()` unconditionally**: Even if the current navstep is not `_iso`, `_iso.UnSet()` is invoked in `UnSet()`. This may be intentional (e.g., cleanup), but could cause side effects if `_iso` expects to be active.
|
||||
- **`Validate(...)` behavior differs slightly between pages**: `ExportSettingsPage` and `ImportSettingsPage` both call `_infoControl.Validate(...)` and report errors only if `displayWindow && !bValid && errors.Count > 0`. `SettingsPage` does the same, but `ImportSettingsPage.Save()` calls `Validate(...)` and *always* reports errors if `errors.Count > 0`, regardless of `displayWindow`.
|
||||
- **Modal restore confirmation uses `Dispatcher.CheckAccess()` incorrectly**: `RestoreConfirmationWindow()` uses `Task.Run(...)` inside a `Dispatcher.CheckAccess()` check, which is redundant and potentially misleading. The `Task.Run` is unnecessary since `Dispatcher.BeginInvoke` is used later.
|
||||
- **`LockPageOrCancel()` may fail silently**: If `LockManager.LockItem(...)` succeeds, `_existingLock` is set, but if it fails and the lock is expired/stolen, the new lock is acquired but `_existingLock` is set *after* `LockManager.LockItem(...)` succeeds—however, the code uses `LockManager.ItemCategories.Sensor` for the new lock (see above), which may not match the original category (`SystemSettings`), risking lock inconsistency.
|
||||
- **`NavControl_PropertyChanged` uses string parsing**: It parses `e.PropertyName` into `PageNavControl.Tags` via `Enum.TryParse`. If the property name changes or is misspelled, the logic silently fails.
|
||||
186
enriched-qwen3-coder-next/DataPRO/DataPRO/Pages/TestObjects.md
Normal file
186
enriched-qwen3-coder-next/DataPRO/DataPRO/Pages/TestObjects.md
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Pages/TestObjects/EditCustomChannelsPage.cs
|
||||
- DataPRO/DataPRO/Pages/TestObjects/ExportGroupPage.cs
|
||||
- DataPRO/DataPRO/Pages/TestObjects/ExportTestSetupPage.cs
|
||||
- DataPRO/DataPRO/Pages/TestObjects/ExportCustomChannelsPage.cs
|
||||
- DataPRO/DataPRO/Pages/TestObjects/ImportGroupPage.cs
|
||||
- DataPRO/DataPRO/Pages/TestObjects/ImportCustomChannelsPage.cs
|
||||
- DataPRO/DataPRO/Pages/TestObjects/RunTestEditSensor.cs
|
||||
- DataPRO/DataPRO/Pages/TestObjects/CustomChannelsPage.cs
|
||||
- DataPRO/DataPRO/Pages/TestObjects/ImportTestObjects.cs
|
||||
generated_at: "2026-04-16T04:24:02.966540+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "196b7080cec16fc1"
|
||||
---
|
||||
|
||||
# TestObjects
|
||||
|
||||
**Documentation: Test Objects Page Module**
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
This module provides UI page implementations for managing *custom channels*, *groups*, and *test setups* during test object preparation workflows (import/export/edit). It defines concrete `DataPROPage` subclasses that host specialized controls (e.g., `Controls.ExportGroup`, `Controls.ImportGroup`, `Controls.ExportTestSetup`, `Controls.ImportCustomChannelsViewModel`, etc.) and expose navigation, validation, and save/export/import functionality. These pages are part of the “Prepare” section of the application and support both legacy control-based workflows (e.g., `ExportGroupPage`, `ImportGroupPage`) and modern MVVM-based workflows (e.g., `ExportCustomChannelsPage`, `ImportCustomChannelsPage`, `CustomChannelsPage`). The module acts as the glue between the UI navigation framework and domain-specific operations (e.g., group/channel creation, import, export, validation).
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `EditCustomChannelsPage`
|
||||
- **Constructor**: `EditCustomChannelsPage(DataModel.TabPageItem item)`
|
||||
Initializes the page with `UsesNAVControl = false`, `UsesSearchControl = false`, `HasNextButton = false`, `HasSaveButton = true`, `UsesModifyEnhancements = true`. Sets `IsAddPage = true` by default.
|
||||
- **Property**: `bool IsAddPage { get; set; }`
|
||||
Controls whether the page title uses the *Add* or *Edit* string resource (`StringResources.Prepare_CustomChannels_EditCustomChannels_Page_AddTitle` / `_EditTitle`). Raises `SetProperty` change notification.
|
||||
- **Override**: `override string UniqueId => MyId`
|
||||
Returns `"Prepare_CustomChannels_EditCustomChannels"`.
|
||||
- **Override**: `override void OnSetActive()`
|
||||
Calls `base.OnSetActive()` and sets `PageHeaderRibbon.ModifyStates.Unmodified`.
|
||||
- **Override**: `override bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`
|
||||
Always returns `true`; no validation logic implemented.
|
||||
- **Overrides**: `SaveAndExitButtonPress()`, `SaveButtonPress()`, `AddPageButtons()` — all call `base.*` and contain no additional logic.
|
||||
|
||||
#### `ExportGroupPage`
|
||||
- **Constructor**: `ExportGroupPage(DataModel.TabPageItem item)`
|
||||
Instantiates `Controls.ExportGroup` as `_infoControl`, sets `PageName`, disables `UsesSearchControl`, `UsesSelectControl`, `HasNextButton`, `UsesNAVControl`, and assigns `_infoControl` to `MainContent`.
|
||||
- **Override**: `override string UniqueId => MyId`
|
||||
Returns `"Prepare_Group_Export"`.
|
||||
- **Override**: `override void OnSetActive()` / `override void UnSet()`
|
||||
Delegates to `_infoControl.OnSetActive()` / `_infoControl.UnSet()`.
|
||||
- **Override**: `override bool OnButtonPress(PageButton button)`
|
||||
Handles the single export button (`ButtonIds.Prepare_Group_Export_Page_ExportButton`) by validating and calling `_infoControl.Export()`. Delegates other button presses to `_infoControl.OnButtonPress(button)` and `base.OnButtonPress(button)`.
|
||||
- **Override**: `override bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)`
|
||||
Delegates to `_infoControl.Validate(...)`. If `displayWindow` is true and validation fails, calls `ReportErrors(errors)`.
|
||||
|
||||
#### `ExportTestSetupPage`
|
||||
- **Constructor**: `ExportTestSetupPage(DataModel.TabPageItem item)`
|
||||
Instantiates `Controls.ExportTestSetup` as `_infoControl`, sets `PageName`, disables `UsesSearchControl`, `UsesSelectControl`, `HasNextButton`, `UsesNAVControl`, and assigns `_infoControl` to `MainContent`.
|
||||
- **Override**: `override string UniqueId => MyId`
|
||||
Returns `"Prepare_TestSetups_Export"`.
|
||||
- **Override**: `override void OnSetActive()` / `override void UnSet()`
|
||||
Delegates to `_infoControl.OnSetActive()` / `_infoControl.UnSet()`.
|
||||
- **Override**: `override bool OnButtonPress(PageButton button)`
|
||||
Handles the single export button (`ButtonIds.Prepare_TestSetups_Export_Page_ExportButton`) by validating and calling `_infoControl.Export()`. Delegates other button presses.
|
||||
- **Override**: `override bool Validate(...)`
|
||||
Delegates to `_infoControl.Validate(...)`, reports errors if `displayWindow && !bValid && errors.Count > 0`.
|
||||
|
||||
#### `ExportCustomChannelsPage`
|
||||
- **Constructor**: `ExportCustomChannelsPage(DataModel.TabPageItem item)`
|
||||
Sets `HeaderRibbon.PageName`, disables `UsesSearchControl`, `UsesSelectControl`, `HasNextButton`, enables `HasBackButton`, disables `UsesNAVControl`.
|
||||
- **Override**: `override string UniqueId => MyId`
|
||||
Returns `"Prepare_CustomChannels_Export"`.
|
||||
- **Override**: `override void OnSetActive()`
|
||||
Calls `InitializeVMsIfNeeded()` and `_vm.OnSetActive(false)`.
|
||||
- **Override**: `override void UnSet()`
|
||||
Calls `_vm.Unset()`.
|
||||
- **Method**: `void InitializeVMsIfNeeded()`
|
||||
Resolves `IUnityContainer` and `IEventAggregator` via `ServiceLocator`. Resolves `ICustomChannelsViewModel` and `ICustomChannelsExportView`, sets `view.DataContext = vm`, calls `vm.InitializeAsync()`, assigns `vm.ExportView = view`, sets `MainContent = view`.
|
||||
- **Override**: `override bool OnButtonPress(PageButton button)`
|
||||
Handles the export button (`ButtonIds.Prepare_CustomChannels_Export_Page_ExportButton`) by validating and calling `_vm.Export()`.
|
||||
- **Override**: `override bool Validate(...)`
|
||||
Always returns `true`; no validation logic.
|
||||
|
||||
#### `ImportGroupPage`
|
||||
- **Constructor**: `ImportGroupPage(DataModel.TabPageItem item)`
|
||||
Instantiates `Controls.ImportGroup` as `_infoControl`, sets `PageName`, disables `UsesSearchControl`, `UsesSelectControl`, `HasNextButton`, `UsesNAVControl`, enables `HasSaveButton`, assigns `_infoControl` to `MainContent`.
|
||||
- **Override**: `override string UniqueId => MyId`
|
||||
Returns `"Prepare_Group_Import"`.
|
||||
- **Override**: `override void OnSetActive()`
|
||||
Sets `HasSaveButton = true`, calls `base.OnSetActive()` and `_infoControl.OnSetActive()`.
|
||||
- **Override**: `override void UnSet()`
|
||||
Calls `_infoControl.UnSet()`.
|
||||
- **Override**: `override bool OnButtonPress(PageButton button)`
|
||||
Delegates to `_infoControl.OnButtonPress(button)` and `base.OnButtonPress(button)`.
|
||||
- **Override**: `override bool Validate(...)`
|
||||
Delegates to `_infoControl.Validate(...)`, reports errors if `displayWindow && !bValid && errors.Count > 0`.
|
||||
- **Method**: `void DoneImporting()`
|
||||
If `_bReturnToHomePage` is true, invokes `MainWindow.GoToPreviousPage()` on the UI thread.
|
||||
- **Overrides**: `SaveAndExitButtonPress()` sets `_bReturnToHomePage = true`; `SaveButtonPress()` sets `_bReturnToHomePage = false`. Both call `Save()`, which validates and calls `_infoControl.Import()`.
|
||||
|
||||
#### `ImportCustomChannelsPage`
|
||||
- **Constructor**: `ImportCustomChannelsPage(TabPageItem item)`
|
||||
Sets `HeaderRibbon.PageName`, disables `UsesSearchControl`, `UsesSelectControl`, `HasNextButton`, enables `HasBackButton`, disables `UsesNAVControl`.
|
||||
- **Override**: `override string UniqueId => MyId`
|
||||
Returns `"Prepare_CustomChannels_Import"`.
|
||||
- **Override**: `override void OnSetActive()`
|
||||
Calls `InitializeVMsIfNeeded()` and `_vm.OnSetActive(true)`.
|
||||
- **Override**: `override void UnSet()`
|
||||
Calls `_vm.Unset()`.
|
||||
- **Method**: `void InitializeVMsIfNeeded()`
|
||||
Resolves `IUnityContainer` and `IEventAggregator` via `ContainerLocator.Container`. Resolves `ICustomChannelsViewModel` and `ICustomChannelsImportView`, sets `view.DataContext = vm`, calls `vm.InitializeAsync()`, assigns `vm.ImportView = view`, sets `MainContent = view`, subscribes to `CustomChannelImportEvent` with `OnCustomChannelImportEvent`.
|
||||
- **Static Method**: `static void OnCustomChannelImportEvent(CustomChannelImportEventArgs args)`
|
||||
Refreshes `IsoDb` and `CustomChannelList.List` on import completion.
|
||||
- **Override**: `override bool OnButtonPress(PageButton button)`
|
||||
Handles the import button (`ButtonIds.Prepare_CustomChannels_Import_Page_ImportButton`) by validating and calling `_vm.Import()`.
|
||||
- **Override**: `override bool Validate(...)`
|
||||
Always returns `true`.
|
||||
|
||||
#### `RunTestEditSensor`
|
||||
- **Constructor**: `RunTestEditSensor()`
|
||||
Instantiates `Controls.EditSensorOrTemplateControl`, sets `PageImage` from embedded resource `"Assets/Tiles/clock.png"`, configures `PageButtons` for Home (Read) and Save (Edit) permissions.
|
||||
- **Property**: `DataModel.TestTemplate CurrentTest { get; set; }`
|
||||
Binds to `_editControl` via `CurrentSensor` setter.
|
||||
- **Property**: `SensorData CurrentSensor { set; }`
|
||||
Sets `_editControl.Calibration1` to latest calibration for the sensor, assigns `value.Calibration`, and sets `_editControl.CurrentModel`.
|
||||
- **Override**: `override string UniqueId => "Record_EditSensor"`
|
||||
- **Override**: `override void OnSetActive()`
|
||||
Sets `PageName` using `StringResources.RunTest_EditSensor` and `CurrentTest.Name`, calls `_editControl.Reset()`.
|
||||
- **Override**: `override bool OnButtonPress(PageButton button)`
|
||||
Handles Home (navigates back) and Save buttons. Save validates and calls static `SaveSensors(_editControl)`.
|
||||
- **Static Method**: `static void SaveSensors(EditSensorOrTemplateControl ctrl)`
|
||||
Commits sensor data and calibration to `SensorsCollection.SensorsList`. Includes logic to derive axis-specific serial numbers/models (commented-out multi-axis handling remains in code).
|
||||
- **Override**: `override bool Validate(...)`
|
||||
Delegates to `IPageContent.Validate(...)` on `_editControl`, reports errors if `displayWindow && !bValid && errors.Count > 0`.
|
||||
|
||||
#### `CustomChannelsPage`
|
||||
- **Constructor**: `CustomChannelsPage(TabPageItem item)`
|
||||
Calls `InitializeComponent()`, sets `UsesNAVControl = false`, `HasRefreshButton = true`, `HasSaveButton = true`, `UsesModifyEnhancements = true`, `UsesSearchControl = false`.
|
||||
- **Override**: `override string UniqueId => MY_ID`
|
||||
Returns `"Prepare_CustomChannels"`.
|
||||
- **Method**: `void InitializeVMsIfNeeded()`
|
||||
Resolves `IUnityContainer` and `IEventAggregator` via `ContainerLocator.Container`. Resolves `IChannelCodesListViewModel` and `IChannelCodesListView`, sets `view.DataContext = vm`, calls `vm.InitializeAsync()`, assigns `vm.View`, sets `MainContent = vm.View`, subscribes to `PageSelectionChanged` event.
|
||||
- **Override**: `override void RefreshButtonPressed()`
|
||||
Calls `InitializeVMsIfNeeded()`, `_vm.OnSetActive()`, and `base.RefreshButtonPressed()`.
|
||||
- **Override**: `override void OnSetActive()`
|
||||
Calls `InitializeVMsIfNeeded()`, configures `_vm` properties (`ShowISOStringBuilder`, `UniqueISOCodesRequired`, `ShowChannelCodeLookupHelper`), sets `MainContent`, `SetModifiedState(Unmodified)`, calls `_vm.OnSetActive()`, publishes `ProgressBarEvent`.
|
||||
- **Override**: `override void UnSet()`
|
||||
Calls `_vm?.Unset()`.
|
||||
- **Override**: `override void SetPagePermissions()`
|
||||
Sets `_vm.IsReadOnly` based on current user’s permission level (`Edit` or lower).
|
||||
- **Override**: `override bool OnButtonPress(PageButton button)`
|
||||
Handles Copy (`Prepare_CustomChannels_Page_CopyButton`) and Delete (`Prepare_CustomChannels_Page_DeleteButton`). Delete uses `ThreadPool.QueueUserWorkItem` to show a confirmation dialog before invoking `_vm.DeleteSelected()` on the UI thread.
|
||||
- **Override**: `override void SaveButtonPress()` / `override void SaveAndExitButtonPress()`
|
||||
Validates, calls `_vm.Save()`, updates state (`Saved` or error), and navigates on `SaveAndExitButtonPress`.
|
||||
- **Override**: `override bool Validate(...)`
|
||||
Calls `_vm.Validate(displayWindow)`.
|
||||
|
||||
#### `ImportTestObjects` *(Note: Not a page class; a utility class)*
|
||||
- **Method**: `void CreateGroup(string serialNumber, string tags)`
|
||||
Creates a new group via `IGroupListViewModel.CreateGroup()`, sets `DisplayName`, `Name`, `Tags`, and stores it in `_igroupsInProgress`. Uses `Dispatcher` to marshal to UI thread if needed.
|
||||
- **Method**: `void CommitGroups(string[] serialNumbers, Action<string, Color> setStatusAction)`
|
||||
Invokes `CommitGroupsFunc(...)` on a background `Task`. Handles group locking via `LockManager`, allows lock stealing by admins, and commits groups via `group.Save(...)`. Calls `setStatusAction` with status text and color.
|
||||
- **Method**: `void AddChannelToGroup(string groupSerialNumber, GroupGRPImportChannel importChannel, IChannelSetting[] channelDefaults)`
|
||||
Adds a channel to a work-in-progress group. Handles ISO code normalization (inserts `"??"` prefix if 14-char), sensor lookup, and populates `GroupChannel` with settings (polarity, range, filter class, digital input mode, squib fire mode, etc.).
|
||||
- **Private Fields**: `_igroupsInProgress`, `_channelsInProgress` — dictionaries to track in-progress groups and their channels during import.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- **Page Identity**: Each page class defines a constant `MyId` or `MY_ID` used for `UniqueId`. This ID must match the expected navigation key in the host framework.
|
||||
- **Control Assignment**: Pages using control-based UI (e.g., `ExportGroupPage`, `ImportGroupPage`) assign their `_infoControl` to `MainContent`. Pages using MVVM assign a view instance to `MainContent`.
|
||||
- **Validation Flow**: For pages delegating validation (`ExportGroupPage`, `ImportGroupPage`, `RunTestEditSensor`, `CustomChannelsPage`), validation failures with `displayWindow = true` trigger `ReportErrors(errors)`.
|
||||
- **Locking Semantics**: `ImportTestObjects.CommitGroups` enforces group-level locking with admin override capability. Locks are acquired before any group operation and released in a `finally` block.
|
||||
- **Thread Affinity**: UI updates (`OnSetActive`, `UnSet`, `DoneImporting`, `OnCustomChannelImportEvent`) occur on the UI thread. Background operations (`CommitGroups`, `DoDeleteChallenge`) use `Task.Run` or `ThreadPool` and marshal back to the UI thread via `Dispatcher`.
|
||||
- **VM Initialization**: Pages using `ICustomChannelsViewModel` or `IChannelCodesListViewModel` guard initialization with `_vm == null` checks in `InitializeVMsIfNeeded()`.
|
||||
- **Button Permissions**: Export/Import buttons are created with `UserPermissionLevels.Edit`. Copy/Delete buttons in `CustomChannelsPage` are initially hidden and shown only when items are selected.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Internal Dependencies
|
||||
- **Controls**:
|
||||
- `Controls.ExportGroup`, `Controls.ImportGroup`, `Controls.ExportTestSetup`, `Controls.ImportCustomChannelsViewModel`, `Controls.EditSensorOrTemplateControl`, `Controls.ExportCustomChannelsView`, `Controls.ImportCustomChannelsView`, `Controls.ChannelCodesListView`, `Controls.ChannelCodesListViewModel`.
|
||||
- **Data Model**:
|
||||
- `DataModel.TabPageItem`, `DataModel.TestTemplate`, `DTS.SensorDB.SensorData`, `DTS.Common.Interface.Groups.IGroup`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `DTS.Common.Interface.Channels.IGroupChannel`, `
|
||||
@@ -0,0 +1,241 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Pages/TestSetups And RunTest/RunTestPageCheckHardware.cs
|
||||
- DataPRO/DataPRO/Pages/TestSetups And RunTest/RunTestPageDiagnostics.cs
|
||||
- DataPRO/DataPRO/Pages/TestSetups And RunTest/RunTestPageRealtime.cs
|
||||
- DataPRO/DataPRO/Pages/TestSetups And RunTest/RunTestPage.cs
|
||||
- DataPRO/DataPRO/Pages/TestSetups And RunTest/RunTestPageExport.cs
|
||||
- DataPRO/DataPRO/Pages/TestSetups And RunTest/DiagnosticsPage.cs
|
||||
- DataPRO/DataPRO/Pages/TestSetups And RunTest/RunTestPageStatusCheck.cs
|
||||
- DataPRO/DataPRO/Pages/TestSetups And RunTest/CollectDataPage.cs
|
||||
- DataPRO/DataPRO/Pages/TestSetups And RunTest/TestSetupsChangePage.cs
|
||||
- DataPRO/DataPRO/Pages/TestSetups And RunTest/QuickSensorCheckPage.cs
|
||||
- DataPRO/DataPRO/Pages/TestSetups And RunTest/TestSetupEditAddHardwarePage.cs
|
||||
generated_at: "2026-04-16T04:23:31.908364+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "ce342ed5d8303b8d"
|
||||
---
|
||||
|
||||
# Documentation: RunTest Page Classes
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module defines a family of page classes used in the DataPRO application’s test execution flow. Each class represents a distinct step in the diagnostic and data acquisition workflow, inheriting from `RunTestBase` (or `DataPROPage` in a few cases) to provide a consistent UI and navigation interface. These pages manage hardware checks, diagnostics execution, real-time monitoring, status line validation, data export, and related operations—orchestrating user interaction, test lifecycle events, and integration with underlying hardware and configuration systems.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes listed below are `public` and defined in the `DataPROWin7` namespace.
|
||||
|
||||
### `RunTestPageCheckHardware`
|
||||
- **Constructors**
|
||||
- `RunTestPageCheckHardware(DataModel.TabPageItem item)`
|
||||
Initializes with a tab item; stores `_item` for title.
|
||||
- `RunTestPageCheckHardware(DataModel.TabPageItem item, int possibleSteps)`
|
||||
Initializes with item and step count; stores `_item`.
|
||||
- **Overrides**
|
||||
- `void OnSetActive()`
|
||||
Calls base; sets `PageName` to `_item.Title`.
|
||||
- `string UniqueId` → `"Diagnostics_CheckHardware"`
|
||||
Constant `MY_ID` used as unique identifier.
|
||||
|
||||
### `RunTestPageDiagnostics`
|
||||
- **Constructors**
|
||||
- `RunTestPageDiagnostics(DataModel.TabPageItem item)`
|
||||
- `RunTestPageDiagnostics(DataModel.TabPageItem item, int possibleSteps)`
|
||||
- **Overrides**
|
||||
- `void OnSetActive()`
|
||||
Calls `((App)Application.Current).StartTest()`, base, then sets `PageName`.
|
||||
- `string UniqueId` → `"Diagnostics"`
|
||||
Constant `MY_ID`.
|
||||
|
||||
### `RunTestPageRealtime`
|
||||
- **Properties**
|
||||
- `bool QuickCheckout { get; set; } = false`
|
||||
- **Constructors**
|
||||
- `RunTestPageRealtime(DataModel.TabPageItem item)`
|
||||
- `RunTestPageRealtime(DataModel.TabPageItem item, int possibleSteps)`
|
||||
- **Overrides**
|
||||
- `void OnSetActive()`
|
||||
Subscribes to `AutomaticModeStatusEvent` once via `IEventAggregator`, calls `StartTest()`, base, sets `PageName`.
|
||||
- `string UniqueId` → `"Diagnostics_Realtime"`
|
||||
- `StrictLevel PageStricknessLevel` (protected override)
|
||||
Returns `StrictLevel.QuickCheckout` if `QuickCheckout` is true; otherwise `StrictLevel.Strict`.
|
||||
|
||||
### `RunTestPage`
|
||||
- **Properties**
|
||||
- `bool StopDiagnosticsPrepareOnEntry { get; set; } = false`
|
||||
- **Constructors**
|
||||
- `RunTestPage(DataModel.TabPageItem item)`
|
||||
- `RunTestPage(DataModel.TabPageItem item, int possibleSteps)`
|
||||
Both set `HasBackButton = false`.
|
||||
- **Overrides**
|
||||
- `void OnSetActive()`
|
||||
Subscribes to `AutomaticModeStatusEvent` once; calls base (does *not* call `StartTest()`).
|
||||
- `string UniqueId` → `"Record"`
|
||||
|
||||
### `RunTestPageExport`
|
||||
- **Properties**
|
||||
- `string DownloadFolder { get; set; } = string.Empty`
|
||||
- `string DTSFile { get; set; } = string.Empty`
|
||||
- `BindingList<ITestEvent> SelectedEventList { get; set; } = new BindingList<ITestEvent>()`
|
||||
- **Constructors**
|
||||
- `RunTestPageExport(DataModel.TabPageItem item)`
|
||||
- `RunTestPageExport(DataModel.TabPageItem item, int possibleSteps)`
|
||||
- **Overrides**
|
||||
- `void OnSetActive()`
|
||||
Calls base, sets `PageName`.
|
||||
- `void Unset()`
|
||||
Releases export files (`_exportROIControl?.ReleaseFiles()`, `_exportALLControl?.ReleaseFiles()`), resets export step completion flags, clears `DTSFile`.
|
||||
- `string UniqueId` → `"Review_ExportData"`
|
||||
- **Methods**
|
||||
- `void ResetCurrentStep()`
|
||||
Calls `PageContent.NavControl.SetCurrentNavStepIndex(0)`.
|
||||
- `void ShowUploadStep(bool bShow)`
|
||||
Sets `_uploadDataNavStep.Visibility` to `Visible` or `Collapsed`.
|
||||
- `bool DoneButtonPress2(DataPROPage nextPage, HomePage homePage, DataPROTabItem nextTab)`
|
||||
Returns `true`.
|
||||
|
||||
### `DiagnosticsPage`
|
||||
- **Constructors**
|
||||
- `DiagnosticsPage(DataModel.TabPageItem item)`
|
||||
- **Overrides**
|
||||
- `void OnSetActive()`
|
||||
Calls base, `SetRunButtonEnabled()`.
|
||||
- `string UniqueId` → `"Diagnostics"`
|
||||
- **Methods**
|
||||
- `bool OnButtonPress(PageButton button)`
|
||||
Handles `Record_DiagnosticsRunButton` by calling `SetNewTest()`.
|
||||
- **Private Members**
|
||||
- `Controls.PageButton _runButton`
|
||||
- `void SetRunButtonEnabled()`
|
||||
Enables `_runButton` only if `SelectedTest != PersistentTestSetupName`.
|
||||
- `void SetNewTest()`
|
||||
Calls `((MainWindow)Application.Current.MainWindow).SetNewTest(...)`.
|
||||
|
||||
### `CollectDataPage`
|
||||
- **Constructors**
|
||||
- `CollectDataPage()`
|
||||
- `CollectDataPage(DataModel.TabPageItem item)`
|
||||
- **Overrides**
|
||||
- `void OnSetActive()`
|
||||
Calls base, `SetRunButtonEnabled()`.
|
||||
- `string UniqueId` → `"CollectData"`
|
||||
- **Methods**
|
||||
- `bool OnButtonPress(PageButton button)`
|
||||
Handles `Record_CollectDataRunButton` by calling `SetNewTest()`.
|
||||
- **Private Members**
|
||||
- `Controls.PageButton _runButton`
|
||||
- `void SetRunButtonEnabled()`
|
||||
Enables `_runButton` only if `SelectedTest != PersistentTestSetupName`.
|
||||
- `void SetNewTest()`
|
||||
Calls `MainWindow.SetNewTest(...)`.
|
||||
|
||||
### `TestSetupsChangePage`
|
||||
- **Constructors**
|
||||
- `TestSetupsChangePage(DataModel.TabPageItem tabPageItem)`
|
||||
- **Overrides**
|
||||
- `void OnSetActive()`
|
||||
Calls base, `SetPagePermissions()`, `ChangeEditVisibility()`.
|
||||
- `string UniqueId` → `"Prepare_ChangeTestSetups"`
|
||||
- **Methods**
|
||||
- `bool OnButtonPress(PageButton button)`
|
||||
Handles `Prepare_TestSetups_Page_MakeCurrentButton` by calling `SetNewTest()`.
|
||||
- **Private Members**
|
||||
- `Controls.PageButton _makeCurrentButton`
|
||||
- `void ChangeEditVisibility()`
|
||||
Controls `_makeCurrentButton` visibility based on `SelectedTest != PersistentTestSetupName`.
|
||||
- `void SetNewTest()`
|
||||
Calls `MainWindow.SetNewTest(...)`.
|
||||
|
||||
### `QuickSensorCheckPage`
|
||||
- **Constants**
|
||||
- `MY_ID = "Diagnostics_QuickSensorCheck"`
|
||||
- **Constructors**
|
||||
- `QuickSensorCheckPage(DataModel.TabPageItem item)`
|
||||
- **Overrides**
|
||||
- `void OnSetActive()`
|
||||
Instantiates `_quickSensorCheck` if null; sets `MainContent`; calls `StartTest()`.
|
||||
- `void Unset()`
|
||||
Calls `EndTest()`, base.
|
||||
- `string UniqueId` → `"Diagnostics_QuickSensorCheck"`
|
||||
- **Properties**
|
||||
- `bool ScanButtonEnabled { get; set; }`
|
||||
- `bool RunButtonEnabled { get; set; }`
|
||||
- **Methods**
|
||||
- `bool OnButtonPress(PageButton button)`
|
||||
Dispatches to `_quickSensorCheck.Scan()`, `.Check()`, or `.Run()` based on button ID.
|
||||
- `bool DoneButtonPress2(...)`
|
||||
Calls `_quickSensorCheck.DoneButtonPress()`.
|
||||
|
||||
### `TestSetupEditAddHardwarePage`
|
||||
- **Properties**
|
||||
- `DataModel.TestTemplate TestTemplate { get; set; }`
|
||||
- **Constructors**
|
||||
- `TestSetupEditAddHardwarePage(DataModel.TabPageItem item)`
|
||||
- **Overrides**
|
||||
- `void OnSetActive()`
|
||||
Subscribes to `HardwareSavedEvent`, initializes VM/view, sets `MainContent`, updates modify state.
|
||||
- `void Unset()`
|
||||
Unsubscribes from `HardwareSavedEvent`.
|
||||
- `string UniqueId` → `"Prepare_TestSetups_EditTestSetup_Page_AddEditHardware"`
|
||||
- `bool Validate(...)`
|
||||
Validates hardware; returns `true` if `StandIn` or `_vm.Validate(...)` succeeds.
|
||||
- **Methods**
|
||||
- `void SetHardware(IDASHardware hw, IISOHardware isoHW)`
|
||||
Sets `_vm` hardware; updates `PageName` based on add/edit mode.
|
||||
- `bool OnButtonPress(PageButton button)`
|
||||
Handles `AddNewDevice` button: saves if modified, then resets for new hardware.
|
||||
- `void SaveAndExitButtonPress()` / `SaveButtonPress()`
|
||||
Validates, saves via `_vm.Save()`, updates referring page state.
|
||||
- **Private Members**
|
||||
- `void InitializeVMsIfNeeded()`, `Subscribe()`, `Unsubscribe()`
|
||||
- `void OnHardwareUpdated(Tuple<int, string> args)`
|
||||
Adds hardware to `TestTemplate`, creates TSRAIR/SLICETC-specific channels if newly added, updates sample rates and AAF rates.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`UniqueId` is constant per class** and used as a stable identifier for navigation and state tracking.
|
||||
- **`OnSetActive()` always calls `base.OnSetActive()`**, except where overridden behavior is explicitly documented.
|
||||
- **`StartTest()` is called in `OnSetActive()`** for `RunTestPageDiagnostics`, `RunTestPageRealtime`, `RunTestPageStatusCheck`, and `QuickSensorCheckPage`, but *not* for `RunTestPage` or `RunTestPageCheckHardware`.
|
||||
- **Event subscription is idempotent**: Each page subscribes to `AutomaticModeStatusEvent` or `HardwareSavedEvent` only once (tracked via `_subscribed`/`_bSubscribed`).
|
||||
- **Hardware pages (`TestSetupEditAddHardwarePage`) use `_referringPage`** to propagate save state changes to the calling page.
|
||||
- **`HasBackButton = false`** for `RunTestPage` and `RunTestPageExport` (explicitly set in constructors).
|
||||
- **`UsesNAVControl = false`** for `DiagnosticsPage`, `CollectDataPage`, `TestSetupsChangePage`, `QuickSensorCheckPage`, and `TestSetupEditAddHardwarePage`.
|
||||
- **`HasSaveButton = true`** only for `TestSetupEditAddHardwarePage`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Dependencies (via imports)
|
||||
- `System.Windows` (`Application`, `Window`, `Visibility`, `Dispatcher`)
|
||||
- `Prism.Ioc` (`IUnityContainer`, `IEventAggregator`, `ContainerLocator`)
|
||||
- `Prism.Events` (`IEventAggregator`, `EventBase`)
|
||||
- `DTS.Common.*` (multiple: `Events`, `Interface`, `Enums`, `Classes`, `SharedResource`)
|
||||
- `DataPROWin7.DataModel`, `DataPROWin7.Common`, `DataPROWin7.Controls`
|
||||
- `System.ComponentModel` (`BindingList`, `PropertyChanged`)
|
||||
|
||||
### Internal Dependencies
|
||||
- `RunTestBase` (base class for all `RunTestPage*` classes)
|
||||
- `DataPROPage` (base class for `DiagnosticsPage`, `CollectDataPage`, `TestSetupsChangePage`, `QuickSensorCheckPage`, `TestSetupEditAddHardwarePage`)
|
||||
- `App` (`((App)Application.Current)`) for `StartTest()`, `EndTest()`, `SetStepComplete()`, `DoMessageBox()`, `PersistentTestSetupName`
|
||||
- `MainWindow` (`SetNewTest()`, `GoToPreviousPage()`)
|
||||
- `DASHardwareList`, `DbOperations`, `DTS.SensorDB.SensorsCollection`, `GroupChannel`, `CommonFunctions`
|
||||
- `IAddEditHardwareViewModel`, `IAddEditHardwareView` (via Unity container resolution)
|
||||
|
||||
### Inferred Callers
|
||||
- Navigation system (via `UniqueId`, `OnSetActive()`, `Unset()`, `DoneButtonPress2()`)
|
||||
- `DataModel.TabPageItem` consumers (e.g., tab navigation)
|
||||
- `AutomaticModeStatusEvent` publishers
|
||||
- `HardwareSavedEvent` publishers (likely from `TestSetupEditAddHardwarePage` save flow)
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`RunTestPageRealtime.PageStricknessLevel` is protected override**, not public—accessed only via base class.
|
||||
- **`RunTestPageStatusCheck.OnSetActive()` modifies `AllowedSteps` at runtime** based on config flags (`TestSetup_TriggerCheckQuickMode`, `TriggerCheckPostRealtime`), potentially altering step availability dynamically.
|
||||
- **`RunTestPageExport.Unset()` resets step completion flags for `ExportALL` and `ExportROI`**, but only if `Unset()` is called (not guaranteed on all navigation paths).
|
||||
- **`TestSetupEditAddHardwarePage.OnHardwareUpdated()` has complex logic for TSRAIR/SLICETC channel creation**, including conditional UART/stream-out channel addition based on clock sync and recording mode.
|
||||
- **`QuickSensorCheckPage` has commented-out auto-discovery code** (`AutoDiscoverOnQuickCheckout`, `AutoDiscoveryCreateTestFromDASConfig`), suggesting incomplete or disabled features.
|
||||
- **`RunTestPage.StopDiagnosticsPrepareOnEntry`** is documented as a config-driven flag to defer diagnostics start, but its usage is not visible in the provided source—only its declaration and comment.
|
||||
- **`DiagnosticsPage` and `CollectDataPage` both use `_selectControl` and `_runButton` similarly**, but `CollectDataPage` has no `UniqueId` constant—uses hardcoded `"CollectData"`.
|
||||
- **`RunTestPageCheckHardware` does not call `StartTest()` in `OnSetActive()`**, unlike other diagnostic pages—intentional or oversight?
|
||||
- **`TestSetupEditAddHardwarePage` uses `_referringPage`**, but its type and initialization are not shown in the source—assumed to be set by base class or caller.
|
||||
60
enriched-qwen3-coder-next/DataPRO/DataPRO/Properties.md
Normal file
60
enriched-qwen3-coder-next/DataPRO/DataPRO/Properties.md
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/Properties/AssemblyInfo.cs
|
||||
- DataPRO/DataPRO/Properties/Resources.Designer.cs
|
||||
generated_at: "2026-04-16T04:06:31.513299+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "83c55db4441c9a28"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## Documentation: `DataPRO.Properties` Assembly
|
||||
|
||||
### 1. Purpose
|
||||
This module provides assembly-level metadata and strongly-typed resource access for the `DataPRO` Windows application, which is designed for interfacing with DTS (Diversified Technical Systems, Inc.) data recorders. It defines assembly attributes (e.g., title, description, version, DPI awareness, and localization support) and exposes localized UI strings used throughout the application via the `Resources` class. It serves as a foundational infrastructure layer for branding, versioning, and internationalization, but contains no business logic or UI rendering code itself.
|
||||
|
||||
### 2. Public Interface
|
||||
The module exposes only internal types (as indicated by `internal class Resources` and absence of `public` modifiers in `AssemblyInfo.cs`). No *public* API surface exists in this assembly. However, the following internal members are defined:
|
||||
|
||||
- **`Resources` class** (internal, static, auto-generated):
|
||||
Provides strongly-typed access to localized string resources.
|
||||
- `ResourceManager ResourceManager { get; }`
|
||||
Returns a cached `System.Resources.ResourceManager` instance for the `DataPROWin7.Properties.Resources` resource base name.
|
||||
- `CultureInfo Culture { get; set; }`
|
||||
Gets or sets the UI culture override for resource lookups.
|
||||
- `string DataPRO_BuildVersionPostamble { get; }`
|
||||
Returns the localized string for the version suffix (e.g., `"v."`).
|
||||
- `string DataPRO_BuildVersionPreamble { get; }`
|
||||
Returns the localized string for the version prefix (e.g., `"v."`).
|
||||
- `string DataPRO_Edition { get; }`
|
||||
Returns the localized string `"Edition"`.
|
||||
- `string DataPRO_MainFormTitle { get; }`
|
||||
Returns the localized main window title `"DataPRO"`.
|
||||
|
||||
> **Note**: All resource accessors are auto-generated and rely on corresponding `.resx` entries (not provided in source). The `Resources` class resides in the `DataPROWin7.Properties` namespace, *not* `DataPRO.Properties`, despite the assembly name.
|
||||
|
||||
### 3. Invariants
|
||||
- **DPI Awareness**: The assembly is explicitly marked with `[DisableDpiAwareness]`, meaning it will *not* scale with system DPI changes and will render at 96 DPI (100% scaling) regardless of display settings.
|
||||
- **Resource Namespace Consistency**: The `ResourceManager` is hardcoded to use `"DataPROWin7.Properties.Resources"` as its base name, implying the `.resx` file must be named `Resources.resx` and reside in a `Properties` folder under the `DataPROWin7` namespace (despite the assembly being named `DataPRO`).
|
||||
- **Versioning**: Both `AssemblyVersion` and `AssemblyFileVersion` are fixed to `"1.0.0.0"`; no dynamic versioning is configured.
|
||||
- **Localization Support**: `NeutralResourcesLanguage` is commented out; thus, fallback resources will be loaded from the main assembly (not satellite assemblies).
|
||||
- **COM Visibility**: `ComVisible(false)` ensures types in this assembly are not exposed to COM by default.
|
||||
|
||||
### 4. Dependencies
|
||||
- **Depends on**:
|
||||
- `System.Windows` (WPF) — via `System.Windows.Media` and `ThemeInfo` usage.
|
||||
- `System.Resources` and `System.Globalization` — for `ResourceManager` and `CultureInfo`.
|
||||
- `System.CodeDom.Compiler`, `System.Diagnostics`, `System.Runtime.CompilerServices`, `System.ComponentModel` — for auto-generated attributes and resource infrastructure.
|
||||
- **Depended on by**:
|
||||
- Other modules in the `DataPRO` solution (e.g., UI forms, business logic layers) that reference this assembly to access localized strings via `DataPROWin7.Properties.Resources`.
|
||||
- The WPF runtime — uses `ThemeInfo` to locate resource dictionaries (here, theme-specific resources are absent, and generic resources reside in the assembly itself).
|
||||
|
||||
### 5. Gotchas
|
||||
- **Namespace Mismatch**: The `Resources` class resides in `DataPROWin7.Properties`, *not* `DataPRO.Properties`, despite the assembly name being `DataPRO`. This may cause confusion when referencing `Resources` (e.g., `DataPROWin7.Properties.Resources.DataPRO_MainFormTitle`).
|
||||
- **Hardcoded Resource Base Name**: The `ResourceManager` uses `"DataPROWin7.Properties.Resources"` literally. Renaming the namespace or `.resx` file without updating this string will cause resource lookups to fail silently (returning `null`).
|
||||
- **DPI Behavior**: `DisableDpiAwareness` may cause UI elements to appear small or blurry on high-DPI displays. This is intentional per the attribute but could be a usability issue.
|
||||
- **Auto-Generated Code Warning**: `Resources.Designer.cs` explicitly warns that manual edits will be lost on regeneration. Changes must be made to the `.resx` file.
|
||||
- **Missing `NeutralResourcesLanguage`**: Without uncommenting and configuring `[NeutralResourcesLanguage("en-US", ...)]`, the fallback culture is the invariant culture, which may impact performance (no satellite assembly optimization).
|
||||
- **No Public API**: This assembly is purely infrastructure; developers should not expect to extend or interact with it beyond consuming `Resources`.
|
||||
66
enriched-qwen3-coder-next/DataPRO/DataPRO/RegionAdapters.md
Normal file
66
enriched-qwen3-coder-next/DataPRO/DataPRO/RegionAdapters.md
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/RegionAdapters/StackPanelRegionAdapter.cs
|
||||
generated_at: "2026-04-16T04:05:23.080286+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "8aeafa51207ca970"
|
||||
---
|
||||
|
||||
# RegionAdapters
|
||||
|
||||
### 1. **Purpose**
|
||||
This module provides a Prism `RegionAdapter` that enables UI elements hosted in a Prism region to be dynamically added to or removed from a WPF `StackPanel`. It bridges Prism’s region management abstraction with the `StackPanel`’s `Children` collection, allowing views to be injected/removed declaratively via Prism regions while maintaining the stacking layout semantics of `StackPanel`. It exists to support modular UI composition in the DataPROWin7 application where views need to be stacked vertically (or horizontally, depending on `StackPanel.Orientation`) without requiring custom layout logic.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
The class is `public`, but its only *publicly instantiable* member is the constructor. All other members are inherited or `protected override` methods.
|
||||
|
||||
- **`StackPanelRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)`**
|
||||
Public constructor. Accepts a Prism `IRegionBehaviorFactory` and passes it to the base `RegionAdapterBase<StackPanel>` constructor. No additional initialization logic.
|
||||
|
||||
- **`protected override void Adapt(IRegion region, StackPanel regionTarget)`**
|
||||
Overrides the base `Adapt` method. Attaches a `CollectionChanged` handler to `region.Views` (a `IViewCollection`). When views are added or removed from the region, it synchronizes those changes to `regionTarget.Children` (i.e., adds/removes `UIElement`s from the `StackPanel`).
|
||||
- On `NotifyCollectionChangedAction.Add`: Adds each new `UIElement` in `e.NewItems` to `regionTarget.Children`.
|
||||
- On `NotifyCollectionChangedAction.Remove`: Removes each `UIElement` in `e.OldItems` from `regionTarget.Children`, *only if* it is currently present (via `Contains` check).
|
||||
- **Note**: Only handles `Add` and `Remove` actions; other actions (e.g., `Reset`, `Replace`, `Move`) are silently ignored.
|
||||
|
||||
- **`protected override IRegion CreateRegion()`**
|
||||
Overrides the base `CreateRegion` method. Always returns a new instance of `AllActiveRegion`, meaning *all views* in the region are kept active and remain in the visual tree (no deactivation/disposal occurs). This aligns with `StackPanel`’s expectation that children persist unless explicitly removed.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
- The `StackPanel`’s `Children` collection is kept in sync with the region’s `Views` collection *only* for `Add` and `Remove` operations. No handling for `Reset`, `Replace`, or `Move` actions is implemented.
|
||||
- Views are added/removed in the order they appear in the `NotifyCollectionChangedEventArgs.NewItems`/`OldItems` collections (via `foreach`).
|
||||
- The `regionTarget` (`StackPanel`) must be non-null when `Adapt` is called, but the method early-exits if `region == null`.
|
||||
- The `AllActiveRegion` returned by `CreateRegion()` ensures all views remain active; no view is deactivated or disposed when removed from the region—only removed from the `StackPanel.Children`. (The view object itself may still be alive in Prism’s region manager unless explicitly disposed elsewhere.)
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
- **Prism.Core / Prism.Wpf**:
|
||||
- `Prism.Regions.RegionAdapterBase<T>` (base class)
|
||||
- `Prism.Regions.IRegionBehaviorFactory` (constructor parameter)
|
||||
- `Prism.Regions.IRegion` and `IViewCollection` (via `region.Views`)
|
||||
- `Prism.Regions.AllActiveRegion` (returned by `CreateRegion()`)
|
||||
- **WPF**:
|
||||
- `System.Windows.Controls.StackPanel`
|
||||
- `System.Windows.UIElement`
|
||||
- `System.Collections.Specialized.NotifyCollectionChangedAction`
|
||||
- **Internal usage**: The namespace `DataPROWin7` suggests this is part of the `DataPROWin7` application assembly. No other internal dependencies are visible in this file.
|
||||
|
||||
**Depended upon by**: Any Prism region registration that targets a `StackPanel` (e.g., via `regionManager.RegisterViewWithRegion("MainRegion", typeof(MyView))` where `"MainRegion"` is bound to a `StackPanel` using this adapter).
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
- **No handling for `Reset`, `Replace`, or `Move` actions**: If the region’s `Views` collection is reset (e.g., via `Clear()` or reassignment), or views are reordered/updated, the `StackPanel.Children` will *not* be updated accordingly. This can lead to stale or incorrect UI state.
|
||||
- **No cleanup on region disposal**: If the region itself is disposed, the `CollectionChanged` handler is *not* detached, potentially causing memory leaks (though Prism typically disposes regions and their behaviors in a coordinated way).
|
||||
- **No `Dispatcher` check**: UI updates (`Children.Add`/`Remove`) occur directly in the `CollectionChanged` event handler. If the handler is invoked off the UI thread (unlikely in Prism’s typical usage, but possible), this could throw `InvalidOperationException`. Prism regions generally marshal to the UI thread, but this is not explicit here.
|
||||
- **`foreach` over `e.NewItems`/`e.OldItems`**: Assumes all items are `UIElement`s. If non-`UIElement` objects are added to the region (e.g., via `IRegionManager.RegisterViewWithRegion` with a view factory returning non-`UIElement`), this will throw at runtime.
|
||||
- **`AllActiveRegion` behavior**: Since *all* views are kept active, views are not deactivated when removed from the `StackPanel`. If views have expensive resources or subscriptions, they may not be cleaned up as expected—consumers must manage view lifecycle separately.
|
||||
- **No `Orientation` awareness**: The adapter does not respect or modify `StackPanel.Orientation`; it assumes the default vertical stacking. Layout behavior is unchanged by the adapter itself.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/ReviewDataSubControls/ReviewTest.cs
|
||||
generated_at: "2026-04-16T04:05:19.721670+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "afe9caebdc33cfcd"
|
||||
---
|
||||
|
||||
# ReviewDataSubControls
|
||||
|
||||
## Documentation: `ReviewTest` Module
|
||||
|
||||
### 1. Purpose
|
||||
This module provides in-memory representations and lifecycle management for test data units (`ReviewTest`) and their associated measurement channels (`ReviewTestChannel`) within the DTS Slice framework. It enables deferred loading of test metadata and raw data (via `Event` and `Serialization.Test`) from disk, supports comparison and ordering of tests (primarily by creation time, then name), and offers cleanup semantics to release unmanaged resources (e.g., persistent channel data). It serves as a bridge between raw serialized test directories and the UI layer (`DataPROPage`) for review and analysis workflows.
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `ReviewTest` class
|
||||
- **`ReviewTest(string testDirectory, DataPROWin7.DataPROPage page)`**
|
||||
Constructor. Initializes the instance with a path to a test directory and a reference to the parent UI page. Extracts `TestName` from the directory name and sets `_creationTime` to the directory’s creation time.
|
||||
- **`DateTime CreationTime { get; }`**
|
||||
Lazily loads and returns the creation time of the test directory. Falls back to `SqlDateTime.MinValue` (year < 1900) if initial value persists, then attempts to read `FileInfo.CreationTime` on `TestDirectory`, swallowing exceptions silently.
|
||||
- **`ReviewTestChannel[] Channels { get; }`**
|
||||
Returns an array of `ReviewTestChannel` objects. Lazily initializes `_channels` by calling `LoadChannels()` if null. `LoadChannels()` iterates over `Event.Modules` and their `Channels`, wrapping each in a new `ReviewTestChannel`.
|
||||
- **`Event Event { get; }`**
|
||||
Returns the loaded `Event` object. Lazily initializes via `LoadEvent()` if null. `LoadEvent()` uses a static lock, deserializes the test directory via `Serialization.SliceRaw.File.Importer.Read`, and constructs an `Event` instance with error-reporting hooked to `_page.ReportErrors`.
|
||||
- **`void Cleanup()`**
|
||||
Disposes all `ReviewTestChannel` instances by calling their `Cleanup()` methods, then nulls `_channels` and `_event`.
|
||||
- **`int CompareTo(ReviewTest right)`**
|
||||
Implements `IComparable<ReviewTest>`. Compares by `CreationTime` descending (note: `right.CreationTime.CompareTo(this.CreationTime)`), and if equal, falls back to lexicographic comparison of `TestName`. Exceptions during time comparison are silently ignored.
|
||||
- **`string TestDirectory { get; }`**
|
||||
Read-only property storing the full path to the test directory.
|
||||
- **`string TestName { get; }`**
|
||||
Read-only property storing the directory name (i.e., `FileInfo.Name` of `TestDirectory`).
|
||||
|
||||
#### `ReviewTestChannel` class
|
||||
- **`ReviewTestChannel(Event.Module.Channel channel, ReviewTest test)`**
|
||||
Constructor. Stores the underlying `Event.Module.Channel` and `ParentTest`.
|
||||
- **`string Name { get; }`**
|
||||
Returns `Channel.ChannelDescriptionString`.
|
||||
- **`bool MultipleTests { get; set; }`**
|
||||
Controls `ToString()` behavior: if `true`, appends the parent test name in parentheses (e.g., `"ChannelName(Test1)"`).
|
||||
- **`System.Drawing.Color Color { get; set; }`**
|
||||
Default `Color.Black`. Used for UI rendering (e.g., line color in plots).
|
||||
- **`string ToString()`**
|
||||
Overrides `Object.ToString()`. Returns `Name` alone if `MultipleTests` is `false` or `ParentTest` is null; otherwise returns `"{Name}({ParentTest.TestName})"`.
|
||||
- **`void Cleanup()`**
|
||||
Disposes `Channel.UnfilteredData` if it is a `DTS.Serialization.SliceRaw.File.PersistentChannel` with `Length > 0`, then nulls `Channel`.
|
||||
|
||||
### 3. Invariants
|
||||
- `TestDirectory` must be a valid directory path; `TestName` is derived from its name.
|
||||
- `_creationTime` is initialized to `SqlDateTime.MinValue` (year < 1900) and only updated lazily on first access to `CreationTime`.
|
||||
- `Channels` and `Event` are lazily initialized and populated only once per instance (via `LoadChannels()` and `LoadEvent()` respectively).
|
||||
- `LoadEvent()` is thread-safe via a static lock (`LoadEventLock`), but `Cleanup()` is *not* thread-safe and must not be called concurrently with property access.
|
||||
- After `Cleanup()` is called, `Channels`, `Event`, and `_channels`/`_event` fields are null; subsequent access to `Channels`/`Event` will re-trigger loading (unless `Cleanup()` is called again).
|
||||
- `ReviewTestChannel.Cleanup()` only disposes `UnfilteredData` if it is a `PersistentChannel` with `Length > 0`.
|
||||
|
||||
### 4. Dependencies
|
||||
**Imports/Usings:**
|
||||
- `System`, `System.Collections.Generic`, `System.Linq`, `System.IO` (standard .NET)
|
||||
- `DTS.Slice.Control` (contains `Event` and likely `IComparable`, `IDisposable` contracts)
|
||||
|
||||
**External Types Referenced (from source):**
|
||||
- `DTS.Slice.Event` (used in `Event` property and `LoadEvent()`)
|
||||
- `DTS.Serialization.SliceRaw.File` (used in `LoadEvent()` for deserialization)
|
||||
- `DTS.Serialization.SliceRaw.File.PersistentChannel` (used in `ReviewTestChannel.Cleanup()`)
|
||||
- `DTS.Serialization.Test` (deserialized type)
|
||||
- `DTS.Serialization.Test.ReportErrors` (delegate type used in `Event` constructor)
|
||||
- `DataPROWin7.DataPROPage` (used for error reporting via `_page.ReportErrors`)
|
||||
|
||||
**Dependents (inferred):**
|
||||
- UI components (e.g., `DataPROPage`) that instantiate `ReviewTest` and manage test review workflows.
|
||||
- Any code that enumerates or compares `ReviewTest` instances (e.g., test lists, sorting).
|
||||
|
||||
### 5. Gotchas
|
||||
- **Silent exception swallowing**: Multiple `try/catch` blocks (in `CreationTime`, `CompareTo`, `LoadEvent`) discard exceptions without logging or propagation. This may mask I/O or deserialization failures.
|
||||
- **Thread-safety mismatch**: `LoadEvent()` is thread-safe (via `lock`), but `Cleanup()` is not. Calling `Cleanup()` while another thread accesses `Event`/`Channels` may cause `NullReferenceException`.
|
||||
- **Lazy initialization side effects**: Accessing `CreationTime` *before* `TestDirectory` is set (e.g., in a derived constructor) could cause `FileInfo` to fail. However, `TestDirectory` is set in the constructor *before* any property access.
|
||||
- **`CompareTo` ordering is descending by time**: `right.CompareTo(this)` yields *descending* order (newest first). This may be counter-intuitive for a `CompareTo` implementation.
|
||||
- **`Channels` returns a *copy* (`ToArray()`)**: Modifications to the returned array do not affect `_channels`. Callers must not expect mutation to persist.
|
||||
- **`ReviewTestChannel.ToString()` behavior is context-sensitive**: The `MultipleTests` flag must be set correctly by the caller (likely by UI logic) to avoid ambiguous channel names.
|
||||
- **`PersistentChannel` disposal is conditional**: Only `UnfilteredData` of type `PersistentChannel` with `Length > 0` is disposed. Other data types (e.g., in-memory buffers) may not be cleaned up.
|
||||
- **No validation of `testDirectory`**: Constructor accepts any string; invalid paths may cause failures later during `LoadEvent()` or `CreationTime` access.
|
||||
104
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo.md
Normal file
104
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo.md
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/TSRAIRGo/TSRAIRGoDashboard.xaml.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/TSRAIRGoMainWindow.xaml.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/TSRAIRGoNavigation.xaml.cs
|
||||
generated_at: "2026-04-16T04:04:59.184159+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "0592e78fbd3bf46e"
|
||||
---
|
||||
|
||||
# TSRAIRGo
|
||||
|
||||
## Documentation: TSRAIRGo Module
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
This module implements the UI navigation and dashboard infrastructure for the **TSRAIRGo** feature within the DataPROWin7 application. It provides a structured interface for navigating between a central dashboard and specific content pages (e.g., *View Data*, *Export Data*) using Prism’s event aggregation pattern. The module is responsible for managing page lifecycle (via `OnSetActive`/`UnSet` methods on `DataPROPage` instances) and delegating navigation events, but **does not contain business logic or data processing**—it serves as a presentation-layer shell.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `TSRAIRGoDashboard` (UserControl)
|
||||
- **Constructor**: `public TSRAIRGoDashboard()`
|
||||
Initializes the dashboard UI via `InitializeComponent()`. No additional logic; serves as a placeholder content page.
|
||||
|
||||
#### `TSRAIRGoMainWindow` (UserControl)
|
||||
- **Constructor**: `public TSRAIRGoMainWindow()`
|
||||
Initializes the main window UI, sets `_tSRAIRGoDashboard` as the initial content, and subscribes to `GotoTSRAIRGoDashboardEvent` via the `IEventAggregator`.
|
||||
- **`SetContent(object content)`**: `public void SetContent(object content)`
|
||||
Sets the `Content` property of the internal `contentControl` to the provided `content`. Used to switch displayed pages.
|
||||
|
||||
#### `TSRAIRGoNavigation` (UserControl)
|
||||
- **Constructor**: `public TSRAIRGoNavigation()`
|
||||
Initializes UI, retrieves `IEventAggregator`, and populates `TabPageItems` via `GetGroupContents()`.
|
||||
- **`ContentControl`**: `public ContentControl ContentControl { get; set; }`
|
||||
Exposed property to allow external wiring of the target `ContentControl` (e.g., set in `TSRAIRGoMainWindow`).
|
||||
- **`GoBackToDashboard_Button_Click(object sender, RoutedEventArgs e)`**: `private void`
|
||||
Event handler for the *Dashboard* button; publishes `GotoTSRAIRGoDashboardEvent` to trigger navigation back to the dashboard.
|
||||
- **`ViewData_Button_Click(object sender, RoutedEventArgs e)`**: `private void`
|
||||
Event handler for the *View Data* button; locates the corresponding `TabPageItem` and navigates to it.
|
||||
- **`ExportData_Button_Click(object sender, RoutedEventArgs e)`**: `private void`
|
||||
Event handler for the *Export Data* button; locates the corresponding `TabPageItem` and navigates to it.
|
||||
- **`NavigateToContent(TabPageItem tabItem)`**: `private void`
|
||||
Performs navigation: unsets the previous page (`_lastPageVisited.UnSet()`), sets `ContentControl.Content`, and activates the new page (`page.OnSetActive()`).
|
||||
- **`GetGroupContents()`**: `private List<TabPageItem> GetGroupContents()`
|
||||
Retrieves all `TabPageItem`s from `TabPageSource.GetGroups("AllGroups")`, ensures their `Content` is initialized via `SetContent()` if null, and filters to only include items whose `Content` is a `DataPROPage`.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **Page Lifecycle Contract**:
|
||||
- Only `TabPageItem.Content` instances that are `DataPROPage` objects are navigated to.
|
||||
- Before navigating to a new page, `_lastPageVisited.UnSet()` is called (if `_lastPageVisited` is non-null).
|
||||
- After setting `ContentControl.Content`, the new page’s `OnSetActive()` method is invoked.
|
||||
- **Content Initialization**:
|
||||
- `TabPageItem.Content` is lazily initialized: `item.SetContent()` is called if `item.Content == null` in `GetGroupContents()`.
|
||||
- **Navigation Target Validation**:
|
||||
- `NavigateToContent` silently aborts if `tabItem.Content` is not a `DataPROPage`.
|
||||
- **Event Subscription**:
|
||||
- `TSRAIRGoMainWindow` subscribes to `GotoTSRAIRGoDashboardEvent` once during construction and never unsubscribes (potential leak if lifecycle is long-lived).
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Imports/References
|
||||
- **Prism**: `Microsoft.Practices.Prism.Events.IEventAggregator`, `Microsoft.Practices.ServiceLocation`
|
||||
- **DataPROWin7 Common**: `DataPROWin7.Common`, `DataPROWin7.DataModel.TabPageSource`, `DataPROWin7.DataModel.TabPageItem`, `DataPROWin7.DataModel.DataPROPage`
|
||||
- **DTS Common**: `DTS.Common.Events.GotoTSRAIRGoDashboardEvent`, `DTS.Common.Events.GotoTSRAIRGoDashboardArg`
|
||||
- **WPF**: Standard UI namespaces (`System.Windows.*`)
|
||||
|
||||
#### Key External Types
|
||||
- `TabPageSource.GetGroups(string)` → Returns groups of `TabPageItem`s (structure inferred).
|
||||
- `TabPageItem.SetContent()` → Initializes `Content` property (implementation unknown).
|
||||
- `DataPROPage.OnSetActive()` / `DataPROPage.UnSet()` → Lifecycle hooks for page activation/deactivation.
|
||||
- `GotoTSRAIRGoDashboardEvent` / `GotoTSRAIRGoDashboardArg` → Prism events for dashboard navigation.
|
||||
|
||||
#### Dependencies *on* this Module
|
||||
- `TSRAIRGoMainWindow` is likely instantiated as the root view for the TSRAIRGo feature.
|
||||
- `TSRAIRGoNavigation` requires external wiring of `ContentControl` (set via `ContentControl` property).
|
||||
- Other modules may publish `GotoTSRAIRGoDashboardEvent` to trigger navigation back to the dashboard.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **Event Subscription Leak**:
|
||||
`TSRAIRGoMainWindow` subscribes to `GotoTSRAIRGoDashboardEvent` but does not unsubscribe (no `Unsubscribe` call). If the `TSRAIRGoMainWindow` instance is long-lived or recreated, duplicate subscriptions may occur.
|
||||
- **Null Safety in Navigation**:
|
||||
`NavigateToContent` silently ignores non-`DataPROPage` content (e.g., if `item.Content` is not a `DataPROPage`). This may mask configuration errors.
|
||||
- **Hardcoded Group Name**:
|
||||
`GetGroupContents()` uses `"AllGroups"` as the group key—assumes this is a valid, stable identifier in `TabPageSource`.
|
||||
- **No Error Handling**:
|
||||
No try/catch around `SetContent()` or `UnSet()`/`OnSetActive()` calls. Exceptions in page lifecycle methods could crash navigation.
|
||||
- **Typo in Event Name**:
|
||||
`OnNavigateToDashbaord` (missing 'r' in "Dashboard")—consistent with source, but may cause confusion.
|
||||
- **Missing Initialization Guard**:
|
||||
`_eventAggregator` is fetched in `TSRAIRGoNavigation` constructor, but the null-check `if (_eventAggregator == null)` is redundant (ServiceLocator throws if missing).
|
||||
|
||||
None identified beyond these.
|
||||
147
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/Classes.md
Normal file
147
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/Classes.md
Normal file
@@ -0,0 +1,147 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/TSRAIRGo/Classes/ViewHelper.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/Classes/ClockSyncReboot.cs
|
||||
generated_at: "2026-04-16T04:08:58.268614+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "442f577aeef3fd57"
|
||||
---
|
||||
|
||||
# Classes
|
||||
|
||||
## Documentation: `ViewHelper` and `ClockSyncReboot` Classes
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
The `ViewHelper` and `ClockSyncReboot` classes reside in the `DataPROWin7.TSRAIRGo.Classes` namespace and serve distinct but complementary roles in the TSRAIRGo application. `ViewHelper` provides lightweight, UI-centric validation logic for WPF text input controls, ensuring only numeric (integer or float) characters are accepted. `ClockSyncReboot` encapsulates the end-to-end workflow for synchronizing clock settings and conditionally rebooting hardware units (DAS devices) to enforce clock configuration consistency—specifically for the TSRAIRGo test environment, with plans to extend to DP. It coordinates with external services (`ConfigurationService`) to query, configure, and reboot devices based on test parameters.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `ViewHelper` (Static Class)
|
||||
|
||||
- **`ValidateFloatOnlyTextBox(TextCompositionEventArgs e)`**
|
||||
Validates that the text being entered into a WPF `TextBox` contains only digits (`0–9`) and a single decimal point (`.`). Uses a regex `[^0-9.]+`; sets `e.Handled = true` if invalid characters are detected, preventing input.
|
||||
|
||||
- **`ValidateIntegerOnlyTextBox(TextCompositionEventArgs e)`**
|
||||
Validates that the text being entered into a WPF `TextBox` contains only digits (`0–9`). Uses a regex `[^0-9]+`; sets `e.Handled = true` if non-digit characters are detected, preventing input.
|
||||
|
||||
> **Note**: Both methods assume `e.Text` is the *newly typed text* (e.g., from `PreviewTextInput`). They do *not* validate the full content of the `TextBox`, only the incoming keystroke.
|
||||
|
||||
#### `ClockSyncReboot` (Static Class)
|
||||
|
||||
- **Delegates**
|
||||
- `SendUnitStatusDelegate(IDASCommunication das, string message)`
|
||||
Callback to notify UI or logging of unit status updates (e.g., “Rebooting”, “Setting Clock Sources”). `das` may be `null` in error cases.
|
||||
- `AlertErrorDelegate(IDASCommunication das, string message)`
|
||||
Callback to report errors. `das` may be `null` if the error is global (e.g., service failure).
|
||||
|
||||
- **`RebootIfNeeded(List<IDASCommunication> dasList, TestTemplate test, SendUnitStatusDelegate setStatus, AlertErrorDelegate setError) → bool`**
|
||||
Main entry point. Checks if clock/PTP domain reconfiguration requires a reboot. If so:
|
||||
1. Calls `SetClocks`,
|
||||
2. Calls `SetPTPDomains`,
|
||||
3. Reboots units flagged by those steps.
|
||||
Returns `true` if *any* units were rebooted; `false` otherwise.
|
||||
|
||||
- **`RebootUnits(List<IDASCommunication> dasList, SendUnitStatusDelegate setStatus, AlertErrorDelegate setError)`**
|
||||
Performs synchronous reboot of devices via `ConfigurationService.Reboot`.
|
||||
- Sends “Rebooting” status to each device.
|
||||
- Waits for reboot completion, then waits `WAIT_AFTER_REBOOT_MS = 3000` ms.
|
||||
- Polls up to `MAX_WAIT_TIME_REBOOT = 10000` ms for all devices to reconnect (via `DASFactory.GetActiveDevices()`).
|
||||
- Logs exceptions via `APILogger.Log` and reports via `setError`.
|
||||
|
||||
- **`SetClocks(List<IDASCommunication> dasList, TestTemplate test, out List<IDASCommunication> unitsNeedRebooting, SendUnitStatusDelegate setStatus, AlertErrorDelegate setError)`**
|
||||
Sets clock sources for devices using `ConfigurationService.SetClocks`.
|
||||
- Uses `test.DASClockMasterList`, `test.ClockSyncProfileMaster`, `test.ClockSyncProfileSlave` as parameters.
|
||||
- Devices returning `CallbackStatus.Success` are added to `unitsNeedRebooting`.
|
||||
- Errors reported via `setError`.
|
||||
|
||||
- **`RebootNeeded(List<IDASCommunication> dasList, TestTemplate test, out List<IDASCommunication> dasNeedingSet, SendUnitStatusDelegate setStatus, AlertErrorDelegate setError) → bool`**
|
||||
Determines if clock/PTP reconfiguration is needed.
|
||||
- Filters `dasList` to devices implementing `IClockSyncActions`.
|
||||
- Calls `GetClocks` and `GetPTPDomains` to fetch current settings.
|
||||
- Compares current `DASClockSyncProfile` to expected profile (based on `DASClockMasterList`).
|
||||
- Returns `true` if any device’s profile mismatched; populates `dasNeedingSet` with devices needing updates.
|
||||
|
||||
- **`GetClocks(List<IDASCommunication> clockDAS, SendUnitStatusDelegate setStatus, AlertErrorDelegate setError)`**
|
||||
Queries devices for current clock settings via `ConfigurationService.GetClocks`.
|
||||
- Blocks until `CallbackStatus.AllFinished`.
|
||||
- Logs exceptions; does *not* set status or error callbacks beyond logging.
|
||||
|
||||
- **`GetPTPDomains(List<IDASCommunication> dasList, SendUnitStatusDelegate setStatus, AlertErrorDelegate setError)`**
|
||||
Queries devices for current PTP domain ID via `ConfigurationService.GetPTPDomain`.
|
||||
- Blocks until `CallbackStatus.AllFinished`.
|
||||
- Logs exceptions; does *not* set status or error callbacks.
|
||||
|
||||
- **`SetPTPDomains(List<IDASCommunication> dasList, TestTemplate test, List<IDASCommunication> unitsNeedRebooting, SendUnitStatusDelegate setStatus, AlertErrorDelegate setError)`**
|
||||
Sets PTP domain ID for devices where:
|
||||
- `test.DASPTPDomainIDList` contains the device’s serial number,
|
||||
- Current `PTPDomainID` differs,
|
||||
- And the device’s clock profile (master/slave) includes “PTP” in its description (via `ResourceManager.GetString(...).GetDescription()`).
|
||||
- Devices returning `CallbackStatus.Success` are added to `unitsNeedRebooting`.
|
||||
- Uses `test.DASPTPDomainIDList` as parameter to `SetPTPDomain`.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **`ViewHelper`**
|
||||
- Input validation is *per-character*, not full-string validation.
|
||||
- Only ASCII digits (`0–9`) and `.` are allowed for float validation; no locale-specific decimal separators (e.g., `,`) are supported.
|
||||
- No validation of *format correctness* (e.g., multiple `.` are allowed by the regex but may be invalid semantically).
|
||||
|
||||
- **`ClockSyncReboot`**
|
||||
- `RebootIfNeeded` only processes devices implementing `IClockSyncActions`. Non-compliant devices are silently skipped.
|
||||
- Clock/PTP domain updates are *not* atomic; reboot is triggered only if clock *or* PTP domain changes require it (per `SetClocks`/`SetPTPDomains` callbacks).
|
||||
- Device reconnection polling (`RebootUnits`) assumes `SerialNumber` uniquely identifies devices in `GetActiveDevices()`.
|
||||
- `SetPTPDomains` only acts on devices where the clock profile description *contains* “PTP” (case-sensitive substring match).
|
||||
- All blocking operations (`WaitOne()`) assume the underlying `ConfigurationService` callbacks will eventually fire; no timeout handling beyond `WaitOne()` (which blocks indefinitely).
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### `ViewHelper`
|
||||
- **Depends on**:
|
||||
- `System.Windows.Input.TextCompositionEventArgs` (WPF input event)
|
||||
- `System.Text.RegularExpressions.Regex`
|
||||
- **Used by**: WPF `TextBox` controls via `PreviewTextInput` event handlers (e.g., `TextBox.PreviewTextInput += ViewHelper.ValidateFloatOnlyTextBox`).
|
||||
|
||||
#### `ClockSyncReboot`
|
||||
- **Depends on**:
|
||||
- `DataPROWin7.DataModel.TestTemplate` (test configuration)
|
||||
- `DTS.Common.Interface.DASFactory.IDASCommunication`, `IClockSyncActions`
|
||||
- `DTS.DASLib.Service.ConfigurationService` (for `GetClocks`, `SetClocks`, `GetPTPDomain`, `SetPTPDomain`, `Reboot`)
|
||||
- `DTS.Common.Utilities.Logging.APILogger`
|
||||
- `System.Windows.Application.Current.DASFactory` (for `GetActiveDevices`)
|
||||
- `DTS.Common.SharedResource.Strings.StringResources` (for status strings)
|
||||
- `DTS.Common.Strings.Strings` (for resource lookup)
|
||||
- `System.Threading.ManualResetEvent`, `System.Diagnostics.Stopwatch`, `System.Linq`, `System.Collections.Generic`
|
||||
- **Used by**: Likely `CheckHardware.xaml.cs` (as noted in comments) and other test orchestration logic in TSRAIRGo.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **`ViewHelper`**
|
||||
- Regex `[^0-9.]+` allows *multiple* decimal points (e.g., `"1.2.3"` passes validation but is invalid).
|
||||
- Leading/trailing whitespace or empty input is not explicitly handled (though `e.Text` for empty input is `""`, which matches the regex and sets `e.Handled = false`).
|
||||
- No support for negative numbers, scientific notation, or locale-aware formatting.
|
||||
|
||||
- **`ClockSyncReboot`**
|
||||
- **Hardcoded timeouts**: `WAIT_AFTER_REBOOT_MS = 3000` and `MAX_WAIT_TIME_REBOOT = 10000` are fixed; no configuration or dynamic adjustment.
|
||||
- **Blocking I/O**: All operations use `ManualResetEvent.WaitOne()` without timeout, risking deadlocks if callbacks fail to fire.
|
||||
- **PTP domain check is fragile**: Uses `ResourceManager.GetString(...).GetDescription().Contains("PTP")`—a substring match on a localized string, which may break with localization or string changes.
|
||||
- **Error handling is inconsistent**: `GetClocks` and `GetPTPDomains` log exceptions but do *not* invoke `setError`; only `SetClocks` and `SetPTPDomains` do.
|
||||
- **`RebootNeeded` swallows exceptions**: Returns `false` on any exception, potentially masking critical failures.
|
||||
- **`RebootUnits` assumes `App.Current.DASFactory` is valid**: Relies on WPF `Application.Current`, which may be `null` in non-UI contexts (e.g., tests).
|
||||
- **No idempotency guarantee**: Re-running `RebootIfNeeded` may trigger redundant reboots if state isn’t persisted or re-queried.
|
||||
- **Thread safety**: Uses `ConfigurationService` in `using` blocks, but no indication of thread-safety for concurrent calls.
|
||||
|
||||
- **General**
|
||||
- Both classes are `static`, limiting testability and dependency injection.
|
||||
- No unit tests or examples provided; behavior inferred solely from source.
|
||||
106
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/Command.md
Normal file
106
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/Command.md
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/TSRAIRGo/Command/HelpButton.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/Command/ViewDataButton.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/Command/TriggerButton.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/Command/DownloadButton.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/Command/TestIdButton.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/Command/ArmDisarmButton.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/Command/DashboardButton.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/Command/ExportDataButton.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/Command/BaseNavigationButtonInfo.cs
|
||||
generated_at: "2026-04-16T04:09:44.731949+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "c7fa4379683efce9"
|
||||
---
|
||||
|
||||
# Navigation Button Command Classes Documentation
|
||||
|
||||
## 1. Purpose
|
||||
This module defines concrete implementations of navigation button command objects for the TSRAIRGo UI framework. Each class represents a specific navigation action (e.g., `Dashboard`, `ViewData`, `Trigger`, etc.) and exposes a standardized `NavigationButtonId` via the `INavigationButtonInfo` interface. These classes inherit from `BaseNavigationButtonInfo`, which provides common button metadata properties (`Text`, `Tooltip`, `Enabled`, `ShowBorder`) with property change notification support for UI data binding. The module serves as a lightweight, declarative mapping between logical button identifiers and their UI presentation layer.
|
||||
|
||||
## 2. Public Interface
|
||||
All classes inherit from `BaseNavigationButtonInfo` and implement `INavigationButtonInfo`. Only the `Id` property is overridden per class.
|
||||
|
||||
- **`DashboardButton`**
|
||||
```csharp
|
||||
public class DashboardButton : BaseNavigationButtonInfo, INavigationButtonInfo
|
||||
```
|
||||
Represents the *Dashboard* navigation button. Returns `NavigationButtonId.Dashboard` for `Id`.
|
||||
|
||||
- **`HelpButton`**
|
||||
```csharp
|
||||
public class HelpButton : BaseNavigationButtonInfo, INavigationButtonInfo
|
||||
```
|
||||
Represents the *Help* navigation button. Returns `NavigationButtonId.Dashboard` for `Id`.
|
||||
⚠️ *Note: Same `Id` as `DashboardButton`.*
|
||||
|
||||
- **`ViewDataButton`**
|
||||
```csharp
|
||||
public class ViewDataButton : BaseNavigationButtonInfo, INavigationButtonInfo
|
||||
```
|
||||
Represents the *View Data* navigation button. Returns `NavigationButtonId.ViewData` for `Id`.
|
||||
|
||||
- **`TriggerButton`**
|
||||
```csharp
|
||||
public class TriggerButton : BaseNavigationButtonInfo, INavigationButtonInfo
|
||||
```
|
||||
Represents the *Trigger* navigation button. Returns `NavigationButtonId.Trigger` for `Id`.
|
||||
|
||||
- **`DownloadButton`**
|
||||
```csharp
|
||||
public class DownloadButton : BaseNavigationButtonInfo, INavigationButtonInfo
|
||||
```
|
||||
Represents the *Download* navigation button. Returns `NavigationButtonId.Download` for `Id`.
|
||||
|
||||
- **`TestIdButton`**
|
||||
```csharp
|
||||
public class TestIdButton : BaseNavigationButtonInfo, INavigationButtonInfo
|
||||
```
|
||||
Represents the *Test ID* navigation button. Returns `NavigationButtonId.TestId` for `Id`.
|
||||
|
||||
- **`ArmDisarmButton`**
|
||||
```csharp
|
||||
public class ArmDisarmButton : BaseNavigationButtonInfo, INavigationButtonInfo
|
||||
```
|
||||
Represents the *Arm/Disarm* navigation button. Returns `NavigationButtonId.ArmDisarm` for `Id`.
|
||||
|
||||
- **`ExportDataButton`**
|
||||
```csharp
|
||||
public class ExportDataButton : BaseNavigationButtonInfo, INavigationButtonInfo
|
||||
```
|
||||
Represents the *Export Data* navigation button. Returns `NavigationButtonId.ExportData` for `Id`.
|
||||
|
||||
### Inherited Properties from `BaseNavigationButtonInfo`
|
||||
All classes expose the following properties (with `INotifyPropertyChanged` support via `BasePropertyChanged`):
|
||||
|
||||
- `string Text` — Button label text.
|
||||
- `string Tooltip` — Hover tooltip text.
|
||||
- `bool Enabled` — Whether the button is interactive (default: `true`).
|
||||
- `bool ShowBorder` — Whether to render a visible border (default: `false`).
|
||||
|
||||
## 3. Invariants
|
||||
- Every button class **must** return a non-null `NavigationButtonId` from its `Id` property.
|
||||
- `BaseNavigationButtonInfo` enforces property change notifications for `Text`, `Tooltip`, `Enabled`, and `ShowBorder` via `OnPropertyChanged`.
|
||||
- The `Enabled` property defaults to `true`; `ShowBorder` defaults to `false`.
|
||||
- No validation or side effects occur in property setters beyond raising `OnPropertyChanged`.
|
||||
|
||||
## 4. Dependencies
|
||||
### Dependencies *of* this module:
|
||||
- **`DTS.Common.Interface.TSRAIRGo.INavigationButtonInfo`** — Interface defining the `Id` contract.
|
||||
- **`DTS.Common.Enums.TSRAIRGo.NavigationButtonId`** — Enum containing valid button identifiers (e.g., `Dashboard`, `ViewData`, `Trigger`, `Download`, `TestId`, `ArmDisarm`, `ExportData`).
|
||||
- **`DTS.Common.Base.BasePropertyChanged`** — Base class providing `INotifyPropertyChanged` implementation.
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- UI layer components that consume `INavigationButtonInfo` instances to render navigation controls (e.g., command bars, toolbars).
|
||||
- Likely used by a command dispatcher or navigation manager (not visible in source) to map button clicks to actions via `NavigationButtonId`.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Duplicate `Id` values**: `DashboardButton` and `HelpButton` both return `NavigationButtonId.Dashboard`. This may cause ambiguity if `Id` is used as a unique key for routing or event handling.
|
||||
- **No behavior implementation**: These classes *only* declare metadata and identity. Actual navigation logic (e.g., what happens when `Trigger` is clicked) is handled elsewhere (e.g., by a command handler or view model).
|
||||
- **No constructor parameters**: All button instances rely on default property values (`Text`, `Tooltip`, etc.) unless explicitly set post-instantiation.
|
||||
- **No validation on `Text`/`Tooltip`**: Empty or null values are permitted (though UI may fail gracefully or crash depending on consumer).
|
||||
- **Historical quirk**: `HelpButton`’s `Id` being `Dashboard` suggests either a legacy alias or a potential bug—verify intent with domain experts.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,187 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/TSRAIRGo/DataProvider/TabPageItemsProvider.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/DataProvider/DASModelProvider.cs
|
||||
generated_at: "2026-04-16T04:09:05.679293+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "4be2e90923d2ffb5"
|
||||
---
|
||||
|
||||
# DataProvider
|
||||
|
||||
## Documentation: `TabPageItemsProvider` and `DASModelProvider` Modules
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module provides two core data abstraction layers for the **TSRAIRGo** application:
|
||||
- `TabPageItemsProvider` aggregates and filters tab page items from a hierarchical group structure (`TabPageSource.GetGroups("AllGroups")`), returning only those items whose `Content` is a `DataPROPage`.
|
||||
- `DASModelProvider` manages the lifecycle, state, and configuration of Data Acquisition System (DAS) hardware devices—handling discovery (UDP multicast), manual IP entry, connection/disconnection events, and synchronization with the underlying `DASFactory`. It exposes a reactive `ObservableCollection<DASModel>` (`DASSource`) and default configuration values used throughout the application.
|
||||
|
||||
Together, these providers decouple UI navigation (via tab pages) and hardware state management from business logic and view layers.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `ITabPageItemsProvider` Interface
|
||||
- `List<TabPageItem> GetGroupContents()`
|
||||
Returns a flat list of `TabPageItem` objects where each item’s `Content` is a `DataPROPage`. Items are sourced from all groups returned by `TabPageSource.GetGroups("AllGroups")`. If an item’s `Content` is `null`, `item.SetContent()` is invoked before filtering.
|
||||
|
||||
#### `TabPageItemsProvider` Class
|
||||
- Implements `ITabPageItemsProvider`.
|
||||
- `public List<TabPageItem> GetGroupContents()`
|
||||
Same behavior as interface method.
|
||||
|
||||
#### `IDASModelProvider` Interface
|
||||
- `ObservableCollection<DASModel> DASSource { get; }`
|
||||
Read-only collection of `DASModel` instances representing discovered or manually added DAS devices.
|
||||
- `int DefaultSampleRate { get; set; }`
|
||||
Gets or sets the default sample rate (Hz) applied to new `DASModel` instances.
|
||||
- `LevelTriggerArg DefaultLevelTrigger { get; set; }`
|
||||
Gets or sets the default level trigger configuration (e.g., thresholds, axis enable flags) for new devices. Initialized to zero thresholds and all axes disabled.
|
||||
- `void WaitTillScanningDone()`
|
||||
Blocks up to 10 seconds for the current UDP scan task to complete. Logs a warning if timeout occurs.
|
||||
- `double DefaultDuration { get; set; }`
|
||||
Gets or sets the default acquisition duration (seconds) for new `DASModel` instances.
|
||||
|
||||
#### `DASModelProvider` Class
|
||||
- Implements `IDASModelProvider` and inherits `DTS.Common.Base.BasePropertyChanged`.
|
||||
- **Constructors & Initialization**
|
||||
- `public DASModelProvider()`
|
||||
Initializes the provider by:
|
||||
- Loading hardware inclusion/exclusion state from `TSRAIRGoTestSetup`.
|
||||
- Adding included hardware via `AddDAS()`, and marking removed hardware via `RemoveDAS()`.
|
||||
- Subscribing to Prism events (`StartStopDASScanEvent`, `AddDASEvent`, `RemoveDASEvent`, `AppStatusEvent`, `NavigateToDashboardEvent`, `IpAddressToPingEvent`).
|
||||
- Subscribing to `DASFactory` events (`DiscoveredDAS`, `OnDeviceArrived`, `OnFactoryChanged`).
|
||||
- Starting a timer (`TimerCallback`) to periodically check device liveness (`CheckLastSeen`).
|
||||
|
||||
- **Public Methods**
|
||||
- `void WaitTillScanningDone()`
|
||||
Waits for `_scanTask` (UDP scan) to finish, up to 10 seconds.
|
||||
- `private void AddDAS(DASHardware das)`
|
||||
Creates a new `DASModel`, adds it to `DASSource`, and initiates `PingAndConnectDAS()` asynchronously. Skips if a device with same `SerialNumber` or `IPAddress` already exists.
|
||||
- `private void RemoveDAS(int dasId)`
|
||||
Creates a `DASModel` for a removed device (by ID), marks `Included = false`, and adds it to `DASSource`.
|
||||
- `private void InsertDASEntryFromUDP(IDiscoveredDevice autoDiscoveredDAS)`
|
||||
Adds a new device discovered via UDP. Updates hardware metadata (firmware, parent, chain position, etc.), checks reachability (`CheckUnreachableAddress`), and starts connection if `Included`.
|
||||
- `private void InsertDASEntryFromUI(string ipAddress)`
|
||||
Adds a device manually entered via UI. Uses provided IP; no hardware metadata is set.
|
||||
- `private void OnDASScanEvent(bool startStopScan)`
|
||||
Starts/stops UDP multicast scan via `DASFactory.DiscoveryThread()`. Starts timer on start; cancels token and stops timer on stop.
|
||||
- `private void OnAddDASEvent(string serial)`
|
||||
Marks device (by serial) as `Included = true`, adds its IP to `DASFactory.SliceDBHostNames`, and publishes `DASListChangedEvent`.
|
||||
- `private void OnRemoveDASEvent(string serial)`
|
||||
Marks device as `Included = false`, removes its IP from `DASFactory.SliceDBHostNames`, resets status to `UNKNOWN`, and publishes `DASListChangedEvent`.
|
||||
- `private void OnIpAddressToPing(IpAddressToPingArg arg)`
|
||||
Calls `InsertDASEntryFromUI(arg.IpAddress)` to add a device by IP.
|
||||
- `private void OnNavigateToDashboard(NavigateToDashboardArg arg)`
|
||||
Re-adds all currently `Included` devices’ IPs to `DASFactory.SliceDBHostNames` and restarts scanning.
|
||||
- `private void OnAppStatusEvent(AppStatusArg arg)`
|
||||
On `Close`/`Shutdown`, stops scanning and sets `_bShuttingDown = true`.
|
||||
|
||||
- **Private Helpers**
|
||||
- `private void AddDASToDASFactory(DASHardware[] das)`
|
||||
Ensures IPs of included devices are in `DASFactory.SliceDBHostNames`.
|
||||
- `private DASModel CreateDASModel(...)` / `CreateDASModelWithIp(...)`
|
||||
Factory methods to instantiate `DASModel` with defaults (`DefaultSampleRate`, `DefaultLevelTrigger`, `DefaultDuration`) and test setup data.
|
||||
- `private void CheckLastSeen(DASModel das)`
|
||||
Marks device `OFFLINE` if last seen > 20 seconds ago and no TCP connection exists.
|
||||
- `private void CorrectDASEntryFromUDP(...)` / `CorrectDASEntryFromUDPIP(...)`
|
||||
Updates existing entries when new UDP info arrives (e.g., IP/serial mismatch resolution).
|
||||
- `private HardwareTypes GetHardwareType(IDiscoveredDevice discoveredDevice)`
|
||||
Maps `DFConstantsAndEnums.MultiCastDeviceClasses` to `HardwareTypes` (e.g., `Ecm` → `SLICE_EthernetController`).
|
||||
- `private void WarnUnreachableDAS(DASModel das)`
|
||||
Publishes `PageErrorEvent` once per unreachable IP via `PageErrorArg`. Uses `_warnedIPAddresses` to dedupe.
|
||||
- `private void CheckUnreachableAddress(DASModel das)`
|
||||
Uses `NetworkUtils.GetAvailableHosts()` and `PingUtils.EliminateBadHosts()` to detect unreachable IPs; triggers warning if none remain.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **`DASSource` Consistency**
|
||||
- No duplicate `SerialNumber` or `IPAddress` entries exist in `DASSource`.
|
||||
- `DASSource` is thread-safe for reads (via `lock(MyLock)` in getter).
|
||||
- `DASSource.CollectionChanged` triggers `DASListChangedEvent`.
|
||||
|
||||
- **Device State Transitions**
|
||||
- `Status` transitions from `ONLINE` → `OFFLINE` only if `LastSeen` > 20s and no TCP connection.
|
||||
- `Status` transitions to `ONLINE` (from `PING_FAILED`, `OFFLINE`, `CONNECT_FAILED`, `UNKNOWN`) upon successful UDP discovery or TCP connection.
|
||||
- `Included` flag controls whether a device’s IP is added to `DASFactory.SliceDBHostNames`.
|
||||
|
||||
- **UDP Discovery Rules**
|
||||
- If a device is discovered with an IP matching an existing entry *without* a serial, the serial is populated (`CorrectDASEntryFromUDPIP`).
|
||||
- If a device is discovered with a serial matching an existing entry, its metadata (IP, last seen) is updated (`CorrectDASEntryFromUDP`).
|
||||
- If both IP and serial match an existing entry, no duplicate is created.
|
||||
|
||||
- **Default Values**
|
||||
- `DefaultSampleRate`, `DefaultDuration`, and `DefaultLevelTrigger` are applied to *all* new `DASModel` instances.
|
||||
- `DefaultLevelTrigger` initializes with `LevelTriggerText = "0.00"` and all axis flags `false`.
|
||||
|
||||
- **Shutdown Safety**
|
||||
- `_bShuttingDown` prevents new device additions during shutdown.
|
||||
- `WaitTillScanningDone()` blocks only if `_scanTask` is active.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### **Internal Dependencies**
|
||||
- `DataPROWin7.DataModel`
|
||||
- Types: `TabPageItem`, `DataPROPage`, `DASHardware`, `DASModel`, `TSRAIRGoStatus`, `HardwareTypes`, `LevelTriggerArg`.
|
||||
- `DataPROWin7.TSRAIRGo.Model`
|
||||
- Types: `TSRAIRGoTestSetup`.
|
||||
- `DTS.Common.*`
|
||||
- Enums: `DFConstantsAndEnums.MultiCastDeviceClasses`, `Hardware`, `CommunicationResult`.
|
||||
- Interfaces: `IDiscoveredDevice`, `DASHardware`, `ICommunication`.
|
||||
- Utilities: `NetworkUtils`, `PingUtils`, `APILogger`, `StringResources`.
|
||||
- Events: `StartStopDASScanEvent`, `AddDASEvent`, `RemoveDASEvent`, `AppStatusEvent`, `NavigateToDashboardEvent`, `IpAddressToPingEvent`, `PageErrorEvent`, `DASListChangedEvent`.
|
||||
- Base: `BasePropertyChanged`.
|
||||
|
||||
#### **External Dependencies**
|
||||
- `Prism.Ioc` (`ContainerLocator.Container`)
|
||||
- `Prism.Events` (`IEventAggregator`)
|
||||
- `System.Threading.Tasks` (`Task`, `CancellationToken`)
|
||||
- `System.Windows.Application` (`Application.Current`)
|
||||
- `DASFactory` singleton (via `((App)Application.Current).DASFactory`)
|
||||
|
||||
#### **Depended Upon By**
|
||||
- UI layers (e.g., views binding to `DASSource`, tab controls using `TabPageItemsProvider.GetGroupContents()`).
|
||||
- Other providers/services that require DAS configuration or tab navigation data.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **`_scanTask` and `CancellationTokenSource` Lifecycle**
|
||||
- `_scanTask` is a `Task` field; if cancelled, `tokenSource` is disposed and re-instantiated on next scan start. Reusing a disposed token source will throw.
|
||||
- `WaitTillScanningDone()` may timeout silently (logs warning but does not throw).
|
||||
|
||||
- **IP/Serial Deduplication Logic**
|
||||
- `CorrectDASEntryFromUDPIP` removes *old* entries with matching IP but empty serial (see comment referencing case #44357). This may cause unexpected removal of manually entered devices if UDP discovery later provides their serial.
|
||||
|
||||
- **`DASSource` Initialization**
|
||||
- `_dasSource` is lazily initialized in the `DASSource` getter under lock. If accessed before `DASModelProvider` constructor completes, it may be `null` (though unlikely due to Prism DI timing).
|
||||
|
||||
- **`CheckLastSeen` Relies on UDP Scan**
|
||||
- Devices are marked `OFFLINE` only if UDP scanning is active (`_scanTask != null && !IsCompleted`). If scanning is stopped, devices may remain `ONLINE` indefinitely even if unreachable.
|
||||
|
||||
- **`DefaultLevelTrigger` Null-Safety**
|
||||
- `DefaultLevelTrigger.LevelTriggerAxis*` properties are nullable (`bool?`). The provider uses `?? false` to avoid `NullReferenceException`.
|
||||
|
||||
- **`InsertDASEntryFromUI` Does Not Set Hardware Metadata**
|
||||
- Manually entered devices lack `Hardware` details (e.g., serial, firmware) until discovered via UDP or TCP.
|
||||
|
||||
- **No Explicit Cleanup**
|
||||
- `DASModelProvider` does not implement `IDisposable`. Timers, event subscriptions, and `CancellationTokenSource` are not explicitly disposed (reliant on app shutdown).
|
||||
|
||||
- **`TabPageItemsProvider` Mutates Input**
|
||||
- `item.SetContent()` is called *in-place* on items from `TabPageSource`. If `TabPageSource` caches items, this could cause side effects.
|
||||
|
||||
- **`DASFactory` IP Management**
|
||||
- `AddDASToDASFactory` and `OnNavigateToDashboard` directly mutate `SliceDBHostNames` array. If `DASFactory` expects immutable arrays, this may cause race conditions.
|
||||
|
||||
None identified beyond those above.
|
||||
213
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/Interface.md
Normal file
213
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/Interface.md
Normal file
@@ -0,0 +1,213 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/TSRAIRGo/Interface/ISystemSettings.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/Interface/IDASModel.cs
|
||||
generated_at: "2026-04-16T04:08:28.443081+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "94097920c62a32f8"
|
||||
---
|
||||
|
||||
# Interface
|
||||
|
||||
## Documentation Page: TSRAIRGo System Settings & DAS Model Interfaces
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
This module defines core interfaces for managing system-wide configuration and device state in the TSRAIRGo testing framework. Specifically, `ISystemSettings` encapsulates global test parameters (e.g., recording mode, duration, scheduling, event count) and provides methods to synchronize these settings with a `TSRAIRGoTestSetup` object, validate constraints, and manage DAS-level trigger subscriptions. `IDASModel` and its related interfaces (`IDASVoltage`, `IDASProgress`, `IDASLevelTrigger`, `IDevicePresence`) model individual DAS (Data Acquisition System) units, exposing hardware metadata (serial number, firmware, calibration date), operational state (clock master, sample rate), connectivity status, and real-time metrics (voltage, progress, level triggers). Together, these interfaces decouple UI and business logic from concrete implementations, enabling modular, testable integration with DAS hardware and test setup workflows.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `ISystemSettings`
|
||||
- **`AvailableRecordingMode RecordingMode { get; }`**
|
||||
Returns the currently selected recording mode (e.g., continuous, event-triggered). Type `AvailableRecordingMode` is defined in `DataPROWin7.Controls`.
|
||||
|
||||
- **`double Duration { get; }`**
|
||||
Gets the total test duration in seconds.
|
||||
|
||||
- **`string SampleRate { get; }`**
|
||||
Gets the sample rate as a string (e.g., `"1000 Hz"`), likely user-facing formatting.
|
||||
|
||||
- **`int NumberOfEvents { get; }`**
|
||||
Gets the configured number of events to record.
|
||||
|
||||
- **`int Interval { get; }`**
|
||||
Gets the interval (in seconds) between events.
|
||||
|
||||
- **`DateTime ScheduleStartDateTimeUTC { get; }`**
|
||||
Gets the scheduled start time in UTC.
|
||||
|
||||
- **`void SubscribeDASLevelTrigger();`**
|
||||
Registers event handlers or listeners to receive level-triggered events from DAS units.
|
||||
|
||||
- **`void UnSubscribeDASLevelTrigger();`**
|
||||
Removes level-trigger event subscriptions.
|
||||
|
||||
- **`void FromTestSetup(TSRAIRGoTestSetup setup);`**
|
||||
Populates the `ISystemSettings` instance using values from the provided `TSRAIRGoTestSetup` object.
|
||||
|
||||
- **`void ApplyToTestSetup(TSRAIRGoTestSetup setup);`**
|
||||
Writes current `ISystemSettings` values into the provided `TSRAIRGoTestSetup` object.
|
||||
|
||||
- **`void ApplyClockSettingsToTestSetup(TSRAIRGoTestSetup setup);`**
|
||||
Writes only clock-related settings (e.g., `ScheduleStartDateTimeUTC`) to the `TSRAIRGoTestSetup`.
|
||||
|
||||
- **`void EnableSystemSettings(bool enable);`**
|
||||
Enables or disables system settings controls (e.g., UI elements) based on the `enable` flag.
|
||||
|
||||
- **`bool ValidateRTCScheduleStartTime();`**
|
||||
Validates that the scheduled start time (`ScheduleStartDateTimeUTC`) is in the future and conformant to real-time clock constraints. Returns `true` if valid.
|
||||
|
||||
- **`bool ValidateInterval();`**
|
||||
Validates that the `Interval` value meets system requirements (e.g., positive, within bounds). Returns `true` if valid.
|
||||
|
||||
---
|
||||
|
||||
#### `IDASModel`
|
||||
- **`bool Included { get; set; }`**
|
||||
Indicates whether this DAS is included in the current test configuration.
|
||||
|
||||
- **`string IPAddress { get; set; }`**
|
||||
Gets or sets the network address of the DAS.
|
||||
|
||||
- **`string CalDate { get; }`**
|
||||
Gets the calibration date (as a string, e.g., `"2023-05-10"`), likely read-only.
|
||||
|
||||
- **`string Firmware { get; }`**
|
||||
Gets the firmware version string.
|
||||
|
||||
- **`string FirstUseDate { get; }`**
|
||||
Gets the first-use date string.
|
||||
|
||||
- **`string EstimatedRecordingTime { get; }`**
|
||||
Gets the estimated total recording time (e.g., `"02:30:15"`).
|
||||
|
||||
- **`string SerialNumber { get; set; }`**
|
||||
Gets or sets the DAS serial number.
|
||||
|
||||
- **`bool IsClockMaster { get; set; }`**
|
||||
Gets or sets whether this DAS acts as the clock master for synchronization.
|
||||
|
||||
- **`int SampleRate { get; set; }`**
|
||||
Gets or sets the sample rate (numeric value, e.g., `1000`).
|
||||
|
||||
- **`IDASCommunication IDAS { get; set; }`**
|
||||
Gets or sets the communication interface instance for interacting with the DAS hardware.
|
||||
|
||||
- **`string NumberOfEvents { get; set; }`**
|
||||
Gets or sets the number of events (stored as string, possibly for UI binding).
|
||||
|
||||
- **`TSRAIRGoStatus.StatusTypes? Status { get; set; }`**
|
||||
Gets or sets the DAS operational status (nullable enum from `TSRAIRGoStatus.StatusTypes`).
|
||||
|
||||
- **`ICommand RemoveDASCommand { get; set; }`**
|
||||
Gets or sets the WPF `ICommand` for removing this DAS from the test setup.
|
||||
|
||||
- **`ICommand AddDASCommand { get; set; }`**
|
||||
Gets or sets the WPF `ICommand` for adding this DAS to the test setup.
|
||||
|
||||
- **`void PingAndConnectDAS(CancellationToken ct);`**
|
||||
Attempts to ping and establish communication with the DAS, respecting cancellation.
|
||||
|
||||
- **`double Duration { get; set; }`**
|
||||
Gets or sets the test duration for this DAS (in seconds).
|
||||
|
||||
- **`double StatusProgress { get; set; }`**
|
||||
Gets or sets the progress value (0.0–1.0) for status reporting.
|
||||
|
||||
- **`bool ShowStatusProgress { get; set; }`**
|
||||
Gets or sets whether to display the progress indicator.
|
||||
|
||||
---
|
||||
|
||||
#### `IDASVoltage`
|
||||
- **`string BatterySoC { get; }`**
|
||||
Gets the battery state of charge as a string (e.g., `"85%"`).
|
||||
|
||||
- **`string InputVoltageStatus { get; }`**
|
||||
Gets the input voltage status (e.g., `"OK"`, `"LOW"`).
|
||||
|
||||
- **`void RebindVoltage();`**
|
||||
Refreshes or reinitializes voltage-related data bindings.
|
||||
|
||||
---
|
||||
|
||||
#### `IDASProgress`
|
||||
- **`double StatusProgress { get; set; }`**
|
||||
Progress value (0.0–1.0) for status reporting.
|
||||
|
||||
- **`bool ShowStatusProgress { get; set; }`**
|
||||
Controls visibility of the progress indicator.
|
||||
|
||||
> **Note**: `IDASProgress` is a subset of `IDASModel`; likely used where only progress state is needed.
|
||||
|
||||
---
|
||||
|
||||
#### `IDASLevelTrigger`
|
||||
- **`double LevelTriggerMaxValue { get; }`**
|
||||
Gets the maximum threshold value for level triggering.
|
||||
|
||||
- **`double LevelTriggerMinValue { get; }`**
|
||||
Gets the minimum threshold value for level triggering.
|
||||
|
||||
- **`string LevelTriggerText { get; set; }`**
|
||||
Gets or sets a user-facing description of the level trigger (e.g., `"Accel X > 5g"`).
|
||||
|
||||
- **`bool LevelTriggerAxis1 { get; set; }`**
|
||||
Gets or sets whether axis 1 is included in level triggering.
|
||||
|
||||
- **`bool LevelTriggerAxis2 { get; set; }`**
|
||||
Gets or sets whether axis 2 is included.
|
||||
|
||||
- **`bool LevelTriggerAxis3 { get; set; }`**
|
||||
Gets or sets whether axis 3 is included.
|
||||
|
||||
- **`void ResetLevelTriggers(double dNewValue);`**
|
||||
Resets level trigger thresholds to `dNewValue`.
|
||||
|
||||
---
|
||||
|
||||
#### `IDevicePresence`
|
||||
- **`void UpdateLastSeen();`**
|
||||
Updates the `LastSeen` timestamp to the current time.
|
||||
|
||||
- **`DateTime LastSeen { get; set; }`**
|
||||
Gets or sets the last time the device was detected.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- `ISystemSettings.Interval` and `ISystemSettings.NumberOfEvents` must be consistent with `ISystemSettings.Duration` (e.g., `Duration = Interval × NumberOfEvents`), though enforcement occurs only during validation (`ValidateInterval()` and `ValidateRTCScheduleStartTime()`).
|
||||
- `ISystemSettings.ScheduleStartDateTimeUTC` must be in UTC; no conversion is performed internally.
|
||||
- `IDASModel.IsClockMaster` must be `true` for exactly one DAS in a multi-DAS test setup (enforced by higher-level logic, not the interface).
|
||||
- `IDASModel.StatusProgress` and `IDASModel.ShowStatusProgress` are intended for UI binding; values are not validated by the interface.
|
||||
- `IDevicePresence.LastSeen` is updated only via `UpdateLastSeen()`; direct assignment is allowed but discouraged.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
- **Depends on**:
|
||||
- `DataPROWin7.Controls` (for `AvailableRecordingMode`)
|
||||
- `DTS.Common` (for `TSRAIRGoTestSetup`, `TSRAIRGoStatus.StatusTypes`)
|
||||
- `System` (core types: `DateTime`, `ICommand`, `CancellationToken`)
|
||||
- `System.Windows.Input` (for `ICommand`)
|
||||
|
||||
- **Depended on by**:
|
||||
- UI layers (e.g., WPF views/viewmodels) that bind to `IDASModel` properties (`IPAddress`, `SerialNumber`, `StatusProgress`, etc.)
|
||||
- Test orchestration logic that uses `ISystemSettings` to configure and validate `TSRAIRGoTestSetup` instances
|
||||
- DAS communication modules implementing `IDASCommunication` (referenced via `IDASModel.IDAS`)
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
- **`SampleRate` type mismatch**: `ISystemSettings.SampleRate` is `string`, while `IDASModel.SampleRate` is `int`. Conversion logic (e.g., parsing `"1000 Hz"` → `1000`) is not defined in these interfaces and must be handled by implementations.
|
||||
- **`NumberOfEvents` inconsistency**: `ISystemSettings.NumberOfEvents` is `int`, but `IDASModel.NumberOfEvents` is `string`. This suggests legacy UI binding requirements; implementations must ensure synchronization.
|
||||
- **`ApplyClockSettingsToTestSetup` vs `ApplyToTestSetup`**: The former likely writes only time-related fields (e.g., `ScheduleStartDateTimeUTC`), while the latter writes all settings. Confusing naming; verify implementation behavior.
|
||||
- **`ValidateRTCScheduleStartTime`**: No indication of tolerance (e.g., minimum future offset). Implementation may assume real-time clock constraints (e.g., ≥ 1 second ahead).
|
||||
- **`IDevicePresence` is minimal**: Only tracks last-seen time; no heartbeat or liveness logic is exposed here.
|
||||
- **No error handling in interface**: Methods like `PingAndConnectDAS` or `ValidateInterval` do not declare exceptions; implementations may throw or return `false` on failure.
|
||||
|
||||
None identified beyond the above.
|
||||
169
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/Model.md
Normal file
169
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/Model.md
Normal file
@@ -0,0 +1,169 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/TSRAIRGo/Model/VoltageStatus.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/Model/DASModel.cs
|
||||
generated_at: "2026-04-16T04:09:38.814473+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "bba78989eaa13b3a"
|
||||
---
|
||||
|
||||
# `DASModel` Documentation
|
||||
|
||||
## 1. Purpose
|
||||
`DASModel` is a core data model class in the TSRAIRGo module that encapsulates state, configuration, and hardware interaction for a single Data Acquisition System (DAS) unit. It serves as the bridge between the UI and low-level DAS hardware communication, managing properties such as serial number, IP address, calibration date, firmware version, sample rate, recording time estimates, battery state of charge (SoC), and DAS status (e.g., `PINGING`, `CONNECTED`, `RECORDING`). It implements several interfaces (`IDASModel`, `IDevicePresence`, `IDASVoltage`, `IDASProgress`, `IDASLevelTrigger`, `IComparable<DASModel>`) to support data binding, command handling, and ordering in UI components. The class also provides methods to perform hardware operations like pinging, querying configuration, retrieving arm status, and refreshing voltage diagnostics.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Constructors
|
||||
- **`DASModel()`**
|
||||
Initializes a new instance with default values, registers `RemoveDASCommand` and `AddDASCommand` as WPF class command bindings, and resolves `IEventAggregator` via `ContainerLocator.Container`.
|
||||
|
||||
### Properties
|
||||
- **`double Duration`**
|
||||
Gets or sets the duration (in seconds) of each event. Changing this property raises `OnPropertyChanged` for `"NumberOfEvents"`.
|
||||
|
||||
- **`bool Included`**
|
||||
Gets or sets whether this DAS is included in the current test setup.
|
||||
|
||||
- **`string IPAddress`**
|
||||
Gets or sets the network IP address of the DAS.
|
||||
|
||||
- **`string CalDate`**
|
||||
Returns the formatted calibration date (`Hardware.CalDate.ToShortDateString()`), or `string.Empty` if `Hardware` is null, `CalDate` is null, or equals `DASDBRecord.INVALID_DATE`.
|
||||
|
||||
- **`string Firmware`**
|
||||
Returns `Hardware.Firmware`, or `string.Empty` if `Hardware` is null.
|
||||
|
||||
- **`string FirstUseDate`**
|
||||
Returns formatted first-use date (`"d"` format), or `"N/A"` if `Hardware.IsFirstUseValid` is false or `Hardware.FirstUseDate` is null.
|
||||
|
||||
- **`DASHardware Hardware`**
|
||||
Gets or sets the underlying hardware object. On set, copies module/chain/distributor position metadata from old to new hardware (see *Gotchas*), and raises property change notifications for `"CalDate"`, `"Firmware"`, `"FirstUseDate"`, and `"EstimatedRecordingTime"`.
|
||||
|
||||
- **`string EstimatedRecordingTime`**
|
||||
Returns a formatted string (e.g., `"2h 15m"`) representing the minimum of battery-based and memory-based remaining recording time, or `"N/A"` if unavailable.
|
||||
|
||||
- **`string SerialNumber`**
|
||||
Gets the serial number from `Hardware.SerialNumber`, or falls back to `_serialNumber` or `IPAddress` if `Hardware` is null. Setting only updates `_serialNumber` when `Hardware` is null.
|
||||
|
||||
- **`bool IsClockMaster`**
|
||||
Gets or sets whether this DAS acts as the clock master.
|
||||
|
||||
- **`int SampleRate`**
|
||||
Gets or sets the sample rate (Hz). Valid values are defined in `AvailableSampleRates`. Changing this raises property change notifications for `"SampleRate"`, `"EstimatedRecordingTime"`, `"NumberOfEvents"`, and publishes a `DASSampleRateChangedEvent`.
|
||||
|
||||
- **`IDASCommunication IDAS`**
|
||||
Gets or sets the communication interface to the DAS hardware.
|
||||
|
||||
- **`TSRAIRGoStatus.StatusTypes? Status`**
|
||||
Gets or sets the current DAS status. Setting this raises property change notifications for `"Status"`, `"StatusBrush"`, `"PrimaryPowerStatus"`, `"PrimaryPowerStatusColor"`, `"BackupBatteryStatus"`, `"BackupBatteryStatusColor"`, `"AvailableSampleRates"`, `"NumberOfEvents"`, `"BatterySoC"`, and `"EstimatedRecordingTime"`. Special handling ignores `CONNECT_FAILED` if current status is `REBOOTING`.
|
||||
|
||||
- **`double StatusProgress`**
|
||||
Gets or sets the progress percentage (0–100) for operations like ping/query.
|
||||
|
||||
- **`bool ShowStatusProgress`**
|
||||
Gets or sets whether to show the progress bar in the UI.
|
||||
|
||||
- **`int[] AvailableSampleRates`**
|
||||
Read-only array of supported sample rates: `{100, 500, 1000, 5000, 10000, 15000, 20000}`.
|
||||
|
||||
- **`string BatterySoC`**
|
||||
Returns battery state of charge as a percentage string (e.g., `"87%"`). Uses `IDAS.BaseInput.BatterySoC` if available; otherwise estimates from `IDAS.BaseInput.BatteryVoltage` via `GetSoCFromBatteryV()`.
|
||||
|
||||
- **`string InputVoltageStatus`**
|
||||
Returns the input voltage as a string with `"V"` suffix (e.g., `"12.4V"`), or `"N/A"` if `IDAS` or `IDAS.BaseInput` is null.
|
||||
|
||||
- **`string NumberOfEvents`**
|
||||
Gets or sets the number of events recorded as a string in `"X/Y"` format, where `Y` is computed by `GetMaxEvents()`.
|
||||
|
||||
- **`double LevelTriggerMaxValue` / `double LevelTriggerMinValue`**
|
||||
Computed thresholds for level triggers based on `SerializedSettings.LevelTriggerMaxPercentage` and `SensorConstants.DefaultRangeHiG`/`DefaultRangeLowG`.
|
||||
|
||||
- **`string LevelTriggerText`**
|
||||
Gets/sets the level trigger magnitude (in `g`). Setter clamps value between `LevelTriggerMinValue` and `LevelTriggerMaxValue`, raises `OnPropertyChanged`, and publishes `DASLevelTriggerChangedEvent`.
|
||||
|
||||
- **`bool LevelTriggerAxis1/2/3`**
|
||||
Gets/sets whether level triggering is enabled for each axis. Each setter publishes `DASLevelTriggerChangedEvent`.
|
||||
|
||||
- **`ICommand RemoveDASCommand` / `ICommand AddDASCommand`**
|
||||
WPF commands that publish `RemoveDASEvent` or `AddDASEvent` with the DAS serial number.
|
||||
|
||||
- **`DateTime LastSeen`**
|
||||
Gets or sets the last time the DAS was observed active.
|
||||
|
||||
### Methods
|
||||
- **`int CompareTo(DASModel b)`**
|
||||
Implements `IComparable<DASModel>`. Prioritizes `Included` DASes, then compares `Hardware` (if present) or `SerialNumber`.
|
||||
|
||||
- **`void RebindVoltage()`**
|
||||
Manually raises property change notifications for all voltage/status-related properties.
|
||||
|
||||
- **`void UpdateEventCount(RecordingModes, DateTime)`**
|
||||
Updates `NumberOfEvents` based on `IDAS.EventInfo` or `IDAS.DASArmStatus.EventNumber`, applying firmware-specific logic (e.g., adding 1 for older firmware in interval mode after scheduled start time). See *Gotchas* for known issues.
|
||||
|
||||
- **`void PingAndConnectDAS(CancellationToken)`**
|
||||
Orchestrates ping → query → voltage refresh → arm status retrieval sequence. Sets `StatusProgress`, `ShowStatusProgress`, and updates `Status` at each stage.
|
||||
|
||||
- **`void QueryConfig(List<IDASCommunication>, bool, bool, CancellationToken, int)`**
|
||||
Queries DAS configuration via `ConfigurationService`. Updates `Hardware` and `IDAS` on success, sets `Status` to `ONLINE`.
|
||||
|
||||
- **`void RefreshVoltageStatus(CancellationToken)`**
|
||||
Calls `DiagnosticsService.PerformVoltageCheck` and raises `OnPropertyChanged` for `"BatterySoC"` and `"InputVoltageStatus"`.
|
||||
|
||||
- **`void GetArmStatus(CancellationToken)`**
|
||||
Calls `ArmingService.GetArmStatus` to fetch current arm state.
|
||||
|
||||
- **`void UpdateLastSeen()`**
|
||||
Sets `LastSeen` to `DateTime.Now`.
|
||||
|
||||
- **`bool FromTestSetup(TSRAIRGoTestSetup)`**
|
||||
Updates `Hardware`, `SampleRate`, and level trigger settings from a `TSRAIRGoTestSetup` instance. Returns `true` if the DAS should be included in the test.
|
||||
|
||||
### Command Classes
|
||||
- **`RemoveDASCommandClass` / `AddDASCommandClass`**
|
||||
Implement `ICommand`. On execution, publish `RemoveDASEvent`/`AddDASEvent` with the DAS serial number. Log errors via `PageErrorEvent`.
|
||||
|
||||
## 3. Invariants
|
||||
- **`Hardware` metadata preservation**: When `Hardware` is reassigned, module/chain/distributor position metadata is copied from the old instance to the new one (see *Gotchas* for caveats).
|
||||
- **`SerialNumber` fallback chain**: If `Hardware` is null, `SerialNumber` falls back to `_serialNumber`, then `IPAddress`.
|
||||
- **`CalDate` invalid handling**: Returns `string.Empty` for invalid calibration dates (`null`, `DASDBRecord.INVALID_DATE`).
|
||||
- **`FirstUseDate` invalid handling**: Returns `"N/A"` if `Hardware.IsFirstUseValid` is false or `Hardware.FirstUseDate` is null.
|
||||
- **`EstimatedRecordingTime` logic**: Always uses `Math.Min(batteryTime, memoryTime)` for remaining time.
|
||||
- **`BatterySoC` fallback**: Uses `IDAS.BaseInput.BatterySoC` if available; otherwise estimates from voltage using `GetSoCFromBatteryV()`.
|
||||
- **`NumberOfEvents` clamping**: Computed event count is capped at `Properties.Settings.Default.TSRAIRGo_DefaultNumberOfEvents`.
|
||||
- **`LevelTriggerText` clamping**: Setter enforces value is within `[LevelTriggerMinValue, LevelTriggerMaxValue]`.
|
||||
- **`Status` transition guard**: Ignores `CONNECT_FAILED` status updates if current status is `REBOOTING`.
|
||||
- **`SampleRate` change event**: Publishing `DASSampleRateChangedEvent` is unconditional on change.
|
||||
- **`RebindVoltage()` scope**: Only updates properties related to voltage/status; does not trigger hardware communication.
|
||||
|
||||
## 4. Dependencies
|
||||
### External Dependencies
|
||||
- **`DTS.Common.*`**: Core shared libraries (e.g., `DTS.Common.Base`, `DTS.Common.Events`, `DTS.Common.Interface.DASFactory`, `DTS.Common.DataModel.Classes.TSRAIRGo`, `DTS.Common.Enums.Sensors`, `DTS.Common.Classes.Hardware`).
|
||||
- **`DTS.DASLib.Service`**: Services for configuration (`ConfigurationService`), diagnostics (`DiagnosticsService`), and arming (`ArmingService`).
|
||||
- **`DTS.SensorDB`**: Contains `DASHardware`, `DASDBRecord`, `SensorConstants`, `SerializedSettings`.
|
||||
- **`Prism.*`**: Prism MVVM framework (`IEventAggregator`, `IContainerRegistry`, `ContainerLocator`).
|
||||
- **WPF types**: `System.Windows`, `System.Windows.Input`, `System.Windows.Media`.
|
||||
- **`DTS.Common.SharedResource.Strings`**: String resources (e.g., `StringResources.Table_NA`).
|
||||
- **`DTS.Common.Utilities.Logging`**: `APILogger`.
|
||||
- **`DataPROWin7.*`**: Internal types (`DataPROWin7.Controls`, `DataPROWin7.DataModel`, `DataPROWin7.SubControls`, `DataPROWin7.TSRAIRGo.Interface`).
|
||||
|
||||
### Dependencies on This Module
|
||||
- **`VoltageStatus`**: Used to expose primary power/backup battery status and colors (see `PrimaryPowerStatus`, `BackupBatteryStatus`, etc.).
|
||||
- **`RemoveDASCommandClass`/`AddDASCommandClass`**: Command classes used by UI to trigger DAS removal/addition.
|
||||
- **`DASModel` is consumed by**:
|
||||
- UI controls (e.g., `HardwareDiscoveryControl`, `EditTestSetupInfoControl`) via data binding.
|
||||
- Event handlers for `DASSampleRateChangedEvent`, `DASLevelTriggerChangedEvent`, `RemoveDASEvent`, `AddDASEvent`.
|
||||
- `DASFactory` (via `IDASCommunication` and `DASHardware`).
|
||||
|
||||
## 5. Gotchas
|
||||
- **`Hardware` metadata copy logic is inverted**: In the `Hardware` setter, the comment notes: *“note this looks backwards but the code was already here…”*. The assignment `value.SetIsModule(_hardware.IsModule())` copies metadata *from the old hardware to the new one*, which is counterintuitive but appears intentional.
|
||||
- **`NumberOfEvents` firmware bug**: For older firmware (< protocol version 35), `UpdateEventCount` incorrectly adds 1 to `EventNumber` when in interval mode *after* the scheduled start time—even if the DAS uses local time instead of UTC. This results in displaying `"1"` when it should be `"0"`. A firmware update is required to fix.
|
||||
- **`CalDate` and `FirstUseDate` return empty strings for invalid dates**: This may cause UI layout shifts if not handled with consistent placeholder text.
|
||||
- **`EstimatedRecordingTime` uses `double.MaxValue` for infinite time**: When battery/memory time is unavailable, `double.MaxValue` is used, which may cause formatting issues if not handled (e.g., `TimeSpan.FromSeconds(double.MaxValue)`).
|
||||
- **`BatterySoC` estimation is linear**: `GetSoCFromBatteryV()` assumes a linear relationship between voltage and SoC between `MIN_BATTERY_VOLTAGE` (2.98V) and `MAX_BATTERY_VOLTAGE` (4.2V). This may not reflect real battery behavior.
|
||||
- **`QueryDAS` thread-safety via lock**: A static lock (`_queryDASLock`) is used to prevent concurrent modification of `SDBHostNames`. This could become a bottleneck under high concurrency.
|
||||
- **`PingAndConnectDAS` uses `Thread.Sleep`**: Hardcoded delays (`150ms`) are used to allow UI updates between stages. This is not cancellation-aware and may cause delays in shutdown.
|
||||
- **`StatusBrush` mapping is exhaustive**: The `_statusToBrush` dictionary covers all `TSRAIRGoStatus.StatusTypes` values, but missing entries would default to `Brush_ApplicationStatus_Idle`.
|
||||
- **`LevelTriggerText` setter ignores invalid input**: If `double.TryParse` fails, the value is not updated and no error is raised.
|
||||
- **`FromTestSetupLevelTrigger` uses channel index mapping**: Axis assignment (e.g., channel 0/3 → Axis1) is hardcoded and may not generalize to all hardware configurations.
|
||||
82
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/View.md
Normal file
82
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/View.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/TSRAIRGo/View/GoMainWindow.xaml.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/View/Dashboard.xaml.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/View/SystemStatus.xaml.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/View/Navigation.xaml.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/View/SystemSettings.xaml.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/View/DASTable.xaml.cs
|
||||
generated_at: "2026-04-16T04:09:29.193668+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "1df2e4a4c362fbd2"
|
||||
---
|
||||
|
||||
# View
|
||||
|
||||
## Documentation: TSRAIRGo View Layer – `DataPROWin7.TSRAIRGo` Namespace
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module provides the WPF UI view layer for the TSRAIRGo application, implementing a set of `UserControl`-based views that serve as the primary presentation units for core functional areas: main window, dashboard, system status, navigation, system settings, and DAS (Data Acquisition System) table. Each view is tightly coupled to its corresponding ViewModel via Prism’s `DataContext` binding and Unity container resolution, enforcing a clean separation of concerns while relying on dependency injection for lifecycle and configuration management. The module does not contain business logic itself but orchestrates UI rendering, user input handling, and event subscription (e.g., `ClearIpAddressEvent`) for reactive behavior.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
All classes are `public partial class`es inheriting from `UserControl`. No public methods or properties beyond those defined by WPF (`ContentControl`, `Loaded` event, etc.) are exposed.
|
||||
|
||||
| Type | Signature | Behavior |
|
||||
|------|-----------|----------|
|
||||
| `GoMainWindow` | `public GoMainWindow()` | Initializes the main window view. Resolves `GoMainWindowViewModel` via Unity and assigns it to `DataContext`. Calls `InitializeComponent()` first. |
|
||||
| `Dashboard` | `public Dashboard()` | Initializes the dashboard view. Resolves `DashboardViewModel` via Unity, stores it in a private readonly field, and assigns to `DataContext`. |
|
||||
| `SystemStatus` | `public SystemStatus()` | Initializes the system status view. Resolves `SystemStatusViewModel` via Unity, stores in private readonly field, and assigns to `DataContext`. |
|
||||
| `Navigation` | `public Navigation()`<br>`public ContentControl ContentControl { get; set; }` | Initializes the navigation view. Resolves `NavigationViewModel`, stores in private readonly field, assigns to `DataContext`. Subscribes to `Loaded` event to invoke `_viewModel.Load()` on first load. Exposes a `ContentControl` property (likely used for content region hosting, though usage not visible in source). |
|
||||
| `SystemSettings` | `public SystemSettings()`<br>`private void NumberValidationTextBox(object sender, TextCompositionEventArgs e)`<br>`private void NumberIntValidationTextBox(object sender, TextCompositionEventArgs e)` | Initializes the system settings view. Resolves `SystemSettingsViewModel`, stores in private readonly field, assigns to `DataContext`. Provides two private event handlers for input validation: `NumberValidationTextBox` delegates to `ViewHelper.ValidateFloatOnlyTextBox`, and `NumberIntValidationTextBox` delegates to `ViewHelper.ValidateIntegerOnlyTextBox`. |
|
||||
| `DASTable` | `public DASTable()`<br>`private void IsClockMaster_Click(object sender, RoutedEventArgs e)`<br>`private void ShowAllToggleButton_Click(object sender, RoutedEventArgs e)`<br>`private void ShowModeToggleButton_Click(object sender, RoutedEventArgs e)`<br>`private void NumberValidationTextBox(object sender, TextCompositionEventArgs e)`<br>`public void OnClearIpAddress(ClearIpAddressArg clearIp)` | Initializes the DAS table view. Resolves `DASTableViewModel` and `IEventAggregator` via Unity. Subscribes to `ClearIpAddressEvent` to clear the `newIpAddress` control. Provides click handlers for UI interactions: `IsClockMaster_Click` enforces mutual exclusivity of `IsClockMaster` across DAS entries; `ShowAllToggleButton_Click` and `ShowModeToggleButton_Click` toggle button label text based on `IsChecked` state using `Strings` constants. `NumberValidationTextBox` delegates to `ViewHelper.ValidateFloatOnlyTextBox`. `OnClearIpAddress` clears the `newIpAddress` control when a `ClearIpAddressArg` with `Clear == true` is received. |
|
||||
|
||||
> **Note**: All view classes rely on `ContainerLocator.Container` (from `Prism.Ioc`) to resolve the Unity container (`IUnityContainer`). No direct instantiation of ViewModels occurs outside of container resolution.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **ViewModel Resolution**: Every view *must* resolve its ViewModel from the Unity container via `ContainerLocator.Container.Resolve<T>()`. No fallback or manual instantiation is present.
|
||||
- **DataContext Assignment**: Each view assigns its resolved ViewModel to `DataContext` *after* `InitializeComponent()` (except `Navigation`, which does so before `Loaded` subscription, but still before `Loaded` fires).
|
||||
- **ViewModel Lifecycle**: ViewModels are resolved per-view instance (no singleton sharing implied by code); lifetime management is handled by the Unity container configuration (not visible here).
|
||||
- **Event Subscription**: `DASTable` subscribes to `ClearIpAddressEvent` on construction and does not unsubscribe — potential memory leak if `DASTable` instances are long-lived and numerous.
|
||||
- **Input Validation**: Text input validation is implemented via event handlers attached to `TextCompositionEventArgs`, delegating to `ViewHelper` methods — no validation logic is embedded in the views themselves.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
| Dependency | Usage | Inferred From |
|
||||
|-----------|-------|---------------|
|
||||
| `Prism.Ioc`, `Unity` | Container resolution (`ContainerLocator.Container`, `IUnityContainer`) | All files |
|
||||
| `DataPROWin7.TSRAIRGo.ViewModel.*` | ViewModel types (`GoMainWindowViewModel`, `DashboardViewModel`, etc.) | All files |
|
||||
| `System.Windows.Controls`, `System.Windows` | WPF base types (`UserControl`, `ContentControl`, `RoutedEventArgs`) | All files |
|
||||
| `DataPROWin7.TSRAIRGo.DataProvider` | `Navigation` imports namespace (but no types used in visible code) | `Navigation.xaml.cs` |
|
||||
| `DTS.Common.Interface` | `IEventAggregator` interface | `DASTable.xaml.cs` |
|
||||
| `DTS.Common.Events.TSRAIRGo` | `ClearIpAddressEvent`, `ClearIpAddressArg` | `DASTable.xaml.cs` |
|
||||
| `DTS.Common.Strings` | `Strings.ShowAll`, `Strings.OnlyIncluded`, `Strings.ShowMore`, `Strings.ShowLess` | `DASTable.xaml.cs` |
|
||||
| `DataPROWin7.TSRAIRGo.Classes` | `ViewHelper`, `SystemSettings` imports namespace | `SystemSettings.xaml.cs`, `DASTable.xaml.cs` |
|
||||
| `DataPROWin7.TSRAIRGo.Model` | `DASModel` type used in `IsClockMaster_Click` | `DASTable.xaml.cs` |
|
||||
|
||||
**Dependents (inferred)**:
|
||||
- These views are likely hosted by a parent window or shell (e.g., `tsrAirGoMainWindow.xaml` hosts `GoMainWindow`), and navigation logic (e.g., `NavigationViewModel`) likely uses `ContentControl` to switch views — though host/shell code is not included here.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **Event Subscription Leak in `DASTable`**: The `ClearIpAddressEvent` subscription is never unsubscribed. If `DASTable` instances are frequently created/destroyed (e.g., in a tabbed interface), this may cause stale handlers to accumulate and trigger on obsolete instances.
|
||||
- **Ambiguous `ContentControl` Usage in `Navigation`**: The `ContentControl` property is declared but never initialized or assigned in the constructor. Its purpose is unclear — possibly intended for Prism region injection, but no Prism `RegionManager` usage is visible.
|
||||
- **`Loaded` Event Dependency in `Navigation`**: `_viewModel.Load()` is called only on the first `Loaded` event. If the control is unloaded/reloaded (e.g., tab switching), `Load()` will not be called again — behavior may be unintended if re-initialization is required.
|
||||
- **`NumberValidationTextBox` Overload Ambiguity**: Both `SystemSettings` and `DASTable` define identical `NumberValidationTextBox` handlers. If XAML names these handlers identically (e.g., `NumberValidationTextBox`), conflicts may arise if controls are reused or merged — though each view is self-contained, this could cause confusion during maintenance.
|
||||
- **No Null Checks on Container Resolution**: All views resolve dependencies without null checks. If the container is misconfigured or unavailable, `Resolve<T>()` may throw — behavior is not handled in code.
|
||||
- **`IsClockMaster_Click` Mutability Assumption**: The handler assumes `_viewModel.DASModelSource` contains mutable `DASModel` instances and that setting `das.IsClockMaster = false` triggers change notifications (e.g., via `INotifyPropertyChanged`). This is not verified in the view code — correctness depends on ViewModel implementation.
|
||||
|
||||
> **None identified from source alone** for other areas (e.g., no obvious threading issues, no hardcoded paths, no deprecated APIs).
|
||||
224
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/ViewModel.md
Normal file
224
enriched-qwen3-coder-next/DataPRO/DataPRO/TSRAIRGo/ViewModel.md
Normal file
@@ -0,0 +1,224 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/TSRAIRGo/ViewModel/DashboardViewModel.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/ViewModel/SystemStatusViewModel.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/ViewModel/GoMainWindowViewModel.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/ViewModel/NavigationViewModel.cs
|
||||
- DataPRO/DataPRO/TSRAIRGo/ViewModel/SystemSettingsViewModel.cs
|
||||
generated_at: "2026-04-16T04:08:28.921820+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "5c829fcaf086124c"
|
||||
---
|
||||
|
||||
# ViewModel
|
||||
|
||||
**Documentation: TSRAIRGo ViewModels Module**
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
This module provides the MVVM-layer view models for the TSRAIRGo application component within the DataPROWin7 system. Its purpose is to encapsulate UI state, coordinate data flow between views and underlying services (via Prism event aggregation and Unity dependency injection), and manage navigation and system configuration logic for the TSRAIRGo workflow. It acts as the intermediary layer between the UI (views) and the domain/data layers, handling user interactions, system state transitions (e.g., start/stop DAS scanning, state machine), and real-time updates (e.g., system status, settings). The module supports dashboard navigation, system status display, system settings configuration, and navigation button management.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `DashboardViewModel`
|
||||
- **Namespace**: `DataPROWin7.TSRAIRGo.ViewModel`
|
||||
- **Inherits**: `DTS.Common.Base.BasePropertyChanged`
|
||||
- **Constructor**: `DashboardViewModel()`
|
||||
- No-op constructor; no initialization logic.
|
||||
- **Properties**: None defined in source.
|
||||
|
||||
#### `SystemStatusViewModel`
|
||||
- **Namespace**: `DataPROWin7.TSRAIRGo.ViewModel`
|
||||
- **Inherits**: `DTS.Common.Base.BasePropertyChanged`
|
||||
- **Constructor**: `SystemStatusViewModel()`
|
||||
- Resolves `IEventAggregator` from `ContainerLocator.Container`.
|
||||
- Subscribes to `SystemStatusEvent` → `OnStatusReceived`.
|
||||
- Subscribes to `SystemErrorEvent` → `OnErrorReceived`.
|
||||
- **Properties**:
|
||||
- `string Message`: Gets/sets the current system status message; raises `OnPropertyChanged("Message")`.
|
||||
- `string Error`: Gets/sets the current system error message; raises `OnPropertyChanged("Error")`.
|
||||
- **Methods**:
|
||||
- `private void OnStatusReceived(SystemStatusArg arg)`: Sets `Message = arg?.Message`.
|
||||
- `private void OnErrorReceived(SystemErrorArg arg)`: Sets `Error = arg?.Error`.
|
||||
|
||||
#### `GoMainWindowViewModel`
|
||||
- **Namespace**: `DataPROWin7.TSRAIRGo.ViewModel`
|
||||
- **Inherits**: `DTS.Common.Base.BasePropertyChanged`
|
||||
- **Constructor**: `GoMainWindowViewModel()`
|
||||
- Resolves `IEventAggregator`.
|
||||
- Subscribes to `NavigateToDashboardEvent` → `OnNavigateToDashboard`.
|
||||
- **Properties**:
|
||||
- `object ContentValue`: Gets/sets the main content area (e.g., `Dashboard` instance); raises `OnPropertyChanged("ContentValue")`.
|
||||
- `object NavigationValue`: Gets/sets the navigation control instance (e.g., `Navigation`); raises `OnPropertyChanged("NavigationValue")`.
|
||||
- **Fields**:
|
||||
- `private Dashboard _tSRAIRGoDashboard`: Lazy-initialized singleton instance of `Dashboard`.
|
||||
- **Methods**:
|
||||
- `private void OnNavigateToDashboard(NavigateToDashboardArg obj)`:
|
||||
- Resolves `Dashboard`, `Navigation`, and `NavigationViewModel` from Unity container.
|
||||
- Sets `ContentValue` to `_tSRAIRGoDashboard`, `NavigationValue` to `Navigation`.
|
||||
- Enables `ViewData`, `ExportData`, and disables `Dashboard` buttons via `NavigationViewModel.EnableButton(...)`.
|
||||
- Publishes `StartStopDASScanEvent(true)` and `StartStopOverallStatusStateMachineEvent(true)` to resume system scanning/state machine.
|
||||
|
||||
#### `NavigationViewModel`
|
||||
- **Namespace**: `DataPROWin7.TSRAIRGo.ViewModel`
|
||||
- **Inherits**: `DTS.Common.Base.BasePropertyChanged`
|
||||
- **Constructor**: `NavigationViewModel(ITabPageItemsProvider tabPageItemsProvider)`
|
||||
- Initializes `NavigationButtonsInfo` dictionary via `InitializeNavigationButtonsInfo()`.
|
||||
- Resolves `IEventAggregator`, `IUnityContainer`, `GoMainWindowViewModel`, and `IHamburgerMenuViewModel`.
|
||||
- Initializes commands via `InitializeCommands()`.
|
||||
- **Properties**:
|
||||
- `List<TabPageItem> TabPageItems`: Populated via `Load()` using `_tabPageItemsProvider.GetGroupContents()`.
|
||||
- `Dictionary<NavigationButtonId, INavigationButtonInfo> NavigationButtonsInfo`: Stores button metadata (enabled state, text, tooltip, border visibility).
|
||||
- `string TestId`: Gets/sets test ID; raises `OnPropertyChanged("TestId")`.
|
||||
- **Commands** (all `DelegateCommand`):
|
||||
- `HelpCommand`, `ArmDisarmCommand`, `TriggerCommand`, `NavigateToDownloadCommand`, `NavigateToViewDataCommand`, `NavigateToExportDataCommand`, `NavigateToDashboardCommand`.
|
||||
- **Navigation Methods**:
|
||||
- `void UpdateNavigationButtonInfo(INavigationButtonInfo navigationButtonInfo)`: Updates existing button info by ID.
|
||||
- `void UpdateNavigationButtonsInfo(IEnumerable<INavigationButtonInfo>)`: Bulk update of button info.
|
||||
- `void EnableHamburgerMenu(bool enable)`: Calls `_hamburgerMenuViewModel.EnableMenu(enable)`.
|
||||
- `void EnableButton(NavigationButtonId id, bool enable)`: Sets `NavigationButtonsInfo[id].Enabled`.
|
||||
- `void ChangeTextButton(NavigationButtonId id, string text, string tooltip)`: Updates `Text` and `Tooltip`.
|
||||
- `void ShowBorder(NavigationButtonId id, bool show)`: Sets `ShowBorder`; marshals to UI thread if needed.
|
||||
- `void Load()`: Populates `TabPageItems`.
|
||||
- `void SetContent(DataPROPage page)`: Sets `ContentValue` on `GoMainWindowViewModel`.
|
||||
- `void GoToExportData()`: Invokes `NavigateToExportData()`.
|
||||
- `bool KeyDown(object sender, KeyEventArgs e)`: Delegates key event to current `DataPROPage`’s `KeyUp` method (note: method name mismatch in source — likely typo).
|
||||
- **Command Implementations**:
|
||||
- `Help()`: Launches `Manuals/TSR AIR Go Quick Start Guide (10920-04040-APN).pdf`; logs and shows message box on failure.
|
||||
- `ArmDisarm()`: Publishes `ArmEvent(new ArmArg())`.
|
||||
- `Trigger()`: Publishes `TriggerEvent(new TriggerArg())`.
|
||||
- `Download()`: Publishes `DTS.Common.Events.TSRAIRGo.DownloadEvent(new DownloadArg())`.
|
||||
- `NavigateToDownload()`:
|
||||
- Conditionally (via `#if _DOWNLOAD_USING_NAVIGATE_TO`) navigates to download tab or invokes `Download()`.
|
||||
- Disables `ArmDisarm`, `Trigger`, `Download`, `ViewData`, `ExportData` buttons; conditionally toggles `Dashboard`.
|
||||
- `NavigateToViewData()`: Finds tab item with `UniqueId == TileUniqueIDs.Review_ViewData.ToString()`, navigates, disables navigation buttons except `ExportData` and `Dashboard`.
|
||||
- `NavigateToExportData()`: Finds tab item with `UniqueId == TileUniqueIDs.Review_ExportData.ToString()`, calls `SetExporting(false)` and publishes `ClearSelectedExportsEvent`, navigates, enables `ViewData`, disables others.
|
||||
- `NavigateToDashboard()`: Publishes `NavigateToDashboardEvent(new NavigateToDashboardArg())`.
|
||||
- **Private Helpers**:
|
||||
- `void NavigateToContent(TabPageItem tabItem)`:
|
||||
- Unsets `_lastPageVisited` (calls `UnSet()`).
|
||||
- Publishes `StartStopDASScanEvent(false)` and `StartStopOverallStatusStateMachineEvent(false)`.
|
||||
- Sets `ContentValue`, calls `page.OnSetActive()`, stores `_lastPageVisited`.
|
||||
|
||||
#### `SystemSettingsViewModel`
|
||||
- **Namespace**: `DataPROWin7.TSRAIRGo.ViewModel`
|
||||
- **Inherits**: `DTS.Common.Base.BasePropertyChanged`, implements `ISystemSettings`
|
||||
- **Constructor**: `SystemSettingsViewModel()`
|
||||
- Initializes `_currentTime` `DispatcherTimer` (1s tick).
|
||||
- Resolves `IEventAggregator`, `IDASModelProvider`, `IUnityContainer`.
|
||||
- Subscribes to `DASSampleRateChangedEvent`, `DASLevelTriggerChangedEvent`, `DASListChangedEvent`.
|
||||
- Initializes commands (`SampleRatesAreMixedResetCommand`, `LevelTriggersAreMixedResetCommand`).
|
||||
- Calls `FromTestSetup(_tsrAirTest)` and `OnDASListChanged(true)` (to handle pre-populated DAS list).
|
||||
- **Properties**:
|
||||
- `bool IsSystemSettingsEnabled`: Enables/disables UI.
|
||||
- `bool SampleRatesAreMixed`: Indicates if DAS units have differing sample rates.
|
||||
- `bool LevelTriggersAreMixed`: Indicates if DAS units have differing level triggers.
|
||||
- `bool LevelTriggersAreMixedAndShowLevelTriggers`, `LevelTriggersAreMixedOrDontShowLevelTriggers`: Derived visibility flags.
|
||||
- `string[] AvailableSampleRates`: Derived from `DFConstantsAndEnums.TSRAIR_ValidSampleRates`, formatted as `"N0"`.
|
||||
- `int SelectedSampleRateIndex`:
|
||||
- *Getter*: Validates sample rates across DAS units; returns `-1` if mixed or invalid.
|
||||
- *Setter*: Updates `_samplesPerSecondAggregate`, propagates to all DAS units, publishes `SystemSettingsSampleRateChangedEvent`.
|
||||
- `string SelectedSampleRateItem`: Unused in logic (set only).
|
||||
- `AvailableRecordingMode SelectedRecordingMode`:
|
||||
- *Setter*: Switches between `Active` and `Scheduled` modes; updates `DurationText`, manages `_currentTime` timer, validates schedule/interval, publishes `SystemSettingsRecordingModeChangedEvent`.
|
||||
- `double Duration`: Gets/sets post-trigger duration; publishes `SystemSettingsDurationChangedEvent`.
|
||||
- `int NumberOfEvents`: Gets/sets scheduled/interval event count (min 1, max 2000); updates `IntervalVisibility`.
|
||||
- `int Interval`: Gets/sets interval between events (in minutes).
|
||||
- `DateTime ScheduleStartDateTimeUTC`: Gets/sets scheduled start time (UTC, seconds truncated).
|
||||
- `string DurationText`: Display string ("PostTrigger" or "EventLength").
|
||||
- `string LevelTriggerText`: Gets formatted `|_levelTriggerValue|` (2 decimal places); setter clamps to min/max and publishes `SystemSettingsLevelTriggerChangedEvent`.
|
||||
- `bool LevelTriggerAxis1/2/3`: Gets/sets axis flags; propagate to `_systemSettingsLevelTrigger` and publish event (if not mixed).
|
||||
- `DateTime CurrentDateTimeUTC`: Returns `DateTime.UtcNow`.
|
||||
- `System.Windows.Visibility ScheduledVisibility`: Visible only in `Scheduled` mode.
|
||||
- `System.Windows.Visibility IntervalVisibility`: Visible only in `Scheduled` mode *and* `NumberOfEvents > 1`.
|
||||
- `ObservableCollection<AvailableRecordingMode> SelectableRecordingModes`: Copy of `_availableRecordingModes`.
|
||||
- `DTS.Common.Classes.ClockSync.ClockSyncProfile SelectedClockSyncProfile`: Clock sync profile selection.
|
||||
- `static DTS.Common.Classes.ClockSync.ClockSyncProfile[] AvailableClockSyncProfiles`: Filters `ClockSyncProfileCollection` (excludes `GPS1PPS`), sorts by `DisplayOrder`.
|
||||
- **Methods**:
|
||||
- `void PopulateDASSampleRate(string serialNumber, double sampleRate)`: Updates `_dasSampleRateList`.
|
||||
- `void PopulateDASLevelTrigger(string serialNumber, LevelTriggerArg)`: Updates `_dasLevelTriggersLookup`.
|
||||
- `void PopulateDASAAFRateList(string serialNumber, float aafRate)`: Updates `_dasAAFRateList`.
|
||||
- `void SubscribeDASLevelTrigger()`: Subscribes to `DASLevelTriggerChangedEvent`.
|
||||
- `void UnSubscribeDASLevelTrigger()`: Unsubscribes.
|
||||
- `void EnableSystemSettings(bool enable)`: Sets `IsSystemSettingsEnabled`.
|
||||
- `void FromTestSetup(TSRAIRGoTestSetup setup)`: Loads settings from test setup.
|
||||
- `void ApplyToTestSetup(TSRAIRGoTestSetup setup)`: Persists settings to test setup.
|
||||
- `void ApplyClockSettingsToTestSetup(TSRAIRGoTestSetup setup)`: Persists clock settings.
|
||||
- `bool ValidateRTCScheduleStartTime()`: Validates start time via `TestTemplate.ValidateScheduleStartTime`.
|
||||
- `bool ValidateInterval()`: Validates interval via `TestTemplate.ValidateInterval`.
|
||||
- **Private Helpers**:
|
||||
- `void DetectSampleRatesMixedFromHardware()`: Updates `SampleRatesAreMixed`, sets `SelectedSampleRateIndex`.
|
||||
- `void DetectLevelTriggerMixedFromHardware()`: Updates level trigger properties and mixed flags.
|
||||
- `void UpdateLevelTriggerVisibility()`: Sets `LevelTriggersAreMixedAndShowLevelTriggers`, `LevelTriggersAreMixedOrDontShowLevelTriggers`.
|
||||
- `void GetLTMinMax(out double min, out double max)`: Computes min/max from `SerializedSettings` and `SensorConstants`.
|
||||
- `void OnDASSampleRateChanged(DASSampleRateArg)`, `OnDASLevelTriggerChanged(LevelTriggerArg)`, `OnDASListChanged(bool)`: Event handlers for DAS changes.
|
||||
- `void CurrenTimeUTC_Tick(...)`: Raises `OnPropertyChanged("CurrentDateTimeUTC")`.
|
||||
- `void OnSampleRatesAreMixedResetCommand()`, `OnLevelTriggersAreMixedResetCommand()`: Reset handlers.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **`NavigationViewModel.NavigationButtonsInfo`**: Must contain entries for all `NavigationButtonId` enum values defined in `DTS.Common.Enums.TSRAIRGo.NavigationButtonId` (e.g., `Help`, `ArmDisarm`, `Trigger`, `Download`, `ViewData`, `ExportData`, `Dashboard`). Initialized once in constructor; later updates must preserve key set.
|
||||
- **`SystemSettingsViewModel.SelectedSampleRateIndex`**:
|
||||
- Returns `-1` if sample rates across DAS units are mixed or if the aggregate rate is not in `AvailableSampleRates`.
|
||||
- Setting a valid index propagates the rate to all DAS units in `_dasSampleRateList`.
|
||||
- **`SystemSettingsViewModel.Duration`**: Represents *post-trigger* duration in seconds (set via `PostTriggerSeconds` from `TSRAIRGoTestSetup`), but `Interval` is in *minutes*.
|
||||
- **`SystemSettingsViewModel.NumberOfEvents`**: Clamped to `[1, 2000]`; affects `IntervalVisibility`.
|
||||
- **`SystemSettingsViewModel.IntervalVisibility`**: `Hidden` unless `SelectedRecordingMode == Scheduled` *and* `NumberOfEvents > 1`.
|
||||
- **`SystemSettingsViewModel.ScheduledVisibility`**: `Collapsed` unless `SelectedRecordingMode == Scheduled`.
|
||||
- **`GoMainWindowViewModel.ContentValue`**: Always set to a `Dashboard` instance on navigation to dashboard; `NavigationValue` to a `Navigation` instance.
|
||||
- **`SystemStatusViewModel.Message/Error`**: May be `null` (safe via `?.` in handlers); updates are immediate and UI-bound.
|
||||
- **`NavigationViewModel.KeyDown`**: Delegates to `DataPROPage.KeyUp` (note: method name mismatch — likely bug).
|
||||
- **`NavigationViewModel.NavigateToContent`**: Always publishes `StartStopDASScanEvent(false)` and `StartStopOverallStatusStateMachineEvent(false)` before navigation.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Internal Dependencies (Module)
|
||||
- **ViewModels**:
|
||||
- `DashboardViewModel`, `SystemStatusViewModel`, `GoMainWindowViewModel`, `NavigationViewModel`, `SystemSettingsViewModel` are co-located and interdependent via Prism events and Unity resolution.
|
||||
- **Commands**:
|
||||
- `NavigationViewModel` uses `Prism.Commands.DelegateCommand`.
|
||||
- **Data/Model**:
|
||||
- `DTS.Common.Base.BasePropertyChanged`: Base class for all view models.
|
||||
- `DTS.Common.Interface.Menu.HamburgerMenu.IHamburgerMenuViewModel`: Used for hamburger menu control.
|
||||
- `DataPROWin7.DataModel.TabPageSource.TabPageItem`, `TileUniqueIDs`, `TabPageSource`: For tab navigation.
|
||||
- `DataPROWin7.TSRAIRGo.DataProvider.IDASModelProvider`: Provides DAS hardware list and defaults.
|
||||
- `DataPROWin7.TSRAIRGo.Interface.ISystemSettings`: Implemented by `SystemSettingsViewModel`.
|
||||
- `DataPROWin7.TSRAIRGo.Command.*`: Command classes (not shown, but referenced).
|
||||
- **Events**:
|
||||
- `DTS.Common.Events.TSRAIRGo.*`: `SystemStatusEvent`, `SystemErrorEvent`, `NavigateToDashboardEvent`, `StartStopDASScanEvent`, `StartStopOverallStatusStateMachineEvent`, `ArmEvent`, `TriggerEvent`, `DownloadEvent`, `DASSampleRateChangedEvent`, `DASLevelTriggerChangedEvent`, `DASListChangedEvent`, `SystemSettingsSampleRateChangedEvent`, `SystemSettingsLevelTriggerChangedEvent`, `SystemSettingsRecordingModeChangedEvent`, `ClearSelectedExportsEvent`, `PageErrorEvent`.
|
||||
- **Resources**:
|
||||
- `DTS.Common.SharedResource.Strings.StringResources`: UI text localization.
|
||||
- `DTS.Common.Constant.DASSpecific.SensorConstants`, `DTS.Common.DataModel.Classes.TestTemplate.*`, `DTS.Slice.Users.UserSettings.*`: For sample rate, trigger, and user settings.
|
||||
|
||||
#### External Dependencies
|
||||
- **Prism**: `IEventAggregator`, `IContainerExtension` (via `ContainerLocator.Container`), `DelegateCommand`.
|
||||
- **Unity**: `IUnityContainer`, `ContainerLocator`.
|
||||
- **WPF**: `DispatcherTimer`, `Application.Current.Dispatcher`, `KeyEventArgs`, `Visibility`.
|
||||
- **System**: `Task`, `Environment.CurrentDirectory`, `Process`, `DateTime`, `Math`, `Array`, `List<T>`, `Dictionary<TKey,TValue>`, `ObservableCollection<T>`.
|
||||
|
||||
#### Inferred Usage
|
||||
- `GoMainWindowViewModel` is likely the root view model for the TSRAIRGo window.
|
||||
- `NavigationViewModel` is injected into views (e.g., navigation bar) and used to manage button states and navigation.
|
||||
- `SystemSettingsViewModel` is likely bound to a settings panel and integrates with `TSRAIRGoTestSetup`.
|
||||
- `SystemStatusViewModel` is likely bound to a status bar.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`NavigationViewModel.KeyDown` calls `page.KeyUp`**: The method name mismatch (`KeyDown` → `KeyUp`) is likely a bug or copy-paste error.
|
||||
- **`SystemSettingsViewModel.Duration` semantics**: Despite being named `Duration`, it represents *post-trigger* duration in *seconds* (set from `PostTriggerSeconds`), while `Interval` is in *minutes*. This may cause confusion.
|
||||
- **`SelectedSampleRateIndex` setter behavior**: Setting an index updates *all* DAS units to the same rate, even if they previously had different rates. This may overwrite per-DAS configuration.
|
||||
- **`AvailableClockSyncProfiles` excludes GPS1PPS**: Hardcoded exclusion of `ClockSyncProfileDefaults.GPS1PPS` (case #44054 referenced) — not configurable.
|
||||
- **`GoMainWindowViewModel.OnNavigateToDashboard` publishes start events**: These events (`StartStopDASScanEvent(true)`, `StartStopOverallStatusStateMachineEvent(true)`) are published *every time* the dashboard is navigated to, not just on initial launch.
|
||||
- **`SystemStatusViewModel` does not unsubscribe**: Event subscriptions in constructor are never unsubscribed — potential memory leak if view model lifetime exceeds event publisher lifetime.
|
||||
- **`NavigationViewModel.NavigateToDownload` uses `#if _DOWNLOAD_USING
|
||||
179
enriched-qwen3-coder-next/DataPRO/DataPRO/View.md
Normal file
179
enriched-qwen3-coder-next/DataPRO/DataPRO/View.md
Normal file
@@ -0,0 +1,179 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/View/ShellView.xaml.cs
|
||||
- DataPRO/DataPRO/View/MainWindow.xaml.cs
|
||||
generated_at: "2026-04-16T04:07:06.973466+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "67f1dae633b92fc4"
|
||||
---
|
||||
|
||||
# View
|
||||
|
||||
**Documentation Page: `MainWindow` (DataPROWin7)**
|
||||
*Last Updated: 2024-06-14*
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
`MainWindow` serves as the primary shell and navigation hub for the DataPRO and TSRAIRGo desktop applications. It implements `IMainView` and `INotifyPropertyChanged`, manages the application’s main UI state (including login, home, and full-screen views), coordinates DASFactory availability, handles licensing and version validation modals, and orchestrates page navigation via the `HomePage` instance. It also integrates with system-level Windows APIs for window management (e.g., maximize/restore, focus switching) and monitors power mode, database connectivity, and license status on startup.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### **Constructors**
|
||||
- **`MainWindow()`**
|
||||
Initializes the window, sets up UI components (`_loginControl`, `_homePage`, `_modalControl`, etc.), registers event handlers, and conditionally navigates to home or login page based on user login state.
|
||||
|
||||
#### **Navigation & Page Management**
|
||||
- **`void GoTo(PageNavigationRequest request)`**
|
||||
Navigates to a named destination (e.g., TestSetups, RunTest) by delegating to `_homePage.GoTo(request)`.
|
||||
- **`void GoTo(DataPROTabItem tab, bool saveState = false)`**
|
||||
Navigates to a specific `DataPROTabItem`, optionally saving current state.
|
||||
- **`void GoToSavedState()`**
|
||||
Restores navigation to the last saved page (see [Gotchas](#gotchas) for context).
|
||||
- **`void GoToHomePage(bool CallOnSetActive = true)`**
|
||||
Navigates to the `HomePage`, clearing the previous-page stack.
|
||||
- **`void GoToLoginPage()`**
|
||||
Navigates to the login screen and sets `UserWasLoggedOutOrIsInLoginScreen = true`.
|
||||
- **`void GoToTimedWaitPage(ManualResetEvent mre, string message, Visibility cancelButtonVisibility)`**
|
||||
Displays a modal progress/wait dialog with a cancel button.
|
||||
- **`void GoToNewPage(DataPROPage page)`**
|
||||
Delegates to `_homePage.GoToNewPage(page)`.
|
||||
- **`void GoToFullScreenGrid(object chart)`**
|
||||
Switches to full-screen grid mode, storing the current content in `_previousPages`.
|
||||
- **`void GoToFullScreenRealtime(RealtimeChart chart, SubControls.Realtime realtime, RunTestBase rtb)`**
|
||||
Enters full-screen real-time mode, embedding the chart and plot info into a dedicated grid.
|
||||
- **`void GoToSmallScreenRealtime()`**
|
||||
Restores the previous content (from `_smallScreenRealtime`) after full-screen real-time.
|
||||
- **`bool HasSaveState`**
|
||||
Returns `true` if `_homePage` has a saved state (i.e., `_homePage?.HasSavedState ?? false`).
|
||||
|
||||
#### **State & Lifecycle**
|
||||
- **`void SetNewTest(TestTemplate test)`**
|
||||
Updates persistent test setup state, sets the ribbon test name, and navigates to the previous page.
|
||||
- **`void GoToPreviousPage()` / `void GoToPreviousPage(bool setActive)`**
|
||||
Navigates back to the prior page; the `setActive` parameter controls whether `OnSetActive()` is invoked.
|
||||
- **`void CloseCurrentPage()` / `void PostCloseCurrentPage()`**
|
||||
Handles graceful application shutdown: prompts for unsaved changes, then closes the window.
|
||||
- **`void CloseTimedWaitPage()`**
|
||||
Dismisses the timed wait dialog.
|
||||
- **`void SystemLoaded()`**
|
||||
Invokes `_loginControl.SetActive()`; used to signal post-initialization readiness.
|
||||
|
||||
#### **UI & Window Control**
|
||||
- **`void SetIcon(Icons icon)`**
|
||||
Sets the window icon to `DataPRO.ico` or `TSRAIRGo.ico` based on `Icons` enum.
|
||||
- **`void UpdateTitle(object o)` / `void UpdateTitle()`**
|
||||
Dynamically updates the window title with app name, version, current test, and page name.
|
||||
- **`void OnButtonMinimize_Click`, `OnButtonRestore_Click`, `OnButtonMaximize_Click`**
|
||||
Standard window state change handlers.
|
||||
- **`void SwitchState()`**
|
||||
Toggles between `Normal` and `Maximized` window states.
|
||||
- **`void SetMainContent(object o)` / `object GetMainContent()`**
|
||||
Directly sets/gets the content of `contentControl`.
|
||||
|
||||
#### **Modal Dialogs**
|
||||
- **`void DoModalWindow(IModalContent content, string msg = null, IList<PageButton> buttonIds = null, PageButton defaultButton = null)`**
|
||||
Displays a modal dialog, queuing if another modal is active.
|
||||
- **`void CloseModalDialog()`**
|
||||
Closes the top modal in the queue and re-enables the main UI.
|
||||
- **`void ShowModalLicensePrompt()` / `ShowModalUnLicensedPrompt()` / `ShowModalProductVersionPrompt()`**
|
||||
Conditionally shows license/version validation modals (disabled in `DEBUG` builds).
|
||||
|
||||
#### **Helper & Utility**
|
||||
- **`void DoChangeView()` / `void CloseChangeView()`**
|
||||
Opens/closes the user-switching dialog (`ChangeView`).
|
||||
- **`void DoDisplayHelp()` / `void CloseDisplayHelp()`**
|
||||
Opens/closes the help dialog (`DisplayHelp`).
|
||||
- **`string GeneratePcId()`**
|
||||
Generates a unique PC identifier XML file for unlicensed-user diagnostics.
|
||||
- **`void AddFullScreenPlotInfo(Control[] controls)` / `void RemoveFullScreenPlotInfo()`**
|
||||
Manages plot info UI in full-screen mode.
|
||||
- **`RealtimeFullScreen GetRealtimeFullScreen()`**
|
||||
Returns the internal `_fullScreen` control instance.
|
||||
|
||||
#### **Event Handlers**
|
||||
- **`void OnButtonPress(PageButton button)`**
|
||||
Routes button presses to specific logic (e.g., license prompts, exit confirmation) via `ButtonIds` enum.
|
||||
- **`void MainWindow_KeyDown`, `MainWindow_KeyUp`**
|
||||
Tracks key states and forwards key events to the active page.
|
||||
- **`bool GetKeyState(Key key)`**
|
||||
Returns whether a key is currently pressed.
|
||||
|
||||
#### **Properties (Public)**
|
||||
- **`bool ConnectedPrimaryDb`**
|
||||
Tracks primary DB connection status; publishes `DBConnectionEvent` on change.
|
||||
- **`bool DASAvailable`**
|
||||
Indicates DASFactory availability.
|
||||
- **`bool DatabaseModified`**
|
||||
Tracks database modification state; triggers `OnSetActive()` on change.
|
||||
- **`string DataPRO_Version`**
|
||||
Version string (e.g., `"DataPRO 3.2.1"`).
|
||||
- **`string PageName`**
|
||||
Current page name; updates window title.
|
||||
- **`string DatabaseVersion`**
|
||||
Database version string.
|
||||
- **`string ModifyText`**
|
||||
State text for "modify" operations.
|
||||
- **`string Title`**
|
||||
Window title (inherited from `Window`, but updated via `UpdateTitle()`).
|
||||
|
||||
#### **Enums**
|
||||
- **`Icons`** (`DataPRO`, `TSRAIRGo`)
|
||||
Used by `SetIcon()`.
|
||||
- **`ButtonIds`** (e.g., `MainWindow_HighPerformanceModeWarningOK`, `MainWindow_ConfirmDataPROExit_YES`)
|
||||
Identifies button presses in `OnButtonPress()`.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
- **UI Thread Safety**: All UI updates (e.g., `SetIcon`, `UpdateTitle`, modal display) use `Dispatcher.CheckAccess()` and `BeginInvoke` when called from non-UI threads.
|
||||
- **Modal Queueing**: Modals are processed sequentially via `_modalContentList`; only one modal is active at a time.
|
||||
- **DASFactory Ownership**: If `CanDASFactoryStart(false)` fails, `DASAvailable` is set to `false`, and `TakeDASOwnership` runs in a background thread to re-acquire ownership.
|
||||
- **License Validation**: Expired/unlicensed/invalid-version prompts are suppressed in `DEBUG` builds and respect `SerializedSettings.DoNotShow*` flags.
|
||||
- **Page Navigation Stack**: `_previousPages` stores prior content for full-screen/grid mode restoration.
|
||||
- **Window Title Consistency**: `UpdateTitle()` is thread-safe via `lock(MyLock)` and `Task.Run` dispatch.
|
||||
- **Exit Flow**: Closing the window triggers `Window_Closing`, which cancels the close event and shows a confirmation modal. Actual exit occurs only after `CloseCurrentPage()` → `PostCloseCurrentPage()`.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
#### **Internal Dependencies**
|
||||
- **`DataPROWin7.Pages.HomePage`**: Core navigation controller.
|
||||
- **`DataPROWin7.Controls.*`**: `ModalUserPrompt`, `ModalLicensePrompt`, `RealtimeChart`, `RealtimeFullScreen`, `GridFullScreen`, `LoginControl2`, `TimedWaitControl`.
|
||||
- **`DTS.Common.Interface`**: `IShellView`, `IMainView`, `IModalContent`, `PageButton`, `DataPROPage`.
|
||||
- **`DTS.Common.Events`**: `TestSetupsList.CurrentTestChangedEvent`, `DatabaseVersionChangedEvent`, `DBConnectionEvent`, `AppStatusEvent`.
|
||||
- **`DTS.DASLib.DASFactory`**: `DASFactory` for resource ownership.
|
||||
- **`DTS.Common.Licensing.SystemInformation`**: `MainBoardInfo`, `ProcessorInfo`, `ComputerSystemInfo`, `MachineInfo`.
|
||||
- **`DTS.Common.Base.App`**: Application-level state (`CurrentUser`, `PersistentTestSetupName`, `LicenseValidationResult`).
|
||||
- **`DTS.Common.Utilities.Logging.APILogger`**: Logging.
|
||||
- **`Prism.Ioc.IContainerLocator`**: Dependency injection (Unity).
|
||||
|
||||
#### **External Dependencies**
|
||||
- **WPF**: `System.Windows`, `System.Windows.Controls`, `System.Windows.Input`, `System.Windows.Interop`.
|
||||
- **.NET Framework**: `System.Threading.Tasks`, `System.Runtime.InteropServices`, `System.Drawing`, `System.Xml.Linq`.
|
||||
- **Windows API**: `user32.dll` (`ShowWindow`, `SetForegroundWindow`).
|
||||
|
||||
#### **Depended Upon**
|
||||
- `ShellView` (minimal; only `IShellView` interface).
|
||||
- Other modules via `IEventAggregator` events (e.g., `DBConnectionEvent`).
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
- **`GoToSavedState()`**: Relies on `_homePage?.GoToSavedState()`; behavior depends on `HomePage` implementation (not in source).
|
||||
- **Modal Reusability**: Modals like `_modalLicensePrompt` are reused; strings and buttons are stored in `_modalMessageList`, `_modalButtonIds`, etc., to avoid reconfiguration (see comments referencing issue #15378).
|
||||
- **`DAS_FACTORY_UNAVAIL_USER_CLOSE`**: Exit code `0x01` is used when the user cancels the DAS factory unavailable warning.
|
||||
- **`UpdateTitle()` Thread Safety**: Uses `_bUpdatingTitle` flag and `lock(MyLock)` to prevent race conditions during concurrent updates.
|
||||
- **`TSRAIRGo_KeyDown`**: For TSRAIRGo mode, key events are routed to `NavigationViewModel`; exceptions are logged but swallowed.
|
||||
- **`Window_Closed`**: Contains a deliberate divide-by-zero (`int i = 1; int j = 10/i;`)—likely a debugging artifact or placeholder.
|
||||
- **Power Mode Warning**: `_modalNotInHighPerformanceMode` is shown only if `!SerializedSettings.IgnorePowerModeWarning && !PowerManagement.IsInHighPowerMode()`.
|
||||
- **`FocusOtherApp()`**: Attempts to restore focus to other DAS-related apps (FTWU, SLICEWare, oldest DataPRO) on exit; falls back silently on error.
|
||||
- **`SetIcon()`**: Uses `pack://application:,,,/ResourceFile.xaml` as the base URI; icons must exist at `Assets/DataPRO.ico` or `Assets/TSRAIRGo.ico`.
|
||||
- **`RunTestPostOnSetActive()`**: Dynamically sets the test setup button style based on `CheckoutMode`.
|
||||
- **`GroupedItemControlClickedAsync()`**: Uses `WaitCursor` and `AppStatusEvent.Busy/Available` to indicate loading.
|
||||
- **`MainWindow_IsEnabledChanged`**: Forcibly focuses the window when re-enabling during real-time mode to preserve key event handling.
|
||||
|
||||
*No other obvious tech debt or quirks identified from source alone.*
|
||||
178
enriched-qwen3-coder-next/DataPRO/DataPRO/ViewModel.md
Normal file
178
enriched-qwen3-coder-next/DataPRO/DataPRO/ViewModel.md
Normal file
@@ -0,0 +1,178 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/ViewModel/ShellViewModel.cs
|
||||
- DataPRO/DataPRO/ViewModel/MainViewModel.cs
|
||||
generated_at: "2026-04-16T04:05:06.867844+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "1d4c107951a8fed1"
|
||||
---
|
||||
|
||||
# ViewModel
|
||||
|
||||
## Documentation: ShellViewModel and MainViewModel
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
The `ShellViewModel` and `MainViewModel` classes implement the core view-model layer for the application’s main shell and main content area, respectively. `ShellViewModel` serves as the top-level container view-model, managing global UI state (e.g., busy indicator, menu/navigation visibility), coordinating region navigation via Prism’s `IRegionManager`, and acting as an event aggregator subscriber for global notifications and busy indicators. `MainViewModel` is a child view-model hosted within `ShellViewModel`’s main region, responsible for managing context-specific regions (e.g., graph, tests, diagnostics) and delegating notifications and busy state updates to the parent shell. Both classes implement Prism’s `BindableBase` (via `BaseViewModel` for `MainViewModel`) and follow the MVVM pattern with interaction requests for modal UI (notifications/confirmations). They are part of the DataPRO Win7 desktop application’s UI infrastructure.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `ShellViewModel`
|
||||
|
||||
- **`ShellViewModel(IShellView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)`**
|
||||
Constructor. Initializes view binding, interaction requests (`NotificationRequest`, `ConfirmationRequest`), and subscribes to `RaiseNotification` and `BusyIndicatorChangeNotification` events.
|
||||
|
||||
- **`void Cleanup()`**
|
||||
No-op stub. Intended for cleanup logic but currently unimplemented.
|
||||
|
||||
- **`Task CleanupAsync()`**
|
||||
Returns `Task.CompletedTask`. No-op stub.
|
||||
|
||||
- **`void Initialize()` / `void Initialize(object parameter)` / `Task InitializeAsync()` / `Task InitializeAsync(object parameter)`**
|
||||
No-op stubs. Intended for initialization logic but currently unimplemented.
|
||||
|
||||
- **`void Activated()`**
|
||||
No-op stub. Called when the view is activated.
|
||||
|
||||
- **`List<FrameworkElement> GetRegions()`**
|
||||
Returns a list of `FrameworkElement` instances in the `ShellView` whose name is `"Region"`, retrieved via `Utils.GetChildrenByName(((ShellView)View).MainShell, "Region", ref items)`.
|
||||
|
||||
- **`object ContextMainRegion { get; set; }`**
|
||||
Gets/sets the content of the `MainRegion` on the `ShellView`. Setting triggers `OnPropertyChanged("ContextMainRegion")`.
|
||||
|
||||
- **`object ContextNavigationRegion { get; set; }`**
|
||||
Gets/sets navigation region content. No property change notification.
|
||||
|
||||
- **`object ContextMenuRegion { get; set; }`**
|
||||
Gets/sets menu region content. No property change notification.
|
||||
|
||||
- **`bool IsDirty { get; private set; }`**
|
||||
Read-only property indicating whether the view-model is dirty. Always `false` (never set).
|
||||
|
||||
- **`bool IsBusy { get; set; }`**
|
||||
Gets/sets busy state. Triggers `OnPropertyChanged("IsBusy")`.
|
||||
|
||||
- **`bool IsMenuIncluded { get; set; }`**
|
||||
Gets/sets whether the menu is included. Triggers `OnPropertyChanged("IsMenuIncluded")`.
|
||||
|
||||
- **`bool IsNavigationIncluded { get; set; }`**
|
||||
Gets/sets whether navigation is included. Triggers `OnPropertyChanged("IsNavigationIncluded")`.
|
||||
|
||||
- **`string HeaderInfo { get; }`**
|
||||
Returns `"MainRegion"`.
|
||||
|
||||
- **`InteractionRequest<Notification> NotificationRequest { get; }`**
|
||||
Interaction request for displaying notification popups.
|
||||
|
||||
- **`InteractionRequest<Confirmation> ConfirmationRequest { get; }`**
|
||||
Interaction request for displaying confirmation popups.
|
||||
|
||||
- **`event PropertyChangedEventHandler PropertyChanged`**
|
||||
Overrides `INotifyPropertyChanged`. Raised via `OnPropertyChanged`.
|
||||
|
||||
#### `MainViewModel`
|
||||
|
||||
- **`MainViewModel(IMainView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)`**
|
||||
Constructor. Initializes view binding, interaction requests, and subscribes to `RaiseNotification` and `BusyIndicatorChangeNotification` events.
|
||||
|
||||
- **`override void Initialize()`**
|
||||
Re-subscribes to `RaiseNotification` and `ShowStatus` events if `_eventAggregator` is null (fallback resolution via `ContainerLocator.Container`).
|
||||
|
||||
- **`override void Initialize(object parameter)`**
|
||||
Sets `Parent` to the passed `IShellViewModel` parameter, and syncs `Parent.IsMenuIncluded`/`IsMenuIncluded` and `Parent.IsNavigationIncluded`/`IsNavigationIncluded`. Also reassigns `View.DataContext = this`.
|
||||
|
||||
- **`override void Activated()`**
|
||||
No-op stub.
|
||||
|
||||
- **`List<FrameworkElement> GetRegions()`**
|
||||
Throws `NotImplementedException`. Intended to return region elements but not implemented.
|
||||
|
||||
- **`object ContextMainRegion { get; set; }`**
|
||||
Gets/sets main region content. Setting triggers `OnPropertyChanged("ContextMainRegion")`.
|
||||
*Note:* Current implementation does *not* update `MainRegion.Content` directly (commented out), nor does it propagate `IsMenuIncluded`/`IsNavigationIncluded` to the parent.
|
||||
|
||||
- **`object ContextNavigationRegion`, `ContextGraphRegion`, `ContextTestsRegion`, `ContextGraphsRegion`, `ContextLegendRegion`, `ContextDiagRegion`, `ContextStatsRegion`, `ContextCursorRegion`, `ContextPropertyRegion`**
|
||||
Public properties for region content. No property change notifications.
|
||||
|
||||
- **`bool IsMenuIncluded { get; set; }`**
|
||||
Gets/sets menu visibility. Triggers `OnPropertyChanged("IsMenuIncluded")`.
|
||||
|
||||
- **`bool IsNavigationIncluded { get; set; }`**
|
||||
Gets/sets navigation visibility. Triggers `OnPropertyChanged("IsNavigationIncluded")`.
|
||||
|
||||
- **`bool IsBusy { get; set; }`**
|
||||
Gets/sets busy state. Triggers `OnPropertyChanged("IsBusy")`.
|
||||
|
||||
- **`string IsBusyMessage { get; set; }`**
|
||||
Gets/sets busy message text. Triggers `OnPropertyChanged("IsBusyMessage")`.
|
||||
|
||||
- **`string HeaderInfo { get; }`**
|
||||
Returns `"MainRegion"`.
|
||||
|
||||
- **`InteractionRequest<Notification> NotificationRequest { get; }`**
|
||||
Interaction request for notifications.
|
||||
|
||||
- **`InteractionRequest<Confirmation> ConfirmationRequest { get; }`**
|
||||
Interaction request for confirmations.
|
||||
|
||||
- **`event PropertyChangedEventHandler PropertyChanged`**
|
||||
Overrides `INotifyPropertyChanged`. Raised via `OnPropertyChanged`.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **View binding**: In both constructors, `View.DataContext = this` is set unconditionally.
|
||||
- **Event subscription**: Both classes subscribe to `RaiseNotification` and `BusyIndicatorChangeNotification` events via `_eventAggregator.GetEvent<T>().Subscribe(...)`.
|
||||
- **Busy state propagation**: `ShellViewModel.OnBusyIndicatorNotification(bool)` sets `IsBusy` directly. `MainViewModel.OnBusyIndicatorNotification(bool)` sets `IsBusy` *and* calls `((App)Application.Current).SetAppBusy()` / `SetAppAvailable()`.
|
||||
- **Notification handling**: `OnRaiseNotification(NotificationContentEventArgs)` in both classes constructs a `Notification` object with `Content` and `Title`, and raises `NotificationRequest`.
|
||||
- In `ShellViewModel`, the `Content` is a *new* `NotificationContentEventArgs` with empty `MessageDetails` and empty `Title` (the original title is used for the `Notification.Title` only).
|
||||
- In `MainViewModel`, the `Content` retains all original fields (`Message`, `MessageDetails`, `Image`, `Title`) in the `NotificationContentEventArgs`.
|
||||
- **Region context properties**: `ContextMainRegion` in `ShellViewModel` directly updates the `MainRegion.Content` on the view. `MainViewModel.ContextMainRegion` does *not* update the view’s region content (commented out).
|
||||
- **Parent sync**: In `MainViewModel.Initialize(object parameter)`, `Parent.IsMenuIncluded` and `Parent.IsNavigationIncluded` are set from local values, but not vice versa.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Dependencies *of* `ShellViewModel` and `MainViewModel`:
|
||||
|
||||
- **Prism libraries**:
|
||||
- `Prism.Events.IEventAggregator`, `Prism.Regions.IRegionManager`, `Prism.Mvvm.BindableBase`, `Prism.Ioc.IContainerLocator`, `Prism.Interactivity.InteractionRequest<Notification/Confirmation>`.
|
||||
- **Unity container**: `IUnityContainer`.
|
||||
- **Common libraries**:
|
||||
- `DTS.Common.Events.*` (e.g., `RaiseNotification`, `BusyIndicatorChangeNotification`, `ShowStatus`, `NotificationContentEventArgs`, `StatusInfo`).
|
||||
- `DTS.Common.Interface.*` (e.g., `IShellView`, `IShellViewModel`, `IMainView`, `IMainViewModel`, `IBaseView`, `IBaseViewModel`).
|
||||
- `DTS.Common.Interactivity.*` (e.g., `Notification`, `Confirmation`).
|
||||
- `DTS.Common.Utils.*` (e.g., `Utils.GetChildrenByName`).
|
||||
- **WPF**: `System.Windows.Application`, `System.Windows.Threading.Dispatcher`, `System.Windows.FrameworkElement`.
|
||||
- **Base class**: `MainViewModel` inherits from `BaseViewModel<MainViewModel>` (from `DTS.Common.Base`), which provides `ContainerLocator`, `RegionManager`, `EventAggregator`, and `UnityContainer` properties (inferred from constructor and usage).
|
||||
|
||||
#### Dependencies *on* `ShellViewModel`/`MainViewModel`:
|
||||
|
||||
- `ShellViewModel` is exported as `[Export(typeof(IShellView))]`, implying it is consumed by Prism’s view-first navigation or container resolution of `IShellView`.
|
||||
- `MainViewModel` is instantiated with `IMainView` and `IShellViewModel` (as `parameter`), implying it is hosted inside the shell and depends on it for region/content coordination.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`GetRegions()` in `MainViewModel` throws `NotImplementedException`** — This method is declared but not implemented and will cause runtime failure if called.
|
||||
- **`ContextMainRegion` in `MainViewModel` does not update the view’s region content** — The setter only updates the backing field and raises `OnPropertyChanged`, but the actual region content assignment (`((MainView)View).MainRegion.Content = value`) is commented out.
|
||||
- **`ContextMainRegion` in `ShellViewModel` directly mutates the view** — It accesses `((ShellView)View).MainRegion.Content`, which assumes the view is `ShellView` (not just `IShellView`). This is a tight coupling to the concrete view type.
|
||||
- **`IsDirty` is never set** — The property is read-only and always `false`. Likely incomplete or unused.
|
||||
- **`ContextNavigationRegion`, `ContextMenuRegion`, and other region properties in `ShellViewModel` have no setter notifications** — Changes will not propagate via `INotifyPropertyChanged`.
|
||||
- **`MainViewModel.Initialize(object parameter)` overwrites `View.DataContext`** — This may be redundant if already set in the constructor, and could cause issues if called multiple times.
|
||||
- **Event subscription duplication in `MainViewModel.Initialize()`** — If `Initialize()` is called multiple times (e.g., during navigation), `RaiseNotification` and `ShowStatus` may be subscribed multiple times, leading to duplicate handlers.
|
||||
- **`ShellViewModel.OnRaiseNotification` discards `MessageDetails`** — The original `NotificationContentEventArgs` has a `MessageDetails` field, but `ShellViewModel` constructs a new instance with empty `MessageDetails` and empty `Title` for the content, only using the original title for the `Notification.Title`. This may cause loss of information.
|
||||
- **Thread safety in `MainViewModel.OnBusyIndicatorNotification`** — The `BusyIndicatorChangeNotification` subscription in `ShellViewModel` uses `ThreadOption.PublisherThread`, but `MainViewModel` does not specify this (defaults to `SubscriberThread`). If events are published on a non-UI thread, `IsBusy` and `SetAppBusy()`/`SetAppAvailable()` may be invoked off-thread, risking cross-thread exceptions (though `Dispatcher.CurrentDispatcher.InvokeAsync` in `OnStatusChange` is safe).
|
||||
- **`HeaderInfo` is hardcoded** — Both classes return `"MainRegion"` literally, regardless of actual region name or context.
|
||||
|
||||
---
|
||||
|
||||
*Documentation generated from provided source files. No external behavior or APIs inferred beyond what is visible in the code.*
|
||||
125
enriched-qwen3-coder-next/DataPRO/DataPRO/obj/x86/Debug.md
Normal file
125
enriched-qwen3-coder-next/DataPRO/DataPRO/obj/x86/Debug.md
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/obj/x86/Debug/DataPRO_Content.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/DataPRO_Content.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/GeneratedInternalTypeHelper.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/GeneratedInternalTypeHelper.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/App.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/App.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageNavControlsGroup.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageNavControlsGroup.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageActionControlsGroup.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageActionControlsGroup.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageActionControlsRibbon.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageActionControlsRibbon.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageHeaderRibbon.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageHeaderRibbon.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageMainContentControl.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageMainContentControl.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageContentControl.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/PageContentControl.g.cs
|
||||
generated_at: "2026-04-16T04:10:04.457084+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "4b4a9b79798a51a4"
|
||||
---
|
||||
|
||||
# Generated XAML Infrastructure Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module contains auto-generated WPF infrastructure code produced by the `PresentationBuildTasks` MSBuild target during compilation. It provides runtime support for XAML parsing, component initialization, and event wiring for the application’s UI elements. Specifically, it enables the WPF runtime to instantiate and connect XAML-defined controls (e.g., `App`, `PageHeaderRibbon`, `PageContentControl`) and their named child elements (e.g., `navControlGrids`, `actionControlGrids`) at runtime. This code is not intended for manual modification or direct consumption—it exists solely to bridge declarative XAML with imperative code-behind during application startup and UI composition.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All public types and methods are generated by the WPF build pipeline and are marked with `[GeneratedCode]` and `[DebuggerNonUserCode]`. None are meant for direct use outside the WPF runtime.
|
||||
|
||||
### `DataPROWin7.App`
|
||||
- **`void InitializeComponent()`**
|
||||
Initializes the `App` instance by wiring `Startup` and `SessionEnding` event handlers (to `Application_Startup` and `Windows_SessionEnding` respectively) and loading the `app.xaml` resource via `Application.LoadComponent`.
|
||||
- **`static void Main()`**
|
||||
Application entry point: instantiates `App`, calls `InitializeComponent()`, then `Run()`.
|
||||
|
||||
### `DataPROWin7.PageNavControlsGroup`
|
||||
- **`void InitializeComponent()`**
|
||||
Loads the `pagenavcontrolsgroup.xaml` resource.
|
||||
- **`void IComponentConnector.Connect(int connectionId, object target)`**
|
||||
Implements `IComponentConnector`: connects XAML-declared controls to fields. For `connectionId == 1`, assigns `target` to the `navControlGrids` field (a `Grid`).
|
||||
|
||||
### `DataPROWin7.PageActionControlsGroup`
|
||||
- **`void InitializeComponent()`**
|
||||
Loads the `pageactioncontrolsgroup.xaml` resource.
|
||||
- **`void IComponentConnector.Connect(int connectionId, object target)`**
|
||||
For `connectionId == 1`, assigns `target` to the `actionControlGrids` field (a `WrapPanel`).
|
||||
|
||||
### `DataPROWin7.PageActionControlsRibbon`
|
||||
- **`void InitializeComponent()`**
|
||||
Loads the `pageactioncontrolsribbon.xaml` resource.
|
||||
- **`void IComponentConnector.Connect(int connectionId, object target)`**
|
||||
For `connectionId == 1`, assigns `target` to the `actionButtonGroupGrids` field (a `WrapPanel`).
|
||||
|
||||
### `DataPROWin7.PageHeaderRibbon`
|
||||
- **`void InitializeComponent()`**
|
||||
Loads the `pageheaderribbon.xaml` resource.
|
||||
- **`void IComponentConnector.Connect(int connectionId, object target)`**
|
||||
For `connectionId == 1`, assigns `target` to the `headerRibbon` field (a `PageHeaderRibbon` instance).
|
||||
For `connectionId == 2`, attaches the `Click` event of a `Button` to the `btnChangeTestSetup_Click` handler.
|
||||
|
||||
### `DataPROWin7.PageMainContentControl`
|
||||
- **`void InitializeComponent()`**
|
||||
Loads the `pagemaincontentcontrol.xaml` resource.
|
||||
- **`void IComponentConnector.Connect(int connectionId, object target)`**
|
||||
For `connectionId == 1`, assigns `target` to the `mainContent` field (a `PageMainContentControl` instance).
|
||||
For `connectionId == 2`, assigns `target` to the `contentControl` field (a `ContentControl`).
|
||||
|
||||
### `DataPROWin7.PageContentControl`
|
||||
- **`void InitializeComponent()`**
|
||||
Loads the `pagecontentcontrol.xaml` resource.
|
||||
- **`internal Delegate _CreateDelegate(Type delegateType, string handler)`**
|
||||
Helper used by `GeneratedInternalTypeHelper` to create delegates for event wiring.
|
||||
- **`void IComponentConnector.Connect(int connectionId, object target)`**
|
||||
For `connectionId == 1`, assigns `target` to the `NavControl` field (a `PageNavControl`).
|
||||
For `connectionId == 2`, assigns `target` to the `MainContentControl` field (a `PageMainContentControl`).
|
||||
For `connectionId == 3`, assigns `target` to the `ActionControlsRibbon` field (a `PageActionControlsRibbon`).
|
||||
|
||||
### `XamlGeneratedNamespace.GeneratedInternalTypeHelper`
|
||||
- **`protected override object CreateInstance(Type type, CultureInfo culture)`**
|
||||
Uses `Activator.CreateInstance` with `BindingFlags.Public | NonPublic | Instance | CreateInstance`.
|
||||
- **`protected override object GetPropertyValue(PropertyInfo propertyInfo, object target, CultureInfo culture)`**
|
||||
Uses `PropertyInfo.GetValue` with `BindingFlags.Default`.
|
||||
- **`protected override void SetPropertyValue(PropertyInfo propertyInfo, object target, object value, CultureInfo culture)`**
|
||||
Uses `PropertyInfo.SetValue` with `BindingFlags.Default`.
|
||||
- **`protected override Delegate CreateDelegate(Type delegateType, object target, string handler)`**
|
||||
Invokes the private `_CreateDelegate` method on `target` via reflection.
|
||||
- **`protected override void AddEventHandler(EventInfo eventInfo, object target, Delegate handler)`**
|
||||
Calls `EventInfo.AddEventHandler`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Content loaded once per instance**: All `InitializeComponent()` implementations use a `_contentLoaded` boolean to ensure initialization occurs exactly once per instance.
|
||||
- **Connection ID mapping is fixed**: The `IComponentConnector.Connect` method uses a `switch` on `connectionId` to map XAML element IDs to fields. This mapping is determined at compile time and must not change without recompilation.
|
||||
- **Resource URIs are canonical**: All `LoadComponent` calls use URIs of the form `/DataPRO;component/{name}.xaml`, indicating embedded resources with `Build Action = Page`.
|
||||
- **No public API surface**: All public methods are implementation details of the WPF build system and should not be called directly.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- **WPF runtime (`PresentationFramework`, `WindowsBase`)**: Required for `Application`, `UserControl`, `IComponentConnector`, and `InternalTypeHelper`.
|
||||
- **Application code-behind**: The generated `App.g.cs` wires events to handlers defined in `App.xaml.cs` (e.g., `Application_Startup`, `Windows_SessionEnding`). Similarly, `PageHeaderRibbon.g.cs` references `btnChangeTestSetup_Click`, implying a corresponding method in `PageHeaderRibbon.xaml.cs`.
|
||||
- **Custom controls**: References to `PageNavControl`, `PageMainContentControl`, `PageHeaderRibbon`, etc., indicate these are user-defined controls in the `DataPROWin7` namespace.
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **MSBuild `PresentationBuildTasks`**: Generates this code during the build.
|
||||
- **XAML source files**: `App.xaml`, `PageNavControlsGroup.xaml`, `PageActionControlsGroup.xaml`, `PageActionControlsRibbon.xaml`, `PageHeaderRibbon.xaml`, `PageMainContentControl.xaml`, `PageContentControl.xaml`, and `app.xaml` (note lowercase) are required inputs.
|
||||
- **`DTS.Common.Converters` namespace**: Imported in `PageHeaderRibbon.g.*.cs`, implying a dependency on an external assembly containing converters.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Auto-generated and ephemeral**: All files are explicitly marked as `<auto-generated>` and warn that changes will be lost on regeneration. **Never modify these files directly.**
|
||||
- **Case-sensitive resource URIs**: URIs like `/DataPRO;component/app.xaml` (lowercase `app.xaml`) vs. `App.xaml` in source may cause issues if the actual file casing differs on case-sensitive filesystems (e.g., Linux).
|
||||
- **Hidden event wiring**: The `PageHeaderRibbon.g.cs` wires `btnChangeTestSetup_Click` without exposing the button name in the generated fields—this implies the button is declared in XAML but not referenced in code-behind, or its name is not exposed as a field (only used for event wiring).
|
||||
- **Unused field suppression**: Fields like `navControlGrids`, `actionControlGrids`, etc., are marked with `[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]`, indicating they are used via reflection (e.g., by `IComponentConnector`) and not directly in C#.
|
||||
- **No public API guarantees**: Types like `GeneratedInternalTypeHelper` are internal helpers with no stability guarantees across framework versions.
|
||||
- **`_CreateDelegate` implementation detail**: The `PageContentControl.g.cs` defines `_CreateDelegate` as `internal`, but `GeneratedInternalTypeHelper` calls it via reflection. This tight coupling is fragile and may break if the method name or signature changes.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,106 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/SensorLayout.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/SensorLayout.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/CheckHardware.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/CheckHardware.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/ArmCheckList.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/ArmCheckList.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/Download.g.cs
|
||||
generated_at: "2026-04-16T04:10:02.267895+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "ac0be56b9d6c9c76"
|
||||
---
|
||||
|
||||
# Documentation: `DataPROWin7.SubControls` Generated UI Classes
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module contains auto-generated WPF UI classes for several sub-controls used in the DataPRO application’s data collection workflow. These classes (`SensorLayout`, `CheckHardware`, `ArmCheckList`, `Download`) are partial implementations derived from XAML files and are responsible for initializing visual elements, wiring up event handlers, and managing the UI state for specific hardware validation and data acquisition steps. They inherit from `DataPROWin7.SubControls.SubControl` (except `SensorLayout`, which inherits from `UserControl`) and serve as the presentation layer for sensor assignment, hardware verification, and download operations.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes expose only one public method: `InitializeComponent()`. Event handlers referenced in the XAML (e.g., `HardwareChannelList_SelectionChanged`, `HardwareUnassign_Click`) are *not* defined in these generated files and must be implemented in the corresponding `.xaml.cs` files (not provided here).
|
||||
|
||||
### `SensorLayout`
|
||||
- **Inherits**: `System.Windows.Controls.UserControl`
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.SubControls.SensorLayout sensorBaseLayout`
|
||||
- `internal ListView lvChannels`
|
||||
- `internal ListView lvSensors`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()`
|
||||
Loads the associated XAML resource (`/DataPRO;component/collectdatasubcontrols/sensorlayout.xaml`) via `Application.LoadComponent`. Ensures initialization occurs only once.
|
||||
|
||||
### `CheckHardware`
|
||||
- **Inherits**: `DataPROWin7.SubControls.SubControl`
|
||||
- **Fields**:
|
||||
- `internal CheckHardware checkHardwarePage`
|
||||
- `internal StatusRibbon ctrlStatusRibbon`
|
||||
- `internal RadioButton rbTreeMode`, `rbExcelMode`
|
||||
- `internal Grid gridExcel`, `gridTreeDisplay`
|
||||
- `internal ContentControl ctrlIncludedContent`, `ctrlAvailableContent`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()`
|
||||
Loads XAML resource (`/DataPRO;component/collectdatasubcontrols/checkhardware.xaml`).
|
||||
- `internal Delegate _CreateDelegate(Type delegateType, string handler)`
|
||||
Helper for delegate creation (used by XAML parser).
|
||||
|
||||
### `ArmCheckList`
|
||||
- **Inherits**: `DataPROWin7.SubControls.SubControl`
|
||||
- **Fields**:
|
||||
- `internal ArmCheckList armSystem`
|
||||
- `internal StatusRibbon ctrlStatusRibbon`
|
||||
- `internal ContentControl ctrlSensorIdContainer`, `ctrlDASVoltageContainer`, `ctrlSquibContainer`, `ctrlEventLineContainer`, `ctrlLevelTriggerContainer`, `ctrlTiltSensorContainer`, `ctrlTemperatureContainer`, `ctrlClockSyncContainer`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()`
|
||||
Loads XAML resource (`/DataPRO;component/collectdatasubcontrols/armchecklist.xaml`).
|
||||
- `internal Delegate _CreateDelegate(Type delegateType, string handler)`
|
||||
|
||||
### `Download`
|
||||
- **Inherits**: `DataPROWin7.SubControls.SubControl`
|
||||
- **Fields**:
|
||||
- `internal Download downloadPage`
|
||||
- `internal StatusRibbon ctrlStatusRibbon`
|
||||
- `internal ContentControl downloadContentControl`
|
||||
- `internal RadioButton rbTreeMode`, `rbExcelMode`
|
||||
- `internal Grid gridExcel`, `gridTreeDisplay`, `TestObjects_Grid`, `DAS_Grid`
|
||||
- `internal ContentControl dgDiagnosticResultsContainer`
|
||||
- `internal GenericTable2 dgDiagnosticResults`
|
||||
- `internal ListView lvAllTestObjects`, `lvHardware`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()`
|
||||
Loads XAML resource (`/DataPRO;component/collectdatasubcontrols/download.xaml`).
|
||||
- `internal Delegate _CreateDelegate(Type delegateType, string handler)`
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- `_contentLoaded` flag ensures `InitializeComponent()` executes exactly once per instance.
|
||||
- All `internal` fields (e.g., `lvChannels`, `rbTreeMode`) are assigned during `Connect()` and must not be null after initialization.
|
||||
- `IComponentConnector.Connect()` is called exactly once per connection ID per instance, and all assignments are final.
|
||||
- Event handlers are attached only during `Connect()` and are never detached in this generated code.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* these classes:
|
||||
- **WPF Framework**: `System.Windows.*`, `System.Windows.Controls.*`, `System.Windows.Markup`
|
||||
- **Custom UI Libraries**:
|
||||
- `DataPROWin7` (namespace): `SubControl`, `StatusRibbon`, `GenericTable2`
|
||||
- `DTS.Common.*`: Controls, Converters, Enums
|
||||
- `Xceed.Wpf.Toolkit.*`: Extended WPF controls (e.g., `Zoombox`, `PropertyGrid`)
|
||||
- **XAML Resources**: Each class depends on its corresponding `.xaml` file (e.g., `SensorLayout.xaml`, `CheckHardware.xaml`).
|
||||
|
||||
### Dependencies *on* these classes:
|
||||
- Unknown from source alone. These are UI sub-controls likely instantiated by a parent window or navigation framework (e.g., `Frame`, `TabControl`) in the main application.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Auto-generated code**: All files are marked `<auto-generated>` and explicitly warn that manual changes will be lost on regeneration. Do not modify these files.
|
||||
- **Event handlers are unimplemented here**: Methods like `HardwareChannelList_SelectionChanged`, `HardwareUnassign_Click`, `rbTreeMode_Checked`, etc., are referenced but not defined. Their implementations must reside in the corresponding `.xaml.cs` files (not provided).
|
||||
- **Redundant `sensorBaseLayout`/`checkHardwarePage` fields**: Each class contains a field referencing itself (e.g., `sensorBaseLayout` of type `SensorLayout`). This is typical for WPF’s code-behind generation and may be unused or used for internal XAML binding.
|
||||
- **No public API surface**: These classes expose no public methods beyond `InitializeComponent()`. All meaningful behavior is implemented in the non-generated `.xaml.cs` files.
|
||||
- **No error handling in `InitializeComponent()`**: If XAML loading fails (e.g., missing resource), exceptions may occur at runtime with no defensive logic in this layer.
|
||||
- **Missing handler for `lvHardware_SelectionChanged` in `Download`**: The handler is attached in `Connect()`, but its implementation is not in this file.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/Diagnostics/CanDiagnosticResult.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/Diagnostics/CanDiagnosticResult.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/Diagnostics/DigitalInputDiagnosticResult.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/Diagnostics/DigitalInputDiagnosticResult.g.i.cs
|
||||
generated_at: "2026-04-16T04:11:02.541938+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "8849b6efc11c9411"
|
||||
---
|
||||
|
||||
# Documentation: Diagnostic Result User Controls
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module contains auto-generated WPF `UserControl` classes used to render diagnostic result views for specific hardware diagnostic types—specifically, CAN bus diagnostics (`CanDiagnosticResult`) and digital input diagnostics (`DigitalInputDiagnosticResult`). These classes serve as the UI layer components that display diagnostic outcomes in the DataPRO application, instantiated and managed by higher-level diagnostic UI containers. They are not business logic components but rather declarative UI wrappers that load their visual structure from corresponding `.xaml` files via WPF’s build-time tooling.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes are `public partial` and inherit from `System.Windows.Controls.UserControl`. They implement `System.Windows.Markup.IComponentConnector`.
|
||||
|
||||
### `CanDiagnosticResult`
|
||||
- **Namespace**: `DataPROWin7.CollectDataSubControls`
|
||||
- **Inherits**: `System.Windows.Controls.UserControl`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()`
|
||||
Loads the XAML content from `/DataPRO;component/collectdatasubcontrols/diagnostics/candiagnosticresult.xaml`. Ensures initialization occurs only once via `_contentLoaded` flag.
|
||||
|
||||
### `DigitalInputDiagnosticResult`
|
||||
- **Namespace**: `DataPROWin7.CollectDataSubControls`
|
||||
- **Inherits**: `System.Windows.Controls.UserControl`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()`
|
||||
Loads the XAML content from `/DataPRO;component/collectdatasubcontrols/diagnostics/digitalinputdiagnosticresult.xaml`. Ensures initialization occurs only once via `_contentLoaded` flag.
|
||||
|
||||
### Interface Implementation (`IComponentConnector.Connect`)
|
||||
- **Signature**: `void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target)`
|
||||
Marks `_contentLoaded = true` on first call. No further logic is present in the generated code. Used by WPF’s runtime binding infrastructure.
|
||||
|
||||
> **Note**: No additional public properties, events, or methods are defined in these generated files. Any application-specific logic (e.g., data binding, event handlers) resides in the corresponding `.xaml.cs` files (not provided here) or in the XAML markup.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- `_contentLoaded` is initialized to `false` and set to `true` on first invocation of `InitializeComponent()` or `IComponentConnector.Connect()`. Subsequent calls to `InitializeComponent()` are no-ops.
|
||||
- `InitializeComponent()` must be called exactly once per instance before the control is used in the visual tree. Calling it multiple times is safe (idempotent), but calling it after the control is part of the visual tree may cause undefined behavior.
|
||||
- Resource URIs are hardcoded relative URIs pointing to embedded resources in the `DataPRO` assembly:
|
||||
- `CanDiagnosticResult`: `/DataPRO;component/collectdatasubcontrols/diagnostics/candiagnosticresult.xaml`
|
||||
- `DigitalInputDiagnosticResult`: `/DataPRO;component/collectdatasubcontrols/diagnostics/digitalinputdiagnosticresult.xaml`
|
||||
- The `Connect()` method is only invoked by WPF’s XAML loader during component initialization and is not intended for manual use.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **WPF Framework Assemblies**: `System.Windows`, `System.Windows.Controls`, `System.Windows.Markup`, `System.Windows.Navigation`, `System.Windows.Media`, etc.
|
||||
- **Application-Specific Assemblies**:
|
||||
- `DataPROWin7` (contains shared types and possibly base classes)
|
||||
- `DTS.Common.Converters` (imported but not directly used in generated code—likely used in XAML or `.xaml.cs`)
|
||||
- **Build Tooling**: Generated by `PresentationBuildTasks` (MSBuild task), runtime version `4.0.30319.42000`.
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- Unknown from source alone. These controls are likely consumed by:
|
||||
- A diagnostic host view (e.g., `DiagnosticResultView.xaml`)
|
||||
- A navigation or tab container in the main UI
|
||||
- Possibly by code-behind in `CollectDataSubControls` or parent views (not visible here).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Auto-generated files**: These files are *not* meant to be manually edited. Any changes will be overwritten on rebuild. Custom logic must be added in the corresponding `.xaml.cs` files (e.g., `CanDiagnosticResult.xaml.cs`).
|
||||
- **No business logic present**: The source files contain only WPF plumbing code. Behavior (e.g., how diagnostic data is bound, displayed, or updated) is defined in the `.xaml` files and `.xaml.cs` files, which are not included.
|
||||
- **Hardcoded resource paths**: The URIs assume the XAML files are compiled as `Resource` (not `Page`) and embedded in the `DataPRO` assembly. If the build action changes, `Application.LoadComponent()` will fail at runtime.
|
||||
- **Namespace mismatch**: The namespace is `DataPROWin7.CollectDataSubControls`, but the assembly appears to be named `DataPRO` (based on the URI `/DataPRO;component/...`). Ensure the assembly name matches expectations.
|
||||
- **No public API surface**: Developers should not expect to interact with these classes beyond instantiation and adding them to a visual tree. No methods beyond `InitializeComponent()` are exposed or meaningful to call directly.
|
||||
|
||||
> **None identified from source alone.** (Note: This section is intentionally minimal—the source provides no insight into runtime behavior beyond initialization mechanics.)
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/Realtime/MeterGraph.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/Realtime/MeterGraph.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/Realtime/GraphPlotInfo.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/Realtime/GraphPlotInfo.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/Realtime/MeterMode.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/Realtime/MeterMode.g.cs
|
||||
generated_at: "2026-04-16T04:11:04.664747+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "ea9f3a7b5e361679"
|
||||
---
|
||||
|
||||
# Documentation: `MeterGraph`, `GraphPlotInfo`, and `MeterMode` Auto-Generated WPF UI Components
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
These three auto-generated files (`MeterGraph.g.cs`, `GraphPlotInfo.g.cs`, and `MeterMode.g.cs`) are WPF UI component stubs generated by the `PresentationBuildTasks` MSBuild target during compilation. They implement the `IComponentConnector` interface to wire up XAML-declared controls to their corresponding code-behind fields in the partial classes `MeterGraph`, `GraphPlotInfo`, and `MeterMode` (defined in `*.xaml.cs` files not included here). Their role is to enable runtime initialization of WPF user controls by loading their XAML resources and establishing connections between named elements in XAML and internal fields in the generated code. They do not contain business logic themselves but serve as infrastructure for the WPF framework to instantiate and connect UI components.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All three classes are `public partial class`es inheriting from `System.Windows.Controls.UserControl` and implementing `System.Windows.Markup.IComponentConnector`. They expose only the following methods:
|
||||
|
||||
### `MeterGraph`
|
||||
- **`public void InitializeComponent()`**
|
||||
Loads the associated XAML resource (`/DataPRO;component/collectdatasubcontrols/realtime/metergraph.xaml`) via `Application.LoadComponent`. Ensures initialization occurs only once via `_contentLoaded` flag.
|
||||
|
||||
### `GraphPlotInfo`
|
||||
- **`public void InitializeComponent()`**
|
||||
Loads the associated XAML resource (`/DataPRO;component/collectdatasubcontrols/realtime/graphplotinfo.xaml`) via `Application.LoadComponent`. Ensures initialization occurs only once via `_contentLoaded` flag.
|
||||
|
||||
### `MeterMode`
|
||||
- **`public void InitializeComponent()`**
|
||||
Loads the associated XAML resource (`/DataPRO;component/collectdatasubcontrols/realtime/metermode.xaml`) via `Application.LoadComponent`. Ensures initialization occurs only once via `_contentLoaded` flag.
|
||||
- **`internal System.Delegate _CreateDelegate(System.Type delegateType, string handler)`**
|
||||
Helper method used by the WPF build tools to create delegates for event handlers declared in XAML (e.g., `Click="Button_Click"`). Not intended for direct use.
|
||||
|
||||
All three classes implement the explicit interface method:
|
||||
- **`void IComponentConnector.Connect(int connectionId, object target)`**
|
||||
Maps `connectionId`s to internal field assignments based on XAML element names. This is called by the WPF runtime during component initialization to wire up named elements (e.g., `x:Name="ctrlGraph"` in XAML) to fields in the generated class.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- `_contentLoaded` is `false` initially and set to `true` after the first successful call to `InitializeComponent()`. Subsequent calls to `InitializeComponent()` are no-ops.
|
||||
- `InitializeComponent()` must be called exactly once per instance before any XAML-bound elements (e.g., `ctrlGraph`, `ddlSelectedChannel`) are accessed; otherwise, null reference exceptions may occur.
|
||||
- `IComponentConnector.Connect()` is called only during initialization and only with valid `connectionId`s defined in the XAML (1 for `MeterGraph`, 1–2 for `GraphPlotInfo`, 1–2 for `MeterMode`). Invalid `connectionId`s result in `_contentLoaded` being set to `true` prematurely, potentially masking missing element definitions.
|
||||
- All referenced XAML files must exist at the specified relative URIs (e.g., `/DataPRO;component/collectdatasubcontrols/realtime/metergraph.xaml`); otherwise, `Application.LoadComponent()` will throw an exception.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies (from source):
|
||||
- **WPF Framework Assemblies**: `System.Windows`, `System.Windows.Controls`, `System.Windows.Markup`, `System.Windows.Media`, etc. (via `using` directives).
|
||||
- **XAML Resources**:
|
||||
- `MeterGraph.xaml` → loaded by `MeterGraph.g.cs`
|
||||
- `GraphPlotInfo.xaml` → loaded by `GraphPlotInfo.g.cs`
|
||||
- `MeterMode.xaml` → loaded by `MeterMode.g.cs`
|
||||
All XAML files reside in `CollectDataSubControls/Realtime/`.
|
||||
|
||||
### External Dependencies:
|
||||
- **`DataPROWin7.CollectDataSubControls.MeterGraph`**: Referenced as `ctrlGraph` in `MeterGraph.g.cs` and `mainChart` in `MeterMode.g.cs`. This is the user-defined partial class (likely defined in `MeterGraph.xaml.cs`) containing the actual logic.
|
||||
- **`DataPROWin7.CollectDataSubControls.GraphPlotInfo`**: Referenced as `ctrlGraphPlotInfo` in `GraphPlotInfo.g.cs`. This is the user-defined partial class (likely defined in `GraphPlotInfo.xaml.cs`).
|
||||
- **`System.Windows.Controls.ComboBox`**: Referenced as `ddlSelectedChannel` in `GraphPlotInfo.g.cs`. Indicates `GraphPlotInfo.xaml` contains a `ComboBox` named `ddlSelectedChannel`.
|
||||
- **`System.Windows.Controls.Primitives.UniformGrid`**: Referenced as `SubGraphsGrid` in `MeterMode.g.cs`. Indicates `MeterMode.xaml` contains a `UniformGrid` named `SubGraphsGrid`.
|
||||
|
||||
### Inferred Usage:
|
||||
- `MeterMode` depends on `MeterGraph` (via `mainChart`), suggesting `MeterMode.xaml` embeds or hosts a `MeterGraph` control.
|
||||
- `GraphPlotInfo` likely provides UI controls (e.g., channel selection via `ddlSelectedChannel`) for configuring or inspecting data plotted in a graph.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Auto-generated files**: These files are regenerated on build. Manual edits will be lost. All logic must reside in the corresponding `*.xaml.cs` partial classes.
|
||||
- **No public API surface**: The classes themselves expose no public methods/properties beyond `InitializeComponent()` and `IComponentConnector`. Actual functionality is in the partial classes (not visible here).
|
||||
- **Field visibility**: Fields like `ctrlGraph`, `ddlSelectedChannel`, and `SubGraphsGrid` are `internal`, meaning they are only accessible within the same assembly. This is standard for WPF auto-generated code but may confuse developers expecting public accessors.
|
||||
- **`_CreateDelegate` is internal**: The `MeterMode.g.cs` file includes `_CreateDelegate`, which is used internally by the WPF build system to wire event handlers. It should not be called directly.
|
||||
- **Missing source files**: The actual logic (e.g., data binding, event handlers, business logic) resides in the corresponding `*.xaml.cs` files (e.g., `MeterGraph.xaml.cs`), which are not provided. Behavior of `MeterGraph`, `GraphPlotInfo`, and `MeterMode` cannot be fully understood from these files alone.
|
||||
- **No validation or error handling in generated code**: If XAML references a non-existent element (e.g., `x:Name="foo"` but no `foo` in XAML), `Connect()` will silently set `_contentLoaded = true` and skip assignment, potentially causing runtime null reference exceptions later.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/ResolveChannels/ResolveChannels.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/CollectDataSubControls/ResolveChannels/ResolveChannels.g.cs
|
||||
generated_at: "2026-04-16T04:11:15.721457+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "3e4d7466dc3f379b"
|
||||
---
|
||||
|
||||
# ResolveChannels Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
The `ResolveChannels` class is a WPF user control (subclass of `SubControl`) responsible for providing a UI to view, filter, and manage channel resolution states in the DataPRO application. It displays channels grouped into logical categories—unresolved, resolved, extra IDs, out-of-place, and hardware channels—and allows users to filter the displayed view using radio buttons for different channel states (All, Open, In Use, Manually Assigned). It integrates with a `StatusRibbon` for status reporting and uses named container `ContentControl`s to host dynamic channel-specific UI content.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
The class exposes only one public method, inherited from WPF component infrastructure:
|
||||
|
||||
- **`public void InitializeComponent()`**
|
||||
Initializes the control by loading its XAML definition (`ResolveChannels.xaml`) and wiring up event handlers for UI elements. Must be called once during construction (typically via the auto-generated partial constructor in the non-auto-generated `.cs` file, not shown here). Idempotent—safe to call multiple times.
|
||||
|
||||
The class implements `System.Windows.Markup.IComponentConnector`, but this is internal infrastructure for XAML parsing and not intended for direct use.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- The control inherits from `DataPROWin7.SubControls.SubControl`, implying it adheres to the base `SubControl` contract (not visible here, but assumed to define lifecycle and integration patterns for sub-controls in the application).
|
||||
- The `_contentLoaded` flag ensures `InitializeComponent()` is idempotent—XAML is loaded and event handlers attached only once.
|
||||
- The `connectionId` values in `IComponentConnector.Connect` are strictly ordered and fixed (1–11), implying tight coupling to the structure of `ResolveChannels.xaml`. Any change to the XAML element order or IDs would break this mapping.
|
||||
- All `internal` field names (`ctrl*`, `rb*`) are generated deterministically from XAML `x:Name` attributes and must match exactly between XAML and generated code.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
**Dependencies (imports/namespaces):**
|
||||
- `DataPROWin7` (root namespace)
|
||||
- `DataPROWin7.Common`, `DataPROWin7.Controls`, `DataPROWin7.SubControls` (other modules)
|
||||
- WPF core namespaces: `System.Windows.*`, `System.Windows.Controls.*`, `System.Windows.Markup`, `System.Diagnostics`, `System`
|
||||
|
||||
**Known external types used:**
|
||||
- `DataPROWin7.SubControls.ResolveChannels` (self-reference in field declaration—likely a typo or placeholder; should refer to the same class)
|
||||
- `DataPROWin7.Controls.StatusRibbon` (`ctrlStatusRibbon`)
|
||||
- `System.Windows.Controls.ContentControl` (for containers)
|
||||
- `System.Windows.Controls.RadioButton` (for filter buttons)
|
||||
|
||||
**Depended upon by:**
|
||||
- Presumably `DataPROWin7.SubControls.SubControl`-aware host code (e.g., main window or navigation manager) that instantiates and embeds `ResolveChannels` as a sub-control.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Field naming inconsistency**: The field `resolveChannels` is declared as type `DataPROWin7.SubControls.ResolveChannels` (same as the class), which is likely a code-generation artifact or typo—should probably be `this` or omitted. This may cause confusion or compilation issues if used.
|
||||
- **Typo in container name**: `ctrlExtraIdsContiner` (missing 'l' in "Container")—consistent in both generated files. A common source of copy-paste errors in manual code.
|
||||
- **Event handler names are inferred but not defined here**: The generated code wires `Checked` events to handlers named `rbAllChecked`, `rbOpenChecked`, `rbInUseChecked`, and `rbManuallyAssignedChecked`. Their implementations are not present in these files and must exist in the non-generated `.cs` partial class file.
|
||||
- **No public API for filtering or data binding**: The control exposes no public methods/properties to programmatically set filters or update channel data—interaction is expected to be UI-driven only. Data binding (if any) is likely handled internally via XAML.
|
||||
- **Hardcoded XAML path**: The `InitializeComponent()` method uses a fixed resource URI (`/DataPRO;component/collectdatasubcontrols/resolvechannels/resolvechannels.xaml`). Any renaming or relocation of the XAML file will break initialization.
|
||||
- **No documentation of channel resolution semantics**: The meaning of “unresolved”, “resolved”, “extra IDs”, “out-of-place”, and “hardware channels” is not defined in this file—requires external domain knowledge or other source files.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Common/ModalDialog.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Common/ModalDialog.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Common/ToastWindow.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Common/ToastWindow.g.i.cs
|
||||
generated_at: "2026-04-16T04:10:23.390644+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "15634ae50b045940"
|
||||
---
|
||||
|
||||
# Documentation: `DataPROWin7.Common` UI Components
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module contains auto-generated WPF UI components for two visual elements: `ModalDialog` and `ToastWindow`. These are generated files produced by the WPF build tooling (`PresentationBuildTasks`) from corresponding `.xaml` source files (`ModalDialog.xaml` and `ToastWindow.xaml`). The module serves as the runtime implementation layer for declarative UI definitions, enabling WPF’s component initialization and XAML-to-code binding infrastructure. It does not contain business logic but provides the foundational UI types used elsewhere in the application for displaying modal dialogs and transient toast notifications.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes are `public partial`, but the only *publicly callable* methods are those defined in the base types (`UserControl`, `Window`) and the auto-generated `InitializeComponent()` method. No custom public methods, properties, or events are defined in these generated files.
|
||||
|
||||
### `ModalDialog` class
|
||||
- **Namespace**: `DataPROWin7.Common`
|
||||
- **Base Type**: `System.Windows.Controls.UserControl`
|
||||
- **Interface Implemented**: `System.Windows.Markup.IComponentConnector`
|
||||
|
||||
#### `public void InitializeComponent()`
|
||||
- **Behavior**: Initializes the component by loading its XAML definition from the embedded resource `/DataPRO;component/common/modaldialog.xaml`. Ensures initialization occurs only once via `_contentLoaded` flag. Must be called before the control is used (typically invoked automatically by the constructor in the non-generated part of the partial class).
|
||||
- **Note**: This method is auto-generated and should not be called manually unless re-initializing the component (e.g., in test scenarios), and doing so may cause side effects if not handled carefully.
|
||||
|
||||
#### `internal System.Windows.Controls.UserControl controlUser`
|
||||
- **Purpose**: A field referencing a named element (`controlUser`) defined in `ModalDialog.xaml`. Used internally by the XAML loader to wire up named controls. Its usage is limited to the generated `Connect` method.
|
||||
|
||||
### `ToastWindow` class
|
||||
- **Namespace**: `DataPROWin7.Common`
|
||||
- **Base Type**: `System.Windows.Window`
|
||||
- **Interface Implemented**: `System.Windows.Markup.IComponentConnector`
|
||||
|
||||
#### `public void InitializeComponent()`
|
||||
- **Behavior**: Initializes the window by loading its XAML definition from `/DataPRO;component/common/toastwindow.xaml`. Also guarded by `_contentLoaded` to prevent duplicate initialization.
|
||||
|
||||
#### `internal System.Windows.Controls.Image ImageViewer`
|
||||
- **Purpose**: References a named `Image` control (`ImageViewer`) defined in `ToastWindow.xaml`. Used to bind or manipulate the image content.
|
||||
|
||||
#### `internal System.Windows.Controls.TextBlock ImageText`
|
||||
- **Purpose**: References a named `TextBlock` control (`ImageText`) defined in `ToastWindow.xaml`. Used to display text content.
|
||||
|
||||
#### `void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target)`
|
||||
- **Behavior**: Implements `IComponentConnector.Connect()` to wire up event handlers and assign named elements from XAML to fields. Specifically:
|
||||
- `connectionId == 1`: Attaches `Window_MouseUp` handler to the `MouseUp` event of the `ToastWindow` instance (`target`).
|
||||
- `connectionId == 2`: Assigns the `target` to `ImageViewer`.
|
||||
- `connectionId == 3`: Assigns the `target` to `ImageText`.
|
||||
- **Note**: This method is not intended for direct invocation; it is called by the WPF runtime during component initialization.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Single Initialization**: Both `ModalDialog` and `ToastWindow` enforce that `InitializeComponent()` is executed at most once via the `_contentLoaded` boolean field. Attempting to call it multiple times has no effect after the first invocation.
|
||||
- **XAML Resource Path**: The XAML resources are expected to be embedded as `Resource` build action files at the paths:
|
||||
- `/DataPRO;component/common/modaldialog.xaml`
|
||||
- `/DataPRO;component/common/toastwindow.xaml`
|
||||
Failure to build the XAML files with the correct build action or path will cause `Application.LoadComponent()` to fail at runtime.
|
||||
- **Control Naming Consistency**: The `connectionId` values and field names (`controlUser`, `ImageViewer`, `ImageText`) are strictly tied to the corresponding `x:Name` attributes in the `.xaml` files. Any mismatch in naming or ordering in the XAML will cause incorrect field assignments or runtime exceptions.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **WPF Runtime**: Requires `System.Windows.*` namespaces (e.g., `System.Windows.Controls`, `System.Windows.Markup`, `System.Windows.Application`).
|
||||
- **Build Tooling**: Generated by `PresentationBuildTasks` (version 4.0.0.0), indicating a .NET Framework 4.0+ WPF project.
|
||||
- **Source XAML Files**:
|
||||
- `..\..\..\..\Common\ModalDialog.xaml`
|
||||
- `..\..\..\..\Common\ToastWindow.xaml`
|
||||
These must exist and be correctly compiled for the generated code to function.
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- **Consumers**: Other parts of the `DataPROWin7` application (e.g., view models or services) likely instantiate and use `ModalDialog` and `ToastWindow` as UI components. The presence of `using DataPROWin7.Common;` in `ToastWindow.g.cs` confirms this namespace is part of the public API surface.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Auto-Generated Files**: These files are *not* meant to be edited manually. Any changes will be overwritten on rebuild. Custom logic must be added via partial class extensions in non-generated source files (e.g., `ModalDialog.xaml.cs`, `ToastWindow.xaml.cs`).
|
||||
- **No Public API Surface**: The generated code provides only infrastructure (XAML loading, field wiring). All meaningful behavior (e.g., dialog logic, toast animation, data binding) resides in the corresponding `.xaml.cs` files, which are *not* included in this source set. Thus, behavior such as how `ToastWindow` is shown, dismissed, or animated is not inferable from these files.
|
||||
- **Event Handler Dependency**: `ToastWindow`’s `Connect()` method assumes a `Window_MouseUp` handler exists in the *non-generated* part of the `ToastWindow` partial class. If that handler is missing, a `MissingMethodException` will occur at runtime during initialization.
|
||||
- **Hardcoded Resource URIs**: The URIs `/DataPRO;component/common/modaldialog.xaml` and `/DataPRO;component/common/toastwindow.xaml` are case-sensitive and path-sensitive. Renaming or moving the XAML files without updating the build system (e.g., via `msbuild` properties) will break initialization.
|
||||
- **Unused Fields**: Both classes declare fields (`controlUser`, `ImageViewer`, `ImageText`) marked with `[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]`, indicating they are used *only* via reflection or XAML wiring—not direct code access. This is normal for generated code but may trigger warnings in static analysis tools if the XAML changes.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/ViewGraphViewControl.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/ViewGraphViewControl.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/StatusRibbon.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/StatusRibbon.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/EditChannelCodesControl.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/EditChannelCodesControl.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/GridFullScreen.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/GridFullScreen.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/RealtimeFullScreen.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/RealtimeFullScreen.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/RenameTestControl.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/RenameTestControl.g.i.cs
|
||||
generated_at: "2026-04-16T04:10:23.583295+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "ef94a03c34dd3aba"
|
||||
---
|
||||
|
||||
# Documentation: Generated WPF Control Files (DataPROWin7.SubControls & DataPROWin7.Controls)
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
These files are **auto-generated WPF component connector files** produced by the `PresentationBuildTasks` MSBuild target during the build process. They are not manually written source code but rather runtime artifacts that bind XAML-defined UI elements to their corresponding C# partial classes (e.g., `ViewGraphViewControl`, `StatusRibbon`, etc.). Their purpose is to enable WPF’s `IComponentConnector` interface implementation for runtime initialization of named controls declared in XAML, including field assignment and event handler wiring. They do not contain business logic themselves but are essential for the correct instantiation and interconnection of UI controls at runtime.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes are `public partial` and implement `System.Windows.Markup.IComponentConnector`. They expose only the following methods:
|
||||
|
||||
### `public void InitializeComponent()`
|
||||
- **Signature**: `public void InitializeComponent()`
|
||||
- **Behavior**: Initializes the control by loading its associated XAML resource using `Application.LoadComponent(this, resourceLocater)`. The resource URI is relative (e.g., `/DataPRO;component/controls/viewgraphviewcontrol.xaml`). Ensures initialization occurs only once via `_contentLoaded` flag.
|
||||
|
||||
### `void IComponentConnector.Connect(int connectionId, object target)`
|
||||
- **Signature**: `void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target)`
|
||||
- **Behavior**: Assigns the `target` object to the appropriate internal field based on `connectionId`. This is used by the WPF runtime to wire up named elements from XAML (e.g., `x:Name="viewGraphViewControl"`) to their corresponding fields in the generated code. Also wires event handlers where specified (e.g., `Click` events for buttons). After processing, sets `_contentLoaded = true`.
|
||||
|
||||
### Internal Fields (assigned during `Connect`)
|
||||
| Class | Field | Type | `connectionId` |
|
||||
|-------|-------|------|----------------|
|
||||
| `ViewGraphViewControl` | `viewGraphViewControl` | `ViewGraphViewControl` | 1 |
|
||||
| `StatusRibbon` | `statusRibbon` | `StatusRibbon` | 1 |
|
||||
| `StatusRibbon` | `lblAggregateStatusText` | `TextBlock` | 2 |
|
||||
| `EditChannelCodesControl` | `editChannelCodes` | `EditChannelCodesControl` | 1 |
|
||||
| `EditChannelCodesControl` | `contentControl` | `ContentControl` | 2 |
|
||||
| `GridFullScreen` | `fullScreenRealtime` | `GridFullScreen` | 1 |
|
||||
| `GridFullScreen` | `CloseButton` | `Button` | 2 |
|
||||
| `RealtimeFullScreen` | `fullScreenRealtime` | `RealtimeFullScreen` | 1 |
|
||||
| `RealtimeFullScreen` | `backButton` | `Button` | 2 |
|
||||
| `RealtimeFullScreen` | `nextButton` | `Button` | 3 |
|
||||
| `RealtimeFullScreen` | `CloseButton` | `Button` | 4 |
|
||||
| `RenameTestControl` | `renameTestControl` | `RenameTestControl` | 1 |
|
||||
| `RenameTestControl` | `ctrlStatusRibbon` | `StatusRibbon` | 2 |
|
||||
| `RenameTestControl` | `tbTestSetupName` | `TextBox` | 3 |
|
||||
| `RenameTestControl` | `tbTestId` | `TextBox` | 4 |
|
||||
| `RenameTestControl` | `btnRename` | `Button` | 5 |
|
||||
|
||||
> **Note**: Event handlers are wired in `Connect` only for controls where the XAML specifies `Click="..."` (e.g., `CloseButton.Click += closeButton_Click`). The handler names (`closeButton_Click`, `btnRename_Click`, etc.) are inferred from the XAML and must be implemented in the corresponding partial class (not in these generated files).
|
||||
|
||||
### `RenameTestControl`-specific method
|
||||
#### `internal System.Delegate _CreateDelegate(System.Type delegateType, string handler)`
|
||||
- **Signature**: `internal System.Delegate _CreateDelegate(System.Type delegateType, string handler)`
|
||||
- **Behavior**: Helper used by the WPF runtime to create delegates for event handlers. Calls `Delegate.CreateDelegate(delegateType, this, handler)`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Initialization Guard**: `_contentLoaded` is `false` initially and set to `true` after `InitializeComponent()` completes or after `Connect()` finishes. Subsequent calls to `InitializeComponent()` return early if `_contentLoaded` is `true`.
|
||||
- **ConnectionId Mapping**: Each `connectionId` value uniquely maps to one field assignment or event wiring per control. No `connectionId` is reused within the same control.
|
||||
- **No Business Logic**: These files contain no domain logic, validation, or state mutation beyond UI wiring. All meaningful behavior resides in the non-generated partial classes (e.g., `ViewGraphViewControl.xaml.cs`).
|
||||
- **XAML-Driven**: Field names and types, event handler subscriptions, and `connectionId` values are strictly derived from the corresponding `.xaml` file’s `x:Name` attributes and event handlers.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* these files:
|
||||
- **WPF Runtime**: Requires `System.Windows.*` namespaces (e.g., `System.Windows.Controls`, `System.Windows.Markup`, `System.Windows.Application`).
|
||||
- **Project Types**: `DataPROWin7` (main project), `DataPROWin7.Controls`, `DataPROWin7.SubControls`.
|
||||
- **XAML Files**: Each `.g.cs`/`.g.i.cs` file is tightly coupled to a specific XAML file (e.g., `ViewGraphViewControl.g.cs` ↔ `ViewGraphViewControl.xaml`).
|
||||
- **External Libraries** (via imports):
|
||||
- `DTS.Common.Converters` (used in `EditChannelCodesControl`)
|
||||
- `Xceed.Wpf.Toolkit.*` (used in `RenameTestControl`)
|
||||
|
||||
### Dependencies *on* these files:
|
||||
- **Non-generated partial classes**: The corresponding `.xaml.cs` files (e.g., `ViewGraphViewControl.xaml.cs`) must declare the same partial class and implement any event handlers referenced in `Connect()` (e.g., `closeButton_Click`, `btnRename_Click`).
|
||||
- **UI Composition**: Controls like `RenameTestControl` depend on `StatusRibbon` (via `ctrlStatusRibbon` field), meaning `StatusRibbon.xaml` must be compiled and available.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Regeneration Risk**: These files are auto-generated and will be overwritten on rebuild. Manual edits are **not preserved** and will be lost.
|
||||
- **No Public API Surface**: These files are implementation details of WPF’s XAML infrastructure. Developers should not call `InitializeComponent()` or `Connect()` directly outside of the framework’s initialization pipeline.
|
||||
- **Event Handler Assumptions**: The presence of `this.CloseButton.Click += ...` in `Connect()` implies that a method named `closeButton_Click` (or similar) must exist in the *non-generated* partial class. If missing, a runtime `MissingMethodException` will occur.
|
||||
- **Case Sensitivity**: Field names (e.g., `fullScreenRealtime` vs. `fullScreenRealtime`) and `connectionId` order are strictly determined by XAML parsing and must match exactly.
|
||||
- **XAML URI Format**: Resource URIs use the pack URI format `/DataPRO;component/controls/[name].xaml`. Changes to project name or build action (e.g., `BuildAction=Page`) may break resource loading.
|
||||
- **No Documentation in Source**: These files contain no XML comments beyond auto-generated summaries (e.g., `/// <summary> InitializeComponent </summary>`). All meaningful documentation must come from the source XAML and `.xaml.cs` files.
|
||||
|
||||
> **None identified from source alone.**
|
||||
@@ -0,0 +1,154 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/ActionLabel.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/ActionLabel.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/NavStepActionButton.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/NavStepActionButton.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/PageButton.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/PageButton.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/ActionButton.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/ActionButton.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/ActionRadioButton.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/ActionRadioButton.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/combobox.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/combobox.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/ModalUserPrompt.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/ModalUserPrompt.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/CustomUIElements/ModalLicensePrompt.g.cs
|
||||
generated_at: "2026-04-16T04:12:46.086061+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "be0f9a2358459c39"
|
||||
---
|
||||
|
||||
# Custom UI Elements Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module contains auto-generated WPF code for a set of custom user interface controls used throughout the DataPRO application. These controls are wrappers around standard WPF controls (Button, RadioButton, etc.) and custom user controls, designed to provide consistent behavior and styling across the UI. The generated code handles XAML resource loading and component connection logic for controls defined in `ActionLabel.xaml`, `ActionButton.xaml`, `ActionRadioButton.xaml`, `NavStepActionButton.xaml`, `PageButton.xaml`, `combobox.xaml`, `ModalUserPrompt.xaml`, and `ModalLicensePrompt.xaml`. These controls serve as reusable UI building blocks for navigation, user prompts, and interactive elements.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes are partial and reside in the `DataPROWin7.Controls` or `DataPROWin7.Controls.CustomUIElements` namespaces. They implement `System.Windows.Markup.IComponentConnector` to support WPF's XAML initialization.
|
||||
|
||||
### `ActionLabel`
|
||||
- **Namespace**: `DataPROWin7.Controls`
|
||||
- **Inherits**: `System.Windows.Controls.UserControl`
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.Controls.ActionLabel thislabel;` — Reference to itself (used for XAML binding).
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()` — Loads the associated XAML resource (`/DataPRO;component/controls/customuielements/actionlabel.xaml`) via `Application.LoadComponent`. Idempotent (only loads once).
|
||||
|
||||
### `ActionButton`
|
||||
- **Namespace**: `DataPROWin7.Controls`
|
||||
- **Inherits**: `System.Windows.Controls.UserControl`
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.Controls.ActionButton thisbutton;`
|
||||
- `internal System.Windows.Controls.Button theactualbutton;`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()` — Loads XAML resource `/DataPRO;component/controls/customuielements/actionbutton.xaml`.
|
||||
- `void IComponentConnector.Connect(int connectionId, object target)` — Connects XAML elements:
|
||||
- `connectionId = 1`: Assigns `thisbutton = (ActionButton)target`.
|
||||
- `connectionId = 2`: Assigns `theactualbutton = (Button)target` and wires `theactualbutton.Click += Button_Click`.
|
||||
|
||||
### `ActionRadioButton`
|
||||
- **Namespace**: `DataPROWin7.Controls`
|
||||
- **Inherits**: `System.Windows.Controls.UserControl`
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.Controls.ActionRadioButton thisbutton;`
|
||||
- `internal System.Windows.Controls.RadioButton theactualbutton;`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()` — Loads XAML resource `/DataPRO;component/controls/customuielements/actionradiobutton.xaml`.
|
||||
- `void IComponentConnector.Connect(int connectionId, object target)` — Connects XAML elements:
|
||||
- `connectionId = 1`: Assigns `thisbutton`.
|
||||
- `connectionId = 2`: Assigns `theactualbutton` and wires `theactualbutton.Click += Button_Click`.
|
||||
|
||||
### `NavStepActionButton`
|
||||
- **Namespace**: `DataPROWin7.Controls.CustomUIElements`
|
||||
- **Inherits**: `System.Windows.Controls.UserControl`
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.Controls.CustomUIElements.NavStepActionButton actionButton;`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()` — Loads XAML resource `/DataPRO;component/controls/customuielements/navstepactionbutton.xaml`.
|
||||
- `void IComponentConnector.Connect(int connectionId, object target)` — Connects XAML elements:
|
||||
- `connectionId = 1`: Assigns `actionButton`.
|
||||
- `connectionId = 2`: Assigns a `Button` target and wires `Click += actionButton_Click`.
|
||||
|
||||
### `PageButton`
|
||||
- **Namespace**: `DataPROWin7.Controls`
|
||||
- **Inherits**: `System.Windows.Controls.UserControl`
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.Controls.PageButton thisbutton;`
|
||||
- `internal System.Windows.Controls.Button theactualbutton;`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()` — Loads XAML resource `/DataPRO;component/controls/customuielements/pagebutton.xaml`.
|
||||
- `void IComponentConnector.Connect(int connectionId, object target)` — Connects XAML elements:
|
||||
- `connectionId = 1`: Assigns `thisbutton`.
|
||||
- `connectionId = 2`: Assigns `theactualbutton` and wires `theactualbutton.Click += Button_Click`.
|
||||
|
||||
### `combobox`
|
||||
- **Namespace**: `DataPROWin7.Controls.CustomUIElements`
|
||||
- **Inherits**: `System.Windows.ResourceDictionary`
|
||||
- **Implements**: `IComponentConnector`, `IStyleConnector`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()` — Loads XAML resource `/DataPRO;component/controls/customuielements/combobox.xaml`.
|
||||
- `void IComponentConnector.Connect(int connectionId, object target)` — No-op (does not assign any fields).
|
||||
- `void IStyleConnector.Connect(int connectionId, object target)` — Adds a `ToolTipOpening` event handler (`ToolTipEventHandler`) to the style via `EventSetter`.
|
||||
|
||||
### `ModalUserPrompt`
|
||||
- **Namespace**: `DataPROWin7.Controls`
|
||||
- **Inherits**: `System.Windows.Controls.UserControl`
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.Controls.ModalUserPrompt myControl;`
|
||||
- `internal System.Windows.Controls.Grid ModalContent;`
|
||||
- `internal System.Windows.Controls.Grid buttonGrid;`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()` — Loads XAML resource `/DataPRO;component/controls/customuielements/modaluserprompt.xaml`.
|
||||
- `void IComponentConnector.Connect(int connectionId, object target)` — Connects XAML elements:
|
||||
- `connectionId = 1`: Assigns `myControl`.
|
||||
- `connectionId = 2`: Assigns `ModalContent`.
|
||||
- `connectionId = 3`: Assigns `buttonGrid`.
|
||||
|
||||
### `ModalLicensePrompt`
|
||||
- **Namespace**: `DataPROWin7.Controls`
|
||||
- **Inherits**: `System.Windows.Controls.UserControl`
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.Controls.ModalLicensePrompt myControl;`
|
||||
- `internal System.Windows.Controls.Grid ModalContent;`
|
||||
- `internal System.Windows.Controls.Grid buttonGrid;`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent()` — Loads XAML resource `/DataPRO;component/controls/customuielements/modallicenseprompt.xaml`.
|
||||
- `void IComponentConnector.Connect(int connectionId, object target)` — Connects XAML elements:
|
||||
- `connectionId = 1`: Assigns `myControl`.
|
||||
- `connectionId = 2`: Assigns `ModalContent`.
|
||||
- `connectionId = 3`: Assigns `buttonGrid`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Initialization idempotency**: `InitializeComponent()` sets `_contentLoaded = true` and returns early if already loaded.
|
||||
- **Component connection safety**: `IComponentConnector.Connect` only assigns fields for known `connectionId` values; otherwise, it sets `_contentLoaded = true`.
|
||||
- **XAML resource path consistency**: All controls load XAML from relative URIs of the form `/DataPRO;component/controls/customuielements/{controlname}.xaml`.
|
||||
- **Event wiring**: For controls with buttons/radiobuttons, event handlers are attached only once during connection (via `+=`), and no deduplication logic is present in the generated code (reliance on WPF’s event system).
|
||||
- **No manual logic**: All public methods are auto-generated and contain no custom business logic.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **WPF framework assemblies** (explicitly imported via `using` statements):
|
||||
`System.Windows.*`, `System.Windows.Controls.*`, `System.Windows.Markup`, `System.Windows.Media.*`, etc.
|
||||
- **Application-level types** (referenced in `ModalUserPrompt.g.i.cs` and `ModalLicensePrompt.g.i.cs`):
|
||||
`DataPROWin7` and `DataPROWin7.Common` namespaces (not included in source; inferred from `using` directives).
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- **Custom UI controls** (`ActionLabel`, `ActionButton`, `ActionRadioButton`, `NavStepActionButton`, `PageButton`, `combobox`, `ModalUserPrompt`, `ModalLicensePrompt`) are used elsewhere in the codebase as reusable components.
|
||||
- **XAML files** (not provided) define the visual structure and event handlers (`Button_Click`, `actionButton_Click`, `ToolTipEventHandler`, etc.) referenced in the generated code.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Auto-generated code**: All files are explicitly marked as `<auto-generated>` and warn that manual changes will be lost on regeneration. Do not modify these files directly.
|
||||
- **Event handler names are not defined here**: The handlers `Button_Click`, `actionButton_Click`, and `ToolTipEventHandler` are referenced but not defined in the provided source. Their implementations must exist in the corresponding `.xaml.cs` partial classes (not included).
|
||||
- **`combobox` is a `ResourceDictionary`**: Unlike other controls, `combobox` is a style/resource dictionary, not a `UserControl`. It is used for theming, not as a standalone UI element.
|
||||
- **Field naming inconsistency**: Some controls use `thisbutton`/`thislabel`, others use `actionButton`/`myControl`. This reflects the XAML `x:Name` attributes, but may cause confusion.
|
||||
- **No public API surface**: These classes expose only initialization logic. All meaningful behavior resides in the corresponding `.xaml.cs` files (not provided), which are not documented here.
|
||||
- **Namespace fragmentation**: Controls are split between `DataPROWin7.Controls` and `DataPROWin7.Controls.CustomUIElements` namespaces, with no clear pattern in the source (e.g., `combobox` is in `CustomUIElements`, while `ActionButton` is in `Controls`).
|
||||
- **Unused fields**: All internal fields (e.g., `thisbutton`, `theactualbutton`) are marked with `[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]`, indicating they are used only via reflection (XAML connection), not direct code access.
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DAS/EditDASRecordControl.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DAS/EditDASRecordControl.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DAS/BuildTestSetupControl.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DAS/BuildTestSetupControl.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DAS/DataRecodersTileControl.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DAS/DataRecodersTileControl.g.i.cs
|
||||
generated_at: "2026-04-16T04:11:52.688805+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "ccf88cd15eca0f90"
|
||||
---
|
||||
|
||||
# Documentation: `EditDASRecordControl`, `BuildTestSetupControl`, `DataRecodersTileControl`
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
These three files (`EditDASRecordControl`, `BuildTestSetupControl`, and `DataRecodersTileControl`) are auto-generated WPF UI control classes that serve as the code-behind implementation for corresponding XAML-defined user controls in the Data Acquisition System (DAS) module of the DataPRO application. They implement the `IComponentConnector` interface to wire up named UI elements declared in XAML to internal fields, and initialize component resources via `Application.LoadComponent`. These controls are part of the UI layer for managing and displaying DAS-related data (e.g., calibration records, test setups, hardware status), but **no business logic is present in these files**—they are purely infrastructure for XAML runtime binding and element access.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All three classes are partial, internal WPF `UserControl` subclasses implementing `IComponentConnector`. They expose only the following public members:
|
||||
|
||||
### `EditDASRecordControl`
|
||||
- **`public void InitializeComponent()`**
|
||||
Initializes the control by loading its XAML resource (`/DataPRO;component/controls/das/editdasrecordcontrol.xaml`) via `Application.LoadComponent`. Ensures initialization occurs only once.
|
||||
|
||||
### `BuildTestSetupControl`
|
||||
- **`public void InitializeComponent()`**
|
||||
Initializes the control by loading its XAML resource (`/DataPRO;component/controls/das/buildtestsetupcontrol.xaml`) via `Application.LoadComponent`. Ensures initialization occurs only once.
|
||||
- **`internal System.Delegate _CreateDelegate(System.Type delegateType, string handler)`**
|
||||
Helper method used by the XAML parser to create delegates for event handlers (e.g., `Click` events). Not intended for direct use.
|
||||
|
||||
### `DataRecodersTileControl`
|
||||
- **`public void InitializeComponent()`**
|
||||
Initializes the control by loading its XAML resource (`/DataPRO;component/controls/das/datarecoderstilecontrol.xaml`) via `Application.LoadComponent`. Ensures initialization occurs only once.
|
||||
|
||||
> **Note**: All three classes also implement the explicit interface method `IComponentConnector.Connect(int connectionId, object target)`, but it is marked `[EditorBrowsable(EditorBrowsableState.Never)]` and is not intended for public consumption.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Initialization idempotency**: `InitializeComponent()` is safe to call multiple times; it sets `_contentLoaded = true` after the first call and returns early on subsequent invocations.
|
||||
- **XAML resource path correctness**: Each control’s XAML must reside at the exact relative URI path specified in `resourceLocater` (e.g., `/DataPRO;component/controls/das/editdasrecordcontrol.xaml`). Mismatched paths will cause runtime failures.
|
||||
- **Connection ID mapping**: The `Connect` method relies on deterministic `connectionId` values assigned by the XAML compiler. These IDs must match those in the corresponding `.xaml` files; otherwise, UI elements will not be wired correctly.
|
||||
- **No runtime state mutation**: These classes do not define or mutate any application state beyond internal field assignments during initialization.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* these generated files:
|
||||
- **WPF runtime**: `System.Windows.*`, `System.Windows.Controls.*`, `System.Windows.Markup`, `System.Windows.Media.*`, etc.
|
||||
- **XAML Behaviors library**: `Microsoft.Xaml.Behaviors.*` (used in `EditDASRecordControl` only).
|
||||
- **Common libraries**:
|
||||
- `DTS.Common.Behaviors`, `DTS.Common.Controls` (for `EditDASRecordControl`)
|
||||
- `DataPROWin7`, `DataPROWin7.Common`, `DataPROWin7.Controls`, `DataPROWin7.Controls.CustomUIElements` (for `BuildTestSetupControl` and `DataRecodersTileControl`)
|
||||
- **XAML source files**:
|
||||
- `EditDASRecordControl.xaml`
|
||||
- `BuildTestSetupControl.xaml`
|
||||
- `DataRecodersTileControl.xaml`
|
||||
|
||||
### Dependencies *on* these files:
|
||||
- **Consumed by**: The WPF application’s main UI (likely `MainWindow.xaml` or a parent control) that includes these controls via XAML `<local:EditDASRecordControl />`-style declarations.
|
||||
- **Generated by**: `PresentationBuildTasks` (MSBuild tooling) during compilation, based on the corresponding `.xaml` files.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Auto-generated code**: These files are **not meant to be manually edited**. Changes will be overwritten on rebuild. All logic must reside in the corresponding `.xaml.cs` files (not provided here).
|
||||
- **Unused field suppression**: Fields like `editDASRecordControl`, `ViewContainer`, `ctrlStatusRibbon`, etc., are marked with `[SuppressMessage("Microsoft.Performance", "CA1823")]` because they are assigned at runtime via `Connect` but never explicitly referenced in the generated code. This is expected and safe.
|
||||
- **Event wiring is implicit**: Event handlers (e.g., `dgTestSetupSelector_Click`, `rbShowModules_Clicked`) are wired in `Connect` but their implementations are *not* present in these files—they must be defined in the partial class (`.xaml.cs`) files.
|
||||
- **Namespace inconsistency**: `DataRecodersTileControl` resides in `DataPROWin7.Controls.DAS`, while the others are in `DataPROWin7.Controls`. Ensure correct namespace usage when referencing.
|
||||
- **No public API surface**: These classes expose no public methods/properties beyond `InitializeComponent()` and `Connect()`. Any interaction must occur through public APIs defined in the associated `.xaml.cs` files (not documented here).
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DAS/HardwareDiscovery/HardwareDiscoveryControl.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DAS/HardwareDiscovery/HardwareDiscoveryControl.g.cs
|
||||
generated_at: "2026-04-16T04:12:54.980453+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "6277c1da3a806db4"
|
||||
---
|
||||
|
||||
# HardwareDiscovery
|
||||
|
||||
## Documentation: `HardwareDiscoveryControl`
|
||||
|
||||
### 1. Purpose
|
||||
`HardwareDiscoveryControl` is a WPF `UserControl` that provides the UI for discovering and managing hardware devices (specifically DAS units, modules, sensors, and channels) in the DataPRO system. It presents two main views: *Included DAS* (currently selected/active devices) and *Available DAS* (discoverable devices), with filtering, inclusion, and display options. The control integrates with a `StatusRibbon` for status feedback and supports IP-based discovery via multicast, as well as filtering by device type (TDAS, SLICE, or All). It is auto-generated from XAML and serves as the view layer in a likely MVVM or code-behind-driven architecture.
|
||||
|
||||
### 2. Public Interface
|
||||
The class `HardwareDiscoveryControl` inherits from `System.Windows.Controls.UserControl` and implements `System.Windows.Markup.IComponentConnector`. It exposes only one *public* method:
|
||||
|
||||
- **`public void InitializeComponent()`**
|
||||
Initializes the control by loading its XAML resource (`/DataPRO;component/controls/das/hardwarediscovery/hardwarediscoverycontrol.xaml`) via `Application.LoadComponent`. Idempotent — safe to call multiple times; subsequent calls are no-ops.
|
||||
|
||||
All other members are `internal` fields and event handlers tied to UI elements defined in the XAML. These are *not* part of the public API and are auto-generated.
|
||||
|
||||
### 3. Invariants
|
||||
- `_contentLoaded` ensures `InitializeComponent()` executes exactly once per instance.
|
||||
- The control is strictly UI-bound: it does not perform discovery itself (no logic for scanning hardware is present in this file).
|
||||
- All named UI elements (`hardwareDiscovery`, `ctrlStatusRibbon`, `rbMulticastIP`, etc.) are assumed to be defined in the corresponding `HardwareDiscoveryControl.xaml` file (not provided), and their `connectionId` mappings in `IComponentConnector.Connect` must match XAML `x:Name` attributes and control hierarchy.
|
||||
- Event handlers (e.g., `rbMulticastIP_Click`, `btnAdd_Click`, `rbTDASFilter_Checked`) are wired *only* via the generated `Connect` method — no other event subscriptions appear in this file.
|
||||
|
||||
### 4. Dependencies
|
||||
**Imports/References (from generated code):**
|
||||
- `System.Windows.*` (WPF core namespaces)
|
||||
- `DataPROWin7`, `DataPROWin7.Controls` (internal project namespaces)
|
||||
- `DTS.Common.Controls` (likely shared UI utilities)
|
||||
|
||||
**Assumed Dependencies (inferred from field types):**
|
||||
- `DataPROWin7.Controls.StatusRibbon` (`ctrlStatusRibbon`) — used for status display.
|
||||
- `DataPROWin7.Controls.HardwareDiscoveryControl` (`hardwareDiscovery`) — *self-reference*; likely a naming artifact or placeholder (field name matches class name, but type is identical to the containing class — may indicate a bug or XAML naming issue).
|
||||
- `System.Windows.Controls.RichTextBox` (`rtbIPAddresses`) — for displaying discovered IP addresses.
|
||||
- `System.Windows.Controls.Primitives.ToggleButton` (`rbMulticastIP`, `rbShowModules`, `rbIncludeConnected`, `rbTDASFilter`, `rbSLICEFilter`, `rbALLFilter`) — for UI toggles.
|
||||
- `System.Windows.Controls.ContentControl` (`ctrlTableContainer`, `ctrlTableAvailableContainer`, `ctrlSensorsContainer`, `ctrlChannelsContainer`) — containers for dynamic content (tables, lists).
|
||||
|
||||
**Depended on by:**
|
||||
- Likely consumed by a parent view or window (e.g., main DAS configuration window), but no explicit callers are visible in this file.
|
||||
|
||||
### 5. Gotchas
|
||||
- **Self-referential field:** The field `internal DataPROWin7.Controls.HardwareDiscoveryControl hardwareDiscovery;` (line 11) is suspicious — it points to an instance of its *own* type, which is almost certainly an error in the XAML (e.g., a misnamed `x:Name` or incorrect root element). This may cause runtime issues or null references.
|
||||
- **Unused fields:** All `internal` fields are marked with `[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]`, indicating they are *not* referenced in the generated code-behind — they exist solely to satisfy the XAML parser’s requirement for named elements. Actual logic (e.g., button click handlers) must be implemented in a separate partial class file (not provided here).
|
||||
- **Event handler names are implied, not defined:** Methods like `rbMulticastIP_Click`, `btnAdd_Click`, `rbShowModules_Clicked`, `rbTDASFilter_Checked`, etc., are *referenced* in `Connect()` but *not declared* in this file. Their implementations must reside in another partial definition of `HardwareDiscoveryControl`.
|
||||
- **No public API for logic:** This file is purely infrastructure for UI initialization. Developers must locate the *non-generated* partial class (e.g., `HardwareDiscoveryControl.xaml.cs`) to understand behavior, data binding, or discovery logic.
|
||||
- **No validation or state logic visible:** Filtering behavior (e.g., `rbTDASFilter_Checked` → `toggleButton_Unchecked`) suggests shared handler logic (`toggleButton_Unchecked`), but the semantics (e.g., mutual exclusivity of filters) are not evident here.
|
||||
|
||||
**None identified from source alone.**
|
||||
*(Note: While the above gotchas are inferred from code structure, the absence of the actual logic and XAML means behavioral details like filter interactions or inclusion rules remain ambiguous.)*
|
||||
@@ -0,0 +1,113 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DataExports/DataHDFExportOptions.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DataExports/DataHDFExportOptions.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DataExports/DataEmptyExportOptions.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DataExports/DataEmptyExportOptions.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DataExports/DataSimpleChapter10ExportOptions.g.i.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DataExports/DataSimpleChapter10ExportOptions.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DataExports/DataDiademExportOptions.g.cs
|
||||
- DataPRO/DataPRO/obj/x86/Debug/Controls/DataExports/DataDiademExportOptions.g.i.cs
|
||||
generated_at: "2026-04-16T04:11:51.384967+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "ea6a38293cace173"
|
||||
---
|
||||
|
||||
# Documentation: DataExport Options Controls
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module contains auto-generated WPF UI controls that implement export configuration UIs for various data export formats (HDF, Diadem, Simple Chapter 10, and an empty/no-op exporter). These controls are `UserControl` subclasses used to present format-specific export options to the user in a GUI. They are part of the `DataPROWin7.Controls` namespace and are generated from corresponding XAML files during the build process. The module serves as the presentation layer for export settings, with no business logic—its sole responsibility is to instantiate and wire up UI elements defined in XAML.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes are partial and generated. They expose only the standard WPF `UserControl` public interface plus one internal field and two methods required for WPF component initialization.
|
||||
|
||||
### `DataHDFExportOptions`
|
||||
- **Namespace**: `DataPROWin7.Controls`
|
||||
- **Base Type**: `System.Windows.Controls.UserControl`
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.Controls.DataHDFExportOptions exportOptions;`
|
||||
Self-reference to the control instance (used by XAML loader).
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent();`
|
||||
Initializes the control by loading its XAML definition from `/DataPRO;component/controls/dataexports/datahdfexportoptions.xaml`. Ensures initialization occurs only once via `_contentLoaded` flag.
|
||||
|
||||
### `DataEmptyExportOptions`
|
||||
- **Namespace**: `DataPROWin7.Controls`
|
||||
- **Base Type**: `System.Windows.Controls.UserControl`
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.Controls.DataEmptyExportOptions exportOptions;`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent();`
|
||||
Initializes the control from `/DataPRO;component/controls/dataexports/dataemptyexportoptions.xaml`.
|
||||
|
||||
### `DataSimpleChapter10ExportOptions`
|
||||
- **Namespace**: `DataPROWin7.Controls`
|
||||
- **Base Type**: `DataPROWin7.Controls.DataExports.DataROIAwareBase` *(Note: Base class not included in this source set)*
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.Controls.DataSimpleChapter10ExportOptions exportOptions;`
|
||||
- `internal System.Windows.Controls.ItemsControl icRegionsOfInterest;`
|
||||
- `internal System.Windows.Controls.ContentControl ChannelSelectContent;`
|
||||
- `internal System.Windows.Controls.ItemsControl icEvent;`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent();`
|
||||
Initializes the control from `/DataPRO;component/controls/dataexports/datasimplechapter10exportoptions.xaml`.
|
||||
|
||||
### `DataDiademExportOptions`
|
||||
- **Namespace**: `DataPROWin7.Controls`
|
||||
- **Base Type**: `System.Windows.Controls.UserControl`
|
||||
- **Fields**:
|
||||
- `internal DataPROWin7.Controls.DataDiademExportOptions exportOptions;`
|
||||
- `internal System.Windows.Controls.ComboBox cmbDiademChannelName200;`
|
||||
- `internal System.Windows.Controls.ComboBox cmbDiademUserComment201;`
|
||||
- `internal System.Windows.Controls.ComboBox cmbDiademReserved1_301;`
|
||||
- `internal System.Windows.Controls.ComboBox cmbDiademReserved2_302;`
|
||||
- **Methods**:
|
||||
- `public void InitializeComponent();`
|
||||
Initializes the control from `/DataPRO;component/controls/dataexports/datadiademexportoptions.xaml`.
|
||||
|
||||
### Interface Implementation
|
||||
All classes implement `System.Windows.Markup.IComponentConnector`:
|
||||
- `void Connect(int connectionId, object target)`
|
||||
Wires up XAML-declared UI elements to fields in the generated class. Each `connectionId` maps to a named element in the XAML:
|
||||
- `connectionId = 1`: Assigns `this.exportOptions = (this)` (self-reference).
|
||||
- `connectionId = 2–5` (only in `DataDiademExportOptions`): Assigns and subscribes event handlers for `ComboBox` controls:
|
||||
- `cmbDiademChannelName200`: Subscribes to `SelectionChanged` and `GotFocus` (calls `SelectAllText`).
|
||||
- `cmbDiademUserComment201`, `cmbDiademReserved1_301`, `cmbDiademReserved2_302`: Same event subscriptions.
|
||||
- `connectionId = 2–4` (only in `DataSimpleChapter10ExportOptions`): Assigns `icRegionsOfInterest`, `ChannelSelectContent`, and `icEvent`.
|
||||
|
||||
> **Note**: Event handler methods (`cmbDiadem*_*_SelectionChanged`, `SelectAllText`) are *not defined* in these generated files and must be implemented in the corresponding `.xaml.cs` partial class files.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Single Initialization**: `_contentLoaded` ensures `InitializeComponent()` executes exactly once per instance.
|
||||
- **XAML Consistency**: The generated code strictly mirrors the XAML file referenced in `resourceLocater`. Any mismatch between XAML element names/IDs and `connectionId` mappings would cause runtime errors.
|
||||
- **No Business Logic**: These classes contain no validation or export logic—only UI wiring. All export behavior resides elsewhere (e.g., view models or export handlers).
|
||||
- **Internal Self-Reference**: The `exportOptions` field always refers to the current instance (`this`). This is a WPF pattern for XAML-to-code binding.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **WPF Framework**: `System.Windows.*`, `System.Windows.Controls.*`, `System.Windows.Markup`, etc.
|
||||
- **Project-Specific Types**:
|
||||
- `DataPROWin7` (root namespace)
|
||||
- `DataPROWin7.Controls.DataExports.DataROIAwareBase` (for `DataSimpleChapter10ExportOptions`)
|
||||
- `DTS.Common.Controls` (for `DataDiademExportOptions`)
|
||||
- `DTS.Common.Converters` (for `DataEmptyExportOptions`)
|
||||
- `DataPROWin7.Controls.Settings` (for `DataEmptyExportOptions`, `DataDiademExportOptions`)
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- **Unknown from source alone**: These controls are consumed by other parts of the application (e.g., export dialogs or view models), but no references to them appear in the provided files. The presence of `DataROIAwareBase` suggests a hierarchy of export options controls, but its definition is not included.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Auto-Generated Code**: All files are marked `<auto-generated>` and explicitly warn that manual edits will be lost on regeneration. Do not modify these files directly.
|
||||
- **Missing Event Handlers**: Event subscriptions (e.g., `SelectionChanged`, `GotFocus`) for `DataDiademExportOptions` reference methods (`cmbDiadem*_*_SelectionChanged`, `SelectAllText`) that are *not defined* in these files. These must be implemented in the corresponding `.xaml.cs` files.
|
||||
- **Unused Fields**: All internal fields (e.g., `exportOptions`, `cmbDiadem*`) are decorated with `[SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]`, indicating they are used via reflection (XAML loader) but appear unused to static analyzers.
|
||||
- **Case Sensitivity**: Resource URIs are case-sensitive (e.g., `/DataPRO;component/controls/dataexports/datadiademexportoptions.xaml`). A mismatch in casing between XAML filename and URI will cause runtime failures.
|
||||
- **Base Class Omission**: `DataSimpleChapter10ExportOptions` inherits from `DataROIAwareBase`, but this base class is not provided. Its behavior (e.g., ROI handling) is unknown from this source.
|
||||
- **No Public API**: These classes expose *no public methods or properties beyond WPF defaults*. Any configuration must occur through data binding to properties defined in the `.xaml.cs` or view model layers.
|
||||
|
||||
> **Note**: No other non-obvious behavior, tech debt, or quirks are identifiable from these generated files alone.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user