Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
226df32
P1: unify COMTRADE row selection authority
masarray Sep 7, 2026
3c0de5e
P1: route COMTRADE pointer selection through row model
masarray Sep 7, 2026
de8639a
P1: remove dual COMTRADE selection state
masarray Sep 7, 2026
443ee95
P1: centralize semantic signal display naming
masarray Sep 7, 2026
42c4c40
P1: make FAT naming formatter a canonical facade
masarray Sep 7, 2026
29da565
P1: route Engineering semantic names through shared authority
masarray Sep 7, 2026
1cc40eb
P1: use semantic signal names in FAT report
masarray Sep 7, 2026
9bfbfa7
P1: preserve IEC reference width across FAT reopen
masarray Sep 7, 2026
8ced385
P1: migrate P0 regressions to unified authorities
masarray Sep 7, 2026
4d65f7a
P1: unify COMTRADE header selection authority
masarray Sep 7, 2026
36fd3cb
P1: update field regressions for unified COMTRADE selection
masarray Sep 7, 2026
423d009
P1 bench: make command safety defaults registration deterministic
masarray Sep 7, 2026
74680f2
P1 bench: route legacy RCB selections through generic multi exporter
masarray Sep 7, 2026
84277f7
P1 bench: make legacy RCB filter independently multi-select
masarray Sep 7, 2026
a30189e
P1 bench: fence stale command feedback before Engineering and FAT pro…
masarray Sep 7, 2026
d37b7a4
P1 bench: add operator supplied relay fascia SVG
masarray Sep 7, 2026
98ae381
P1 bench: replace IED fascia with supplied SVG vector
masarray Sep 7, 2026
5fc43b1
P1 bench: update fascia regression for supplied SVG artwork
masarray Sep 7, 2026
a858211
P1 bench: lock physical relay hotfix contracts
masarray Sep 7, 2026
adec9a7
P1 bench: keep freshness enum internal in regression theory
masarray Sep 7, 2026
1b33476
P1 bench: migrate legacy fascia test to supplied relay artwork
masarray Sep 7, 2026
9e89779
P1 bench: keep legacy SCL XML out of JSON reports
masarray Sep 7, 2026
0b1d815
P1 bench: regress legacy SCL JSON cycle
masarray Sep 7, 2026
a3e6501
P1 bench: disambiguate SCL export regression shim
masarray Sep 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions Assets/RelayFascia.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 7 additions & 41 deletions FaultRecordWindow.HeaderSelection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ namespace ArIED61850Tester;

/// <summary>
/// Adds a tri-state select-all checkbox to the fault-record Get column. A record with relay
/// files is selectable whether it is a first download or an intentional re-download. Native
/// first-download rows use FaultRecordRow.IsSelected; Downloaded rows use the staged-overwrite
/// selection set owned by RedownloadUx.
/// files is selectable whether it is a first download or an intentional re-download.
/// FaultRecordRow.IsSelected is the single transfer-selection authority for every row.
/// </summary>
public partial class FaultRecordWindow
{
Expand Down Expand Up @@ -105,33 +104,7 @@ private void FaultRecordHeaderSelectionCheckBox_Click(object sender, RoutedEvent
try
{
foreach (var row in Records)
{
if (!HasTransferableFiles(row))
{
row.IsSelected = false;
_redownloadSelections.Remove(row.Record.RecordId);
continue;
}

if (!target)
{
row.IsSelected = false;
_redownloadSelections.Remove(row.Record.RecordId);
continue;
}

if (row.LocalState == FaultRecordLocalState.Downloaded)
{
row.IsSelected = false;
_redownloadSelections.Add(row.Record.RecordId);
ConfigureRecordRow(row);
}
else
{
_redownloadSelections.Remove(row.Record.RecordId);
row.IsSelected = row.CanSelectForDownload;
}
}
row.IsSelected = target && row.CanSelectForDownload;
}
finally
{
Expand All @@ -140,6 +113,7 @@ private void FaultRecordHeaderSelectionCheckBox_Click(object sender, RoutedEvent

RaiseSelectionState();
UpdateSmartSelectionUi();
ConfigureVisibleRecordRows();
RefreshFaultRecordHeaderSelection();
}

Expand Down Expand Up @@ -184,33 +158,25 @@ private void RefreshFaultRecordHeaderSelection()
if (header == null)
return;

var eligibleCount = Records.Count(HasTransferableFiles);
var eligibleCount = Records.Count(row => row.CanSelectForDownload);
header.IsEnabled = !IsBusy && eligibleCount > 0;
header.IsChecked = GetFaultRecordHeaderSelectionState();
}

private bool? GetFaultRecordHeaderSelectionState()
{
var eligible = Records.Where(HasTransferableFiles).ToArray();
var eligible = Records.Where(row => row.CanSelectForDownload).ToArray();
if (eligible.Length == 0)
return false;

var selected = eligible.Count(IsSelectedForTransfer);
var selected = eligible.Count(row => row.IsSelected);
if (selected == 0)
return false;
if (selected == eligible.Length)
return true;
return null;
}

private static bool HasTransferableFiles(FaultRecordRow row)
=> row.Record.Files.Count > 0;

private bool IsSelectedForTransfer(FaultRecordRow row)
=> row.LocalState == FaultRecordLocalState.Downloaded
? _redownloadSelections.Contains(row.Record.RecordId)
: row.IsSelected;

private void FaultRecordHeaderSelectionWindow_Closed(object? sender, EventArgs e)
{
PropertyChanged -= FaultRecordHeaderSelectionWindow_PropertyChanged;
Expand Down
24 changes: 6 additions & 18 deletions FaultRecordWindow.RedownloadSelectionAuthority.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ namespace ArIED61850Tester;

/// <summary>
/// One pointer-selection authority for the fault-record grid. Clicking either the SELECT
/// checkbox or anywhere on a transferable record row toggles the same selection exactly once.
/// Downloaded records use the staged-overwrite selection set; first-time records keep the
/// existing model IsSelected flag. Visual checkbox state is committed after the input event so
/// WPF's native CheckBox mouse-state transition cannot repaint over the operator's tick.
/// checkbox or anywhere on a transferable record row toggles FaultRecordRow.IsSelected exactly
/// once. Local Downloaded state never owns a second selection set; it only changes transfer
/// semantics from first download to staged atomic replacement.
/// </summary>
public partial class FaultRecordWindow
{
Expand All @@ -34,28 +33,17 @@ private static void RedownloadSelectionAuthority_Down(object sender, MouseButton
window.IsBusy ||
e.ChangedButton != MouseButton.Left ||
!TryResolveTransferRow(e.OriginalSource as DependencyObject, out var row) ||
row.Record.Files.Count == 0)
!row.CanSelectForDownload)
{
return;
}

if (row.LocalState == FaultRecordLocalState.Downloaded)
{
var recordId = row.Record.RecordId;
if (!window._redownloadSelections.Add(recordId))
window._redownloadSelections.Remove(recordId);
}
else
{
if (!row.CanSelectForDownload)
return;
row.IsSelected = !row.IsSelected;
}
row.IsSelected = !row.IsSelected;

// Suppress the native checkbox/DataGrid toggle so one pointer action means exactly
// one selection change. Repaint after input processing; doing this synchronously in
// PreviewMouseDown lets the CheckBox template's pressed-state transition erase the
// visible tick even though the selection count already changed.
// visible tick even though the model already changed.
e.Handled = true;
window.Dispatcher.BeginInvoke(
DispatcherPriority.Input,
Expand Down
Loading
Loading