minor updates
This commit is contained in:
+25
@@ -1119,6 +1119,13 @@ impl App {
|
||||
}
|
||||
|
||||
/// Generate a default export filename (without extension) for a capture
|
||||
/// Path relative to the import directory for display; falls back to full path if not under import_dir.
|
||||
fn path_relative_to_import(path: &std::path::Path, import_dir: &std::path::Path) -> String {
|
||||
path.strip_prefix(import_dir)
|
||||
.map(|p| p.to_string_lossy().to_string())
|
||||
.unwrap_or_else(|_| path.to_string_lossy().to_string())
|
||||
}
|
||||
|
||||
fn default_export_filename(capture: &Capture) -> String {
|
||||
format!(
|
||||
"{}_{}",
|
||||
@@ -1387,6 +1394,7 @@ impl App {
|
||||
// Deduplicate: same signal can decode at multiple stream positions (e.g. Ford V0 across bursts)
|
||||
let mut seen: std::collections::HashSet<(String, u64, Option<u32>, Option<u8>)> =
|
||||
std::collections::HashSet::new();
|
||||
let mut any_decoded_added = false;
|
||||
for (protocol_name, decoded, segment_pairs) in decoded_list {
|
||||
let key = (
|
||||
protocol_name.clone(),
|
||||
@@ -1427,11 +1435,26 @@ impl App {
|
||||
if research_mode || capture.protocol.is_some() {
|
||||
if !self.capture_duplicate_of_existing(&capture) {
|
||||
self.next_capture_id += 1;
|
||||
capture.source_file = Some(Self::path_relative_to_import(path, self.storage.import_dir()));
|
||||
self.captures.push(capture);
|
||||
imported += 1;
|
||||
any_decoded_added = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// When no protocol decoded the stream, add a single Unknown capture if research_mode (same as live capture).
|
||||
if !any_decoded_added && research_mode && !raw_pairs.is_empty() {
|
||||
let mut capture = crate::capture::Capture::from_pairs_with_rf(
|
||||
self.next_capture_id,
|
||||
frequency,
|
||||
raw_pairs.clone(),
|
||||
None,
|
||||
);
|
||||
self.next_capture_id += 1;
|
||||
capture.source_file = Some(Self::path_relative_to_import(path, self.storage.import_dir()));
|
||||
self.captures.push(capture);
|
||||
imported += 1;
|
||||
}
|
||||
}
|
||||
Err(e) => tracing::warn!("Failed to import {:?}: {}", path, e),
|
||||
}
|
||||
@@ -1439,6 +1462,7 @@ impl App {
|
||||
match crate::export::fob::import_fob(path, self.next_capture_id) {
|
||||
Ok(mut capture) => {
|
||||
self.next_capture_id += 1;
|
||||
capture.source_file = Some(Self::path_relative_to_import(path, self.storage.import_dir()));
|
||||
// Re-run decoder when Unknown and raw_pairs present (same as .sub)
|
||||
if capture.status == crate::capture::CaptureStatus::Unknown
|
||||
&& !capture.raw_pairs.is_empty()
|
||||
@@ -1638,6 +1662,7 @@ impl App {
|
||||
make: None,
|
||||
model: None,
|
||||
region: None,
|
||||
source_file: None,
|
||||
};
|
||||
self.next_capture_id += 1;
|
||||
self.captures.push(capture);
|
||||
|
||||
@@ -76,6 +76,9 @@ pub struct Capture {
|
||||
/// Region (e.g. NA, EU) for vulnerability lookup and .fob export.
|
||||
#[serde(default)]
|
||||
pub region: Option<String>,
|
||||
/// Source file path when imported from .sub or .fob; None for live captures.
|
||||
#[serde(default)]
|
||||
pub source_file: Option<String>,
|
||||
}
|
||||
|
||||
/// Modulation type used by protocol (encoding: PWM vs Manchester)
|
||||
@@ -154,6 +157,7 @@ impl Capture {
|
||||
make: None,
|
||||
model: None,
|
||||
region: None,
|
||||
source_file: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -306,6 +306,7 @@ fn import_fob_v2(fob: &FobFile, next_id: u32) -> Result<Capture> {
|
||||
make: None,
|
||||
model: None,
|
||||
region: None,
|
||||
source_file: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -376,6 +377,7 @@ fn import_fob_v1(fob: &FobFileV1, next_id: u32) -> Result<Capture> {
|
||||
make: None,
|
||||
model: None,
|
||||
region: None,
|
||||
source_file: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -271,6 +271,23 @@ fn render_signal_detail(frame: &mut Frame, area: Rect, capture: &crate::capture:
|
||||
Span::styled(raw_info, raw_style),
|
||||
]));
|
||||
|
||||
// Row 8: File path (imported .sub/.fob only; blank for live captures)
|
||||
let file_display = capture
|
||||
.source_file
|
||||
.as_deref()
|
||||
.unwrap_or("");
|
||||
left_lines.push(Line::from(vec![
|
||||
Span::styled(" File: ", label_style),
|
||||
Span::styled(
|
||||
file_display,
|
||||
if file_display.is_empty() {
|
||||
Style::default().fg(Color::DarkGray)
|
||||
} else {
|
||||
value_style
|
||||
},
|
||||
),
|
||||
]));
|
||||
|
||||
// Build the title
|
||||
let title = format!(
|
||||
" Signal #{:02} — {} ",
|
||||
|
||||
Reference in New Issue
Block a user