This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,262 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Model/Enums.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Model/TestModificationModel.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Model/TestModelManipulation.cs
generated_at: "2026-04-16T11:09:33.877186+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "1e3214665d63bf12"
---
# Test Modification Module Documentation
## 1. Purpose
This module provides functionality for modifying test data within the DTS Viewer application. It manages the state of user-initiated modifications to channel parameters (sensitivity, EU multiplier/offset, T0 timing, line fit, software filters, data flags, and descriptions) and handles the persistence of these changes to both `.dts` metadata files and binary `.chn` channel files. The module supports backup/restore operations to allow reverting modifications and maintains change tracking to indicate which properties have been modified from their original values.
---
## 2. Public Interface
### Enums.cs
#### `Keys` Enum
```csharp
public enum Keys
{
ApplyShiftT0ModsTestOnly // System Setting for whether to restrict "Shift T0" test modifications to "Test" only.
}
```
- Defines a configuration key for controlling T0 modification behavior.
---
### TestModificationModel.cs
#### `TestModificationModel` Class
Implements `ITestModificationModel`. A model class that tracks modification state for a selected test channel.
**Calibration Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `CalDate` | `string` | Returns calibration date as short date string, or empty if `Cal` is null. |
| `ModifyDate` | `string` | Returns modify date/time string, or empty if `Cal` is null. |
| `CalSensitivity` | `double` | Gets/sets sensitivity from first calibration record. Returns `double.NaN` if unavailable. |
| `ProportionalToExcitation` | `bool` | Returns whether calibration is proportional to excitation. |
| `ShowSensorCal` | `bool` | Returns true if `Cal` and `Sensor` are non-null and calibration is not non-linear. |
| `NonLinear` | `bool` | Returns whether calibration is non-linear. |
| `Cal` | `ISensorCalDbRecord` | The latest calibration record for the channel. |
| `Sensor` | `ISensorDbRecord` | The sensor corresponding to the channel. |
**Channel Selection & Modification Tracking:**
| Property | Type | Description |
|----------|------|-------------|
| `SelectedChannel` | `ITestChannel` | The currently selected test channel. |
| `Description` | `string` | Channel description string. |
| `IsModifiedDescription` | `bool` | True if `Description` differs from `SelectedChannel.ChannelDescriptionString`. |
| `EuMultiplier` | `double` | EU multiplier value. |
| `IsModifiedEuMultiplier` | `bool` | True if `EuMultiplier` differs from `SelectedChannel.Multiplier`. |
| `EuOffset` | `double` | EU offset value. |
| `IsModifiedEuOffset` | `bool` | True if `EuOffset` differs from `SelectedChannel.UserOffsetEu`. |
| `T0` | `double` | T0 timing offset (in ms). |
| `IsModifiedT0` | `bool` | True if `T0` is not 0. |
| `T1` | `double` | Line fit start point (in ms). |
| `T2` | `double` | Line fit end point (in ms). |
| `IsModifiedLineFit` | `bool` | True if `T1` or `T2` is not 0. |
| `Sensitivity` | `double` | Sensitivity value. |
| `IsModifiedSensitivity` | `bool` | True if `Sensitivity` differs from `SelectedChannel.Sensitivity`. |
| `SelectedFilter` | `IFilterClass` | Selected software filter (defaults to `FilterClassType.Unfiltered`). |
| `IsModifiedFilter` | `bool` | True if `SelectedFilter` differs from channel's software filter. |
| `SelectedDataFlag` | `DataFlag` | Selected data flag. |
| `IsModifiedDataFlag` | `bool` | True if `SelectedDataFlag` differs from channel's data flag. |
| `IsModified` | `bool` | Aggregate flag indicating any modification exists and `SelectedChannel` is not null. |
**Control Enable/Disable Properties:**
| Property | Type | Default |
|----------|------|---------|
| `EnableSensitivityControl` | `bool` | `true` |
| `EnableLineFitControl` | `bool` | `true` |
| `EnableEUOffsetControl` | `bool` | `true` |
| `EnableEUMultiplierControl` | `bool` | `true` |
| `EnableFilterControl` | `bool` | `true` |
| `EnableDescriptionControl` | `bool` | `true` |
| `IsDataFlagEnabled` | `bool` | `true` |
| `IsT0Enabled` | `bool` | `true` |
**T0 Mode Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `T0Mode` | `T0Mode` | Gets/sets T0 mode (`Test` or `DAS`). When `IsT0ModeTestOnly` is true, setter forces value to `T0Mode.Test`. |
| `IsT0ModeTestOnly` | `bool` | When true, restricts T0 mode to `Test` only. |
**Other Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `Parent` | `ITestModificationViewModel` | Reference to parent view model. |
| `IsSaved` | `bool` | Property exists but has no implementation visible. |
**Methods:**
```csharp
public bool ValidateT0()
```
- Validates that T0 falls within the dataset's time range (between start and end times).
- Returns `true` if `SelectedChannel` or `SelectedChannel.ParentModule` is null.
- Calculates valid range from `StartRecordSampleNumber`, `TriggerSampleNumbers[0]`, `NumberOfSamples`, and `SampleRateHz`.
```csharp
public void OnPropertyChanged(string propertyName)
```
- Raises `PropertyChanged` event.
- Updates `IsModified` aggregate flag when non-IsModified properties change.
- Calls `Parent?.PublishChanges()`.
**Commands:**
```csharp
public DelegateCommand UpdateDatabaseCommand
```
- Executes `UpdateDatabaseMethod()` which delegates to `Parent.UpdateDatabaseMethod()`.
---
### TestModelManipulation.cs
#### `TestModelManipulation` Class
Static utility class for file-based test modification operations.
**Constants:**
| Constant | Value | Description |
|----------|-------|-------------|
| `UNUSED_START_TIME` | `0` | Placeholder for test serialization. |
| `UNUSED_DATA_COLLECTION_LENGTH` | `0` | Placeholder for test serialization. |
| `BackupHeaderExtension` | `".header.bak"` | Extension for header-only backups. |
| `BackupFileExtension` | `".bak"` | Extension for full file backups. |
**Public Methods:**
```csharp
public static void UndoAllModification(ITestModificationModel model)
```
- Reverts all modifications by restoring `.dts` and all `.chn` files from backups.
- Publishes `ChannelsModificationNotification`, `RefreshTestRequestEvent`, and `TestModificationEvent`.
```csharp
public static bool BackupExists(ITestModificationModel model)
```
- Returns true if either `.dts.bak` or `.chn.bak` files exist for the selected channel.
```csharp
public static bool SaveModification(ITestModificationModel model, bool useISOCodeFilterMapping, bool bUseZeroForUnfiltered)
```
- Persists all modifications to disk.
- Handles T0 changes (applying to test or DAS based on `T0Mode`).
- Handles filter changes with optional ISO code mapping.
- Handles sensitivity, EU multiplier/offset, description, data flag, and line fit changes.
- Publishes `TestModificationEvent` on completion.
```csharp
public static bool SaveModificationDataFlag(ITestModificationModel model)
```
- Saves only data flag modifications.
- Publishes `ChannelsModificationNotification` and repopulates model from channel.
```csharp
public static void ApplyLineFit(ITestModificationModel model, Test.Module.Channel channel)
```
- Applies linear interpolation between sample indices derived from `T1` and `T2`.
- Backs up channel file (full backup, not header-only).
- Modifies ADC data in place using straight-line fit between two points.
```csharp
public static void PreviewLineFit(ITestModificationModel model)
```
- Publishes `ChannelsModificationLineFitNotification` with calculated start/end indices for UI preview without disk modification.
```csharp
public static void UndoModification(ITestModificationModel model)
```
- Reverts in-memory changes by repopulating from channel.
- Publishes `ChannelsModificationNotification`.
```csharp
public static void PopulateFromChannel(ITestModificationModel model)
```
- Initializes model properties from `SelectedChannel` values.
- Resets `T0`, `T1`, `T2` to 0.
---
## 3. Invariants
1. **Calibration Record Access**: `CalSensitivity` getter assumes `Cal.Records.Records[0]` exists if the collection is non-null and non-empty. No bounds checking beyond length > 0.
2. **Modification Flag Consistency**: `IsModified` is always `false` when `SelectedChannel` is null, regardless of other modification flags.
3. **T0Mode Restriction**: When `IsT0ModeTestOnly` is `true`, the `T0Mode` setter always forces the value to `T0Mode.Test`, ignoring the provided value.
4. **Backup File Semantics**: Backup files (`.bak`) represent the **original** unmodified files. If a backup exists, it is never overwritten by subsequent backup operations.
5. **Line Fit Index Ordering**: `ApplyLineFit` automatically swaps start/end indices if `startIndex > endIndex`.
6. **T0 Validation Range**: `ValidateT0()` calculates time range assuming `TriggerSampleNumbers[0]` exists (no bounds check on the list).
7. **Channel Matching**: `SaveModification` matches channels by both `ChannelId` AND `BinaryFileName` suffix for most operations (except T0 modifications which apply more broadly).
---
## 4. Dependencies
### Imports (This module depends on):
**From TestModificationModel.cs:**
- `DTS.Common` - Common utilities
- `DTS.Common.Classes.Sensors` - Sensor classes
- `DTS.Common.Enums.Sensors` - Sensor enums
- `DTS.Common.Interface` - Common interfaces
- `DTS.Common.Interface.Sensors` - Sensor interfaces
- `DTS.Common.Interface.Sensors.SoftwareFilters` - Filter interfaces
- `DTS.SensorDB` - Sensor database interfaces (`ISensorCalDbRecord`, `ISensorDbRecord`)
- `Prism.Commands` - `DelegateCommand`
**From TestModelManipulation.cs:**
- `DTS.Common` - Common utilities
- `DTS.Common.Classes.Sensors` - Sensor classes
- `DTS.Common.Events` - Event types (`TestModificationEvent`, `TestModificationArgs`, `ChannelsModificationNotification`, `ChannelsModificationLineFitNotification`, `LineFitArgs`, `RefreshTestRequestEvent`)
- `DTS.Common.Interface` - `ITestChannel`
- `DTS.Common.Settings` - `SettingsDB`
- `DTS.Common.Utilities.Logging` - `APILogger`
- `DTS.Serialization` - Serialization utilities (`Serialization.SliceRaw.File`)
- `Prism.Ioc` - `ContainerLocator`
- `Prism.Events` - `IEventAggregator`
### External Type References (Interfaces expected from elsewhere):
- `ITestModificationModel` - Interface implemented by `TestModificationModel`
- `ITestModificationViewModel` - Parent view model interface
- `ITestChannel` - Test channel interface
- `ISensorCalDbRecord` - Calibration database record
- `ISensorDbRecord` - Sensor database record
- `IFilterClass` / `FilterClass` - Software filter abstraction
- `T0Mode` - Enum for T0 modification scope
- `DataFlag` - Enum for data flags
- `Test.Module.Channel` / `Test.Module.AnalogInputChannel` - Channel types from serialization
- `Test` / `TestSetup` - Test structure types
---
## 5. Gotchas
1. **Namespace Mismatch**: `TestModificationModel.cs` is declared in namespace `DTS.Viewer.ChartOptions.Model` despite residing in `DTS.Viewer.TestModification/Model/`. This may cause confusion when locating the class.
2. **IsSaved Property**: The `IsSaved` property has a getter but no visible setter or backing field implementation. Its behavior is unclear from source alone.
3. **T0 Mode DAS Logic**: In `SaveModification`, when `T0Mode == T0Mode.DAS`, T0 changes are applied to modules that **do not** contain the selected channel but share the same `BaseSerialNumber` as the module that does. This could affect more channels than expected.
4. **Line Fit Data Type**: `ApplyLineFit` casts ADC data to `short` after floating-point interpolation, which could cause precision loss or overflow for extreme values.
5. **Thread.Sleep in File Writing**: `WriteDTSFileChanges` includes `System.Threading.Thread.Sleep(10)` after writing the DTS file. The reason for this delay is not documented in source.
6. **Backup Strategy Selection**: `BackupChannelIfNeeded` uses header-only backup for sensitivity/T0/filter changes (when `useISOCodeFilterMapping` is true), but full backup for line fit. This is a performance optimization but means different modification types have different restore behaviors.
7. **FilterClassType Default**: `SelectedFilter` defaults to `FilterClassType.Unfiltered`, but the source does not show the definition of `FilterClassType` enum.
8. **PropertyChanged Event Naming**: `RebindCalProperties` raises events with string property names rather than using `nameof()` operator, which could lead to runtime errors if property names change.

View File

@@ -0,0 +1,47 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:08:52.753562+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "159c8c375f9a8da3"
---
# Properties
## Documentation: DTS.Viewer.TestModification Assembly Configuration
### 1. Purpose
This file provides assembly-level metadata and configuration for the `DTS.Viewer.TestModification` module. It exists to define the identity, versioning, and COM visibility settings for the compiled output (DLL or EXE) using standard .NET attributes. Its role is strictly configuration; it contains no executable logic or type definitions.
### 2. Public Interface
This file does not expose classes or methods. It configures the following assembly-level attributes:
* **`AssemblyTitle`**: Set to `"DTS.Viewer.TestModification"`.
* **`AssemblyDescription`**: Set to an empty string.
* **`AssemblyConfiguration`**: Set to an empty string.
* **`AssemblyCompany`**: Set to an empty string.
* **`AssemblyProduct`**: Set to `"DTS.Viewer.TestModification"`.
* **`AssemblyCopyright`**: Set to `"Copyright © 2017"`.
* **`AssemblyTrademark`**: Set to an empty string.
* **`AssemblyCulture`**: Set to an empty string (indicates the assembly is culture-neutral).
* **`ComVisible`**: Set to `false`. This prevents types within this assembly from being visible to COM components by default.
* **`Guid`**: Set to `"5ee7c61f-e9fe-479b-be1f-78a142341c3b"`. This acts as a unique identifier for the assembly if exposed to COM.
* **`AssemblyVersion`**: Set to `"1.0.0.0"`.
* **`AssemblyFileVersion`**: Set to `"1.0.0.0"`.
### 3. Invariants
* **Versioning:** The assembly version and file version are explicitly pinned to `1.0.0.0`. They will not auto-increment with builds unless this file is modified or the project is configured to override these attributes elsewhere (e.g., in a CI/CD pipeline).
* **COM Visibility:** All types in this assembly are hidden from COM components unless a specific type overrides this by applying `[ComVisible(true)]` at the class level.
### 4. Dependencies
* **Internal Dependencies:**
* `System.Reflection`
* `System.Runtime.CompilerServices`
* `System.Runtime.InteropServices`
* **External Consumers:** The compiled assembly produced by the `DTS.Viewer.TestModification` project depends on this configuration for its identity. The build system consumes this file to embed the manifest resource.
### 5. Gotchas
* **Empty Metadata:** Several fields (`AssemblyDescription`, `AssemblyCompany`, `AssemblyConfiguration`) are initialized but left empty. This may result in incomplete metadata in the compiled binary properties.
* **Legacy Project Format:** The existence of this file suggests a traditional .NET Framework project structure (non-SDK style). Modern .NET Core/5+ projects typically define these properties in the `.csproj` file.
* **Hardcoded Version:** The version numbers are hardcoded. If the codebase evolves, these versions must be manually updated here to reflect new releases.

View File

@@ -0,0 +1,83 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:08:29.234915+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "46010437bced3eec"
---
# Documentation: DTS.Viewer.TestModification.Resources
## 1. Purpose
This module provides localization support for the `DTS.Viewer.TestModification` namespace. It consists of a strongly-typed resource wrapper class, `StringResources`, which provides compile-time access to localized strings (likely sourced from a `.resx` file), and a XAML markup extension, `TranslateExtension`, that allows WPF UI elements to bind to these localized strings declaratively.
## 2. Public Interface
### Class: `TranslateExtension`
**Namespace:** `DTS.Viewer.TestModification`
**Inheritance:** `System.Windows.Markup.MarkupExtension`
This class allows XAML bindings to retrieve localized strings using a resource key.
* **Constructor**
* `public TranslateExtension(string key)`: Initializes the extension with the specific resource key to look up.
* **Method**
* `public override object ProvideValue(IServiceProvider serviceProvider)`: Returns the localized string associated with the `_key`. If the key is null, empty, or not found in the resource manager, it returns an error string constant.
### Class: `StringResources`
**Namespace:** `DTS.Viewer.TestModification.Resources`
**Accessibility:** `internal`
A strongly-typed resource class auto-generated by Visual Studio. It exposes localized strings as static properties.
* **Properties**
* `internal static global::System.Resources.ResourceManager ResourceManager`: Returns the cached `ResourceManager` instance responsible for retrieving resources.
* `internal static global::System.Globalization.CultureInfo Culture`: Gets or sets the current `CultureInfo` used for resource lookups.
* **Resource String Properties (Static)**
* `string CalDate`: "Cal date"
* `string DataFlag`: "Data Flag:"
* `string Description`: "Description:"
* `string EUMultiplier`: "EU Multiplier:"
* `string EUOffset`: "EU Offset:"
* `string FailedToModifySensitivity`: "Failed to modify sensitivity: "
* `string Filter`: "Filter:"
* `string LineFit`: "Line Fit:"
* `string ModifyDate`: "Modify date"
* `string NonLinear`: "Non-linear"
* `string PleaseLockHeader`: "To enable, please lock a single channel."
* `string Preview`: "Preview"
* `string ProportionalToExcitation`: "Proportional to excitation"
* `string Sensitivity`: "Sensitivity:"
* `string SensorCalibration`: "Sensor calibration (most recent in db)"
* `string ShiftT0ms`: "Shift T₀ (ms):"
* `string T0MustBeInDataset`: "Modification can not be made, T0 must be in the dataset."
* `string T1ms`: "T₁ (ms):"
* `string T2ms`: "T₂ (ms):"
* `string Undo`: "Cancel"
* `string UndoAll`: "Restore All"
* `string UndoAllPrompt`: "This will revert your saved test modifications to the backup on file. Continue?"
* `string UndoPrompt`: "This will undo any change(s) to this channel made before saving. Continue?"
* `string UpdateDatabase`: "Update database"
* `string WriteFiles`: "Write"
* `string WriteFilesPrompt`: "Are you sure you want to write these changes to disk?"
## 3. Invariants
* **Non-Null Return:** `TranslateExtension.ProvideValue` will never return `null`. It guarantees a string return, either the localized value or a specific error identifier.
* **Error Identifier:** If a resource key is not found, the return value must contain the constant `#stringnotfound#`. If the key is null or empty, it returns exactly `#stringnotfound#`. If the key is valid but missing from resources, it returns `#stringnotfound#` followed by a space and the missing key.
* **Auto-generation:** `StringResources` is marked with `GeneratedCodeAttribute`. Its members are strictly derived from the underlying resource source (e.g., `.resx`). Manual modifications to this file will be lost upon regeneration.
## 4. Dependencies
* **Internal Dependencies:**
* `TranslateExtension` depends on `StringResources` to perform the actual string lookup via `StringResources.ResourceManager`.
* **External Dependencies:**
* `System.Windows.Markup`: Required for `MarkupExtension` and `MarkupExtensionReturnTypeAttribute` (WPF specific).
* `System.Resources`: Required for `ResourceManager`.
* `System.Globalization`: Required for `CultureInfo`.
## 5. Gotchas
* **Auto-Generated File:** `StringResources.Designer.cs` is auto-generated. Developers must edit the corresponding `.resx` file (not present in the provided source) to add or modify strings; editing this `.cs` file directly is futile as changes will be overwritten.
* **Internal Visibility:** The `StringResources` class is `internal`. It cannot be accessed from outside the `DTS.Viewer.TestModification` assembly.
* **Silent Failures in UI:** `TranslateExtension` does not throw exceptions for missing keys. Instead, it returns strings like `#stringnotfound# MissingKey`. This behavior aids in debugging missing translations visually in the UI but requires the developer to inspect the string content rather than catching exceptions.
* **Static Culture:** The `StringResources.Culture` property is static. Changing it will affect all subsequent resource lookups within that assembly context, which implies the application is responsible for managing the UI culture lifecycle globally.

View File

@@ -0,0 +1,56 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/View/TestModificationView.xaml.cs
generated_at: "2026-04-16T11:09:12.708524+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "3165a969f0d942bf"
---
# Documentation: TestModificationView
## 1. Purpose
`TestModificationView` is a WPF user control that provides the interaction logic for a view related to test modification functionality. It implements the `ITestModificationView` interface and exposes available filter classes (CFC - Channel Filter Classes) for use in the UI, specifically retrieving filter options from `AnalogSettingDefaults`. The module appears to be part of a larger sensor data viewing and modification system within the DTS Viewer application.
## 2. Public Interface
### `TestModificationView()` (Constructor)
**Signature:** `public TestModificationView()`
Initializes a new instance of the view by calling `InitializeComponent()`, which loads the XAML-defined UI components.
---
### `AvailableCFC` (Property)
**Signature:** `public List<IFilterClass> AvailableCFC { get; }`
**Behavior:** Returns a list of available filter classes by instantiating a new `AnalogSettingDefaults` object and accessing its `FilterOptions` property. This property is read-only (getter only). The comment references "FB 13120" indicating this was implemented for a specific feature request or bug fix.
## 3. Invariants
- The `AvailableCFC` property will never return `null` (assuming `AnalogSettingDefaults.FilterOptions` never returns `null`).
- Each call to `AvailableCFC` creates a new `AnalogSettingDefaults` instance; the property does not cache or reuse a single instance.
- The view must be initialized via `InitializeComponent()` before any UI element access.
## 4. Dependencies
### This module depends on:
- `DTS.Common.Interface` - Provides `ITestModificationView` interface that this class implements
- `DTS.Common.Interface.Sensors.SoftwareFilters` - Provides `IFilterClass` interface used in the `AvailableCFC` property return type
- `DTS.SensorDB` - Provides `AnalogSettingDefaults` class used to retrieve filter options
- `System.Windows.Controls` - WPF base classes (UserControl, inferred from partial class pattern)
- `System.Collections.Generic` - Provides `List<T>` collection type
### What depends on this module:
- Cannot be determined from source alone. Consumers would be modules that reference `ITestModificationView` or directly instantiate `TestModificationView`.
## 5. Gotchas
1. **Unused import:** `System.Text.RegularExpressions` is imported but never used in this file. This may indicate leftover code from refactoring.
2. **Namespace suppression:** The file includes `// ReSharper disable CheckNamespace`, suggesting the namespace `DTS.Viewer.TestModification` may not match the project's folder structure conventions, or ReSharper is flagging a namespace mismatch.
3. **Property allocation pattern:** The `AvailableCFC` property instantiates a new `AnalogSettingDefaults` object on every access. If called frequently (e.g., in a binding or loop), this could create unnecessary object allocations. Consider whether caching would be appropriate.
4. **FB 13120 reference:** The comment references a tracking identifier (likely FogBugz or similar issue tracker). The context and resolution of this issue are not documented in code.

View File

@@ -0,0 +1,133 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/ViewModel/TestModificationViewModel.cs
generated_at: "2026-04-16T11:08:10.828283+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "297454e79e1ccbbd"
---
# Documentation: TestModificationViewModel
## 1. Purpose
`TestModificationViewModel` is a Prism-based ViewModel responsible for managing test data modifications within the DTS Viewer application. It provides functionality to modify channel properties such as T0 (time zero), sensitivity, line fit, EU multipliers/offsets, filters, and data flags. The module interfaces with the sensor database to retrieve and update calibration records, and coordinates with the broader application via event aggregation for channel selection, T0 shifting, and modification state synchronization.
---
## 2. Public Interface
### Constructor
```csharp
public TestModificationViewModel(
ITestModificationView view,
IRegionManager regionManager,
IEventAggregator eventAggregator,
IUnityContainer unityContainer)
```
Initializes the ViewModel, sets up the View's DataContext, creates interaction requests, and subscribes to `RaiseNotification`, `GraphSelectedChannelsNotification`, `ShiftT0Event`, and `SetUseZeroForUnfilteredEvent` events.
---
### Public Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| `Initialize` | `void Initialize()` | Override; no-op implementation. |
| `Initialize` | `void Initialize(object parameter)` | Override; sets `Parent` property from parameter cast to `IBaseViewModel`. |
| `UpdateDatabaseMethod` | `void UpdateDatabaseMethod()` | Updates calibration in the sensor database. Sets `CalibrationId` to -1, updates `ModifyDate` to current time, creates a new `SensorCalibration`, inserts via `DbOperations.SensorCalibrationsInsert`, and refreshes `Model.Cal` with latest calibration. Publishes `PageErrorEvent` on failure. |
| `PublishChanges` | `void PublishChanges()` | If `Model.IsModifiedDataFlag` is true, saves data flag modification immediately via `TestModelManipulation.SaveModificationDataFlag`. Publishes `TestModificationChangedEvent` with the Model. |
---
### Public Properties
| Property | Type | Description |
|----------|------|-------------|
| `View` | `ITestModificationView` | Gets/sets the associated View. |
| `Parent` | `IBaseViewModel` | Gets/sets the parent ViewModel. |
| `NotificationRequest` | `InteractionRequest<Notification>` | Interaction request for displaying notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | Interaction request for displaying confirmations. |
| `PreviewCommand` | `DelegateCommand` | Executes `PreviewMethod()` - calls `TestModelManipulation.PreviewLineFit(Model)`. |
| `WriteCommand` | `DelegateCommand` | Executes `WriteMethod()` - validates T0, prompts user, calls `TestModelManipulation.SaveModification`. |
| `UndoCommand` | `DelegateCommand` | Executes `UndoMethod()` - prompts user, calls `TestModelManipulation.UndoModification`. |
| `UndoAllCommand` | `DelegateCommand` | Executes `UndoAllMethod()` - prompts user, calls `TestModelManipulation.UndoAllModification`. |
| `UseISOCodeFilterMapping` | `bool` | Controls whether ISOCode field filter matches channel's SoftwareFilter. Default: `false`. |
| `Model` | `TestModificationModel` | The model containing test modification state. Setter updates `Parent` reference. |
| `UseZeroForUnfiltered` | `bool` | Gets/sets whether to use zero for unfiltered values. |
| `IsFilterEnabled` | `bool` | Gets/sets filter enabled state. Raises `OnPropertyChanged`. |
| `TestModificationVisability` | `bool` | Controls visibility of test modification UI. Raises `OnPropertyChanged`. |
| `HeaderInfo` | `string` | Returns `"TestSummaryRegion"`. |
| `IsBusy` | `bool` | Gets/sets busy state. Raises `OnPropertyChanged`. |
| `IsDirty` | `bool` | Gets/sets dirty state. |
| `IsNavigationIncluded` | `bool` | Gets/sets navigation inclusion state. |
| `IsBackedUp` | `bool` | Gets (private sets) whether backup exists. Raises `OnPropertyChanged`. |
---
### Events
| Event | Type | Description |
|-------|------|-------------|
| `PropertyChanged` | `PropertyChangedEventHandler` | Raised when a property value changes. |
---
## 3. Invariants
1. **Single-Channel Selection**: `TestModificationVisability` is `true` only when exactly one channel is selected (`channels.Count == 1 && channels.Count(x => x.IsSelected) == 1`).
2. **T0 Validation**: T0 cannot be shifted beyond the bounds of the test dataset. `Model.ValidateT0()` must return `true` before write operations proceed.
3. **Calibration ID Reset**: When updating the database via `UpdateDatabaseMethod()`, `CalibrationId` is always set to `-1` before insertion.
4. **Analog Sensor Calibration Display**: Calibration records are only loaded/displayed for sensors where `SensorType == 0` (analog sensors).
5. **Calibration Sorting**: Calibrations are sorted ascending by `CalibrationDate`, then by `ModifyDate` as a tiebreaker. The "latest" calibration is the last element after sorting.
6. **Permission-Based Controls**: All edit controls (`EnableSensitivityControl`, `EnableLineFitControl`, `EnableDescriptionControl`, `EnableEUMultiplierControl`, `EnableEUOffsetControl`, `EnableFilterControl`, `IsT0Enabled`, `IsDataFlagEnabled`) are gated by `viewModel.DoesUserHaveEditPermission`.
---
## 4. Dependencies
### This Module Depends On:
- `DTS.Common.Base` - `BaseViewModel<T>`
- `DTS.Common.Events` - Event types (`PageErrorEvent`, `RaiseNotification`, `GraphSelectedChannelsNotification`, `ShiftT0Event`, `SetUseZeroForUnfilteredEvent`, `TestModificationChangedEvent`, `ShowT0CursorEvent`)
- `DTS.Common.Interactivity` - `InteractionRequest<T>`, `Notification`, `Confirmation`
- `DTS.Common.Interface` - `IBaseViewModel`, `ITestModificationViewModel`, `ITestModificationView`, `IViewerMainViewModel`
- `DTS.Common.Interface.Sensors` - `ISensorDbRecord`, `ISensorCalDbRecord`
- `DTS.Common.Settings` - `SettingsDB`, `Keys`
- `DTS.Common.Storage` - (content not visible, inferred from namespace)
- `DTS.Common.Utilities.Logging` - `APILogger`
- `DTS.SensorDB` - `DbOperations`, `SensorCalibration`
- `DTS.Viewer.ChartOptions.Model` - (content not visible)
- `DTS.Viewer.TestModification.Model` - `TestModificationModel`, `TestModelManipulation`
- `Prism.Commands` - `DelegateCommand`
- `Prism.Events` - `IEventAggregator`
- `Prism.Regions` - `IRegionManager`
- `Unity` - `IUnityContainer`
### What Depends On This Module:
- Not determinable from source alone. Inferred consumers would be the View (`TestModificationView`) and the main application shell via region navigation.
---
## 5. Gotchas
1. **Typo in Property Name**: `TestModificationVisability` is misspelled (should be "Visibility"). This may cause confusion when referencing the property.
2. **Malformed XML Comment**: The `GetLatestCalibration` method has a malformed XML comment with `<summary>` used as both opening and closing tag instead of `</summary>`.
3. **Silent Exception Swallowing**: `GetLatestCalibration` catches all exceptions and returns `null` without logging. The comment explicitly states: *"there's no access to APILogger here, so rather than adding a reference, just eat the error"*.
4. **Member Hiding with `new` Keyword**: Several members (`OnPropertyChanged`, `PropertyChanged`, `IsBusy`, `IsDirty`, `IsNavigationIncluded`) use the `new` keyword to hide base class members, which can lead to unexpected behavior when casting to base types.
5. **Yoda Condition Style**: The codebase uses Yoda conditions (`null == sensor` instead of `sensor == null`) consistently throughout.
6. **Hardcoded Calibration ID**: `cal.CalibrationId = -1` is used as a marker for new calibrations. The significance of `-1` is not documented in code.
7. **Static `IsPopulating` Property**: `IsPopulating` is a static property used to prevent `PublishChanges` from executing during model population, which could cause issues if multiple instances exist.
8. **Feature Request Reference**: A comment references an internal case URL: `http://manuscript.dts.local/f/cases/43735/` for the database update feature.