feat(import): Z-wafer CSV import button with result banner

- importZWaferCsv slot on FileBrowser — converts and adds to list
- SourcePanel: import icon button → FileDialog → importSummary banner
  (auto-dismisses after 5s, loads the converted file into streamController)
- wafer_map_item: showExtremes default → true
This commit is contained in:
jack
2026-07-12 16:54:24 -07:00
parent 7d98759b43
commit 6003bde84d
8 changed files with 363 additions and 37 deletions
+27
View File
@@ -1,3 +1,5 @@
from __future__ import annotations
from datetime import datetime
from pathlib import Path
from typing import Optional, Tuple
@@ -74,6 +76,31 @@ class ZWaferParser:
return wafer_data # Incomplete file — return partial data
# ===== Data Row Extraction =====
def parse_data_rows(self, file_path: str) -> list[str]:
"""Return data rows after the 'data' marker, with the leading
row-index column stripped (each row realigned to `csv_headers`).
Uses the same line normalization as `_process_header` so the split
point matches exactly what header parsing used.
"""
rows: list[str] = []
seen_data_marker = False
with Path(file_path).open("r", encoding="utf-8") as f:
for raw_line in f:
line = raw_line.rstrip().rstrip(",").strip()
if not line or line.replace(",", "").strip() == "":
continue
parts = [p.strip() for p in line.split(",")]
if not seen_data_marker:
if parts[0].lower() == "data":
seen_data_marker = True
continue
rows.append(",".join(parts[1:]))
return rows
# ===== Metadata Parsing =====
def _parse_header_line(self, wafer_data: ZWaferData, parts: list) -> bool:
"""Parse key=value pairs from header line. Returns True if handled."""