Add WIM file selection section
This commit is contained in:
parent
70525ae6e0
commit
89e768e3a4
7 changed files with 156 additions and 45 deletions
|
|
@ -657,8 +657,9 @@ fn build_footer_string(cur_mode: Mode) -> String {
|
||||||
| Mode::PEMenu
|
| Mode::PEMenu
|
||||||
| Mode::PreClone
|
| Mode::PreClone
|
||||||
| Mode::PostClone
|
| Mode::PostClone
|
||||||
| Mode::ScanWinImages
|
| Mode::ScanWinSources
|
||||||
| Mode::SelectTableType
|
| Mode::SelectTableType
|
||||||
|
| Mode::SelectWinSource
|
||||||
| Mode::SelectWinImage
|
| Mode::SelectWinImage
|
||||||
| Mode::SetUserName => {
|
| Mode::SetUserName => {
|
||||||
panic!("This shouldn't happen?")
|
panic!("This shouldn't happen?")
|
||||||
|
|
@ -774,7 +775,8 @@ fn build_left_items(app: &App) -> Action {
|
||||||
| Mode::PreClone
|
| Mode::PreClone
|
||||||
| Mode::Clone
|
| Mode::Clone
|
||||||
| Mode::PostClone
|
| Mode::PostClone
|
||||||
| Mode::ScanWinImages
|
| Mode::ScanWinSources
|
||||||
|
| Mode::SelectWinSource
|
||||||
| Mode::SelectWinImage
|
| Mode::SelectWinImage
|
||||||
| Mode::SetUserName => {
|
| Mode::SetUserName => {
|
||||||
panic!("This shouldn't happen?")
|
panic!("This shouldn't happen?")
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@
|
||||||
"<Ctrl-c>": "Quit",
|
"<Ctrl-c>": "Quit",
|
||||||
"<Ctrl-z>": "Suspend"
|
"<Ctrl-z>": "Suspend"
|
||||||
},
|
},
|
||||||
"ScanWinImages": {
|
"ScanWinSources": {
|
||||||
"<Enter>": "Process",
|
"<Enter>": "Process",
|
||||||
"<n>": "FindWimNetwork",
|
"<n>": "FindWimNetwork",
|
||||||
"<q>": "Quit",
|
"<q>": "Quit",
|
||||||
|
|
@ -196,6 +196,15 @@
|
||||||
"<Ctrl-c>": "Quit",
|
"<Ctrl-c>": "Quit",
|
||||||
"<Ctrl-z>": "Suspend"
|
"<Ctrl-z>": "Suspend"
|
||||||
},
|
},
|
||||||
|
"SelectWinSource": {
|
||||||
|
"<Enter>": "Process",
|
||||||
|
"<Up>": "KeyUp",
|
||||||
|
"<Down>": "KeyDown",
|
||||||
|
"<q>": "Quit",
|
||||||
|
"<Ctrl-d>": "Quit",
|
||||||
|
"<Ctrl-c>": "Quit",
|
||||||
|
"<Ctrl-z>": "Suspend"
|
||||||
|
},
|
||||||
"SelectWinImage": {
|
"SelectWinImage": {
|
||||||
"<Enter>": "Process",
|
"<Enter>": "Process",
|
||||||
"<Up>": "KeyUp",
|
"<Up>": "KeyUp",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ pub enum Mode {
|
||||||
SelectParts,
|
SelectParts,
|
||||||
PostClone,
|
PostClone,
|
||||||
// Windows Installer
|
// Windows Installer
|
||||||
ScanWinImages,
|
ScanWinSources,
|
||||||
|
SelectWinSource,
|
||||||
SelectWinImage,
|
SelectWinImage,
|
||||||
SetUserName,
|
SetUserName,
|
||||||
// WinPE
|
// WinPE
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,8 @@ impl App {
|
||||||
| Mode::LogView
|
| Mode::LogView
|
||||||
| Mode::PEMenu
|
| Mode::PEMenu
|
||||||
| Mode::Process
|
| Mode::Process
|
||||||
| Mode::ScanWinImages
|
| Mode::ScanWinSources
|
||||||
|
| Mode::SelectWinSource
|
||||||
| Mode::SelectWinImage
|
| Mode::SelectWinImage
|
||||||
| Mode::SetBootMode
|
| Mode::SetBootMode
|
||||||
| Mode::SetUserName => panic!("This shouldn't happen?"),
|
| Mode::SetUserName => panic!("This shouldn't happen?"),
|
||||||
|
|
@ -157,7 +158,8 @@ impl App {
|
||||||
| Mode::LogView
|
| Mode::LogView
|
||||||
| Mode::PEMenu
|
| Mode::PEMenu
|
||||||
| Mode::Process
|
| Mode::Process
|
||||||
| Mode::ScanWinImages
|
| Mode::ScanWinSources
|
||||||
|
| Mode::SelectWinSource
|
||||||
| Mode::SelectWinImage
|
| Mode::SelectWinImage
|
||||||
| Mode::SetBootMode
|
| Mode::SetBootMode
|
||||||
| Mode::SetUserName => panic!("This shouldn't happen?"),
|
| Mode::SetUserName => panic!("This shouldn't happen?"),
|
||||||
|
|
@ -639,7 +641,8 @@ fn build_footer_string(cur_mode: Mode) -> String {
|
||||||
| Mode::LogView
|
| Mode::LogView
|
||||||
| Mode::PEMenu
|
| Mode::PEMenu
|
||||||
| Mode::Process
|
| Mode::Process
|
||||||
| Mode::ScanWinImages
|
| Mode::ScanWinSources
|
||||||
|
| Mode::SelectWinSource
|
||||||
| Mode::SelectWinImage
|
| Mode::SelectWinImage
|
||||||
| Mode::SetBootMode
|
| Mode::SetBootMode
|
||||||
| Mode::SetUserName => panic!("This shouldn't happen?"),
|
| Mode::SetUserName => panic!("This shouldn't happen?"),
|
||||||
|
|
@ -715,7 +718,8 @@ fn build_left_items(app: &App) -> Action {
|
||||||
| Mode::LogView
|
| Mode::LogView
|
||||||
| Mode::PEMenu
|
| Mode::PEMenu
|
||||||
| Mode::Process
|
| Mode::Process
|
||||||
| Mode::ScanWinImages
|
| Mode::ScanWinSources
|
||||||
|
| Mode::SelectWinSource
|
||||||
| Mode::SelectWinImage
|
| Mode::SelectWinImage
|
||||||
| Mode::SetBootMode
|
| Mode::SetBootMode
|
||||||
| Mode::SetUserName => panic!("This shouldn't happen?"),
|
| Mode::SetUserName => panic!("This shouldn't happen?"),
|
||||||
|
|
|
||||||
|
|
@ -102,8 +102,9 @@ impl App {
|
||||||
Mode::Home | Mode::InstallDrivers => Mode::ScanDisks,
|
Mode::Home | Mode::InstallDrivers => Mode::ScanDisks,
|
||||||
Mode::ScanDisks => Mode::SelectDisks,
|
Mode::ScanDisks => Mode::SelectDisks,
|
||||||
Mode::SelectDisks => Mode::SelectTableType,
|
Mode::SelectDisks => Mode::SelectTableType,
|
||||||
Mode::SelectTableType => Mode::ScanWinImages,
|
Mode::SelectTableType => Mode::ScanWinSources,
|
||||||
Mode::ScanWinImages => Mode::SelectWinImage,
|
Mode::ScanWinSources => Mode::SelectWinSource,
|
||||||
|
Mode::SelectWinSource => Mode::SelectWinImage,
|
||||||
Mode::SelectWinImage => Mode::SetUserName,
|
Mode::SelectWinImage => Mode::SetUserName,
|
||||||
Mode::SetUserName => Mode::Confirm,
|
Mode::SetUserName => Mode::Confirm,
|
||||||
Mode::Confirm => Mode::Process, // i.e. format, apply, etc
|
Mode::Confirm => Mode::Process, // i.e. format, apply, etc
|
||||||
|
|
@ -144,7 +145,7 @@ impl App {
|
||||||
String::from("Scanning Disks..."),
|
String::from("Scanning Disks..."),
|
||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
Mode::ScanWinImages => self.state.scan_wim_local(),
|
Mode::ScanWinSources => self.state.scan_wim_local(),
|
||||||
Mode::Done => {
|
Mode::Done => {
|
||||||
self.action_tx
|
self.action_tx
|
||||||
.send(Action::DisplayPopup(popup::Type::Success, popup::fortune()))?;
|
.send(Action::DisplayPopup(popup::Type::Success, popup::fortune()))?;
|
||||||
|
|
@ -297,12 +298,13 @@ impl App {
|
||||||
self.action_tx.send(Action::SetMode(Mode::SelectDisks))?;
|
self.action_tx.send(Action::SetMode(Mode::SelectDisks))?;
|
||||||
}
|
}
|
||||||
Mode::SetUserName => {
|
Mode::SetUserName => {
|
||||||
self.action_tx.send(Action::SetMode(Mode::SelectWinImage))?;
|
self.action_tx
|
||||||
|
.send(Action::SetMode(Mode::SelectWinSource))?;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
Action::Process => match self.cur_mode {
|
Action::Process => match self.cur_mode {
|
||||||
Mode::Confirm | Mode::ScanWinImages => {
|
Mode::Confirm | Mode::ScanWinSources => {
|
||||||
self.action_tx.send(Action::NextScreen)?;
|
self.action_tx.send(Action::NextScreen)?;
|
||||||
}
|
}
|
||||||
Mode::Done => {
|
Mode::Done => {
|
||||||
|
|
@ -338,7 +340,7 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Mode::SelectWinImage => {
|
Mode::SelectWinSource => {
|
||||||
// TODO: FIXME
|
// TODO: FIXME
|
||||||
// PLAN: Abuse Action::Select to send (file_index, image_index) to set all at once
|
// PLAN: Abuse Action::Select to send (file_index, image_index) to set all at once
|
||||||
// self.state.wim_file_index = TODO;
|
// self.state.wim_file_index = TODO;
|
||||||
|
|
@ -399,8 +401,9 @@ fn build_footer_string(cur_mode: Mode) -> String {
|
||||||
"(Enter) to select / / (i) to install driver / (r) to rescan / (q) to quit",
|
"(Enter) to select / / (i) to install driver / (r) to rescan / (q) to quit",
|
||||||
),
|
),
|
||||||
Mode::SelectTableType => String::from("(Enter) to select / (b) to go back / (q) to quit"),
|
Mode::SelectTableType => String::from("(Enter) to select / (b) to go back / (q) to quit"),
|
||||||
|
Mode::SelectWinSource => String::from("(Enter) to select / (q) to quit"),
|
||||||
Mode::SelectWinImage => String::from("(Enter) to select / (q) to quit"),
|
Mode::SelectWinImage => String::from("(Enter) to select / (q) to quit"),
|
||||||
Mode::ScanWinImages => {
|
Mode::ScanWinSources => {
|
||||||
String::from("(Enter) to continue / (n) to scan network / (q) to quit")
|
String::from("(Enter) to continue / (n) to scan network / (q) to quit")
|
||||||
}
|
}
|
||||||
Mode::SetUserName => String::from("(Enter) to continue / (Esc) to go back"),
|
Mode::SetUserName => String::from("(Enter) to continue / (Esc) to go back"),
|
||||||
|
|
@ -445,15 +448,25 @@ fn build_left_items(app: &App) -> Action {
|
||||||
title = String::from("Processing");
|
title = String::from("Processing");
|
||||||
// TODO: FIXME
|
// TODO: FIXME
|
||||||
}
|
}
|
||||||
Mode::ScanWinImages => {
|
Mode::ScanWinSources => {
|
||||||
select_type = SelectionType::Loop;
|
select_type = SelectionType::Loop;
|
||||||
title = String::from("Scanning");
|
title = String::from("Scanning");
|
||||||
// TODO: FIXME
|
// TODO: FIXME
|
||||||
}
|
}
|
||||||
|
Mode::SelectWinSource => {
|
||||||
|
select_type = SelectionType::One;
|
||||||
|
title = String::from("Select Windows Source");
|
||||||
|
if let Ok(wim_sources) = app.state.wim_sources.lock() {
|
||||||
|
wim_sources
|
||||||
|
.get_file_list()
|
||||||
|
.iter()
|
||||||
|
.for_each(|wim_file| items.push(wim_file.path.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
Mode::SelectWinImage => {
|
Mode::SelectWinImage => {
|
||||||
select_type = SelectionType::One;
|
select_type = SelectionType::One;
|
||||||
title = String::from("Select Windows Image");
|
title = String::from("Select Windows Image");
|
||||||
// TODO: FIXME, I think this whole section could be better...
|
// TODO: FIXME
|
||||||
}
|
}
|
||||||
Mode::SelectDisks => {
|
Mode::SelectDisks => {
|
||||||
select_type = SelectionType::One;
|
select_type = SelectionType::One;
|
||||||
|
|
@ -546,7 +559,65 @@ fn build_right_items(app: &App) -> Action {
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|disk| items.push(get_disk_description_right(disk, &None)));
|
.for_each(|disk| items.push(get_disk_description_right(disk, &None)));
|
||||||
}
|
}
|
||||||
Mode::SelectTableType | Mode::SelectWinImage | Mode::SetUserName | Mode::Confirm => {
|
Mode::SelectWinSource => {
|
||||||
|
// Disk Info
|
||||||
|
let type_str = match app.state.table_type.clone().unwrap() {
|
||||||
|
PartitionTableType::Guid => "GPT",
|
||||||
|
PartitionTableType::Legacy => "MBR",
|
||||||
|
};
|
||||||
|
let mut label_dv_lines = vec![
|
||||||
|
DVLine {
|
||||||
|
line_parts: vec![
|
||||||
|
String::from("Dest"),
|
||||||
|
String::from(" (WARNING: ALL DATA WILL BE DELETED!)"),
|
||||||
|
],
|
||||||
|
line_colors: vec![Color::Cyan, Color::Red],
|
||||||
|
},
|
||||||
|
DVLine {
|
||||||
|
line_parts: vec![format!(" (Will be formatted {type_str})")],
|
||||||
|
line_colors: vec![Color::Yellow],
|
||||||
|
},
|
||||||
|
DVLine::blank(),
|
||||||
|
];
|
||||||
|
let disk_list = app.state.disk_list.lock().unwrap();
|
||||||
|
if let Some(index) = app.state.disk_index_dest
|
||||||
|
&& let Some(disk) = disk_list.get(index)
|
||||||
|
{
|
||||||
|
get_disk_description_right(disk, &None)
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|dv_line| label_dv_lines.push(dv_line));
|
||||||
|
}
|
||||||
|
labels.push(label_dv_lines);
|
||||||
|
|
||||||
|
// WIM Info
|
||||||
|
if let Ok(wim_sources) = app.state.wim_sources.lock() {
|
||||||
|
wim_sources.get_file_list().iter().for_each(|source| {
|
||||||
|
let mut wim_dv_lines = vec![
|
||||||
|
DVLine {
|
||||||
|
line_parts: vec![String::from("WIM Info")],
|
||||||
|
line_colors: vec![Color::Cyan],
|
||||||
|
},
|
||||||
|
DVLine {
|
||||||
|
line_parts: vec![source.path.clone()],
|
||||||
|
line_colors: vec![Color::Reset],
|
||||||
|
},
|
||||||
|
DVLine::blank(),
|
||||||
|
DVLine {
|
||||||
|
line_parts: vec![String::from("Images")],
|
||||||
|
line_colors: vec![Color::Blue],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
source.images.iter().for_each(|image| {
|
||||||
|
wim_dv_lines.push(DVLine {
|
||||||
|
line_parts: vec![format!("{image}")],
|
||||||
|
line_colors: vec![Color::Reset],
|
||||||
|
})
|
||||||
|
});
|
||||||
|
items.push(wim_dv_lines);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mode::SelectTableType | Mode::SetUserName | Mode::Confirm => {
|
||||||
// Labels
|
// Labels
|
||||||
let dest_dv_line = DVLine {
|
let dest_dv_line = DVLine {
|
||||||
line_parts: vec![
|
line_parts: vec![
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ impl Component for WimScan {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> {
|
fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> {
|
||||||
if self.mode != Mode::ScanWinImages {
|
if self.mode != Mode::ScanWinSources {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
frame.render_widget(Clear, area);
|
frame.render_widget(Clear, area);
|
||||||
|
|
@ -117,36 +117,26 @@ impl Component for WimScan {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|wimfile| ListItem::new(format!("{}\n\n", wimfile.path))),
|
.map(|wimfile| ListItem::new(format!("{}\n\n", wimfile.path))),
|
||||||
);
|
);
|
||||||
let left_list = List::new(left_list)
|
let left_list = List::new(left_list).block(
|
||||||
.block(
|
Block::default()
|
||||||
Block::default()
|
.borders(Borders::ALL)
|
||||||
.borders(Borders::ALL)
|
.padding(Padding::new(1, 1, 1, 1)),
|
||||||
.padding(Padding::new(1, 1, 1, 1)),
|
);
|
||||||
)
|
|
||||||
.highlight_spacing(HighlightSpacing::Always)
|
|
||||||
.highlight_style(Style::new().green().bold())
|
|
||||||
.highlight_symbol(" --> ")
|
|
||||||
.repeat_highlight_symbol(false);
|
|
||||||
frame.render_widget(left_list, left_body);
|
frame.render_widget(left_list, left_body);
|
||||||
|
|
||||||
// Network
|
// Network
|
||||||
let mut right_list = Vec::new();
|
let mut right_list = Vec::new();
|
||||||
right_list.extend(
|
right_list.extend(wim_sources.network.iter().map(|wimfile| {
|
||||||
wim_sources
|
ListItem::new(format!(
|
||||||
.network
|
"{}\n\n",
|
||||||
.iter()
|
wimfile.path.split("\\").last().unwrap_or(&wimfile.path)
|
||||||
.map(|wimfile| ListItem::new(format!("{}\n\n", wimfile.path))),
|
))
|
||||||
|
}));
|
||||||
|
let right_list = List::new(right_list).block(
|
||||||
|
Block::default()
|
||||||
|
.borders(Borders::ALL)
|
||||||
|
.padding(Padding::new(1, 1, 1, 1)),
|
||||||
);
|
);
|
||||||
let right_list = List::new(right_list)
|
|
||||||
.block(
|
|
||||||
Block::default()
|
|
||||||
.borders(Borders::ALL)
|
|
||||||
.padding(Padding::new(1, 1, 1, 1)),
|
|
||||||
)
|
|
||||||
.highlight_spacing(HighlightSpacing::Always)
|
|
||||||
.highlight_style(Style::new().green().bold())
|
|
||||||
.highlight_symbol(" --> ")
|
|
||||||
.repeat_highlight_symbol(false);
|
|
||||||
frame.render_widget(right_list, right_body);
|
frame.render_widget(right_list, right_body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,12 +62,30 @@ static WIN_BUILDS: LazyLock<HashMap<&str, &str>> = LazyLock::new(|| {
|
||||||
])
|
])
|
||||||
});
|
});
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct WimFile {
|
pub struct WimFile {
|
||||||
pub path: String,
|
pub path: String,
|
||||||
pub images: Vec<WimImage>,
|
pub images: Vec<WimImage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl WimFile {
|
||||||
|
pub fn summary(&self) -> String {
|
||||||
|
let mut s = format!("{self}");
|
||||||
|
self.images.iter().for_each(|image| {
|
||||||
|
let image = format!("\n\t\t{image}");
|
||||||
|
s.push_str(&image);
|
||||||
|
});
|
||||||
|
|
||||||
|
s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for WimFile {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.path.split("\\").last().unwrap_or(&self.path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq for WimFile {
|
impl PartialEq for WimFile {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.path == other.path
|
self.path == other.path
|
||||||
|
|
@ -144,6 +162,22 @@ impl WimSources {
|
||||||
self.network.sort();
|
self.network.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_file(&self, index: usize) -> WimFile {
|
||||||
|
let num_local = self.local.len();
|
||||||
|
let index = if index < num_local {
|
||||||
|
index
|
||||||
|
} else {
|
||||||
|
index - num_local
|
||||||
|
};
|
||||||
|
self.local.get(index).unwrap().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_file_list(&self) -> Vec<WimFile> {
|
||||||
|
let mut list = self.local.clone();
|
||||||
|
list.append(&mut self.network.clone());
|
||||||
|
list
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reset_all(&mut self) {
|
pub fn reset_all(&mut self) {
|
||||||
self.local.clear();
|
self.local.clear();
|
||||||
self.network.clear();
|
self.network.clear();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue