Skip to content

TableView sweep batch 1: header-click sorter + 21 non-sorting dialog grids - #13018

Merged
niksedk merged 2 commits into
mainfrom
experiment/tableview-batch1
Jul 31, 2026
Merged

TableView sweep batch 1: header-click sorter + 21 non-sorting dialog grids#13018
niksedk merged 2 commits into
mainfrom
experiment/tableview-batch1

Conversation

@niksedk

@niksedk niksedk commented Jul 31, 2026

Copy link
Copy Markdown
Member

Continues the TableView migration from #13017 (main subtitle grid, issue #13015).

What

1. Header-click sorting for TableView (TableViewHeaderSorter in TableViewExtras): TableView has no sorting, so this fills the gap for later batches — register sortable columns with a key selector, clicking the header sorts ascending/descending (stable) with an ▲/▼ arrow, selection preserved. It reorders the backing collection in place (TableView has no view layer), so it's for grids where collection order is presentation-only. Not yet wired anywhere — batch 2 will use it. MakeTableView also gained single-select support for picker dialogs.

2. Batch 1 conversions — every dialog grid that had no sorting (21 windows):
BinaryEdit, Bookmarks, ErrorList, FindText, Compare, ExportCustomTextFormat, ExportImageBased, ImportCsvXlsxCustomColumns, RestoreAutoBackup, BatchErrorList, FixNames, MergeContinuationLines, MergeTwoSubtitles, SortBy, FindDoubleLines, FindDoubleWords, AutoTranslate, CopyPasteTranslate, ShotChanges (list + generate), ActorVoiceMapping, ReviewSpeech, ReviewSpeechHistory, VideoOcr.

Each grid keyboard-focuses its rows now, so the #13015 screen-reader fix applies to these dialogs too.

