mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
Refactor UI event handlers to a new module
Moves all UI event handling logic from the initialization script into a new, dedicated module `FFUUI.Core.Handlers.psm1`. This change improves code organization and separation of concerns by centralizing event handler registration.
This commit is contained in:
@@ -0,0 +1,312 @@
|
||||
function Register-EventHandlers {
|
||||
param([PSCustomObject]$State)
|
||||
WriteLog "Registering UI event handlers..."
|
||||
|
||||
# Hyper-V tab event handlers
|
||||
$State.Controls.cmbVMSwitchName.Add_SelectionChanged({
|
||||
param($eventSource, $selectionChangedEventArgs)
|
||||
# The state object is available via the parent window's Tag property
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
|
||||
$selectedItem = $eventSource.SelectedItem
|
||||
if ($selectedItem -eq 'Other') {
|
||||
$localState.Controls.txtCustomVMSwitchName.Visibility = 'Visible'
|
||||
$localState.Controls.txtVMHostIPAddress.Text = '' # Clear IP for custom
|
||||
}
|
||||
else {
|
||||
$localState.Controls.txtCustomVMSwitchName.Visibility = 'Collapsed'
|
||||
if ($localState.Data.vmSwitchMap.ContainsKey($selectedItem)) {
|
||||
$localState.Controls.txtVMHostIPAddress.Text = $localState.Data.vmSwitchMap[$selectedItem]
|
||||
}
|
||||
else {
|
||||
$localState.Controls.txtVMHostIPAddress.Text = '' # Clear IP if not found in map
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
# Windows Settings tab Event Handlers
|
||||
$State.Controls.txtISOPath.Add_TextChanged({
|
||||
param($eventSource, $textChangedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
Get-WindowsSettingsCombos -isoPath $localState.Controls.txtISOPath.Text -State $localState
|
||||
})
|
||||
|
||||
$State.Controls.cmbWindowsRelease.Add_SelectionChanged({
|
||||
param($eventSource, $selectionChangedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$selectedReleaseValue = 11 # Default if null
|
||||
if ($null -ne $localState.Controls.cmbWindowsRelease.SelectedItem) {
|
||||
$selectedReleaseValue = $localState.Controls.cmbWindowsRelease.SelectedItem.Value
|
||||
}
|
||||
# Only need to update the Version combo when Release changes
|
||||
Update-WindowsVersionCombo -selectedRelease $selectedReleaseValue -isoPath $localState.Controls.txtISOPath.Text -State $localState
|
||||
# Also update the SKU combo (now derives values internally)
|
||||
Update-WindowsSkuCombo -State $localState
|
||||
})
|
||||
|
||||
$State.Controls.btnBrowseISO.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$ofd = New-Object System.Windows.Forms.OpenFileDialog
|
||||
$ofd.Filter = "ISO files (*.iso)|*.iso"
|
||||
$ofd.Title = "Select Windows ISO File"
|
||||
if ($ofd.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $localState.Controls.txtISOPath.Text = $ofd.FileName }
|
||||
})
|
||||
|
||||
# Drivers Tab Event Handlers
|
||||
$State.Controls.chkDownloadDrivers.Add_Checked({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$localState.Controls.cmbMake.Visibility = 'Visible'
|
||||
$localState.Controls.btnGetModels.Visibility = 'Visible'
|
||||
$localState.Controls.spMakeSection.Visibility = 'Visible'
|
||||
$localState.Controls.spModelFilterSection.Visibility = 'Visible'
|
||||
$localState.Controls.lstDriverModels.Visibility = 'Visible'
|
||||
$localState.Controls.spDriverActionButtons.Visibility = 'Visible'
|
||||
})
|
||||
$State.Controls.chkDownloadDrivers.Add_Unchecked({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$localState.Controls.cmbMake.Visibility = 'Collapsed'
|
||||
$localState.Controls.btnGetModels.Visibility = 'Collapsed'
|
||||
$localState.Controls.spMakeSection.Visibility = 'Collapsed'
|
||||
$localState.Controls.spModelFilterSection.Visibility = 'Collapsed'
|
||||
$localState.Controls.lstDriverModels.Visibility = 'Collapsed'
|
||||
$localState.Controls.spDriverActionButtons.Visibility = 'Collapsed'
|
||||
$localState.Controls.lstDriverModels.ItemsSource = $null
|
||||
$localState.Data.allDriverModels.Clear()
|
||||
$localState.Controls.txtModelFilter.Text = ""
|
||||
})
|
||||
|
||||
$State.Controls.btnGetModels.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
|
||||
$selectedMake = $localState.Controls.cmbMake.SelectedItem
|
||||
$localState.Controls.txtStatus.Text = "Getting models for $selectedMake..."
|
||||
$window.Cursor = [System.Windows.Input.Cursors]::Wait
|
||||
$eventSource.IsEnabled = $false
|
||||
try {
|
||||
# Get ALL previously selected models to preserve them, regardless of make.
|
||||
$allPreviouslySelectedModels = @($localState.Data.allDriverModels | Where-Object { $_.IsSelected })
|
||||
|
||||
# Get newly fetched models for the current make
|
||||
$newlyFetchedStandardizedModels = Get-ModelsForMake -SelectedMake $selectedMake -State $localState
|
||||
|
||||
$combinedModelsList = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
$modelIdentifiersInCombinedList = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
|
||||
|
||||
# Add all previously selected models first to preserve their 'IsSelected' state.
|
||||
foreach ($item in $allPreviouslySelectedModels) {
|
||||
$combinedModelsList.Add($item)
|
||||
$modelIdentifiersInCombinedList.Add("$($item.Make)::$($item.Model)") | Out-Null
|
||||
}
|
||||
|
||||
# Add newly fetched models, but only if they are not already in the list.
|
||||
# This prevents overwriting a selected model with an unselected one.
|
||||
$addedNewCount = 0
|
||||
foreach ($item in $newlyFetchedStandardizedModels) {
|
||||
if ($modelIdentifiersInCombinedList.Add("$($item.Make)::$($item.Model)")) {
|
||||
$combinedModelsList.Add($item)
|
||||
$addedNewCount++
|
||||
}
|
||||
}
|
||||
|
||||
# Sort the combined list
|
||||
$sortedModels = $combinedModelsList | Sort-Object @{Expression = { $_.IsSelected }; Descending = $true }, Make, Model
|
||||
|
||||
# Create a new list object from the sorted results. This is safer than modifying the existing list
|
||||
# that the UI is bound to, which can cause inconsistency errors.
|
||||
$newList = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
if ($null -ne $sortedModels) {
|
||||
# Sort-Object can return a single object or an array. Ensure it's always treated as a collection.
|
||||
foreach ($model in @($sortedModels)) {
|
||||
$newList.Add($model)
|
||||
}
|
||||
}
|
||||
$localState.Data.allDriverModels = $newList
|
||||
|
||||
# Update the UI ItemsSource to point to the new list and clear the filter
|
||||
$localState.Controls.lstDriverModels.ItemsSource = $localState.Data.allDriverModels
|
||||
$localState.Controls.txtModelFilter.Text = ""
|
||||
|
||||
if ($localState.Data.allDriverModels.Count -gt 0) {
|
||||
$localState.Controls.spModelFilterSection.Visibility = 'Visible'
|
||||
$localState.Controls.lstDriverModels.Visibility = 'Visible'
|
||||
$localState.Controls.spDriverActionButtons.Visibility = 'Visible'
|
||||
$statusText = "Displaying $($localState.Data.allDriverModels.Count) models."
|
||||
if ($newlyFetchedStandardizedModels.Count -gt 0 -and $addedNewCount -eq 0 -and $allPreviouslySelectedModels.Count -gt 0) {
|
||||
$statusText = "Fetched $($newlyFetchedStandardizedModels.Count) models for $selectedMake; all were already in the selected list. Displaying $($localState.Data.allDriverModels.Count) total selected models."
|
||||
}
|
||||
elseif ($addedNewCount -gt 0) {
|
||||
$statusText = "Added $addedNewCount new models for $selectedMake. Displaying $($localState.Data.allDriverModels.Count) total models."
|
||||
}
|
||||
elseif ($newlyFetchedStandardizedModels.Count -eq 0 -and $selectedMake -eq 'Lenovo' ) {
|
||||
$statusText = if ($allPreviouslySelectedModels.Count -gt 0) { "No new models found for $selectedMake. Displaying $($allPreviouslySelectedModels.Count) previously selected models." } else { "No models found for $selectedMake." }
|
||||
}
|
||||
elseif ($newlyFetchedStandardizedModels.Count -eq 0) {
|
||||
$statusText = "No new models found for $selectedMake. Displaying $($localState.Data.allDriverModels.Count) previously selected models."
|
||||
}
|
||||
$localState.Controls.txtStatus.Text = $statusText
|
||||
}
|
||||
else {
|
||||
$localState.Controls.spModelFilterSection.Visibility = 'Collapsed'
|
||||
$localState.Controls.lstDriverModels.Visibility = 'Collapsed'
|
||||
$localState.Controls.spDriverActionButtons.Visibility = 'Collapsed'
|
||||
$localState.Controls.txtStatus.Text = "No models to display for $selectedMake."
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$localState.Controls.txtStatus.Text = "Error getting models: $($_.Exception.Message)"
|
||||
[System.Windows.MessageBox]::Show("Error getting models: $($_.Exception.Message)", "Error", "OK", "Error")
|
||||
if ($null -eq $localState.Data.allDriverModels -or $localState.Data.allDriverModels.Count -eq 0) {
|
||||
$localState.Controls.spModelFilterSection.Visibility = 'Collapsed'
|
||||
$localState.Controls.lstDriverModels.Visibility = 'Collapsed'
|
||||
$localState.Controls.spDriverActionButtons.Visibility = 'Collapsed'
|
||||
$localState.Controls.lstDriverModels.ItemsSource = $null
|
||||
$localState.Controls.txtModelFilter.Text = ""
|
||||
}
|
||||
}
|
||||
finally {
|
||||
$window.Cursor = $null
|
||||
$eventSource.IsEnabled = $true
|
||||
}
|
||||
})
|
||||
$State.Controls.txtModelFilter.Add_TextChanged({
|
||||
param($sourceObject, $textChangedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($sourceObject)
|
||||
$localState = $window.Tag
|
||||
Search-DriverModels -filterText $localState.Controls.txtModelFilter.Text -State $localState
|
||||
})
|
||||
|
||||
$State.Controls.btnDownloadSelectedDrivers.Add_Click({
|
||||
param($buttonSender, $clickEventArgs)
|
||||
|
||||
$window = [System.Windows.Window]::GetWindow($buttonSender)
|
||||
$localState = $window.Tag
|
||||
|
||||
$selectedDrivers = @($localState.Controls.lstDriverModels.Items | Where-Object { $_.IsSelected })
|
||||
if (-not $selectedDrivers) {
|
||||
[System.Windows.MessageBox]::Show("No drivers selected to download.", "Download Drivers", "OK", "Information")
|
||||
return
|
||||
}
|
||||
|
||||
$buttonSender.IsEnabled = $false
|
||||
$localState.Controls.pbOverallProgress.Visibility = 'Visible'
|
||||
$localState.Controls.pbOverallProgress.Value = 0
|
||||
$localState.Controls.txtStatus.Text = "Preparing driver downloads..."
|
||||
|
||||
# Define common necessary task-specific variables locally
|
||||
# Ensure required selections are made
|
||||
if ($null -eq $localState.Controls.cmbWindowsRelease.SelectedItem) {
|
||||
[System.Windows.MessageBox]::Show("Please select a Windows Release.", "Missing Information", "OK", "Warning")
|
||||
$buttonSender.IsEnabled = $true
|
||||
$localState.Controls.pbOverallProgress.Visibility = 'Collapsed'
|
||||
$localState.Controls.txtStatus.Text = "Driver download cancelled."
|
||||
return
|
||||
}
|
||||
if ($null -eq $localState.Controls.cmbWindowsArch.SelectedItem) {
|
||||
[System.Windows.MessageBox]::Show("Please select a Windows Architecture.", "Missing Information", "OK", "Warning")
|
||||
$buttonSender.IsEnabled = $true
|
||||
$localState.Controls.pbOverallProgress.Visibility = 'Collapsed'
|
||||
$localState.Controls.txtStatus.Text = "Driver download cancelled."
|
||||
return
|
||||
}
|
||||
if (($selectedDrivers | Where-Object { $_.Make -eq 'HP' }) -and $null -ne $localState.Controls.cmbWindowsVersion -and $null -eq $localState.Controls.cmbWindowsVersion.SelectedItem) {
|
||||
[System.Windows.MessageBox]::Show("HP drivers are selected. Please select a Windows Version.", "Missing Information", "OK", "Warning")
|
||||
$buttonSender.IsEnabled = $true
|
||||
$localState.Controls.pbOverallProgress.Visibility = 'Collapsed'
|
||||
$localState.Controls.txtStatus.Text = "Driver download cancelled."
|
||||
return
|
||||
}
|
||||
|
||||
$localDriversFolder = $localState.Controls.txtDriversFolder.Text
|
||||
$localWindowsRelease = $localState.Controls.cmbWindowsRelease.SelectedItem.Value
|
||||
$localWindowsArch = $localState.Controls.cmbWindowsArch.SelectedItem
|
||||
$localWindowsVersion = if ($null -ne $localState.Controls.cmbWindowsVersion -and $null -ne $localState.Controls.cmbWindowsVersion.SelectedItem) { $localState.Controls.cmbWindowsVersion.SelectedItem } else { $null }
|
||||
$coreStaticVars = Get-CoreStaticVariables
|
||||
$localHeaders = $coreStaticVars.Headers
|
||||
$localUserAgent = $coreStaticVars.UserAgent
|
||||
$compressDrivers = $localState.Controls.chkCompressDriversToWIM.IsChecked
|
||||
|
||||
$localState.Controls.txtStatus.Text = "Processing all selected drivers..."
|
||||
WriteLog "Processing all selected drivers: $($selectedDrivers.Model -join ', ')"
|
||||
|
||||
$taskArguments = @{
|
||||
DriversFolder = $localDriversFolder
|
||||
WindowsRelease = $localWindowsRelease
|
||||
WindowsArch = $localWindowsArch
|
||||
WindowsVersion = $localWindowsVersion
|
||||
Headers = $localHeaders
|
||||
UserAgent = $localUserAgent
|
||||
CompressToWim = $compressDrivers
|
||||
}
|
||||
|
||||
Invoke-ParallelProcessing -ItemsToProcess $selectedDrivers `
|
||||
-ListViewControl $localState.Controls.lstDriverModels `
|
||||
-IdentifierProperty 'Model' `
|
||||
-StatusProperty 'DownloadStatus' `
|
||||
-TaskType 'DownloadDriverByMake' `
|
||||
-TaskArguments $taskArguments `
|
||||
-CompletedStatusText 'Completed' `
|
||||
-ErrorStatusPrefix 'Error: ' `
|
||||
-WindowObject $window `
|
||||
-MainThreadLogPath $localState.LogFilePath
|
||||
|
||||
$overallSuccess = $true
|
||||
# Check if any item has an error status after processing
|
||||
# We iterate over $localState.Controls.lstDriverModels.Items because their DownloadStatus property was updated by Invoke-ParallelProcessing
|
||||
foreach ($item in ($localState.Controls.lstDriverModels.Items | Where-Object { $_.IsSelected })) {
|
||||
# Check only originally selected items
|
||||
if ($item.DownloadStatus -like 'Error:*') {
|
||||
$overallSuccess = $false
|
||||
WriteLog "Error detected for model $($item.Model) (Make: $($item.Make)): $($item.DownloadStatus)"
|
||||
# No break here, log all errors
|
||||
}
|
||||
}
|
||||
|
||||
$localState.Controls.pbOverallProgress.Visibility = 'Collapsed'
|
||||
$buttonSender.IsEnabled = $true
|
||||
if ($overallSuccess) {
|
||||
$localState.Controls.txtStatus.Text = "All selected driver downloads processed."
|
||||
[System.Windows.MessageBox]::Show("All selected driver downloads processed. Check status column for details.", "Download Process Finished", "OK", "Information")
|
||||
}
|
||||
else {
|
||||
$localState.Controls.txtStatus.Text = "Driver downloads processed with some errors. Check status column and log."
|
||||
[System.Windows.MessageBox]::Show("Driver downloads processed, but some errors occurred. Please check the status column for each driver and the log file for details.", "Download Process Finished with Errors", "OK", "Warning")
|
||||
}
|
||||
})
|
||||
|
||||
$State.Controls.btnClearDriverList.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$localState.Controls.lstDriverModels.ItemsSource = $null
|
||||
$localState.Data.allDriverModels.Clear()
|
||||
$localState.Controls.txtModelFilter.Text = ""
|
||||
$localState.Controls.txtStatus.Text = "Driver list cleared."
|
||||
})
|
||||
|
||||
$State.Controls.btnSaveDriversJson.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
Save-DriversJson -State $localState
|
||||
})
|
||||
|
||||
$State.Controls.btnImportDriversJson.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
Import-DriversJson -State $localState
|
||||
})
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function *
|
||||
@@ -405,315 +405,4 @@ function Initialize-VMSwitchData {
|
||||
}
|
||||
}
|
||||
|
||||
function Register-EventHandlers {
|
||||
param([PSCustomObject]$State)
|
||||
WriteLog "Registering UI event handlers..."
|
||||
|
||||
# Hyper-V tab event handlers
|
||||
$State.Controls.cmbVMSwitchName.Add_SelectionChanged({
|
||||
param($eventSource, $selectionChangedEventArgs)
|
||||
# The state object is available via the parent window's Tag property
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
|
||||
$selectedItem = $eventSource.SelectedItem
|
||||
if ($selectedItem -eq 'Other') {
|
||||
$localState.Controls.txtCustomVMSwitchName.Visibility = 'Visible'
|
||||
$localState.Controls.txtVMHostIPAddress.Text = '' # Clear IP for custom
|
||||
}
|
||||
else {
|
||||
$localState.Controls.txtCustomVMSwitchName.Visibility = 'Collapsed'
|
||||
if ($localState.Data.vmSwitchMap.ContainsKey($selectedItem)) {
|
||||
$localState.Controls.txtVMHostIPAddress.Text = $localState.Data.vmSwitchMap[$selectedItem]
|
||||
}
|
||||
else {
|
||||
$localState.Controls.txtVMHostIPAddress.Text = '' # Clear IP if not found in map
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
# Windows Settings tab Event Handlers
|
||||
$State.Controls.txtISOPath.Add_TextChanged({
|
||||
param($eventSource, $textChangedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
Get-WindowsSettingsCombos -isoPath $localState.Controls.txtISOPath.Text -State $localState
|
||||
})
|
||||
|
||||
$State.Controls.cmbWindowsRelease.Add_SelectionChanged({
|
||||
param($eventSource, $selectionChangedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$selectedReleaseValue = 11 # Default if null
|
||||
if ($null -ne $localState.Controls.cmbWindowsRelease.SelectedItem) {
|
||||
$selectedReleaseValue = $localState.Controls.cmbWindowsRelease.SelectedItem.Value
|
||||
}
|
||||
# Only need to update the Version combo when Release changes
|
||||
Update-WindowsVersionCombo -selectedRelease $selectedReleaseValue -isoPath $localState.Controls.txtISOPath.Text -State $localState
|
||||
# Also update the SKU combo (now derives values internally)
|
||||
Update-WindowsSkuCombo -State $localState
|
||||
})
|
||||
|
||||
$State.Controls.btnBrowseISO.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$ofd = New-Object System.Windows.Forms.OpenFileDialog
|
||||
$ofd.Filter = "ISO files (*.iso)|*.iso"
|
||||
$ofd.Title = "Select Windows ISO File"
|
||||
if ($ofd.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $localState.Controls.txtISOPath.Text = $ofd.FileName }
|
||||
})
|
||||
|
||||
# Drivers Tab Event Handlers
|
||||
$State.Controls.chkDownloadDrivers.Add_Checked({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$localState.Controls.cmbMake.Visibility = 'Visible'
|
||||
$localState.Controls.btnGetModels.Visibility = 'Visible'
|
||||
$localState.Controls.spMakeSection.Visibility = 'Visible'
|
||||
$localState.Controls.spModelFilterSection.Visibility = 'Visible'
|
||||
$localState.Controls.lstDriverModels.Visibility = 'Visible'
|
||||
$localState.Controls.spDriverActionButtons.Visibility = 'Visible'
|
||||
})
|
||||
$State.Controls.chkDownloadDrivers.Add_Unchecked({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$localState.Controls.cmbMake.Visibility = 'Collapsed'
|
||||
$localState.Controls.btnGetModels.Visibility = 'Collapsed'
|
||||
$localState.Controls.spMakeSection.Visibility = 'Collapsed'
|
||||
$localState.Controls.spModelFilterSection.Visibility = 'Collapsed'
|
||||
$localState.Controls.lstDriverModels.Visibility = 'Collapsed'
|
||||
$localState.Controls.spDriverActionButtons.Visibility = 'Collapsed'
|
||||
$localState.Controls.lstDriverModels.ItemsSource = $null
|
||||
$localState.Data.allDriverModels.Clear()
|
||||
$localState.Controls.txtModelFilter.Text = ""
|
||||
})
|
||||
|
||||
$State.Controls.btnGetModels.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
|
||||
$selectedMake = $localState.Controls.cmbMake.SelectedItem
|
||||
$localState.Controls.txtStatus.Text = "Getting models for $selectedMake..."
|
||||
$window.Cursor = [System.Windows.Input.Cursors]::Wait
|
||||
$eventSource.IsEnabled = $false
|
||||
try {
|
||||
# Get ALL previously selected models to preserve them, regardless of make.
|
||||
$allPreviouslySelectedModels = @($localState.Data.allDriverModels | Where-Object { $_.IsSelected })
|
||||
|
||||
# Get newly fetched models for the current make
|
||||
$newlyFetchedStandardizedModels = Get-ModelsForMake -SelectedMake $selectedMake -State $localState
|
||||
|
||||
$combinedModelsList = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
$modelIdentifiersInCombinedList = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
|
||||
|
||||
# Add all previously selected models first to preserve their 'IsSelected' state.
|
||||
foreach ($item in $allPreviouslySelectedModels) {
|
||||
$combinedModelsList.Add($item)
|
||||
$modelIdentifiersInCombinedList.Add("$($item.Make)::$($item.Model)") | Out-Null
|
||||
}
|
||||
|
||||
# Add newly fetched models, but only if they are not already in the list.
|
||||
# This prevents overwriting a selected model with an unselected one.
|
||||
$addedNewCount = 0
|
||||
foreach ($item in $newlyFetchedStandardizedModels) {
|
||||
if ($modelIdentifiersInCombinedList.Add("$($item.Make)::$($item.Model)")) {
|
||||
$combinedModelsList.Add($item)
|
||||
$addedNewCount++
|
||||
}
|
||||
}
|
||||
|
||||
# Sort the combined list
|
||||
$sortedModels = $combinedModelsList | Sort-Object @{Expression = { $_.IsSelected }; Descending = $true }, Make, Model
|
||||
|
||||
# Create a new list object from the sorted results. This is safer than modifying the existing list
|
||||
# that the UI is bound to, which can cause inconsistency errors.
|
||||
$newList = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
if ($null -ne $sortedModels) {
|
||||
# Sort-Object can return a single object or an array. Ensure it's always treated as a collection.
|
||||
foreach ($model in @($sortedModels)) {
|
||||
$newList.Add($model)
|
||||
}
|
||||
}
|
||||
$localState.Data.allDriverModels = $newList
|
||||
|
||||
# Update the UI ItemsSource to point to the new list and clear the filter
|
||||
$localState.Controls.lstDriverModels.ItemsSource = $localState.Data.allDriverModels
|
||||
$localState.Controls.txtModelFilter.Text = ""
|
||||
|
||||
if ($localState.Data.allDriverModels.Count -gt 0) {
|
||||
$localState.Controls.spModelFilterSection.Visibility = 'Visible'
|
||||
$localState.Controls.lstDriverModels.Visibility = 'Visible'
|
||||
$localState.Controls.spDriverActionButtons.Visibility = 'Visible'
|
||||
$statusText = "Displaying $($localState.Data.allDriverModels.Count) models."
|
||||
if ($newlyFetchedStandardizedModels.Count -gt 0 -and $addedNewCount -eq 0 -and $allPreviouslySelectedModels.Count -gt 0) {
|
||||
$statusText = "Fetched $($newlyFetchedStandardizedModels.Count) models for $selectedMake; all were already in the selected list. Displaying $($localState.Data.allDriverModels.Count) total selected models."
|
||||
}
|
||||
elseif ($addedNewCount -gt 0) {
|
||||
$statusText = "Added $addedNewCount new models for $selectedMake. Displaying $($localState.Data.allDriverModels.Count) total models."
|
||||
}
|
||||
elseif ($newlyFetchedStandardizedModels.Count -eq 0 -and $selectedMake -eq 'Lenovo' ) {
|
||||
$statusText = if ($allPreviouslySelectedModels.Count -gt 0) { "No new models found for $selectedMake. Displaying $($allPreviouslySelectedModels.Count) previously selected models." } else { "No models found for $selectedMake." }
|
||||
}
|
||||
elseif ($newlyFetchedStandardizedModels.Count -eq 0) {
|
||||
$statusText = "No new models found for $selectedMake. Displaying $($localState.Data.allDriverModels.Count) previously selected models."
|
||||
}
|
||||
$localState.Controls.txtStatus.Text = $statusText
|
||||
}
|
||||
else {
|
||||
$localState.Controls.spModelFilterSection.Visibility = 'Collapsed'
|
||||
$localState.Controls.lstDriverModels.Visibility = 'Collapsed'
|
||||
$localState.Controls.spDriverActionButtons.Visibility = 'Collapsed'
|
||||
$localState.Controls.txtStatus.Text = "No models to display for $selectedMake."
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$localState.Controls.txtStatus.Text = "Error getting models: $($_.Exception.Message)"
|
||||
[System.Windows.MessageBox]::Show("Error getting models: $($_.Exception.Message)", "Error", "OK", "Error")
|
||||
if ($null -eq $localState.Data.allDriverModels -or $localState.Data.allDriverModels.Count -eq 0) {
|
||||
$localState.Controls.spModelFilterSection.Visibility = 'Collapsed'
|
||||
$localState.Controls.lstDriverModels.Visibility = 'Collapsed'
|
||||
$localState.Controls.spDriverActionButtons.Visibility = 'Collapsed'
|
||||
$localState.Controls.lstDriverModels.ItemsSource = $null
|
||||
$localState.Controls.txtModelFilter.Text = ""
|
||||
}
|
||||
}
|
||||
finally {
|
||||
$window.Cursor = $null
|
||||
$eventSource.IsEnabled = $true
|
||||
}
|
||||
})
|
||||
$State.Controls.txtModelFilter.Add_TextChanged({
|
||||
param($sourceObject, $textChangedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($sourceObject)
|
||||
$localState = $window.Tag
|
||||
Search-DriverModels -filterText $localState.Controls.txtModelFilter.Text -State $localState
|
||||
})
|
||||
|
||||
$State.Controls.btnDownloadSelectedDrivers.Add_Click({
|
||||
param($buttonSender, $clickEventArgs)
|
||||
|
||||
$window = [System.Windows.Window]::GetWindow($buttonSender)
|
||||
$localState = $window.Tag
|
||||
|
||||
$selectedDrivers = @($localState.Controls.lstDriverModels.Items | Where-Object { $_.IsSelected })
|
||||
if (-not $selectedDrivers) {
|
||||
[System.Windows.MessageBox]::Show("No drivers selected to download.", "Download Drivers", "OK", "Information")
|
||||
return
|
||||
}
|
||||
|
||||
$buttonSender.IsEnabled = $false
|
||||
$localState.Controls.pbOverallProgress.Visibility = 'Visible'
|
||||
$localState.Controls.pbOverallProgress.Value = 0
|
||||
$localState.Controls.txtStatus.Text = "Preparing driver downloads..."
|
||||
|
||||
# Define common necessary task-specific variables locally
|
||||
# Ensure required selections are made
|
||||
if ($null -eq $localState.Controls.cmbWindowsRelease.SelectedItem) {
|
||||
[System.Windows.MessageBox]::Show("Please select a Windows Release.", "Missing Information", "OK", "Warning")
|
||||
$buttonSender.IsEnabled = $true
|
||||
$localState.Controls.pbOverallProgress.Visibility = 'Collapsed'
|
||||
$localState.Controls.txtStatus.Text = "Driver download cancelled."
|
||||
return
|
||||
}
|
||||
if ($null -eq $localState.Controls.cmbWindowsArch.SelectedItem) {
|
||||
[System.Windows.MessageBox]::Show("Please select a Windows Architecture.", "Missing Information", "OK", "Warning")
|
||||
$buttonSender.IsEnabled = $true
|
||||
$localState.Controls.pbOverallProgress.Visibility = 'Collapsed'
|
||||
$localState.Controls.txtStatus.Text = "Driver download cancelled."
|
||||
return
|
||||
}
|
||||
if (($selectedDrivers | Where-Object { $_.Make -eq 'HP' }) -and $null -ne $localState.Controls.cmbWindowsVersion -and $null -eq $localState.Controls.cmbWindowsVersion.SelectedItem) {
|
||||
[System.Windows.MessageBox]::Show("HP drivers are selected. Please select a Windows Version.", "Missing Information", "OK", "Warning")
|
||||
$buttonSender.IsEnabled = $true
|
||||
$localState.Controls.pbOverallProgress.Visibility = 'Collapsed'
|
||||
$localState.Controls.txtStatus.Text = "Driver download cancelled."
|
||||
return
|
||||
}
|
||||
|
||||
$localDriversFolder = $localState.Controls.txtDriversFolder.Text
|
||||
$localWindowsRelease = $localState.Controls.cmbWindowsRelease.SelectedItem.Value
|
||||
$localWindowsArch = $localState.Controls.cmbWindowsArch.SelectedItem
|
||||
$localWindowsVersion = if ($null -ne $localState.Controls.cmbWindowsVersion -and $null -ne $localState.Controls.cmbWindowsVersion.SelectedItem) { $localState.Controls.cmbWindowsVersion.SelectedItem } else { $null }
|
||||
$coreStaticVars = Get-CoreStaticVariables
|
||||
$localHeaders = $coreStaticVars.Headers
|
||||
$localUserAgent = $coreStaticVars.UserAgent
|
||||
$compressDrivers = $localState.Controls.chkCompressDriversToWIM.IsChecked
|
||||
|
||||
$localState.Controls.txtStatus.Text = "Processing all selected drivers..."
|
||||
WriteLog "Processing all selected drivers: $($selectedDrivers.Model -join ', ')"
|
||||
|
||||
$taskArguments = @{
|
||||
DriversFolder = $localDriversFolder
|
||||
WindowsRelease = $localWindowsRelease
|
||||
WindowsArch = $localWindowsArch
|
||||
WindowsVersion = $localWindowsVersion
|
||||
Headers = $localHeaders
|
||||
UserAgent = $localUserAgent
|
||||
CompressToWim = $compressDrivers
|
||||
}
|
||||
|
||||
Invoke-ParallelProcessing -ItemsToProcess $selectedDrivers `
|
||||
-ListViewControl $localState.Controls.lstDriverModels `
|
||||
-IdentifierProperty 'Model' `
|
||||
-StatusProperty 'DownloadStatus' `
|
||||
-TaskType 'DownloadDriverByMake' `
|
||||
-TaskArguments $taskArguments `
|
||||
-CompletedStatusText 'Completed' `
|
||||
-ErrorStatusPrefix 'Error: ' `
|
||||
-WindowObject $window `
|
||||
-MainThreadLogPath $localState.LogFilePath
|
||||
|
||||
$overallSuccess = $true
|
||||
# Check if any item has an error status after processing
|
||||
# We iterate over $localState.Controls.lstDriverModels.Items because their DownloadStatus property was updated by Invoke-ParallelProcessing
|
||||
foreach ($item in ($localState.Controls.lstDriverModels.Items | Where-Object { $_.IsSelected })) {
|
||||
# Check only originally selected items
|
||||
if ($item.DownloadStatus -like 'Error:*') {
|
||||
$overallSuccess = $false
|
||||
WriteLog "Error detected for model $($item.Model) (Make: $($item.Make)): $($item.DownloadStatus)"
|
||||
# No break here, log all errors
|
||||
}
|
||||
}
|
||||
|
||||
$localState.Controls.pbOverallProgress.Visibility = 'Collapsed'
|
||||
$buttonSender.IsEnabled = $true
|
||||
if ($overallSuccess) {
|
||||
$localState.Controls.txtStatus.Text = "All selected driver downloads processed."
|
||||
[System.Windows.MessageBox]::Show("All selected driver downloads processed. Check status column for details.", "Download Process Finished", "OK", "Information")
|
||||
}
|
||||
else {
|
||||
$localState.Controls.txtStatus.Text = "Driver downloads processed with some errors. Check status column and log."
|
||||
[System.Windows.MessageBox]::Show("Driver downloads processed, but some errors occurred. Please check the status column for each driver and the log file for details.", "Download Process Finished with Errors", "OK", "Warning")
|
||||
}
|
||||
})
|
||||
|
||||
$State.Controls.btnClearDriverList.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$localState.Controls.lstDriverModels.ItemsSource = $null
|
||||
$localState.Data.allDriverModels.Clear()
|
||||
$localState.Controls.txtModelFilter.Text = ""
|
||||
$localState.Controls.txtStatus.Text = "Driver list cleared."
|
||||
})
|
||||
|
||||
$State.Controls.btnSaveDriversJson.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
Save-DriversJson -State $localState
|
||||
})
|
||||
|
||||
$State.Controls.btnImportDriversJson.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
Import-DriversJson -State $localState
|
||||
})
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function *
|
||||
|
||||
@@ -73,6 +73,7 @@ NestedModules = @('FFUUI.Core.Applications.psm1',
|
||||
'FFUUI.Core.Drivers.HP.psm1',
|
||||
'FFUUI.Core.Drivers.Lenovo.psm1',
|
||||
'FFUUI.Core.Drivers.Microsoft.psm1',
|
||||
'FFUUI.Core.Handlers.psm1',
|
||||
'FFUUI.Core.Initialize.psm1',
|
||||
'FFUUI.Core.Shared.psm1',
|
||||
'FFUUI.Core.WindowsSettings.psm1',
|
||||
|
||||
Reference in New Issue
Block a user