Notable mappings

  • Former Auto-width columns → fixed pixel widths (TableView has no content sizing); the text column stays the star column. Time columns reuse the main grid's widths (Show/Hide 110–120, Duration 90).
  • DataGridCheckboxMultiSelect: shift/ctrl extended selection is native ListBox behavior; the Space-toggles-checkbox piece moved into TableViewExtras.AddSpaceToggle (BinaryEdit Forced, FixNames, MergeContinuationLines). The old helper class remains for the not-yet-converted DataGrids.
  • BinaryEdit's mode-dependent zone-dot column goes through TableViewColumnManager (TableView columns have no IsVisible).
  • VideoOcr's editable Text column (TableView has no cell editing) became a borderless in-cell two-way TextBox; focusing it selects its row so double-tap seek and Delete act on the edited line.
  • Dropped only DataGrid-isms with no behavior behind them: IsReadOnly, CanUserSortColumns (all false/no-op here), GridLinesVisibility overrides (cell themes follow the user's grid-lines setting), RowHeight (rows auto-size).

Testing

Builds clean; no new warnings (remaining mentions of "DataGrid" in converted files are explanatory comments). Runtime smoke tests to do per dialog — the riskiest spots:

  • BinaryEdit: zone column toggling, Space-toggles-Forced, insert before/after selection handling
  • VideoOcr: in-cell text editing + Delete key + double-tap seek
  • FixNames / MergeContinuationLines: Space toggle + checkbox columns
  • Compare: two synced grids scroll/selection
  • AutoTranslate: row grid context menu + scroll-follow during translation

Remaining for batch 2: the ~48 grids with CanUserSortColumns = true (only 3 use SortMemberPath deliberately: Shortcuts, BatchConvert, FixCommonErrors) — deciding per window whether to wire TableViewHeaderSorter or drop the nominal sorting.

🤖 Generated with Claude Code

niksedk and others added 2 commits July 31, 2026 11:24
TableView has no column sorting, so TableViewHeaderSorter fills the gap:
register sortable columns with a key selector, clicking the header sorts
the grid's ItemsSource in place (stable, toggling ascending/descending)
with an arrow indicator, preserving selection. Unlike the DataGrid this
reorders the backing collection, so it is only for grids where collection
order is presentation-only.

Also let MakeTableView create single-select grids for the picker dialogs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Batch 1 of the TableView sweep (after the main grid in #13017): every
DataGrid without sorting becomes a TableView built from the shared
TableViewExtras component, so keyboard focus lands on rows and screen
readers can follow the current line in these dialogs too (issue #13015).

Converted: BinaryEdit, Bookmarks, ErrorList, FindText, Compare,
ExportCustomTextFormat, ExportImageBased, ImportCsvXlsxCustomColumns,
RestoreAutoBackup, BatchErrorList, FixNames, MergeContinuationLines,
MergeTwoSubtitles, SortBy, FindDoubleLines, FindDoubleWords,
AutoTranslate, CopyPasteTranslate, ShotChanges (both windows),
ActorVoiceMapping, ReviewSpeech, ReviewSpeechHistory, VideoOcr.

Notable mappings:
- Former Auto-width columns get fixed pixel widths (TableView has no
  content sizing); the main text column stays the star column.
- DataGridCheckboxMultiSelect: extended selection is native ListBox
  behavior; its Space-toggles-checkbox piece is now
  TableViewExtras.AddSpaceToggle, used by BinaryEdit, FixNames and
  MergeContinuationLines. The helper class stays for the remaining
  DataGrids.
- BinaryEdit's mode-dependent zone column uses TableViewColumnManager.
- VideoOcr's editable text column becomes an in-cell two-way TextBox
  (TableView has no cell editing); focusing it selects its row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@niksedk
niksedk marked this pull request as ready for review July 31, 2026 09:42
@niksedk
niksedk merged commit 0f878d2 into main Jul 31, 2026
0 of 2 checks passed
@niksedk
niksedk deleted the experiment/tableview-batch1 branch July 31, 2026 09:43
pull Bot pushed a commit to A-Archives-and-Forks/subtitleedit that referenced this pull request Jul 31, 2026
Batch 2 of the TableView sweep (SubtitleEdit#13017, SubtitleEdit#13018): every remaining DataGrid
with CanUserSortColumns=true but no deliberate SortMemberPath sorting.
Rows take keyboard focus, so the screen-reader fix (SubtitleEdit#13015) now covers
these dialogs too.

Sorting was decided per grid. In the DataGrid only plain text columns
ever sorted (a view-level sort); TableViewHeaderSorter reorders the
backing collection, so it is wired only where the list order is
presentation-only and nothing consumes collection order:

- Wired (12 grids): FontCollector, FindRule, ManualChosenEncoding,
  PickFontName, PickLayerFilter, PickRuleProfile, PickOnlineSubtitle,
  and the track lists in PickMatroskaTrack/PickMp4Track/PickTsTrack/
  PickVobSubLanguage - with typed keys (numeric stream ids, nullable
  comparers) and header-double-click guards where double-tap accepted
  the dialog.
- Dropped everywhere else: subtitle/fix previews in timeline order,
  ASSA/SSA style and attachment lists (order is written to the file),
  MultipleReplace exports, batch queues, join/split file lists, and
  embedded-track lists (order is the output track order). Each carries
  a code comment with the reason.

Other notable mappings:
- DataGridCheckboxMultiSelect replaced by native extended selection +
  TableViewExtras.AddSpaceToggle (AiReview, ApplyDurationLimits,
  ConvertActors, FixNetflixErrors incl. its canToggle semantics,
  PickLayerFilter, RemoveTextForHearingImpaired; RemoveUnicodeCharacters
  hand-rolls it to coexist with its in-cell ReplaceWith TextBox editor).
- Home/End first/last-row navigation hoisted into
  TableViewExtras.AttachHomeEndNavigation (sync + Assa/Ssa windows).
- AssaStyles' DataGridCollectionView category filter replaced by a plain
  rebuilt ObservableCollection view.
- IsFocused checks on grids became IsKeyboardFocusWithin (focus lands on
  row containers now) in CutVideo/PickMatroskaTrack/PickVobSubLanguage.
- Sync-point lists show a column header now (TableView cannot hide
  headers).

Remaining DataGrids: Shortcuts, BatchConvert and FixCommonErrors (real
SortMemberPath sorting) - batch 3.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant