3994 lines
145 KiB
PowerShell
3994 lines
145 KiB
PowerShell
using namespace System.Windows.Forms
|
|
using namespace System.Drawing
|
|
|
|
#region Class Definition
|
|
|
|
class BaseComponent {
|
|
static [SettingsManager] $SettingsManager
|
|
static [LogManager] $LogManager
|
|
static [AccessibilityManager] $AccessibilityManager
|
|
|
|
static [void] InitializeShared([SettingsManager]$SettingsManager, [LogManager]$LogManager) {
|
|
[BaseComponent]::SettingsManager = $SettingsManager
|
|
[BaseComponent]::LogManager = $LogManager
|
|
[BaseComponent]::AccessibilityManager = [AccessibilityManager]::new($SettingsManager, $LogManager)
|
|
}
|
|
|
|
[object] GetSetting([string]$key) {
|
|
return [BaseComponent]::SettingsManager.Get($key)
|
|
}
|
|
|
|
[object] GetSetting([string]$key, [object]$defaultValue) {
|
|
return [BaseComponent]::SettingsManager.Get($key, $defaultValue)
|
|
}
|
|
|
|
[void] SetSetting([string]$key, [object]$value) {
|
|
[BaseComponent]::SettingsManager.Set($key, $value)
|
|
}
|
|
|
|
[void] LogInfo([string]$message) {
|
|
if ($null -ne [BaseComponent]::LogManager) {
|
|
[BaseComponent]::LogManager.Info($message)
|
|
}
|
|
}
|
|
}
|
|
|
|
class SettingsManager {
|
|
[System.String]$SettingsPath
|
|
[System.Collections.Hashtable]$Settings
|
|
|
|
SettingsManager([System.String]$appName) {
|
|
$appDataPath = [Environment]::GetFolderPath('ApplicationData')
|
|
$appFolder = Join-Path $appDataPath $appName
|
|
|
|
if (-not (Test-Path $appFolder)) {
|
|
New-Item -Path $appFolder -ItemType Directory -Force | Out-Null
|
|
}
|
|
|
|
$this.SettingsPath = Join-Path $appFolder "settings.json"
|
|
$this.Load()
|
|
$this.EnsureDefaults()
|
|
}
|
|
|
|
[void] Load() {
|
|
if (Test-Path $this.SettingsPath) {
|
|
try {
|
|
$json = Get-Content $this.SettingsPath -Raw | ConvertFrom-Json
|
|
$this.Settings = @{}
|
|
foreach ($prop in $json.PSObject.Properties) {
|
|
$this.Settings[$prop.Name] = $prop.Value
|
|
}
|
|
} catch {
|
|
Write-Warning "Fehler beim Laden der Settings: $_"
|
|
$this.Settings = @{}
|
|
}
|
|
} else {
|
|
$this.Settings = @{}
|
|
}
|
|
}
|
|
|
|
# NEU: Stellt sicher, dass Standard-Einstellungen vorhanden sind
|
|
[void] EnsureDefaults() {
|
|
if (-not $this.Settings.ContainsKey("MenuStructure")) {
|
|
$this.Settings["MenuStructure"] = $this.GetDefaultMenuStructure()
|
|
$this.Save()
|
|
}
|
|
|
|
if (-not $this.Settings.ContainsKey("WindowWidth")) {
|
|
$this.Settings["WindowWidth"] = 1024
|
|
}
|
|
|
|
if (-not $this.Settings.ContainsKey("WindowHeight")) {
|
|
$this.Settings["WindowHeight"] = 768
|
|
}
|
|
|
|
if (-not $this.Settings.ContainsKey("SplitterDistance")) {
|
|
$this.Settings["SplitterDistance"] = 200
|
|
}
|
|
|
|
if (-not $this.Settings.ContainsKey("TemplatePath")) {
|
|
$this.Settings["TemplatePath"] = (Join-Path -Path $this.Settings["RootPath"] -ChildPath "Templates")
|
|
}
|
|
|
|
if (-not $this.Settings.ContainsKey("FunctionsPath")) {
|
|
$this.Settings["FunctionsPath"] = (Join-Path -Path $this.Settings["RootPath"] -ChildPath "Functions")
|
|
}
|
|
|
|
if (-not $this.Settings.ContainsKey("DeploymentPath")) {
|
|
$this.Settings["DeploymentPath"] = (Join-Path -Path $this.Settings["RootPath"] -ChildPath "Deployments")
|
|
}
|
|
}
|
|
|
|
# NEU: Standard-Menüstruktur
|
|
[object] GetDefaultMenuStructure() {
|
|
return @(
|
|
@{
|
|
Name = "Datei"
|
|
Text = "Datei"
|
|
Items = @(
|
|
@{ Name = "Import"; Text = "Import" }
|
|
@{ Name = "Export"; Text = "Export" }
|
|
@{ Name = "Refresh"; Text = "Aktualisieren" }
|
|
@{ Type = "Separator" }
|
|
@{ Name = "Exit"; Text = "Beenden" }
|
|
)
|
|
},
|
|
@{
|
|
Name = "Settings"
|
|
Text = "Einstellungen"
|
|
Items = @(
|
|
@{ Name = "OpenFolder"; Text = "Ordner wählen..." }
|
|
@{ Name = "ResetMenu"; Text = "Menü zurücksetzen" }
|
|
)
|
|
},
|
|
@{
|
|
Name = "TemplateDesigner"
|
|
Text = "Template Designer"
|
|
},
|
|
@{
|
|
Name = "Help"
|
|
Text = "Hilfe"
|
|
Items = @(
|
|
@{ Name = "About"; Text = "Über..." }
|
|
)
|
|
}
|
|
)
|
|
}
|
|
|
|
[void] Save() {
|
|
try {
|
|
$this.Settings | ConvertTo-Json -Depth 10 | Set-Content $this.SettingsPath -Encoding UTF8
|
|
} catch {
|
|
Write-Warning "Fehler beim Speichern der Settings: $_"
|
|
}
|
|
}
|
|
|
|
[object] Get([System.String]$key) {
|
|
return $this.Settings[$key]
|
|
}
|
|
|
|
[object] Get([System.String]$key, [object]$defaultValue) {
|
|
if ($this.Settings.ContainsKey($key)) {
|
|
return $this.Settings[$key]
|
|
}
|
|
return $defaultValue
|
|
}
|
|
|
|
[void] Set([System.String]$key, [object]$value) {
|
|
$this.Settings[$key] = $value
|
|
$this.Save()
|
|
}
|
|
|
|
[bool] Contains([System.String]$key) {
|
|
return $this.Settings.ContainsKey($key)
|
|
}
|
|
|
|
[void] Remove([System.String]$key) {
|
|
if ($this.Settings.ContainsKey($key)) {
|
|
$this.Settings.Remove($key)
|
|
$this.Save()
|
|
}
|
|
}
|
|
|
|
[System.Collections.Hashtable] GetAll() {
|
|
return $this.Settings
|
|
}
|
|
|
|
# NEU: Holt die Menüstruktur
|
|
[System.Array] GetMenuStructure() {
|
|
if ($this.Settings.ContainsKey("MenuStructure")) {
|
|
# Konvertiere PSCustomObject zurück zu Hashtable
|
|
return $this.ConvertToHashtable($this.Settings["MenuStructure"])
|
|
}
|
|
return $this.GetDefaultMenuStructure()
|
|
}
|
|
|
|
# NEU: Setzt eine neue Menüstruktur
|
|
[void] SetMenuStructure([System.Array]$menuStructure) {
|
|
$this.Settings["MenuStructure"] = $menuStructure
|
|
$this.Save()
|
|
}
|
|
|
|
# NEU: Setzt Menü auf Standard zurück
|
|
[void] ResetMenuStructure() {
|
|
$this.Settings["MenuStructure"] = $this.GetDefaultMenuStructure()
|
|
$this.Save()
|
|
}
|
|
|
|
# Hilfsfunktion: Konvertiert PSCustomObject zu Hashtable (für JSON-Deserialisierung)
|
|
hidden [object] ConvertToHashtable([object]$obj) {
|
|
if ($obj -is [System.Management.Automation.PSCustomObject]) {
|
|
$hash = @{}
|
|
foreach ($property in $obj.PSObject.Properties) {
|
|
$hash[$property.Name] = $this.ConvertToHashtable($property.Value)
|
|
}
|
|
return $hash
|
|
}
|
|
elseif ($obj -is [System.Array] -or $obj -is [System.Collections.ArrayList]) {
|
|
$array = @()
|
|
foreach ($item in $obj) {
|
|
$array += $this.ConvertToHashtable($item)
|
|
}
|
|
return $array
|
|
}
|
|
else {
|
|
return $obj
|
|
}
|
|
}
|
|
}
|
|
|
|
class StateManager {
|
|
[System.Collections.Hashtable] $State = @{}
|
|
[System.Collections.ArrayList] $Buttons = @()
|
|
[System.Collections.Hashtable] $MenuItems = @{}
|
|
[System.Collections.ArrayList] $Forms = @()
|
|
|
|
# Registriert einen Button mit seiner Bedingung
|
|
[void] RegisterButton([ButtonBuilder]$buttonBuilder) {
|
|
$this.Buttons.Add($buttonBuilder) | Out-Null
|
|
}
|
|
|
|
# NEU: Registriert ein Menü-Item
|
|
[void] RegisterMenuItem([string]$menuName, [MenuBuilder]$menuBuilder) {
|
|
$this.MenuItems[$menuName] = $menuBuilder
|
|
}
|
|
|
|
# Registriert einen Button mit seiner Bedingung
|
|
[void] RegisterForm([System.Object]$form) {
|
|
$this.Forms.Add($form) | Out-Null
|
|
}
|
|
|
|
# Setzt einen State-Wert und aktualisiert alle Buttons und Menüs
|
|
[void] SetState([string]$key, [object]$value) {
|
|
$this.State[$key] = $value
|
|
$this.UpdateAll()
|
|
}
|
|
|
|
[void] SetStates([hashtable]$states) {
|
|
foreach ($key in $states.Keys) {
|
|
$this.State[$key] = $states[$key]
|
|
}
|
|
$this.UpdateAll()
|
|
}
|
|
|
|
# Holt einen State-Wert
|
|
[object] GetState([string]$key) {
|
|
return $this.State[$key]
|
|
}
|
|
|
|
[hashtable] GetAllStates() {
|
|
return $this.State.Clone()
|
|
}
|
|
|
|
# Aktualisiert alle registrierten Buttons
|
|
[void] UpdateAllButtons() {
|
|
foreach ($button in $this.Buttons) {
|
|
$button.UpdateEnabledState()
|
|
}
|
|
}
|
|
|
|
# NEU: Aktualisiert alle registrierten Menü-Items
|
|
[void] UpdateAllMenuItems() {
|
|
foreach ($menuName in $this.MenuItems.Keys) {
|
|
$this.MenuItems[$menuName].UpdateMenuItemState($menuName)
|
|
}
|
|
}
|
|
|
|
# Aktualisiert alle registrierten Buttons
|
|
[void] UpdateAllForms() {
|
|
foreach ($form in $this.Forms) {
|
|
$form.UpdateVisibleState()
|
|
}
|
|
}
|
|
|
|
# NEU: Aktualisiert alles (Buttons + Menüs)
|
|
[void] UpdateAll() {
|
|
$this.UpdateAllButtons()
|
|
$this.UpdateAllMenuItems()
|
|
$this.UpdateAllForms()
|
|
}
|
|
}
|
|
|
|
class LogManager {
|
|
[System.String]$LogPath
|
|
[bool]$EnableConsole = $false
|
|
|
|
LogManager([System.String]$appName) {
|
|
$appDataPath = [Environment]::GetFolderPath('ApplicationData')
|
|
$logFolder = Join-Path $appDataPath "$appName\Logs"
|
|
|
|
if (-not (Test-Path $logFolder)) {
|
|
New-Item -Path $logFolder -ItemType Directory -Force | Out-Null
|
|
}
|
|
|
|
$timestamp = Get-Date -Format "yyyyMMdd"
|
|
$this.LogPath = Join-Path $logFolder "log_$timestamp.txt"
|
|
}
|
|
|
|
[void] Info([string]$message) {
|
|
$this.Write("INFO", $message)
|
|
}
|
|
|
|
[void] Warning([string]$message) {
|
|
$this.Write("WARN", $message)
|
|
}
|
|
|
|
[void] Error([string]$message) {
|
|
$this.Write("ERROR", $message)
|
|
}
|
|
|
|
hidden [void] Write([string]$level, [string]$message) {
|
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|
$logLine = "[$timestamp] [$level] $message"
|
|
|
|
Add-Content -Path $this.LogPath -Value $logLine
|
|
|
|
if ($this.EnableConsole) {
|
|
Write-Host $logLine
|
|
}
|
|
}
|
|
}
|
|
|
|
class AccessibilityManager {
|
|
[SettingsManager] $SettingsManager
|
|
[LogManager] $LogManager
|
|
[System.Collections.ArrayList] $FontControls = @()
|
|
[System.Collections.ArrayList] $Forms = @()
|
|
[System.Collections.ArrayList] $LayoutContainers = @()
|
|
[hashtable] $AccessibilitySettings = @{}
|
|
|
|
|
|
AccessibilityManager([SettingsManager]$SettingsManager, [LogManager]$LogManager) {
|
|
$this.SettingsManager = $SettingsManager
|
|
$this.LogManager = $LogManager
|
|
$this.InitializeDefaults()
|
|
}
|
|
|
|
# Initialisiert Standard-Accessibility-Einstellungen
|
|
[void] InitializeDefaults() {
|
|
$this.AccessibilitySettings = @{
|
|
FontSize = @{ Min = 6; Max = 32; Default = 9; Step = 1 }
|
|
FontSizeStep = @{ Min = 1; Max = 5; Default = 1 }
|
|
HighContrast = @{ Default = $false }
|
|
KeyboardShortcuts = @{ Default = $true }
|
|
ScreenReaderSupport = @{ Default = $false }
|
|
}
|
|
|
|
# Stelle sicher, dass alle Settings existieren
|
|
foreach ($key in $this.AccessibilitySettings.Keys) {
|
|
if (-not $this.SettingsManager.Contains($key)) {
|
|
$this.SettingsManager.Set($key, $this.AccessibilitySettings[$key].Default)
|
|
}
|
|
}
|
|
}
|
|
|
|
# Registriert ein Form für Accessibility-Features
|
|
[void] RegisterForm([System.Windows.Forms.Form]$form) {
|
|
if (-not $this.Forms.Contains($form)) {
|
|
$this.Forms.Add($form) | Out-Null
|
|
$this.AttachMouseWheelHandler($form)
|
|
$this.AttachKeyboardShortcuts($form)
|
|
$this.LogManager.Info("Form registriert für Accessibility-Features")
|
|
}
|
|
}
|
|
|
|
# Registriert Container für automatisches Layout-Update
|
|
[void] RegisterLayoutContainer([System.Windows.Forms.Control]$container) {
|
|
if (-not $this.LayoutContainers.Contains($container)) {
|
|
$this.LayoutContainers.Add($container) | Out-Null
|
|
$this.LogManager.Info("Layout-Container registriert: $($container.GetType().Name)")
|
|
}
|
|
}
|
|
|
|
# Registriert ein Control für Font-Updates
|
|
[void] RegisterFontControl([System.Windows.Forms.Control]$control) {
|
|
if (-not $this.FontControls.Contains($control)) {
|
|
$this.FontControls.Add($control) | Out-Null
|
|
$this.ApplyFontSize($control)
|
|
}
|
|
}
|
|
|
|
# Registriert mehrere Controls
|
|
[void] RegisterFontControls([System.Windows.Forms.Control[]]$controls) {
|
|
foreach ($control in $controls) {
|
|
$this.RegisterFontControl($control)
|
|
}
|
|
}
|
|
|
|
# Registriert alle Controls eines Forms/Containers rekursiv
|
|
[void] RegisterAllControls([System.Windows.Forms.Control]$container) {
|
|
# Registriere das Container-Control selbst (wenn es Text hat)
|
|
if ($container.GetType().GetProperty("Font") -ne $null) {
|
|
$this.RegisterFontControl($container)
|
|
}
|
|
|
|
# Durchlaufe alle Child-Controls rekursiv
|
|
foreach ($control in $container.Controls) {
|
|
$this.RegisterAllControls($control)
|
|
}
|
|
|
|
$this.LogManager.Info("Alle Controls von '$($container.GetType().Name)' registriert (Total: $($this.FontControls.Count))")
|
|
}
|
|
|
|
# Optional: Registriert nur bestimmte Control-Typen
|
|
[void] RegisterControlsByType([System.Windows.Forms.Control]$container, [Type[]]$types) {
|
|
foreach ($control in $container.Controls) {
|
|
if ($types -contains $control.GetType()) {
|
|
$this.RegisterFontControl($control)
|
|
}
|
|
# Rekursiv durch Child-Controls
|
|
if ($control.Controls.Count -gt 0) {
|
|
$this.RegisterControlsByType($control, $types)
|
|
}
|
|
}
|
|
}
|
|
|
|
# Fügt MouseWheel-Handler für Strg + Mausrad hinzu
|
|
hidden [void] AttachMouseWheelHandler([System.Windows.Forms.Form]$form) {
|
|
$form.Add_MouseWheel({
|
|
param($sender, $e)
|
|
|
|
if ([System.Windows.Forms.Control]::ModifierKeys -eq [System.Windows.Forms.Keys]::Control) {
|
|
$delta = if ($e.Delta -gt 0) { 1 } else { -1 }
|
|
[BaseComponent]::AccessibilityManager.ChangeFontSize($delta)
|
|
$e.Handled = $true
|
|
}
|
|
}.GetNewClosure())
|
|
}
|
|
|
|
# Fügt Tastatur-Shortcuts hinzu
|
|
hidden [void] AttachKeyboardShortcuts([System.Windows.Forms.Form]$form) {
|
|
$form.KeyPreview = $true
|
|
$form.Add_KeyDown({
|
|
param($sender, $e)
|
|
|
|
# Strg + 0: Reset auf Standard
|
|
if ($e.Control -and $e.KeyCode -eq [System.Windows.Forms.Keys]::D0) {
|
|
[BaseComponent]::AccessibilityManager.ResetFontSize()
|
|
$e.Handled = $true
|
|
}
|
|
|
|
# Strg + Plus: Größer
|
|
if ($e.Control -and ($e.KeyCode -eq [System.Windows.Forms.Keys]::Add -or $e.KeyCode -eq [System.Windows.Forms.Keys]::Oemplus)) {
|
|
[BaseComponent]::AccessibilityManager.ChangeFontSize(1)
|
|
$e.Handled = $true
|
|
}
|
|
|
|
# Strg + Minus: Kleiner
|
|
if ($e.Control -and ($e.KeyCode -eq [System.Windows.Forms.Keys]::Subtract -or $e.KeyCode -eq [System.Windows.Forms.Keys]::OemMinus)) {
|
|
[BaseComponent]::AccessibilityManager.ChangeFontSize(-1)
|
|
$e.Handled = $true
|
|
}
|
|
|
|
# F11: High Contrast Toggle (optional)
|
|
if ($e.KeyCode -eq [System.Windows.Forms.Keys]::F11) {
|
|
[BaseComponent]::AccessibilityManager.ToggleHighContrast()
|
|
$e.Handled = $true
|
|
}
|
|
}.GetNewClosure())
|
|
}
|
|
|
|
# Ändert die Schriftgröße
|
|
[void] ChangeFontSize([int]$delta) {
|
|
$settings = $this.AccessibilitySettings["FontSize"]
|
|
$currentSize = $this.SettingsManager.Get("FontSize", $settings.Default)
|
|
$step = $this.SettingsManager.Get("FontSizeStep", 1)
|
|
$newSize = $currentSize + ($delta * $step)
|
|
|
|
# Begrenzung
|
|
if ($newSize -lt $settings.Min) { $newSize = $settings.Min }
|
|
if ($newSize -gt $settings.Max) { $newSize = $settings.Max }
|
|
|
|
if ($newSize -ne $currentSize) {
|
|
$this.SettingsManager.Set("FontSize", $newSize)
|
|
$this.UpdateAllFonts()
|
|
$this.LogManager.Info("Schriftgröße geändert: $currentSize -> $newSize")
|
|
}
|
|
}
|
|
|
|
# Setzt Schriftgröße zurück
|
|
[void] ResetFontSize() {
|
|
$defaultSize = $this.AccessibilitySettings["FontSize"].Default
|
|
$this.SettingsManager.Set("FontSize", $defaultSize)
|
|
$this.UpdateAllFonts()
|
|
$this.LogManager.Info("Schriftgröße zurückgesetzt auf: $defaultSize")
|
|
}
|
|
|
|
# Wendet Schriftgröße auf ein Control an
|
|
hidden [void] ApplyFontSize([System.Windows.Forms.Control]$control) {
|
|
$fontSize = $this.SettingsManager.Get("FontSize", 9)
|
|
try {
|
|
$control.Font = New-Object System.Drawing.Font($control.Font.FontFamily, $fontSize)
|
|
} catch {
|
|
$this.LogManager.Warning("Fehler beim Setzen der Schriftgröße für Control: $_")
|
|
}
|
|
}
|
|
|
|
# Aktualisiert alle registrierten Controls
|
|
[void] UpdateAllFonts() {
|
|
foreach ($control in $this.FontControls) {
|
|
if ($null -ne $control -and -not $control.IsDisposed) {
|
|
$this.ApplyFontSize($control)
|
|
}
|
|
}
|
|
$this.UpdateAllLayouts()
|
|
}
|
|
|
|
# Aktualisiert das Layout aller registrierten Container
|
|
hidden [void] UpdateAllLayouts() {
|
|
foreach ($container in $this.LayoutContainers) {
|
|
if ($null -ne $container -and -not $container.IsDisposed) {
|
|
# GroupBoxes: AutoSize aktivieren
|
|
if ($container -is [System.Windows.Forms.GroupBox]) {
|
|
$container.AutoSize = $true
|
|
$container.AutoSizeMode = 'GrowAndShrink'
|
|
}
|
|
|
|
# FlowLayoutPanel: PerformLayout erzwingen
|
|
if ($container -is [System.Windows.Forms.FlowLayoutPanel]) {
|
|
foreach ($child in $container.Controls) {
|
|
if ($child -is [System.Windows.Forms.GroupBox]) {
|
|
$child.AutoSize = $true
|
|
$child.AutoSizeMode = 'GrowAndShrink'
|
|
|
|
# Breite anpassen
|
|
$child.Width = $container.ClientSize.Width - 20
|
|
}
|
|
}
|
|
|
|
$container.PerformLayout()
|
|
$container.Refresh()
|
|
}
|
|
|
|
# Panel: PerformLayout
|
|
if ($container -is [System.Windows.Forms.Panel]) {
|
|
$container.PerformLayout()
|
|
}
|
|
}
|
|
}
|
|
|
|
$this.LogManager.Info("Layout-Update abgeschlossen")
|
|
}
|
|
|
|
# Schaltet High Contrast Modus um
|
|
[void] ToggleHighContrast() {
|
|
$currentState = $this.SettingsManager.Get("HighContrast", $false)
|
|
$newState = -not $currentState
|
|
$this.SettingsManager.Set("HighContrast", $newState)
|
|
$this.ApplyHighContrast($newState)
|
|
$this.LogManager.Info("High Contrast: $newState")
|
|
}
|
|
|
|
# Wendet High Contrast auf alle Forms an
|
|
hidden [void] ApplyHighContrast([bool]$enabled) {
|
|
foreach ($form in $this.Forms) {
|
|
if ($null -ne $form -and -not $form.IsDisposed) {
|
|
if ($enabled) {
|
|
# Form-Hintergrund
|
|
$form.BackColor = [System.Drawing.Color]::Black
|
|
$form.ForeColor = [System.Drawing.Color]::White
|
|
|
|
# NEU: Rekursiv alle Controls anpassen
|
|
$this.ApplyHighContrastToControls($form, $enabled)
|
|
} else {
|
|
$form.BackColor = [System.Drawing.SystemColors]::Control
|
|
$form.ForeColor = [System.Drawing.SystemColors]::ControlText
|
|
|
|
# NEU: Rekursiv alle Controls zurücksetzen
|
|
$this.ApplyHighContrastToControls($form, $enabled)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# NEU: Wendet High Contrast rekursiv auf alle Controls an
|
|
hidden [void] ApplyHighContrastToControls([System.Windows.Forms.Control]$control, [bool]$enabled) {
|
|
if ($enabled) {
|
|
# Schwarzer Hintergrund → Weiße Schrift
|
|
switch ($control.GetType().Name) {
|
|
'Panel' {
|
|
$control.BackColor = [System.Drawing.Color]::Black
|
|
$control.ForeColor = [System.Drawing.Color]::White
|
|
}
|
|
'FlowLayoutPanel' {
|
|
$control.BackColor = [System.Drawing.Color]::Black
|
|
$control.ForeColor = [System.Drawing.Color]::White
|
|
}
|
|
'GroupBox' {
|
|
$control.BackColor = [System.Drawing.Color]::Black
|
|
$control.ForeColor = [System.Drawing.Color]::White
|
|
}
|
|
'Label' {
|
|
$control.ForeColor = [System.Drawing.Color]::White
|
|
# Transparent oder schwarz
|
|
if ($control.BackColor -ne [System.Drawing.Color]::Transparent) {
|
|
$control.BackColor = [System.Drawing.Color]::Black
|
|
}
|
|
}
|
|
'Button' {
|
|
$control.BackColor = [System.Drawing.Color]::FromArgb(40, 40, 40)
|
|
$control.ForeColor = [System.Drawing.Color]::White
|
|
$control.FlatStyle = 'Flat'
|
|
}
|
|
'TextBox' {
|
|
$control.BackColor = [System.Drawing.Color]::FromArgb(30, 30, 30)
|
|
$control.ForeColor = [System.Drawing.Color]::White
|
|
}
|
|
'TreeView' {
|
|
$control.BackColor = [System.Drawing.Color]::FromArgb(20, 20, 20)
|
|
$control.ForeColor = [System.Drawing.Color]::White
|
|
}
|
|
'ListBox' {
|
|
$control.BackColor = [System.Drawing.Color]::FromArgb(20, 20, 20)
|
|
$control.ForeColor = [System.Drawing.Color]::White
|
|
}
|
|
'DataGridView' {
|
|
$control.BackgroundColor = [System.Drawing.Color]::Black
|
|
$control.ForeColor = [System.Drawing.Color]::White
|
|
$control.DefaultCellStyle.BackColor = [System.Drawing.Color]::FromArgb(30, 30, 30)
|
|
$control.DefaultCellStyle.ForeColor = [System.Drawing.Color]::White
|
|
$control.ColumnHeadersDefaultCellStyle.BackColor = [System.Drawing.Color]::FromArgb(50, 50, 50)
|
|
$control.ColumnHeadersDefaultCellStyle.ForeColor = [System.Drawing.Color]::White
|
|
}
|
|
'TabControl' {
|
|
$control.BackColor = [System.Drawing.Color]::Black
|
|
$control.ForeColor = [System.Drawing.Color]::White
|
|
}
|
|
'TabPage' {
|
|
$control.BackColor = [System.Drawing.Color]::Black
|
|
$control.ForeColor = [System.Drawing.Color]::White
|
|
}
|
|
}
|
|
} else {
|
|
# Zurück zu Standard-Farben
|
|
switch ($control.GetType().Name) {
|
|
'Panel' {
|
|
$control.BackColor = [System.Drawing.SystemColors]::Control
|
|
$control.ForeColor = [System.Drawing.SystemColors]::ControlText
|
|
}
|
|
'FlowLayoutPanel' {
|
|
$control.BackColor = [System.Drawing.SystemColors]::Control
|
|
$control.ForeColor = [System.Drawing.SystemColors]::ControlText
|
|
}
|
|
'GroupBox' {
|
|
$control.BackColor = [System.Drawing.SystemColors]::Control
|
|
$control.ForeColor = [System.Drawing.SystemColors]::ControlText
|
|
}
|
|
'Label' {
|
|
$control.ForeColor = [System.Drawing.SystemColors]::ControlText
|
|
if ($control.BackColor -ne [System.Drawing.Color]::Transparent) {
|
|
$control.BackColor = [System.Drawing.SystemColors]::Control
|
|
}
|
|
}
|
|
'Button' {
|
|
$control.BackColor = [System.Drawing.SystemColors]::Control
|
|
$control.ForeColor = [System.Drawing.SystemColors]::ControlText
|
|
$control.FlatStyle = 'Standard'
|
|
}
|
|
'TextBox' {
|
|
$control.BackColor = [System.Drawing.SystemColors]::Window
|
|
$control.ForeColor = [System.Drawing.SystemColors]::WindowText
|
|
}
|
|
'TreeView' {
|
|
$control.BackColor = [System.Drawing.SystemColors]::Window
|
|
$control.ForeColor = [System.Drawing.SystemColors]::WindowText
|
|
}
|
|
'ListBox' {
|
|
$control.BackColor = [System.Drawing.SystemColors]::Window
|
|
$control.ForeColor = [System.Drawing.SystemColors]::WindowText
|
|
}
|
|
'DataGridView' {
|
|
$control.BackgroundColor = [System.Drawing.SystemColors]::Control
|
|
$control.ForeColor = [System.Drawing.SystemColors]::ControlText
|
|
$control.DefaultCellStyle.BackColor = [System.Drawing.SystemColors]::Window
|
|
$control.DefaultCellStyle.ForeColor = [System.Drawing.SystemColors]::WindowText
|
|
$control.ColumnHeadersDefaultCellStyle.BackColor = [System.Drawing.SystemColors]::Control
|
|
$control.ColumnHeadersDefaultCellStyle.ForeColor = [System.Drawing.SystemColors]::ControlText
|
|
}
|
|
'TabControl' {
|
|
$control.BackColor = [System.Drawing.SystemColors]::Control
|
|
$control.ForeColor = [System.Drawing.SystemColors]::ControlText
|
|
}
|
|
'TabPage' {
|
|
$control.BackColor = [System.Drawing.SystemColors]::Control
|
|
$control.ForeColor = [System.Drawing.SystemColors]::ControlText
|
|
}
|
|
}
|
|
}
|
|
|
|
# Rekursiv für alle Child-Controls
|
|
foreach ($child in $control.Controls) {
|
|
$this.ApplyHighContrastToControls($child, $enabled)
|
|
}
|
|
}
|
|
|
|
# Gibt aktuelle Accessibility-Einstellungen zurück
|
|
[hashtable] GetCurrentSettings() {
|
|
return @{
|
|
FontSize = $this.SettingsManager.Get("FontSize", 9)
|
|
HighContrast = $this.SettingsManager.Get("HighContrast", $false)
|
|
KeyboardShortcuts = $this.SettingsManager.Get("KeyboardShortcuts", $true)
|
|
}
|
|
}
|
|
|
|
# Setzt eine spezifische Accessibility-Einstellung
|
|
[void] SetAccessibilitySetting([string]$key, [object]$value) {
|
|
$this.SettingsManager.Set($key, $value)
|
|
|
|
# Wende Änderung sofort an
|
|
switch ($key) {
|
|
"FontSize" { $this.UpdateAllFonts() }
|
|
"HighContrast" { $this.ApplyHighContrast($value) }
|
|
}
|
|
}
|
|
}
|
|
|
|
class FormBuilder : BaseComponent {
|
|
|
|
[System.String] $Title
|
|
[System.Windows.Forms.Form] $Form
|
|
[MenuBuilder] $Menu
|
|
[StatusStripBuilder] $StatusBar
|
|
|
|
|
|
FormBuilder($Title){
|
|
$this.Form = New-Object System.Windows.Forms.Form
|
|
$this.Form.Text = $Title
|
|
$this.Form.StartPosition = "CenterScreen"
|
|
|
|
# HIER wird RegisterForm automatisch aufgerufen:
|
|
[BaseComponent]::AccessibilityManager.RegisterForm($this.Form)
|
|
}
|
|
|
|
# Registriert ein Control für Accessibility-Features
|
|
[FormBuilder] RegisterAccessibleControl([System.Windows.Forms.Control]$control) {
|
|
[BaseComponent]::AccessibilityManager.RegisterFontControl($control)
|
|
return $this
|
|
}
|
|
|
|
# Registriert mehrere Controls
|
|
[FormBuilder] RegisterAccessibleControls([System.Windows.Forms.Control[]]$controls) {
|
|
[BaseComponent]::AccessibilityManager.RegisterFontControls($controls)
|
|
return $this
|
|
}
|
|
|
|
# NEU: Registriert automatisch ALLE Controls des Forms
|
|
[FormBuilder] RegisterAllAccessibleControls() {
|
|
[BaseComponent]::AccessibilityManager.RegisterAllControls($this.Form)
|
|
return $this
|
|
}
|
|
|
|
# NEU: Registriert nur bestimmte Control-Typen (z.B. nur TextBoxen und Labels)
|
|
[FormBuilder] RegisterAccessibleControlsByType([Type[]]$types) {
|
|
[BaseComponent]::AccessibilityManager.RegisterControlsByType($this.Form, $types)
|
|
return $this
|
|
}
|
|
|
|
[FormBuilder] AddMenu([MenuBuilder]$menuBuilder) {
|
|
$this.Menu = $menuBuilder
|
|
$this.Form.Controls.Add($menuBuilder.GetMenuStrip())
|
|
return $this
|
|
}
|
|
|
|
# Fügt eine StatusBar hinzu
|
|
[FormBuilder] AddStatusBar([StatusStripBuilder]$statusBar) {
|
|
$this.StatusBar = $statusBar
|
|
$this.Form.Controls.Add($statusBar.GetStatusStrip())
|
|
return $this
|
|
}
|
|
|
|
# Fügt ein SplitPanel hinzu
|
|
[FormBuilder] AddSplitPanel([SplitPanelBuilder]$splitPanel) {
|
|
$this.Form.Controls.Add($splitPanel.GetSplitContainer())
|
|
return $this
|
|
}
|
|
|
|
# Fügt ein beliebiges Control hinzu
|
|
[FormBuilder] AddControl([System.Windows.Forms.Control]$control) {
|
|
$this.Form.Controls.Add($control)
|
|
return $this
|
|
}
|
|
|
|
# Fügt mehrere Controls hinzu
|
|
[FormBuilder] AddControls([System.Windows.Forms.Control[]]$controls) {
|
|
foreach ($control in $controls) {
|
|
$this.Form.Controls.Add($control)
|
|
}
|
|
return $this
|
|
}
|
|
|
|
[void] SetTitle($Title) {
|
|
$this.Form.Text = $Title
|
|
}
|
|
|
|
# Setzt die Größe des Forms
|
|
[FormBuilder] SetSize([int]$width, [int]$height) {
|
|
$this.Form.Size = New-Object System.Drawing.Size($width, $height)
|
|
return $this
|
|
}
|
|
|
|
# Setzt nur die Breite
|
|
[FormBuilder] SetWidth([int]$width) {
|
|
$this.Form.Width = $width
|
|
return $this
|
|
}
|
|
|
|
# Setzt nur die Höhe
|
|
[FormBuilder] SetHeight([int]$height) {
|
|
$this.Form.Height = $height
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Mindestgröße
|
|
[FormBuilder] SetMinimumSize([int]$width, [int]$height) {
|
|
$this.Form.MinimumSize = New-Object System.Drawing.Size($width, $height)
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Maximalgröße
|
|
[FormBuilder] SetMaximumSize([int]$width, [int]$height) {
|
|
$this.Form.MaximumSize = New-Object System.Drawing.Size($width, $height)
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Startposition
|
|
[FormBuilder] SetStartPosition([System.String]$position) {
|
|
$this.Form.StartPosition = [System.Windows.Forms.FormStartPosition]::$position
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Location (Position auf dem Bildschirm)
|
|
[FormBuilder] SetLocation([int]$x, [int]$y) {
|
|
$this.Form.Location = New-Object System.Drawing.Point($x, $y)
|
|
return $this
|
|
}
|
|
|
|
# Setzt den WindowState
|
|
[FormBuilder] SetWindowState([System.String]$state) {
|
|
$this.Form.WindowState = [System.Windows.Forms.FormWindowState]::$state
|
|
return $this
|
|
}
|
|
|
|
[FormBuilder] AddLoadHandler([scriptblock]$handler) {
|
|
$this.Form.Add_Load($handler)
|
|
return $this
|
|
}
|
|
|
|
# Shown Event (wenn Form zum ersten Mal angezeigt wird)
|
|
[FormBuilder] AddShownHandler([scriptblock]$handler) {
|
|
$this.Form.Add_Shown($handler)
|
|
return $this
|
|
}
|
|
|
|
# FormClosing Event (bevor Form geschlossen wird - kann abgebrochen werden)
|
|
[FormBuilder] AddFormClosingHandler([scriptblock]$handler) {
|
|
$this.Form.Add_FormClosing($handler)
|
|
return $this
|
|
}
|
|
|
|
# FormClosed Event (nachdem Form geschlossen wurde)
|
|
[FormBuilder] AddFormClosedHandler([scriptblock]$handler) {
|
|
$this.Form.Add_FormClosed($handler)
|
|
return $this
|
|
}
|
|
|
|
# Resize Event
|
|
[FormBuilder] AddResizeHandler([scriptblock]$handler) {
|
|
$this.Form.Add_Resize($handler)
|
|
return $this
|
|
}
|
|
|
|
# Move Event
|
|
[FormBuilder] AddMoveHandler([scriptblock]$handler) {
|
|
$this.Form.Add_Move($handler)
|
|
return $this
|
|
}
|
|
|
|
# KeyDown Event
|
|
[FormBuilder] AddKeyDownHandler([scriptblock]$handler) {
|
|
$this.Form.Add_KeyDown($handler)
|
|
return $this
|
|
}
|
|
|
|
# Activate Event (wenn Form aktiviert wird)
|
|
[FormBuilder] AddActivateHandler([scriptblock]$handler) {
|
|
$this.Form.Add_Activated($handler)
|
|
return $this
|
|
}
|
|
|
|
# Deactivate Event
|
|
[FormBuilder] AddDeactivateHandler([scriptblock]$handler) {
|
|
$this.Form.Add_Deactivate($handler)
|
|
return $this
|
|
}
|
|
|
|
# Generischer Event-Handler für alle Events
|
|
[FormBuilder] AddEventHandler([System.String]$eventName, [scriptblock]$handler) {
|
|
$this.Form."Add_$eventName"($handler)
|
|
return $this
|
|
}
|
|
|
|
[void] Show(){
|
|
[void]$this.Form.ShowDialog()
|
|
}
|
|
}
|
|
|
|
class MenuBuilder : BaseComponent{
|
|
|
|
[System.Windows.Forms.MenuStrip] $MenuStrip
|
|
[System.Collections.Hashtable] $MenuItems = @{}
|
|
[System.Collections.Hashtable] $MenuConditions = @{}
|
|
[StateManager] $StateManager = $null
|
|
|
|
MenuBuilder() {
|
|
$this.MenuStrip = New-Object System.Windows.Forms.MenuStrip
|
|
$this.MenuStrip.Dock = 'Top'
|
|
}
|
|
|
|
# NEU: Setzt den StateManager
|
|
[MenuBuilder] WithStateManager([StateManager]$stateManager) {
|
|
$this.StateManager = $stateManager
|
|
return $this
|
|
}
|
|
|
|
# Fügt ein Hauptmenü-Element hinzu - JETZT MIT RETURN
|
|
[MenuBuilder] AddMainMenu([System.String]$name, [System.String]$text) {
|
|
$menuItem = New-Object System.Windows.Forms.ToolStripMenuItem $text
|
|
$this.MenuStrip.Items.Add($menuItem) | Out-Null
|
|
$this.MenuItems[$name] = $menuItem
|
|
return $this | Out-Null
|
|
}
|
|
|
|
# Fügt ein Untermenü-Element hinzu - JETZT MIT RETURN
|
|
[MenuBuilder] AddSubMenu([System.String]$parentName, [System.String]$name, [System.String]$text) {
|
|
if ($this.MenuItems.ContainsKey($parentName)) {
|
|
$menuItem = New-Object System.Windows.Forms.ToolStripMenuItem $text
|
|
$this.MenuItems[$parentName].DropDownItems.Add($menuItem) | Out-Null
|
|
$this.MenuItems[$name] = $menuItem
|
|
return $this | Out-Null
|
|
}
|
|
throw "Parent menu '$parentName' nicht gefunden"
|
|
}
|
|
|
|
# NEU: Fügt mehrere Untermenüs auf einmal hinzu
|
|
[MenuBuilder] AddSubMenus([System.String]$parentName, [hashtable[]]$items) {
|
|
foreach ($item in $items) {
|
|
if ($item.Type -eq "Separator") {
|
|
$this.AddSeparator($parentName)
|
|
}
|
|
else {
|
|
$this.AddSubMenu($parentName, $item.Name, $item.Text)
|
|
if ($item.Handler) {
|
|
$this.SetClickHandler($item.Name, $item.Handler)
|
|
}
|
|
}
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# NEU: Erstellt komplettes Menü aus einer Struktur
|
|
[MenuBuilder] BuildFromStructure([hashtable[]]$structure) {
|
|
foreach ($mainMenu in $structure) {
|
|
$this.AddMainMenu($mainMenu.Name, $mainMenu.Text)
|
|
|
|
if ($mainMenu.Items) {
|
|
$this.AddSubMenus($mainMenu.Name, $mainMenu.Items)
|
|
}
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Fügt einen Separator hinzu - JETZT MIT RETURN
|
|
[MenuBuilder] AddSeparator([System.String]$parentName) {
|
|
if ($this.MenuItems.ContainsKey($parentName)) {
|
|
$this.MenuItems[$parentName].DropDownItems.Add('-') | Out-Null
|
|
}
|
|
return $this | Out-Null
|
|
}
|
|
|
|
# Setzt einen Event-Handler für ein Menü-Element - JETZT MIT RETURN
|
|
[MenuBuilder] SetClickHandler([System.String]$menuName, [scriptblock]$handler) {
|
|
if ($this.MenuItems.ContainsKey($menuName)) {
|
|
$this.MenuItems[$menuName].Add_Click($handler)
|
|
}
|
|
return $this | Out-Null
|
|
}
|
|
|
|
# NEU: Setzt einen Click-Handler mit Enable-Bedingung
|
|
[MenuBuilder] SetClickHandler([System.String]$menuName, [scriptblock]$handler, [scriptblock]$enableCondition) {
|
|
if ($this.MenuItems.ContainsKey($menuName)) {
|
|
$this.MenuItems[$menuName].Add_Click($handler)
|
|
$this.MenuConditions[$menuName] = $enableCondition
|
|
|
|
# Initial den Status setzen
|
|
$this.UpdateMenuItemState($menuName)
|
|
|
|
# Bei StateManager registrieren
|
|
if ($null -ne $this.StateManager) {
|
|
$this.StateManager.RegisterMenuItem($menuName, $this)
|
|
}
|
|
}
|
|
return $this | Out-Null
|
|
}
|
|
|
|
# NEU: Setzt mehrere Click-Handler auf einmal
|
|
[MenuBuilder] SetClickHandlers([System.Collections.Hashtable]$handlers) {
|
|
foreach ($key in $handlers.Keys) {
|
|
$this.SetClickHandler($key, $handlers[$key])
|
|
}
|
|
return $this | Out-Null
|
|
}
|
|
|
|
# NEU: Setzt mehrere Click-Handler mit Bedingungen
|
|
[MenuBuilder] SetClickHandlersWithConditions([System.Collections.Hashtable]$handlers) {
|
|
foreach ($key in $handlers.Keys) {
|
|
$config = $handlers[$key]
|
|
if ($config.Condition) {
|
|
$this.SetClickHandler($key, $config.Handler, $config.Condition)
|
|
} else {
|
|
$this.SetClickHandler($key, $config.Handler)
|
|
}
|
|
}
|
|
return $this | Out-Null
|
|
}
|
|
|
|
# NEU: Aktualisiert den Enabled-Status eines Menü-Items
|
|
[void] UpdateMenuItemState([System.String]$menuName) {
|
|
if ($this.MenuItems.ContainsKey($menuName) -and $this.MenuConditions.ContainsKey($menuName)) {
|
|
try {
|
|
$result = & $this.MenuConditions[$menuName]
|
|
$this.MenuItems[$menuName].Enabled = [bool]$result
|
|
} catch {
|
|
Write-Warning "Fehler beim Evaluieren der Menu-Bedingung für '$menuName': $_"
|
|
$this.MenuItems[$menuName].Enabled = $false
|
|
}
|
|
}
|
|
}
|
|
|
|
# NEU: Aktualisiert alle Menü-Items mit Bedingungen
|
|
[void] UpdateAllMenuItems() {
|
|
foreach ($menuName in $this.MenuConditions.Keys) {
|
|
$this.UpdateMenuItemState($menuName)
|
|
}
|
|
}
|
|
|
|
# Gibt das MenuStrip-Objekt zurück
|
|
[System.Windows.Forms.MenuStrip] GetMenuStrip() {
|
|
return $this.MenuStrip
|
|
}
|
|
|
|
# Aktiviert/Deaktiviert ein Menü-Element - JETZT MIT RETURN
|
|
[MenuBuilder] SetEnabled([System.String]$menuName, [bool]$enabled) {
|
|
if ($this.MenuItems.ContainsKey($menuName)) {
|
|
$this.MenuItems[$menuName].Enabled = $enabled
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# NEU: Holt ein Menü-Item
|
|
[System.Windows.Forms.ToolStripMenuItem] GetMenuItem([System.String]$menuName) {
|
|
if ($this.MenuItems.ContainsKey($menuName)) {
|
|
return $this.MenuItems[$menuName]
|
|
}
|
|
return $null
|
|
}
|
|
}
|
|
|
|
class StatusStripBuilder : BaseComponent{
|
|
[System.Windows.Forms.StatusStrip] $StatusStrip
|
|
[System.Collections.Hashtable] $Labels = @{}
|
|
|
|
StatusStripBuilder() {
|
|
$this.StatusStrip = New-Object System.Windows.Forms.StatusStrip
|
|
}
|
|
|
|
# Fügt ein Label zur StatusBar hinzu
|
|
[System.Windows.Forms.ToolStripStatusLabel] AddLabel([System.String]$name, [System.String]$text) {
|
|
$label = New-Object System.Windows.Forms.ToolStripStatusLabel
|
|
$label.Text = $text
|
|
$this.StatusStrip.Items.Add($label) | Out-Null
|
|
$this.Labels[$name] = $label
|
|
return $label
|
|
}
|
|
|
|
# Fügt ein Label mit Spring-Eigenschaft hinzu (füllt verfügbaren Platz)
|
|
[System.Windows.Forms.ToolStripStatusLabel] AddSpringLabel([System.String]$name, [System.String]$text) {
|
|
$label = New-Object System.Windows.Forms.ToolStripStatusLabel
|
|
$label.Text = $text
|
|
$label.Spring = $true
|
|
$label.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft
|
|
$this.StatusStrip.Items.Add($label) | Out-Null
|
|
$this.Labels[$name] = $label
|
|
return $label
|
|
}
|
|
|
|
# Setzt den Text eines Labels
|
|
[void] SetText([System.String]$labelName, [System.String]$text) {
|
|
if ($this.Labels.ContainsKey($labelName)) {
|
|
$this.Labels[$labelName].Text = $text
|
|
}
|
|
}
|
|
|
|
# Fügt einen Separator hinzu
|
|
[void] AddSeparator() {
|
|
$separator = New-Object System.Windows.Forms.ToolStripSeparator
|
|
$this.StatusStrip.Items.Add($separator) | Out-Null
|
|
}
|
|
|
|
# Fügt eine ProgressBar hinzu
|
|
[System.Windows.Forms.ToolStripProgressBar] AddProgressBar([System.String]$name) {
|
|
$progressBar = New-Object System.Windows.Forms.ToolStripProgressBar
|
|
$progressBar.Size = New-Object System.Drawing.Size(100, 16)
|
|
$this.StatusStrip.Items.Add($progressBar) | Out-Null
|
|
$this.Labels[$name] = $progressBar
|
|
return $progressBar
|
|
}
|
|
|
|
# Setzt den Fortschritt einer ProgressBar
|
|
[void] SetProgress([System.String]$progressBarName, [int]$value) {
|
|
if ($this.Labels.ContainsKey($progressBarName)) {
|
|
$this.Labels[$progressBarName].Value = $value
|
|
}
|
|
}
|
|
|
|
# Gibt das StatusStrip-Objekt zurück
|
|
[System.Windows.Forms.StatusStrip] GetStatusStrip() {
|
|
return $this.StatusStrip
|
|
}
|
|
|
|
# Zeigt/Versteckt ein Element
|
|
[void] SetVisible([System.String]$itemName, [bool]$visible) {
|
|
if ($this.Labels.ContainsKey($itemName)) {
|
|
$this.Labels[$itemName].Visible = $visible
|
|
}
|
|
}
|
|
|
|
# Setzt die Hintergrundfarbe eines Labels
|
|
[void] SetBackColor([System.String]$labelName, [System.Drawing.Color]$color) {
|
|
if ($this.Labels.ContainsKey($labelName)) {
|
|
$this.Labels[$labelName].BackColor = $color
|
|
}
|
|
}
|
|
|
|
# Setzt die Textfarbe eines Labels
|
|
[void] SetForeColor([System.String]$labelName, [System.Drawing.Color]$color) {
|
|
if ($this.Labels.ContainsKey($labelName)) {
|
|
$this.Labels[$labelName].ForeColor = $color
|
|
}
|
|
}
|
|
}
|
|
|
|
class SplitPanelBuilder : BaseComponent{
|
|
[System.Windows.Forms.SplitContainer] $SplitContainer
|
|
|
|
[Int] $DesiredPanel1MinSize = 100
|
|
[Int] $DesiredPanel2MinSize = 250
|
|
[Int] $DesiredSplitterDistance = 200
|
|
[Double] $SplitterDistanceRatio = 0.0
|
|
|
|
SplitPanelBuilder([System.String]$orientation) {
|
|
$this.SplitContainer = New-Object System.Windows.Forms.SplitContainer
|
|
$this.SplitContainer.Dock = 'Fill'
|
|
|
|
if ($orientation -eq 'Horizontal') {
|
|
$this.SplitContainer.Orientation = 'Horizontal'
|
|
} else {
|
|
$this.SplitContainer.Orientation = 'Vertical'
|
|
}
|
|
}
|
|
|
|
# Konstruktor mit MinSize-Optionen - Verzögerte Initialisierung
|
|
SplitPanelBuilder([System.String]$orientation, [int]$splitterDistance, [int]$panel1MinSize, [int]$panel2MinSize) {
|
|
$this.SplitContainer = New-Object System.Windows.Forms.SplitContainer
|
|
$this.SplitContainer.Dock = 'Fill'
|
|
$this.SplitContainer.Orientation = $orientation
|
|
|
|
# Speichere die gewünschten Werte für spätere Initialisierung
|
|
$this.DesiredPanel1MinSize = $panel1MinSize
|
|
$this.DesiredPanel2MinSize = $panel2MinSize
|
|
$this.DesiredSplitterDistance = $splitterDistance
|
|
|
|
# Setze nur die absolut notwendigen Anfangswerte
|
|
$this.SplitContainer.Panel1MinSize = [Math]::Min($panel1MinSize, 25)
|
|
$this.SplitContainer.Panel2MinSize = 25
|
|
}
|
|
|
|
# Konstruktor mit Verhältnis (Ratio) für SplitterDistance
|
|
SplitPanelBuilder([System.String]$orientation, [double]$splitterRatio, [int]$panel1MinSize, [int]$panel2MinSize) {
|
|
$this.SplitContainer = New-Object System.Windows.Forms.SplitContainer
|
|
$this.SplitContainer.Dock = 'Fill'
|
|
$this.SplitContainer.Orientation = $orientation
|
|
|
|
# Speichere die gewünschten Werte
|
|
$this.DesiredPanel1MinSize = $panel1MinSize
|
|
$this.DesiredPanel2MinSize = $panel2MinSize
|
|
$this.SplitterDistanceRatio = $splitterRatio
|
|
|
|
# Setze nur die absolut notwendigen Anfangswerte
|
|
$this.SplitContainer.Panel1MinSize = [Math]::Min($panel1MinSize, 25)
|
|
$this.SplitContainer.Panel2MinSize = 25
|
|
}
|
|
|
|
# Initialisiert den SplitContainer mit den finalen Werten (nach Form.Shown)
|
|
[void] InitializeAfterShown([System.Windows.Forms.Form]$form) {
|
|
# Bestimme verfügbare Breite/Höhe aus dem SplitContainer selbst
|
|
$availableSize = if ($this.SplitContainer.Orientation -eq 'Vertical') {
|
|
$this.SplitContainer.Width
|
|
} else {
|
|
$this.SplitContainer.Height
|
|
}
|
|
|
|
# Sicherheitscheck: Mindestgröße
|
|
if ($availableSize -lt 100) {
|
|
Write-Warning "SplitContainer zu klein: $availableSize px. Verwende ClientSize."
|
|
$availableSize = if ($this.SplitContainer.Orientation -eq 'Vertical') {
|
|
$form.ClientSize.Width
|
|
} else {
|
|
$form.ClientSize.Height
|
|
}
|
|
}
|
|
|
|
# Panel2MinSize anpassen falls nötig
|
|
$proposedPanel2 = $this.DesiredPanel2MinSize
|
|
$maxAllowed = $availableSize - $this.DesiredPanel1MinSize - $this.SplitContainer.SplitterWidth
|
|
|
|
if ($maxAllowed -lt 25) {
|
|
# Nicht genug Platz - verwende Minimalkonfiguration
|
|
$this.SplitContainer.Panel1MinSize = 25
|
|
$this.SplitContainer.Panel2MinSize = 25
|
|
$this.SplitContainer.SplitterDistance = 25
|
|
Write-Warning "Nicht genug Platz für gewünschte MinSizes. Verwende Minimalwerte."
|
|
return
|
|
}
|
|
|
|
if ($proposedPanel2 -gt $maxAllowed) {
|
|
$proposedPanel2 = [Math]::Max(25, [int]($maxAllowed / 2))
|
|
}
|
|
|
|
# Panel1MinSize setzen
|
|
$this.SplitContainer.Panel1MinSize = $this.DesiredPanel1MinSize
|
|
|
|
# Panel2MinSize setzen
|
|
$this.SplitContainer.Panel2MinSize = $proposedPanel2
|
|
|
|
# SplitterDistance berechnen und setzen
|
|
if ($this.SplitterDistanceRatio -gt 0) {
|
|
# Wenn Ratio angegeben wurde
|
|
$desired = [int]($availableSize * $this.SplitterDistanceRatio)
|
|
} else {
|
|
# Wenn fester Wert angegeben wurde
|
|
$desired = $this.DesiredSplitterDistance
|
|
}
|
|
|
|
# Validierung mit strengeren Grenzen
|
|
$minAllowed = $this.SplitContainer.Panel1MinSize
|
|
$maxAllowed = $availableSize - $this.SplitContainer.Panel2MinSize - $this.SplitContainer.SplitterWidth
|
|
|
|
if ($desired -lt $minAllowed) {
|
|
$desired = $minAllowed
|
|
}
|
|
if ($desired -gt $maxAllowed) {
|
|
$desired = $maxAllowed
|
|
}
|
|
|
|
# Finale Sicherheitsprüfung
|
|
if ($desired -lt 1) {
|
|
$desired = $minAllowed
|
|
}
|
|
|
|
$this.SplitContainer.SplitterDistance = $desired
|
|
}
|
|
|
|
# Setzt Padding für Panel mit Berücksichtigung der Menühöhe
|
|
[void] SetPanelPaddingWithMenu([int]$panelNumber, [System.Windows.Forms.MenuStrip]$menu, [int]$left, [int]$right, [int]$bottom) {
|
|
try {
|
|
$menuHeight = $menu.Height
|
|
$topPadding = $menuHeight + 6
|
|
} catch {
|
|
$topPadding = 36 # Fallback
|
|
}
|
|
|
|
$padding = New-Object System.Windows.Forms.Padding($left, $topPadding, $right, $bottom)
|
|
|
|
if ($panelNumber -eq 1) {
|
|
$this.SplitContainer.Panel1.Padding = $padding
|
|
} else {
|
|
$this.SplitContainer.Panel2.Padding = $padding
|
|
}
|
|
}
|
|
|
|
[System.Windows.Forms.SplitterPanel] GetPanel1() {
|
|
return $this.SplitContainer.Panel1
|
|
}
|
|
|
|
# KORREKTUR: Gibt $this zurück für Fluent API
|
|
[SplitPanelBuilder] AddToPanel1([System.Windows.Forms.Control]$control) {
|
|
$this.SplitContainer.Panel1.Controls.Add($control)
|
|
return $this
|
|
}
|
|
|
|
# KORREKTUR: Gibt $this zurück für Fluent API
|
|
[SplitPanelBuilder] ClearPanel1() {
|
|
$this.SplitContainer.Panel1.Controls.Clear()
|
|
return $this
|
|
}
|
|
|
|
[System.Windows.Forms.SplitterPanel] GetPanel2() {
|
|
return $this.SplitContainer.Panel2
|
|
}
|
|
|
|
# KORREKTUR: Gibt $this zurück für Fluent API
|
|
[SplitPanelBuilder] AddToPanel2([System.Windows.Forms.Control]$control) {
|
|
$this.SplitContainer.Panel2.Controls.Add($control)
|
|
return $this
|
|
}
|
|
|
|
# KORREKTUR: Gibt $this zurück für Fluent API
|
|
[SplitPanelBuilder] ClearPanel2() {
|
|
$this.SplitContainer.Panel2.Controls.Clear()
|
|
return $this
|
|
}
|
|
|
|
# Berechnet die optimale SplitterDistance basierend auf den Controls in Panel1
|
|
[void] AutoSizeSplitterToPanel1Content() {
|
|
$maxSize = 0
|
|
|
|
foreach ($control in $this.SplitContainer.Panel1.Controls) {
|
|
if ($this.SplitContainer.Orientation -eq 'Vertical') {
|
|
# Bei vertikaler Orientierung: Breite berechnen
|
|
$requiredSize = $control.Right + $control.Margin.Right
|
|
} else {
|
|
# Bei horizontaler Orientierung: Höhe berechnen
|
|
$requiredSize = $control.Bottom + $control.Margin.Bottom
|
|
}
|
|
|
|
if ($requiredSize -gt $maxSize) {
|
|
$maxSize = $requiredSize
|
|
}
|
|
}
|
|
|
|
# Padding von Panel1 berücksichtigen
|
|
if ($this.SplitContainer.Orientation -eq 'Vertical') {
|
|
$maxSize += $this.SplitContainer.Panel1.Padding.Right
|
|
} else {
|
|
$maxSize += $this.SplitContainer.Panel1.Padding.Bottom
|
|
}
|
|
|
|
# Sicherheitsabstand hinzufügen
|
|
$maxSize += 10
|
|
|
|
# Mit Constraints validieren und setzen
|
|
$this.SetSplitterDistance($maxSize)
|
|
}
|
|
|
|
# Setzt die Splitter-Position mit Validierung
|
|
[SplitPanelBuilder] SetSplitterDistance([int]$distance) {
|
|
$minDistance = $this.SplitContainer.Panel1MinSize
|
|
$maxDistance = $this.SplitContainer.Width - $this.SplitContainer.Panel2MinSize
|
|
|
|
if ($distance -lt $minDistance) {
|
|
$this.SplitContainer.SplitterDistance = $minDistance
|
|
}
|
|
elseif ($distance -gt $maxDistance) {
|
|
$this.SplitContainer.SplitterDistance = $maxDistance
|
|
}
|
|
else {
|
|
$this.SplitContainer.SplitterDistance = $distance
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Fixiert den Splitter
|
|
[SplitPanelBuilder] SetFixedPanel([System.String]$panel) {
|
|
switch ($panel) {
|
|
'Panel1' { $this.SplitContainer.FixedPanel = 'Panel1' }
|
|
'Panel2' { $this.SplitContainer.FixedPanel = 'Panel2' }
|
|
default { $this.SplitContainer.FixedPanel = 'None' }
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Verhindert das Verschieben des Splitters
|
|
[SplitPanelBuilder] SetIsSplitterFixed([bool]$fixed) {
|
|
$this.SplitContainer.IsSplitterFixed = $fixed
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Splitter-Breite
|
|
[SplitPanelBuilder] SetSplitterWidth([int]$width) {
|
|
$this.SplitContainer.SplitterWidth = $width
|
|
return $this
|
|
}
|
|
|
|
# Gibt das SplitContainer-Objekt zurück
|
|
[System.Windows.Forms.SplitContainer] GetSplitContainer() {
|
|
return $this.SplitContainer
|
|
}
|
|
}
|
|
|
|
class FlowLayoutPanelBuilder {
|
|
[System.Windows.Forms.FlowLayoutPanel]$control
|
|
|
|
FlowLayoutPanelBuilder() {
|
|
$this.control = New-Object System.Windows.Forms.FlowLayoutPanel
|
|
# Standard-Einstellungen
|
|
$this.control.Dock = 'Fill'
|
|
$this.control.AutoScroll = $true
|
|
$this.control.FlowDirection = 'TopDown'
|
|
$this.control.WrapContents = $false
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] SetDock([System.String]$dock) {
|
|
$this.control.Dock = [System.Windows.Forms.DockStyle]::$dock
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] SetAutoScroll([bool]$autoScroll) {
|
|
$this.control.AutoScroll = $autoScroll
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] SetFlowDirection([System.String]$direction) {
|
|
$this.control.FlowDirection = [System.Windows.Forms.FlowDirection]::$direction
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] SetWrapContents([bool]$wrap) {
|
|
$this.control.WrapContents = $wrap
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] SetPadding([int]$all) {
|
|
$this.control.Padding = New-Object System.Windows.Forms.Padding($all)
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] SetPadding([int]$left, [int]$top, [int]$right, [int]$bottom) {
|
|
$this.control.Padding = New-Object System.Windows.Forms.Padding($left, $top, $right, $bottom)
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] SetBackColor([System.Drawing.Color]$color) {
|
|
$this.control.BackColor = $color
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] SetWidth([int]$width) {
|
|
$this.control.Width = $width
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] SetHeight([int]$height) {
|
|
$this.control.Height = $height
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] SetSize([int]$width, [int]$height) {
|
|
$this.control.Width = $width
|
|
$this.control.Height = $height
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] SetBorderStyle([System.String]$style) {
|
|
$this.control.BorderStyle = [System.Windows.Forms.BorderStyle]::$style
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] AddControl([System.Windows.Forms.Control]$childControl) {
|
|
$this.control.Controls.Add($childControl)
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] AddControls([System.Windows.Forms.Control[]]$controls) {
|
|
foreach ($ctrl in $controls) {
|
|
$this.control.Controls.Add($ctrl)
|
|
}
|
|
return $this
|
|
}
|
|
|
|
[FlowLayoutPanelBuilder] ClearControls() {
|
|
$this.control.Controls.Clear()
|
|
return $this
|
|
}
|
|
|
|
[System.Windows.Forms.FlowLayoutPanel] AddTo([System.Windows.Forms.Control]$parent) {
|
|
$parent.Controls.Add($this.control)
|
|
return $this.control
|
|
}
|
|
|
|
[System.Windows.Forms.FlowLayoutPanel] Build() {
|
|
return $this.control
|
|
}
|
|
}
|
|
|
|
class ButtonBuilder : BaseComponent {
|
|
[System.Windows.Forms.Button] $Button
|
|
[scriptblock] $EnableCondition = $null
|
|
[StateManager] $StateManager = $null
|
|
|
|
ButtonBuilder() {
|
|
$this.Button = New-Object System.Windows.Forms.Button
|
|
$this.Button.Font = New-Object System.Drawing.Font("Segoe UI", $this.GetSetting("FontSize"))
|
|
$this.SetSize(40, 40)
|
|
$this.Button.Margin = New-Object System.Windows.Forms.Padding(5)
|
|
}
|
|
|
|
ButtonBuilder([System.String]$text) {
|
|
$this.Button = New-Object System.Windows.Forms.Button
|
|
$this.Button.Text = $text
|
|
$this.Button.Font = New-Object System.Drawing.Font("Segoe UI", $this.GetSetting("FontSize"))
|
|
$this.SetSize(40, 40)
|
|
}
|
|
|
|
# Konstruktor mit Text und Höhe
|
|
ButtonBuilder([System.String]$text, [int]$height) {
|
|
$this.Button = New-Object System.Windows.Forms.Button
|
|
$this.Button.Text = $text
|
|
$this.Button.Height = $height
|
|
$this.Button.Font = New-Object System.Drawing.Font("Segoe UI", $this.GetSetting("FontSize"))
|
|
}
|
|
|
|
# Setzt den Text
|
|
[ButtonBuilder] SetText([System.String]$text) {
|
|
$this.Button.Text = $text
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Höhe
|
|
[ButtonBuilder] SetHeight([int]$height) {
|
|
$this.Button.Height = $height
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Breite
|
|
[ButtonBuilder] SetWidth([int]$width) {
|
|
$this.Button.Width = $width
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Größe
|
|
[ButtonBuilder] SetSize([int]$width, [int]$height) {
|
|
$this.Button.Size = New-Object System.Drawing.Size($width, $height)
|
|
return $this
|
|
}
|
|
|
|
# Setzt das Dock
|
|
[ButtonBuilder] SetDock([System.String]$dock) {
|
|
$this.Button.Dock = $dock
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Position
|
|
[ButtonBuilder] SetLocation([int]$x, [int]$y) {
|
|
$this.Button.Location = New-Object System.Drawing.Point($x, $y)
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Schriftart
|
|
[ButtonBuilder] SetFont([System.String]$fontFamily, [int]$fontSize) {
|
|
$this.Button.Font = New-Object System.Drawing.Font($fontFamily, $fontSize)
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Schriftart mit Stil
|
|
[ButtonBuilder] SetFont([System.String]$fontFamily, [int]$fontSize, [System.Drawing.FontStyle]$fontStyle) {
|
|
$this.Button.Font = New-Object System.Drawing.Font($fontFamily, $fontSize, $fontStyle)
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Hintergrundfarbe
|
|
[ButtonBuilder] SetBackColor([System.Drawing.Color]$color) {
|
|
$this.Button.BackColor = $color
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Textfarbe
|
|
[ButtonBuilder] SetForeColor([System.Drawing.Color]$color) {
|
|
$this.Button.ForeColor = $color
|
|
return $this
|
|
}
|
|
|
|
# Setzt den Enabled-Status
|
|
[ButtonBuilder] SetEnabled([bool]$enabled) {
|
|
$this.Button.Enabled = $enabled
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Sichtbarkeit
|
|
[ButtonBuilder] SetVisible([bool]$visible) {
|
|
$this.Button.Visible = $visible
|
|
return $this
|
|
}
|
|
|
|
# Setzt das FlatStyle
|
|
[ButtonBuilder] SetFlatStyle([System.String]$style) {
|
|
switch ($style) {
|
|
'Flat' { $this.Button.FlatStyle = 'Flat' }
|
|
'Popup' { $this.Button.FlatStyle = 'Popup' }
|
|
'Standard' { $this.Button.FlatStyle = 'Standard' }
|
|
'System' { $this.Button.FlatStyle = 'System' }
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt ein MDL2-Icon
|
|
[ButtonBuilder] SetMDL2Icon([System.String]$unicodeChar) {
|
|
$this.Button.Font = New-Object System.Drawing.Font("Segoe MDL2 Assets", 14)
|
|
$this.Button.Text = $unicodeChar
|
|
return $this
|
|
}
|
|
|
|
# Setzt ein Fluent-Icon
|
|
[ButtonBuilder] SetFluentIcon([System.String]$unicodeChar) {
|
|
$this.Button.Font = New-Object System.Drawing.Font("Segoe Fluent Icons", 14)
|
|
$this.Button.Text = $unicodeChar
|
|
return $this
|
|
}
|
|
|
|
# NEU: Bindet Button an StateManager (ohne Bedingung)
|
|
[ButtonBuilder] WithStateManager([StateManager]$stateManager) {
|
|
$this.StateManager = $stateManager
|
|
return $this
|
|
}
|
|
|
|
# NEU: Kombinierte Methode - Bedingung + StateManager
|
|
[ButtonBuilder] BindEnabled([scriptblock]$condition, [StateManager]$stateManager) {
|
|
$this.EnableCondition = $condition
|
|
$this.StateManager = $stateManager
|
|
$this.UpdateEnabledState()
|
|
return $this
|
|
}
|
|
|
|
# Original-Methode - nur Bedingung, kein StateManager
|
|
[ButtonBuilder] BindEnabled([scriptblock]$condition) {
|
|
$this.EnableCondition = $condition
|
|
$this.UpdateEnabledState()
|
|
return $this
|
|
}
|
|
|
|
# Aktualisiert den Enabled-Status basierend auf der Bedingung
|
|
[void] UpdateEnabledState() {
|
|
if ($null -ne $this.EnableCondition) {
|
|
try {
|
|
$result = & $this.EnableCondition
|
|
$this.Button.Enabled = [bool]$result
|
|
} catch {
|
|
Write-Warning "Fehler beim Evaluieren der Enable-Bedingung: $_"
|
|
$this.Button.Enabled = $false
|
|
}
|
|
}
|
|
}
|
|
|
|
# Setzt den Click-Handler
|
|
[ButtonBuilder] SetClickHandler([scriptblock]$handler) {
|
|
$this.Button.Add_Click($handler)
|
|
return $this
|
|
}
|
|
|
|
# Setzt einen Tooltip
|
|
[ButtonBuilder] SetToolTip([System.String]$text) {
|
|
$tooltip = New-Object System.Windows.Forms.ToolTip
|
|
$tooltip.SetToolTip($this.Button, $text)
|
|
return $this
|
|
}
|
|
|
|
# Setzt das Anchor
|
|
[ButtonBuilder] SetAnchor([System.Windows.Forms.AnchorStyles]$anchor) {
|
|
$this.Button.Anchor = $anchor
|
|
return $this
|
|
}
|
|
|
|
# Gibt das Button-Objekt zurück
|
|
[System.Windows.Forms.Button] GetButton() {
|
|
return $this.Button
|
|
}
|
|
|
|
# Fügt den Button zu einem Control hinzu
|
|
[void] AddTo([System.Windows.Forms.Control]$parent) {
|
|
$parent.Controls.Add($this.Button)
|
|
}
|
|
|
|
# NEU: Build mit Auto-Registrierung beim StateManager
|
|
[System.Windows.Forms.Button] Build() {
|
|
# Auto-Registrierung wenn StateManager gesetzt
|
|
if ($null -ne $this.StateManager -and $null -ne $this.EnableCondition) {
|
|
$this.StateManager.RegisterButton($this)
|
|
}
|
|
return $this.Button
|
|
}
|
|
}
|
|
|
|
class LabelBuilder : BaseComponent {
|
|
[System.Windows.Forms.Label] $Label
|
|
|
|
LabelBuilder([System.String]$text) {
|
|
$this.Label = New-Object System.Windows.Forms.Label
|
|
$this.Label.Text = $text
|
|
$this.Label.Font = New-Object System.Drawing.Font("Segoe UI", $this.GetSetting("FontSize"))
|
|
}
|
|
|
|
# Konstruktor mit Text und Höhe
|
|
LabelBuilder([System.String]$text, [int]$height) {
|
|
$this.Label = New-Object System.Windows.Forms.Label
|
|
$this.Label.Text = $text
|
|
$this.Label.Height = $height
|
|
$this.Label.Font = New-Object System.Drawing.Font("Segoe UI", $this.GetSetting("FontSize"))
|
|
}
|
|
|
|
# Setzt den Text
|
|
[LabelBuilder] SetText([System.String]$text) {
|
|
$this.Label.Text = $text
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Höhe
|
|
[LabelBuilder] SetHeight([int]$height) {
|
|
$this.Label.Height = $height
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Breite
|
|
[LabelBuilder] SetWidth([int]$width) {
|
|
$this.Label.Width = $width
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Größe
|
|
[LabelBuilder] SetSize([int]$width, [int]$height) {
|
|
$this.Label.Size = New-Object System.Drawing.Size($width, $height)
|
|
return $this
|
|
}
|
|
|
|
# Setzt das Dock
|
|
[LabelBuilder] SetDock([System.String]$dock) {
|
|
$this.Label.Dock = $dock
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Position
|
|
[LabelBuilder] SetLocation([int]$x, [int]$y) {
|
|
$this.Label.Location = New-Object System.Drawing.Point($x, $y)
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Schriftart
|
|
[LabelBuilder] SetFont([System.String]$fontFamily, [int]$fontSize) {
|
|
$this.Label.Font = New-Object System.Drawing.Font($fontFamily, $fontSize)
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Schriftart mit Stil
|
|
[LabelBuilder] SetFont([System.String]$fontFamily, [int]$fontSize, [System.Drawing.FontStyle]$fontStyle) {
|
|
$this.Label.Font = New-Object System.Drawing.Font($fontFamily, $fontSize, $fontStyle)
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Hintergrundfarbe
|
|
[LabelBuilder] SetBackColor([System.Drawing.Color]$color) {
|
|
$this.Label.BackColor = $color
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Textfarbe
|
|
[LabelBuilder] SetForeColor([System.Drawing.Color]$color) {
|
|
$this.Label.ForeColor = $color
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Textausrichtung
|
|
[LabelBuilder] SetTextAlign([System.Drawing.ContentAlignment]$alignment) {
|
|
$this.Label.TextAlign = $alignment
|
|
return $this
|
|
}
|
|
|
|
# Setzt AutoSize
|
|
[LabelBuilder] SetAutoSize([bool]$autoSize) {
|
|
$this.Label.AutoSize = $autoSize
|
|
return $this
|
|
}
|
|
|
|
# Setzt den Enabled-Status
|
|
[LabelBuilder] SetEnabled([bool]$enabled) {
|
|
$this.Label.Enabled = $enabled
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Sichtbarkeit
|
|
[LabelBuilder] SetVisible([bool]$visible) {
|
|
$this.Label.Visible = $visible
|
|
return $this
|
|
}
|
|
|
|
# Setzt BorderStyle
|
|
[LabelBuilder] SetBorderStyle([System.String]$style) {
|
|
switch ($style) {
|
|
'None' { $this.Label.BorderStyle = 'None' }
|
|
'FixedSingle' { $this.Label.BorderStyle = 'FixedSingle' }
|
|
'Fixed3D' { $this.Label.BorderStyle = 'Fixed3D' }
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt das Padding
|
|
[LabelBuilder] SetPadding([int]$left, [int]$top, [int]$right, [int]$bottom) {
|
|
$this.Label.Padding = New-Object System.Windows.Forms.Padding($left, $top, $right, $bottom)
|
|
return $this
|
|
}
|
|
|
|
# Setzt das Margin
|
|
[LabelBuilder] SetMargin([int]$left, [int]$top, [int]$right, [int]$bottom) {
|
|
$this.Label.Margin = New-Object System.Windows.Forms.Padding($left, $top, $right, $bottom)
|
|
return $this
|
|
}
|
|
|
|
# Setzt das Padding (alle Seiten gleich)
|
|
[LabelBuilder] SetPadding([int]$all) {
|
|
$this.Label.Padding = New-Object System.Windows.Forms.Padding($all)
|
|
return $this
|
|
}
|
|
|
|
# Setzt das Anchor
|
|
[LabelBuilder] SetAnchor([System.Windows.Forms.AnchorStyles]$anchor) {
|
|
$this.Label.Anchor = $anchor
|
|
return $this
|
|
}
|
|
|
|
# Setzt einen Tooltip
|
|
[LabelBuilder] SetToolTip([System.String]$text) {
|
|
$tooltip = New-Object System.Windows.Forms.ToolTip
|
|
$tooltip.SetToolTip($this.Label, $text)
|
|
return $this
|
|
}
|
|
|
|
# Setzt das UseMnemonic (für & Zeichen)
|
|
[LabelBuilder] SetUseMnemonic([bool]$useMnemonic) {
|
|
$this.Label.UseMnemonic = $useMnemonic
|
|
return $this
|
|
}
|
|
|
|
# Gibt das Label-Objekt zurück
|
|
[System.Windows.Forms.Label] GetLabel() {
|
|
return $this.Label
|
|
}
|
|
|
|
# Fügt das Label zu einem Control hinzu
|
|
[void] AddTo([System.Windows.Forms.Control]$parent) {
|
|
$parent.Controls.Add($this.Label)
|
|
}
|
|
|
|
[System.Windows.Forms.Label] Build() {
|
|
return $this.Label
|
|
}
|
|
}
|
|
|
|
class TreeViewBuilder : BaseComponent {
|
|
[System.Windows.Forms.TreeView]$control
|
|
|
|
TreeViewBuilder() {
|
|
$this.control = New-Object System.Windows.Forms.TreeView
|
|
# Standard-Einstellungen
|
|
$this.control.Dock = 'Fill'
|
|
$this.control.HideSelection = $false
|
|
$this.control.ShowPlusMinus = $true
|
|
$this.control.ShowRootLines = $true
|
|
$this.control.FullRowSelect = $true
|
|
}
|
|
|
|
[TreeViewBuilder] SetDock([System.String]$dock) {
|
|
$this.control.Dock = [System.Windows.Forms.DockStyle]::$dock
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] SetFont([System.String]$family, [float]$size) {
|
|
$this.control.Font = New-Object System.Drawing.Font($family, $size)
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] SetFont([System.String]$family, [float]$size, [System.Drawing.FontStyle]$style) {
|
|
$this.control.Font = New-Object System.Drawing.Font($family, $size, $style)
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] SetHideSelection([bool]$hide) {
|
|
$this.control.HideSelection = $hide
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] SetShowPlusMinus([bool]$show) {
|
|
$this.control.ShowPlusMinus = $show
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] SetShowRootLines([bool]$show) {
|
|
$this.control.ShowRootLines = $show
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] SetFullRowSelect([bool]$select) {
|
|
$this.control.FullRowSelect = $select
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] SetShowLines([bool]$show) {
|
|
$this.control.ShowLines = $show
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] SetCheckBoxes([bool]$show) {
|
|
$this.control.CheckBoxes = $show
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] SetImageList([System.Windows.Forms.ImageList]$imageList) {
|
|
$this.control.ImageList = $imageList
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] SetBackColor([System.Drawing.Color]$color) {
|
|
$this.control.BackColor = $color
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] SetForeColor([System.Drawing.Color]$color) {
|
|
$this.control.ForeColor = $color
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] AddNode([System.String]$name) {
|
|
$this.control.Nodes.Add([System.Windows.Forms.TreeNode]::new($name)) | Out-Null
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] AddNode([System.Windows.Forms.TreeNode]$node) {
|
|
$this.control.Nodes.Add($node) | Out-Null
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] AddNodes([System.Windows.Forms.TreeNode[]]$nodes) {
|
|
foreach ($node in $nodes) {
|
|
$this.control.Nodes.Add($node) | Out-Null
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# NEU: Lädt Hashtable/Template in TreeView
|
|
[TreeViewBuilder] LoadTemplate([object]$template, [System.String]$rootName = "Template") {
|
|
$this.control.Nodes.Clear()
|
|
$rootNode = $this.control.Nodes.Add($rootName)
|
|
|
|
try {
|
|
if ($template -is [System.Collections.IDictionary]) {
|
|
# WICHTIG: Keine Sortierung, Keys in Original-Reihenfolge
|
|
foreach ($key in $template.Keys) {
|
|
$this.AddTreeNodeRecursive($rootNode, $template[$key], $key, "")
|
|
}
|
|
} else {
|
|
$this.AddTreeNodeRecursive($rootNode, $template, $rootName, "")
|
|
}
|
|
} catch {
|
|
$rootNode.Nodes.Add("Fehler beim Lesen: $($_.Exception.Message)") | Out-Null
|
|
}
|
|
|
|
$rootNode.ExpandAll()
|
|
return $this
|
|
}
|
|
|
|
# NEU: Rekursive Methode zum Hinzufügen von Nodes
|
|
hidden [void] AddTreeNodeRecursive([System.Windows.Forms.TreeNode]$parentNode, [object]$value, [System.String]$name, [System.String]$path) {
|
|
$currentPath = if ($path -eq "") { $name } else { "$path.$name" }
|
|
|
|
if ($value -is [System.Collections.IDictionary]) {
|
|
$node = $parentNode.Nodes.Add($name, $name)
|
|
$node.Tag = @{ Type = "Hashtable"; Path = $currentPath; Value = $value }
|
|
|
|
# WICHTIG: KEIN Sort-Object! Behält die Original-Reihenfolge bei
|
|
foreach ($k in $value.Keys) {
|
|
$this.AddTreeNodeRecursive($node, $value[$k], $k, $currentPath)
|
|
}
|
|
}
|
|
elseif ($value -is [System.Collections.IEnumerable] -and -not ($value -is [string])) {
|
|
$node = $parentNode.Nodes.Add($name, $name)
|
|
$node.Tag = @{ Type = "Array"; Path = $currentPath; Value = $value }
|
|
$i = 0
|
|
foreach ($item in $value) {
|
|
$this.AddTreeNodeRecursive($node, $item, "[$i]", $currentPath)
|
|
$i++
|
|
}
|
|
}
|
|
else {
|
|
$displayText = "$name = $value"
|
|
$node = $parentNode.Nodes.Add($name, $displayText)
|
|
$node.Tag = @{ Type = "Value"; Path = $currentPath; Key = $name; Value = $value }
|
|
}
|
|
}
|
|
|
|
# NEU: Löscht alle Nodes
|
|
[TreeViewBuilder] ClearNodes() {
|
|
$this.control.Nodes.Clear()
|
|
return $this
|
|
}
|
|
|
|
[TreeViewBuilder] AddEventHandler([System.String]$eventName, [scriptblock]$handler) {
|
|
$this.control."Add_$eventName"($handler)
|
|
return $this
|
|
}
|
|
|
|
[System.Windows.Forms.TreeView] AddTo([System.Windows.Forms.Control]$parent) {
|
|
$parent.Controls.Add($this.control)
|
|
return $this.control
|
|
}
|
|
|
|
[System.Windows.Forms.TreeView] Build() {
|
|
return $this.control
|
|
}
|
|
}
|
|
|
|
class DataGridViewBuilder : BaseComponent{
|
|
[System.Windows.Forms.DataGridView] $control
|
|
|
|
DataGridViewBuilder() {
|
|
$this.control = New-Object System.Windows.Forms.DataGridView
|
|
$this.control.Dock = "Fill"
|
|
$this.control.ColumnHeadersHeight = 30
|
|
$this.control.AutoSizeColumnsMode = "Fill"
|
|
}
|
|
|
|
[DataGridViewBuilder] SetAllowAddRows([Boolean] $enabled) {
|
|
$this.control.AllowUserToAddRows = $enabled
|
|
return $this
|
|
}
|
|
|
|
[DataGridViewBuilder] SetHeaderColumns([System.Array] $Columns) {
|
|
foreach($Column in $Columns){
|
|
$this.control.Columns.Add($Column,$Column)
|
|
}
|
|
return $this
|
|
}
|
|
|
|
[DataGridViewBuilder] SetHeaderColumnReadOnly([System.String] $Name) {
|
|
$this.control.Columns[$Name].ReadOnly = $true
|
|
return $this
|
|
}
|
|
|
|
[System.Windows.Forms.DataGridView] Build() {
|
|
return $this.control
|
|
}
|
|
}
|
|
|
|
class GroupBoxBuilder : BaseComponent {
|
|
[System.Windows.Forms.GroupBox]$control
|
|
[bool]$autoSizeToContent = $false
|
|
|
|
GroupBoxBuilder([System.String]$text) {
|
|
$this.control = New-Object System.Windows.Forms.GroupBox
|
|
$this.control.Text = $text
|
|
$this.control.Font = New-Object System.Drawing.Font("Segoe UI", $this.GetSetting("FontSize"),[System.Drawing.FontStyle]::Bold)
|
|
#$this.control.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowOnly
|
|
}
|
|
|
|
[GroupBoxBuilder] SetText([System.String]$text) {
|
|
$this.control.Text = $text
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetWidth([int]$width) {
|
|
$this.control.Width = $width
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetHeight([int]$height) {
|
|
$this.control.Height = $height
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetSize([int]$width, [int]$height) {
|
|
$this.control.Width = $width
|
|
$this.control.Height = $height
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetFont([System.String]$family, [float]$size) {
|
|
$this.control.Font = New-Object System.Drawing.Font($family, $size)
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetFont([System.String]$family, [float]$size, [System.Drawing.FontStyle]$style) {
|
|
$this.control.Font = New-Object System.Drawing.Font($family, $size, $style)
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetMargin([int]$all) {
|
|
$this.control.Margin = New-Object System.Windows.Forms.Padding($all)
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetMargin([int]$left, [int]$top, [int]$right, [int]$bottom) {
|
|
$this.control.Margin = New-Object System.Windows.Forms.Padding($left, $top, $right, $bottom)
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetPadding([int]$all) {
|
|
$this.control.Padding = New-Object System.Windows.Forms.Padding($all)
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetPadding([int]$left, [int]$top, [int]$right, [int]$bottom) {
|
|
$this.control.Padding = New-Object System.Windows.Forms.Padding($left, $top, $right, $bottom)
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetDock([System.String]$dock) {
|
|
$this.control.Dock = [System.Windows.Forms.DockStyle]::$dock
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetBackColor([System.Drawing.Color]$color) {
|
|
$this.control.BackColor = $color
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetForeColor([System.Drawing.Color]$color) {
|
|
$this.control.ForeColor = $color
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetAutoSize([bool]$autoSize) {
|
|
$this.control.AutoSize = $autoSize
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] SetAutoSizeMode([System.String]$autoSizeMode) {
|
|
$this.control.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::$autoSizeMode
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] AddControl([System.Windows.Forms.Control]$childControl) {
|
|
$this.control.Controls.Add($childControl)
|
|
return $this
|
|
}
|
|
|
|
[GroupBoxBuilder] AddControls([System.Windows.Forms.Control[]]$controls) {
|
|
foreach ($ctrl in $controls) {
|
|
$this.control.Controls.Add($ctrl)
|
|
}
|
|
return $this
|
|
}
|
|
|
|
[System.Windows.Forms.GroupBox] AddTo([System.Windows.Forms.Control]$parent) {
|
|
$parent.Controls.Add($this.control)
|
|
return $this.control
|
|
}
|
|
|
|
[System.Windows.Forms.GroupBox] Build() {
|
|
return $this.control
|
|
}
|
|
}
|
|
|
|
class ListBoxBuilder : BaseComponent {
|
|
[System.Windows.Forms.ListBox]$control
|
|
|
|
ListBoxBuilder() {
|
|
$this.control = New-Object System.Windows.Forms.ListBox
|
|
# Standard-Einstellungen
|
|
$this.control.DisplayMember = 'BaseName'
|
|
$this.control.ValueMember = 'FullName'
|
|
$this.control.Dock = 'Fill'
|
|
$this.control.Font = New-Object System.Drawing.Font("Segoe UI", $this.GetSetting("FontSize"))
|
|
}
|
|
|
|
[ListBoxBuilder] SetDock([System.String]$dock) {
|
|
$this.control.Dock = [System.Windows.Forms.DockStyle]::$dock
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetFont([System.String]$family, [float]$size) {
|
|
$this.control.Font = New-Object System.Drawing.Font($family, $size)
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetFont([System.String]$family, [float]$size, [System.Drawing.FontStyle]$style) {
|
|
$this.control.Font = New-Object System.Drawing.Font($family, $size, $style)
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetSelectionMode([System.String]$mode) {
|
|
$this.control.SelectionMode = [System.Windows.Forms.SelectionMode]::$mode
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetBackColor([System.Drawing.Color]$color) {
|
|
$this.control.BackColor = $color
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetForeColor([System.Drawing.Color]$color) {
|
|
$this.control.ForeColor = $color
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetBorderStyle([System.String]$style) {
|
|
$this.control.BorderStyle = [System.Windows.Forms.BorderStyle]::$style
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetHorizontalScrollbar([bool]$show) {
|
|
$this.control.HorizontalScrollbar = $show
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetIntegralHeight([bool]$integral) {
|
|
$this.control.IntegralHeight = $integral
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetSorted([bool]$sorted) {
|
|
$this.control.Sorted = $sorted
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetHeight([Int]$height) {
|
|
$this.control.Height = $height
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] AddItem([object]$item) {
|
|
$this.control.Items.Add($item) | Out-Null
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] AddItems([object[]]$items) {
|
|
foreach ($item in $items) {
|
|
$this.control.Items.Add($item) | Out-Null
|
|
}
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] ClearItems() {
|
|
$this.control.Items.Clear()
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetDataSource([object]$dataSource) {
|
|
$this.control.DataSource = $dataSource
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetDisplayMember([System.String]$member) {
|
|
$this.control.DisplayMember = $member
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] SetValueMember([System.String]$member) {
|
|
$this.control.ValueMember = $member
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] AddSelectedIndexChangedHandler([scriptblock]$handler) {
|
|
$this.control.Add_SelectedIndexChanged($handler)
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] AddMouseDoubleClickHandler([scriptblock]$handler) {
|
|
$this.control.Add_MouseDoubleClick($handler)
|
|
return $this
|
|
}
|
|
|
|
[ListBoxBuilder] AddEventHandler([System.String]$eventName, [scriptblock]$handler) {
|
|
$this.control."Add_$eventName"($handler)
|
|
return $this
|
|
}
|
|
|
|
[System.Windows.Forms.ListBox] AddTo([System.Windows.Forms.Control]$parent) {
|
|
$parent.Controls.Add($this.control)
|
|
return $this.control
|
|
}
|
|
|
|
[System.Windows.Forms.ListBox] Build() {
|
|
return $this.control
|
|
}
|
|
}
|
|
|
|
class PanelBuilder : BaseComponent{
|
|
[System.Windows.Forms.Panel]$control
|
|
|
|
[scriptblock] $EnableCondition = $null
|
|
[StateManager] $StateManager = $null
|
|
|
|
|
|
PanelBuilder() {
|
|
$this.control = New-Object System.Windows.Forms.Panel
|
|
}
|
|
|
|
[PanelBuilder] SetDock([System.String]$dock) {
|
|
$this.control.Dock = [System.Windows.Forms.DockStyle]::$dock
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetWidth([int]$width) {
|
|
$this.control.Width = $width
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetHeight([int]$height) {
|
|
$this.control.Height = $height
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetSize([int]$width, [int]$height) {
|
|
$this.control.Size = New-Object System.Drawing.Size($width, $height)
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetLocation([int]$x, [int]$y) {
|
|
$this.control.Location = New-Object System.Drawing.Point($x, $y)
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetBackColor([System.Drawing.Color]$color) {
|
|
$this.control.BackColor = $color
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetForeColor([System.Drawing.Color]$color) {
|
|
$this.control.ForeColor = $color
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetBorderStyle([System.String]$style) {
|
|
$this.control.BorderStyle = [System.Windows.Forms.BorderStyle]::$style
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetAutoScroll([bool]$autoScroll) {
|
|
$this.control.AutoScroll = $autoScroll
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetPadding([int]$all) {
|
|
$this.control.Padding = New-Object System.Windows.Forms.Padding($all)
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetPadding([int]$left, [int]$top, [int]$right, [int]$bottom) {
|
|
$this.control.Padding = New-Object System.Windows.Forms.Padding($left, $top, $right, $bottom)
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetMargin([int]$all) {
|
|
$this.control.Margin = New-Object System.Windows.Forms.Padding($all)
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetMargin([int]$left, [int]$top, [int]$right, [int]$bottom) {
|
|
$this.control.Margin = New-Object System.Windows.Forms.Padding($left, $top, $right, $bottom)
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetAnchor([System.Windows.Forms.AnchorStyles]$anchor) {
|
|
$this.control.Anchor = $anchor
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetVisible([bool]$visible) {
|
|
$this.control.Visible = $visible
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetEnabled([bool]$enabled) {
|
|
$this.control.Enabled = $enabled
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetAutoSize([bool]$autoSize) {
|
|
$this.control.AutoSize = $autoSize
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetAutoSizeMode([System.String]$mode) {
|
|
$this.control.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::$mode
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] AddControl([System.Windows.Forms.Control]$childControl) {
|
|
$this.control.Controls.Add($childControl)
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] AddControls([System.Windows.Forms.Control[]]$controls) {
|
|
foreach ($ctrl in $controls) {
|
|
$this.control.Controls.Add($ctrl)
|
|
}
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] ClearControls() {
|
|
$this.control.Controls.Clear()
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] AddEventHandler([System.String]$eventName, [scriptblock]$handler) {
|
|
$this.control."Add_$eventName"($handler)
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetName([System.String]$name) {
|
|
$this.control.Name = $name
|
|
return $this
|
|
}
|
|
|
|
[PanelBuilder] SetTag([object]$tag) {
|
|
$this.control.Tag = $tag
|
|
return $this
|
|
}
|
|
|
|
[System.Windows.Forms.Panel] AddTo([System.Windows.Forms.Control]$parent) {
|
|
$parent.Controls.Add($this.control)
|
|
return $this.control
|
|
}
|
|
|
|
[PanelBuilder] BindEnabled([scriptblock]$condition, [StateManager]$stateManager) {
|
|
$this.EnableCondition = $condition
|
|
$this.StateManager = $stateManager
|
|
$this.UpdateVisibleState()
|
|
return $this
|
|
}
|
|
|
|
# Aktualisiert den Visible-Status basierend auf der Bedingung
|
|
[void] UpdateVisibleState() {
|
|
if ($null -ne $this.EnableCondition) {
|
|
try {
|
|
$result = & $this.EnableCondition
|
|
$this.control.Visible = [bool]$result
|
|
} catch {
|
|
Write-Warning "Fehler beim Evaluieren der Visible-Bedingung: $_"
|
|
$this.control.Visible = $false
|
|
}
|
|
}
|
|
}
|
|
|
|
[System.Windows.Forms.Panel] Build() {
|
|
if ($null -ne $this.StateManager -and $null -ne $this.EnableCondition) {
|
|
$this.StateManager.RegisterForm($this)
|
|
}
|
|
return $this.control
|
|
}
|
|
|
|
[System.Windows.Forms.Panel] GetPanel() {
|
|
return $this.control
|
|
}
|
|
}
|
|
|
|
class DialogBuilder : BaseComponent {
|
|
[object] $Dialog # Kann FileDialog oder FolderBrowserDialog sein
|
|
[System.String] $DialogType
|
|
|
|
# Privater Konstruktor
|
|
hidden DialogBuilder([System.String]$type) {
|
|
$this.DialogType = $type
|
|
|
|
switch ($type) {
|
|
"Open" {
|
|
$this.Dialog = New-Object System.Windows.Forms.OpenFileDialog
|
|
$this.Dialog.Multiselect = $false
|
|
$this.Dialog.Filter = "Alle Dateien (*.*)|*.*"
|
|
$this.Dialog.FilterIndex = 1
|
|
$this.Dialog.RestoreDirectory = $true
|
|
}
|
|
"Save" {
|
|
$this.Dialog = New-Object System.Windows.Forms.SaveFileDialog
|
|
$this.Dialog.OverwritePrompt = $true
|
|
$this.Dialog.Filter = "Alle Dateien (*.*)|*.*"
|
|
$this.Dialog.FilterIndex = 1
|
|
$this.Dialog.RestoreDirectory = $true
|
|
}
|
|
"Folder" {
|
|
$this.Dialog = New-Object System.Windows.Forms.FolderBrowserDialog
|
|
$this.Dialog.ShowNewFolderButton = $true
|
|
}
|
|
}
|
|
}
|
|
|
|
# === FACTORY-METHODEN ===
|
|
|
|
static [DialogBuilder] OpenFile() {
|
|
return [DialogBuilder]::new("Open")
|
|
}
|
|
|
|
static [DialogBuilder] SaveFile() {
|
|
return [DialogBuilder]::new("Save")
|
|
}
|
|
|
|
static [DialogBuilder] SelectFolder() {
|
|
return [DialogBuilder]::new("Folder")
|
|
}
|
|
|
|
# === GEMEINSAME METHODEN (FileDialog) ===
|
|
|
|
# Setzt den Titel
|
|
[DialogBuilder] SetTitle([System.String]$title) {
|
|
if ($this.DialogType -eq "Folder") {
|
|
$this.Dialog.Description = $title
|
|
} else {
|
|
$this.Dialog.Title = $title
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt den Filter (nur File-Dialoge)
|
|
[DialogBuilder] SetFilter([System.String]$filter) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
$this.Dialog.Filter = $filter
|
|
} else {
|
|
Write-Warning "Filter ist nur für File-Dialoge verfügbar"
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt den aktiven Filter-Index (nur File-Dialoge)
|
|
[DialogBuilder] SetFilterIndex([int]$index) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
$this.Dialog.FilterIndex = $index
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt das Initial-Verzeichnis
|
|
[DialogBuilder] SetInitialDirectory([System.String]$path) {
|
|
if ($this.DialogType -eq "Folder") {
|
|
if (Test-Path $path) {
|
|
$this.Dialog.SelectedPath = $path
|
|
} else {
|
|
Write-Warning "Pfad existiert nicht: $path"
|
|
}
|
|
} else {
|
|
if (Test-Path $path) {
|
|
$this.Dialog.InitialDirectory = $path
|
|
} else {
|
|
Write-Warning "Pfad existiert nicht: $path"
|
|
}
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt den Standard-Dateinamen (nur File-Dialoge)
|
|
[DialogBuilder] SetFileName([System.String]$fileName) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
$this.Dialog.FileName = $fileName
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Prüft ob Datei existieren muss (nur File-Dialoge)
|
|
[DialogBuilder] SetCheckFileExists([bool]$check) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
$this.Dialog.CheckFileExists = $check
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Prüft ob Pfad existieren muss (nur File-Dialoge)
|
|
[DialogBuilder] SetCheckPathExists([bool]$check) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
$this.Dialog.CheckPathExists = $check
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Wiederherstellt letztes Verzeichnis (nur File-Dialoge)
|
|
[DialogBuilder] SetRestoreDirectory([bool]$restore) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
$this.Dialog.RestoreDirectory = $restore
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Validiert Namen gegen ungültige Zeichen (nur File-Dialoge)
|
|
[DialogBuilder] SetValidateNames([bool]$validate) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
$this.Dialog.ValidateNames = $validate
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Dereferenziert Links/Shortcuts (nur File-Dialoge)
|
|
[DialogBuilder] SetDereferenceLinks([bool]$dereference) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
$this.Dialog.DereferenceLinks = $dereference
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Standard-Erweiterung (nur File-Dialoge)
|
|
[DialogBuilder] SetDefaultExt([System.String]$ext) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
$this.Dialog.DefaultExt = $ext.TrimStart('.')
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Fügt automatisch Erweiterung hinzu (nur File-Dialoge)
|
|
[DialogBuilder] SetAddExtension([bool]$add) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
$this.Dialog.AddExtension = $add
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt Custom Places (nur File-Dialoge)
|
|
[DialogBuilder] AddCustomPlace([System.String]$path) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
if (Test-Path $path) {
|
|
$this.Dialog.CustomPlaces.Add($path)
|
|
}
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt mehrere Custom Places (nur File-Dialoge)
|
|
[DialogBuilder] AddCustomPlaces([System.String[]]$paths) {
|
|
if ($this.DialogType -ne "Folder") {
|
|
foreach ($path in $paths) {
|
|
if (Test-Path $path) {
|
|
$this.Dialog.CustomPlaces.Add($path)
|
|
}
|
|
}
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# === OPENFILEDIALOG-SPEZIFISCH ===
|
|
|
|
# Aktiviert/Deaktiviert Mehrfachauswahl
|
|
[DialogBuilder] SetMultiselect([bool]$multiselect) {
|
|
if ($this.DialogType -eq "Open") {
|
|
$this.Dialog.Multiselect = $multiselect
|
|
} else {
|
|
Write-Warning "Multiselect ist nur für OpenFileDialog verfügbar"
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Zeigt Read-Only Checkbox
|
|
[DialogBuilder] SetShowReadOnly([bool]$show) {
|
|
if ($this.DialogType -eq "Open") {
|
|
$this.Dialog.ShowReadOnly = $show
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt Read-Only Status
|
|
[DialogBuilder] SetReadOnlyChecked([bool]$checked) {
|
|
if ($this.DialogType -eq "Open") {
|
|
$this.Dialog.ReadOnlyChecked = $checked
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# === SAVEFILEDIALOG-SPEZIFISCH ===
|
|
|
|
# Warnt bei Überschreiben
|
|
[DialogBuilder] SetOverwritePrompt([bool]$prompt) {
|
|
if ($this.DialogType -eq "Save") {
|
|
$this.Dialog.OverwritePrompt = $prompt
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Warnt beim Erstellen neuer Dateien
|
|
[DialogBuilder] SetCreatePrompt([bool]$prompt) {
|
|
if ($this.DialogType -eq "Save") {
|
|
$this.Dialog.CreatePrompt = $prompt
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# === FOLDERBROWSERDIALOG-SPEZIFISCH ===
|
|
|
|
# Zeigt "Neuer Ordner"-Button
|
|
[DialogBuilder] SetShowNewFolderButton([bool]$show) {
|
|
if ($this.DialogType -eq "Folder") {
|
|
$this.Dialog.ShowNewFolderButton = $show
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt die Beschreibung (Folder-spezifisch)
|
|
[DialogBuilder] SetDescription([System.String]$description) {
|
|
if ($this.DialogType -eq "Folder") {
|
|
$this.Dialog.Description = $description
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt den Root-Folder (Folder-spezifisch)
|
|
[DialogBuilder] SetRootFolder([System.String]$specialFolder) {
|
|
if ($this.DialogType -eq "Folder") {
|
|
try {
|
|
$this.Dialog.RootFolder = [System.Environment+SpecialFolder]::$specialFolder
|
|
} catch {
|
|
Write-Warning "Ungültiger SpecialFolder: $specialFolder"
|
|
}
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Setzt den ausgewählten Pfad (Folder-spezifisch)
|
|
[DialogBuilder] SetSelectedPath([System.String]$path) {
|
|
if ($this.DialogType -eq "Folder") {
|
|
if (Test-Path $path) {
|
|
$this.Dialog.SelectedPath = $path
|
|
} else {
|
|
Write-Warning "Pfad existiert nicht: $path"
|
|
}
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# Verwendet die neue Folder-Browser-Darstellung (Vista-Style)
|
|
[DialogBuilder] SetUseDescriptionForTitle([bool]$use) {
|
|
if ($this.DialogType -eq "Folder") {
|
|
$this.Dialog.UseDescriptionForTitle = $use
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# === VOREINGESTELLTE FILTER ===
|
|
|
|
# Schnell-Methode für häufige Filter (nur File-Dialoge)
|
|
[DialogBuilder] SetCommonFilter([System.String]$type) {
|
|
if ($this.DialogType -eq "Folder") {
|
|
Write-Warning "Filter sind für FolderBrowserDialog nicht verfügbar"
|
|
return $this
|
|
}
|
|
|
|
switch ($type) {
|
|
'Text' {
|
|
$this.Dialog.Filter = "Text-Dateien (*.txt)|*.txt|Alle Dateien (*.*)|*.*"
|
|
$this.Dialog.DefaultExt = "txt"
|
|
}
|
|
'PowerShell' {
|
|
$this.Dialog.Filter = "PowerShell-Dateien (*.ps1;*.psm1;*.psd1)|*.ps1;*.psm1;*.psd1|Alle Dateien (*.*)|*.*"
|
|
$this.Dialog.DefaultExt = "ps1"
|
|
}
|
|
'PSD1' {
|
|
$this.Dialog.Filter = "PowerShell Data-Dateien (*.psd1)|*.psd1|Alle Dateien (*.*)|*.*"
|
|
$this.Dialog.DefaultExt = "psd1"
|
|
}
|
|
'JSON' {
|
|
$this.Dialog.Filter = "JSON-Dateien (*.json)|*.json|Alle Dateien (*.*)|*.*"
|
|
$this.Dialog.DefaultExt = "json"
|
|
}
|
|
'XML' {
|
|
$this.Dialog.Filter = "XML-Dateien (*.xml)|*.xml|Alle Dateien (*.*)|*.*"
|
|
$this.Dialog.DefaultExt = "xml"
|
|
}
|
|
'CSV' {
|
|
$this.Dialog.Filter = "CSV-Dateien (*.csv)|*.csv|Alle Dateien (*.*)|*.*"
|
|
$this.Dialog.DefaultExt = "csv"
|
|
}
|
|
'Excel' {
|
|
$this.Dialog.Filter = "Excel-Dateien (*.xlsx;*.xls)|*.xlsx;*.xls|Alle Dateien (*.*)|*.*"
|
|
$this.Dialog.DefaultExt = "xlsx"
|
|
}
|
|
'Image' {
|
|
$this.Dialog.Filter = "Bild-Dateien (*.png;*.jpg;*.jpeg;*.gif;*.bmp)|*.png;*.jpg;*.jpeg;*.gif;*.bmp|Alle Dateien (*.*)|*.*"
|
|
$this.Dialog.DefaultExt = "png"
|
|
}
|
|
'All' {
|
|
$this.Dialog.Filter = "Alle Dateien (*.*)|*.*"
|
|
}
|
|
default {
|
|
Write-Warning "Unbekannter Filter-Typ: $type"
|
|
}
|
|
}
|
|
return $this
|
|
}
|
|
|
|
# === SHOW UND BUILD ===
|
|
|
|
# Zeigt den Dialog und gibt das Ergebnis zurück
|
|
[System.Collections.Hashtable] Show() {
|
|
$result = @{
|
|
Result = $false
|
|
FileName = $null
|
|
FileNames = @()
|
|
SafeFileName = $null
|
|
SafeFileNames = @()
|
|
SelectedPath = $null
|
|
}
|
|
|
|
$dialogResult = $this.Dialog.ShowDialog()
|
|
|
|
if ($dialogResult -eq 'OK') {
|
|
$result.Result = $true
|
|
|
|
if ($this.DialogType -eq "Folder") {
|
|
$result.SelectedPath = $this.Dialog.SelectedPath
|
|
$result.FileName = $this.Dialog.SelectedPath
|
|
} else {
|
|
$result.FileName = $this.Dialog.FileName
|
|
$result.SafeFileName = $this.Dialog.SafeFileName
|
|
|
|
if ($this.DialogType -eq "Open") {
|
|
$result.FileNames = $this.Dialog.FileNames
|
|
$result.SafeFileNames = $this.Dialog.SafeFileNames
|
|
} else {
|
|
$result.FileNames = @($this.Dialog.FileName)
|
|
$result.SafeFileNames = @($this.Dialog.SafeFileName)
|
|
}
|
|
}
|
|
}
|
|
|
|
return $result
|
|
}
|
|
|
|
# Zeigt den Dialog mit Custom Parent Window
|
|
[System.Collections.Hashtable] Show([System.Windows.Forms.IWin32Window]$owner) {
|
|
$result = @{
|
|
Result = $false
|
|
FileName = $null
|
|
FileNames = @()
|
|
SafeFileName = $null
|
|
SafeFileNames = @()
|
|
SelectedPath = $null
|
|
}
|
|
|
|
$dialogResult = $this.Dialog.ShowDialog($owner)
|
|
|
|
if ($dialogResult -eq 'OK') {
|
|
$result.Result = $true
|
|
|
|
if ($this.DialogType -eq "Folder") {
|
|
$result.SelectedPath = $this.Dialog.SelectedPath
|
|
$result.FileName = $this.Dialog.SelectedPath
|
|
} else {
|
|
$result.FileName = $this.Dialog.FileName
|
|
$result.SafeFileName = $this.Dialog.SafeFileName
|
|
|
|
if ($this.DialogType -eq "Open") {
|
|
$result.FileNames = $this.Dialog.FileNames
|
|
$result.SafeFileNames = $this.Dialog.SafeFileNames
|
|
} else {
|
|
$result.FileNames = @($this.Dialog.FileName)
|
|
$result.SafeFileNames = @($this.Dialog.SafeFileName)
|
|
}
|
|
}
|
|
}
|
|
|
|
return $result
|
|
}
|
|
|
|
# Gibt das Dialog-Objekt zurück (für erweiterte Szenarien)
|
|
[object] Build() {
|
|
return $this.Dialog
|
|
}
|
|
|
|
# Dispose des Dialogs
|
|
[void] Dispose() {
|
|
if ($null -ne $this.Dialog) {
|
|
$this.Dialog.Dispose()
|
|
}
|
|
}
|
|
}
|
|
|
|
class TemplateBuilder : BaseComponent{
|
|
|
|
[System.Collections.Specialized.OrderedDictionary] $Template
|
|
|
|
# Konstruktor: Pfad zu PSD1-Datei
|
|
TemplateBuilder([System.String]$TemplatePath) {
|
|
$this.Template = $this.ConvertFromPowerShellDataString($TemplatePath)
|
|
}
|
|
|
|
# Konstruktor: Hashtable direkt übergeben
|
|
TemplateBuilder([hashtable]$TemplateHashtable) {
|
|
$this.Template = $this.ConvertHashtableToOrdered($TemplateHashtable)
|
|
}
|
|
|
|
# Konstruktor: OrderedDictionary direkt übergeben
|
|
TemplateBuilder([System.Collections.Specialized.OrderedDictionary]$TemplateOrdered) {
|
|
$this.Template = $TemplateOrdered
|
|
}
|
|
|
|
# Hilfsmethode: Konvertiert eine normale Hashtable in OrderedDictionary (rekursiv)
|
|
hidden [System.Collections.Specialized.OrderedDictionary] ConvertHashtableToOrdered([hashtable]$Hashtable) {
|
|
$ordered = New-Object System.Collections.Specialized.OrderedDictionary
|
|
|
|
foreach ($key in $Hashtable.Keys) {
|
|
$value = $Hashtable[$key]
|
|
|
|
# Rekursive Konvertierung für verschachtelte Hashtables
|
|
if ($value -is [hashtable]) {
|
|
$ordered[$key] = $this.ConvertHashtableToOrdered($value)
|
|
}
|
|
# Array mit Hashtables
|
|
elseif ($value -is [array]) {
|
|
$arrayResult = @()
|
|
foreach ($item in $value) {
|
|
if ($item -is [hashtable]) {
|
|
$arrayResult += $this.ConvertHashtableToOrdered($item)
|
|
}
|
|
else {
|
|
$arrayResult += $item
|
|
}
|
|
}
|
|
$ordered[$key] = $arrayResult
|
|
}
|
|
else {
|
|
$ordered[$key] = $value
|
|
}
|
|
}
|
|
|
|
return $ordered
|
|
}
|
|
|
|
# Concat mit einer dynamischen Anzahl von Argumenten
|
|
static [string] Concat([object[]]$input) {
|
|
return (($input | ForEach-Object { [string]$_ }) -join '')
|
|
}
|
|
|
|
# ToLower-Methode
|
|
static [string] ToLower([object[]]$input) {
|
|
if ($input.Count -lt 1) {
|
|
return ""
|
|
}
|
|
|
|
return ([string]$input[0]).ToLowerInvariant()
|
|
}
|
|
|
|
# ToUpper-Methode
|
|
static [string] ToUpper([object[]]$input) {
|
|
if ($input.Count -lt 1) {
|
|
return ""
|
|
}
|
|
|
|
return ([string]$input[0]).ToUpperInvariant()
|
|
}
|
|
|
|
# FirstIndexOf-Methode
|
|
static [string] FirstIndexOf([object[]] $input){
|
|
if ($input.Count -lt 1) {
|
|
return ""
|
|
}
|
|
|
|
return [string]$input[0]
|
|
}
|
|
|
|
# LastIndexOf-Methode
|
|
static [string] LastIndexOf([object[]] $input){
|
|
if ($input.Count -lt 1) {
|
|
return ""
|
|
}
|
|
|
|
return [string]$input[-1]
|
|
}
|
|
|
|
# IndexOf-Methode
|
|
static [string] IndexOf([object[]] $input){
|
|
if ($input.Count -lt 2) {
|
|
throw "IndexOf benötigt mindestens zwei Argumente."
|
|
}
|
|
|
|
return [string]$input[[int]$input[-1]]
|
|
}
|
|
|
|
# Substring-Methode
|
|
static [String] Substring([object[]] $input){
|
|
if($input.Count -eq 2){
|
|
return ([string]$input[0]).Substring([int]$input[1])
|
|
|
|
}elseif($input.Count -eq 3){
|
|
return ([string]$input[0]).Substring([int]$input[1],[int]$input[2])
|
|
|
|
}else{
|
|
throw "Substring erwartet zwei oder drei Argumente."
|
|
}
|
|
}
|
|
|
|
# Replace-Methode
|
|
static [String] Replace([object[]] $input){
|
|
if ($input.Count -lt 3) {
|
|
throw "Replace erwartet drei Argumente."
|
|
}
|
|
|
|
return ([string]$input[0]).Replace([string]$input[1],[string]$input[2])
|
|
}
|
|
|
|
hidden [System.Collections.Specialized.OrderedDictionary] ResolveDeploymentParameterDefaultValues(){
|
|
$TemplateClone = $this.Template
|
|
|
|
if($TemplateClone.Contains("Parameters")){
|
|
foreach($Parameter in $this.Template.Parameters.GetEnumerator()){
|
|
if(!$Parameter.Value.Contains("Value")){
|
|
$TemplateClone.Parameters[$Parameter.Name].Value = $this.Template.Parameters[$Parameter.Name].DefaultValue
|
|
}
|
|
}
|
|
}
|
|
return $TemplateClone
|
|
}
|
|
|
|
[System.Collections.Specialized.OrderedDictionary] ResolveDeploymentDataVariables(){
|
|
|
|
|
|
$TemplateClone = $this.ResolveDeploymentParameterDefaultValues()
|
|
|
|
# Erst Variables auflösen (können Parameter-Referenzen enthalten)
|
|
if ($TemplateClone.Variables) {
|
|
$resolvedVariables = New-Object System.Collections.Specialized.OrderedDictionary
|
|
# WICHTIG: Keys-Array erstellen, um Collection-Modification zu vermeiden
|
|
$varKeys = @($TemplateClone.Variables.Keys)
|
|
foreach ($varKey in $varKeys) {
|
|
$resolvedVariables[$varKey] = $this.ResolveValue($TemplateClone.Variables[$varKey],$TemplateClone.Parameters,$TemplateClone.Variables)
|
|
}
|
|
$TemplateClone.Variables = $resolvedVariables
|
|
}
|
|
|
|
# Dann den Rest des Templates auflösen
|
|
# WICHTIG: Keys-Array erstellen, um Collection-Modification zu vermeiden
|
|
$templateKeys = @($TemplateClone.Keys)
|
|
foreach ($key in $templateKeys) {
|
|
if ($key -ne 'Variables' -and $key -ne 'Parameters') {
|
|
$TemplateClone[$key] = $this.ResolveValue($TemplateClone[$key],$TemplateClone.Parameters,$TemplateClone.Variables)
|
|
}
|
|
}
|
|
|
|
return $TemplateClone
|
|
}
|
|
|
|
hidden [System.Collections.Specialized.OrderedDictionary] ConvertFromPowerShellDataString($TemplatePath){
|
|
$errors = $null
|
|
$tokens = $null
|
|
|
|
$ast = [System.Management.Automation.Language.Parser]::ParseFile(
|
|
$TemplatePath,
|
|
[ref]$tokens,
|
|
[ref]$errors
|
|
)
|
|
|
|
if ($errors) {
|
|
throw "Fehler beim Parsen der Datei: $($errors[0].Message)"
|
|
}
|
|
|
|
$hashtableAst = $ast.Find({
|
|
$args[0] -is [System.Management.Automation.Language.HashtableAst]
|
|
}, $true)
|
|
|
|
if (-not $hashtableAst) {
|
|
throw "Keine Hashtable im $TemplatePath gefunden"
|
|
}
|
|
|
|
$this.Template = $this.ConvertToOrderedHashtable($hashtableAst)
|
|
|
|
return $this.Template
|
|
}
|
|
|
|
hidden [System.Collections.Specialized.OrderedDictionary] ConvertToOrderedHashtable([System.Management.Automation.Language.HashtableAst]$HashtableAst){
|
|
$ordered = New-Object System.Collections.Specialized.OrderedDictionary
|
|
|
|
$sortedKvps = $HashtableAst.KeyValuePairs | Sort-Object { $_.Item1.Extent.StartOffset }
|
|
|
|
foreach ($kvp in $sortedKvps) {
|
|
$key = [string]$this.ConvertAstValue($kvp.Item1)
|
|
$value = $this.ConvertAstValue($kvp.Item2)
|
|
$ordered.Add($key, $value)
|
|
}
|
|
|
|
return $ordered
|
|
}
|
|
|
|
hidden [System.Object] ConvertAstValue([System.Management.Automation.Language.Ast]$Ast) {
|
|
if ($null -eq $Ast) {
|
|
return $null
|
|
}
|
|
|
|
if ($Ast -is [System.Management.Automation.Language.PipelineAst]) {
|
|
if ($Ast.PipelineElements.Count -eq 1 -and $Ast.PipelineElements[0] -is [System.Management.Automation.Language.CommandExpressionAst]) {
|
|
return $this.ConvertAstValue($Ast.PipelineElements[0].Expression)
|
|
}
|
|
|
|
return $Ast.SafeGetValue()
|
|
}
|
|
|
|
if ($Ast -is [System.Management.Automation.Language.CommandExpressionAst]) {
|
|
return $this.ConvertAstValue($Ast.Expression)
|
|
}
|
|
|
|
if ($Ast -is [System.Management.Automation.Language.ParenExpressionAst]) {
|
|
return $this.ConvertAstValue($Ast.Pipeline)
|
|
}
|
|
|
|
if ($Ast -is [System.Management.Automation.Language.ArrayExpressionAst]) {
|
|
return $this.ConvertAstValue($Ast.SubExpression)
|
|
}
|
|
|
|
if ($Ast -is [System.Management.Automation.Language.StatementBlockAst]) {
|
|
if ($Ast.Statements.Count -eq 1 -and $Ast.Statements[0] -is [System.Management.Automation.Language.PipelineAst]) {
|
|
return $this.ConvertAstValue($Ast.Statements[0])
|
|
}
|
|
|
|
throw "Nicht unterstützter Ausdruck in PSD1-Datei: $($Ast.Extent.Text)"
|
|
}
|
|
|
|
if ($Ast -is [System.Management.Automation.Language.ArrayLiteralAst]) {
|
|
$result = @()
|
|
foreach ($element in $Ast.Elements) {
|
|
$result += $this.ConvertAstValue($element)
|
|
}
|
|
|
|
return $result
|
|
}
|
|
|
|
if ($Ast -is [System.Management.Automation.Language.HashtableAst]) {
|
|
return $this.ConvertToOrderedHashtable($Ast)
|
|
}
|
|
|
|
if ($Ast -is [System.Management.Automation.Language.VariableExpressionAst]) {
|
|
switch ($Ast.VariablePath.UserPath) {
|
|
'true' { return $true }
|
|
'false' { return $false }
|
|
'null' { return $null }
|
|
default { return $Ast.Extent.Text }
|
|
}
|
|
}
|
|
|
|
try {
|
|
return $Ast.SafeGetValue()
|
|
}
|
|
catch {
|
|
return $Ast.Extent.Text
|
|
}
|
|
}
|
|
|
|
hidden [System.Object] ResolveValue($Value, $Parameters, $Variables){
|
|
$resolutionStack = [System.Collections.Generic.List[string]]::new()
|
|
return $this.ResolveValueInternal($Value, $Parameters, $Variables, $resolutionStack)
|
|
}
|
|
|
|
hidden [System.Object] ResolveValueInternal($Value, $Parameters, $Variables, [System.Collections.Generic.List[string]]$ResolutionStack){
|
|
if ($Value -is [string]) {
|
|
$trimmedValue = $Value.Trim()
|
|
if ($this.IsTemplateExpression($trimmedValue)) {
|
|
return $this.EvaluateTemplateExpression($trimmedValue.Substring(1, $trimmedValue.Length - 2), $Parameters, $Variables, $ResolutionStack)
|
|
}
|
|
|
|
return $this.ResolveInlineTemplateExpressions($Value, $Parameters, $Variables, $ResolutionStack)
|
|
}
|
|
elseif ($Value -is [System.Collections.IDictionary]) {
|
|
$resolved = New-Object System.Collections.Specialized.OrderedDictionary
|
|
foreach ($key in $Value.Keys) {
|
|
$resolved[$key] = $this.ResolveValueInternal($Value[$key], $Parameters, $Variables, $ResolutionStack)
|
|
}
|
|
return $resolved
|
|
}
|
|
elseif ($Value -is [array]) {
|
|
$resolved = @()
|
|
foreach ($item in $Value) {
|
|
$resolved += $this.ResolveValueInternal($item, $Parameters, $Variables, $ResolutionStack)
|
|
}
|
|
return $resolved
|
|
}
|
|
else {
|
|
return $Value
|
|
}
|
|
}
|
|
|
|
hidden [bool] IsTemplateExpression([string]$Value) {
|
|
if ([string]::IsNullOrWhiteSpace($Value)) {
|
|
return $false
|
|
}
|
|
|
|
if (-not ($Value.StartsWith('[') -and $Value.EndsWith(']'))) {
|
|
return $false
|
|
}
|
|
|
|
return $this.IsFunctionInvocation($Value.Substring(1, $Value.Length - 2))
|
|
}
|
|
|
|
hidden [bool] IsFunctionInvocation([string]$Value) {
|
|
return $Value.Trim() -match '^[A-Za-z_][A-Za-z0-9_]*\s*\(.*\)$'
|
|
}
|
|
|
|
hidden [string] ResolveInlineTemplateExpressions([string]$Value, $Parameters, $Variables, [System.Collections.Generic.List[string]]$ResolutionStack) {
|
|
$resolved = $Value
|
|
$matches = [regex]::Matches($Value, '\[[^\[\]]+\]')
|
|
|
|
for ($i = $matches.Count - 1; $i -ge 0; $i--) {
|
|
$match = $matches[$i]
|
|
$expressionText = $match.Value.Substring(1, $match.Value.Length - 2)
|
|
if (-not $this.IsFunctionInvocation($expressionText)) {
|
|
continue
|
|
}
|
|
|
|
$replacement = $this.EvaluateTemplateExpression($expressionText, $Parameters, $Variables, $ResolutionStack)
|
|
$resolved = $resolved.Remove($match.Index, $match.Length).Insert($match.Index, [string]$replacement)
|
|
}
|
|
|
|
return $resolved
|
|
}
|
|
|
|
hidden [System.Object] EvaluateTemplateExpression([string]$ExpressionText, $Parameters, $Variables, [System.Collections.Generic.List[string]]$ResolutionStack) {
|
|
$trimmedExpression = $ExpressionText.Trim()
|
|
if ($trimmedExpression -notmatch '^([A-Za-z_][A-Za-z0-9_]*)\s*\((.*)\)$') {
|
|
return $ExpressionText
|
|
}
|
|
|
|
$functionName = $matches[1]
|
|
$argumentsText = $matches[2]
|
|
$resolvedArguments = @()
|
|
$result = $null
|
|
|
|
foreach ($argument in $this.SplitExpressionArguments($argumentsText)) {
|
|
$resolvedArguments += ,($this.ResolveExpressionToken($argument, $Parameters, $Variables, $ResolutionStack))
|
|
}
|
|
|
|
switch ($functionName.ToLowerInvariant()) {
|
|
'parameter' { $result = $this.GetParameterValue([string]$resolvedArguments[0], $Parameters); break }
|
|
'parameters' { $result = $this.GetParameterValue([string]$resolvedArguments[0], $Parameters); break }
|
|
'variable' { $result = $this.GetVariableValue([string]$resolvedArguments[0], $Parameters, $Variables, $ResolutionStack); break }
|
|
'variables' { $result = $this.GetVariableValue([string]$resolvedArguments[0], $Parameters, $Variables, $ResolutionStack); break }
|
|
'concat' { $result = [TemplateBuilder]::Concat($resolvedArguments); break }
|
|
'tolower' { $result = [TemplateBuilder]::ToLower($resolvedArguments); break }
|
|
'toupper' { $result = [TemplateBuilder]::ToUpper($resolvedArguments); break }
|
|
'firstindexof' { $result = [TemplateBuilder]::FirstIndexOf($resolvedArguments); break }
|
|
'lastindexof' { $result = [TemplateBuilder]::LastIndexOf($resolvedArguments); break }
|
|
'indexof' { $result = [TemplateBuilder]::IndexOf($resolvedArguments); break }
|
|
'substring' { $result = [TemplateBuilder]::Substring($resolvedArguments); break }
|
|
'replace' { $result = [TemplateBuilder]::Replace($resolvedArguments); break }
|
|
default {
|
|
throw "Nicht unterstützte Template-Funktion '$functionName'"
|
|
return $null
|
|
}
|
|
}
|
|
|
|
return $result
|
|
}
|
|
|
|
hidden [string[]] SplitExpressionArguments([string]$ArgumentsText) {
|
|
$arguments = New-Object 'System.Collections.Generic.List[string]'
|
|
if ([string]::IsNullOrWhiteSpace($ArgumentsText)) {
|
|
return $arguments.ToArray()
|
|
}
|
|
|
|
$builder = New-Object System.Text.StringBuilder
|
|
$depth = 0
|
|
$inSingleQuote = $false
|
|
$inDoubleQuote = $false
|
|
|
|
for ($i = 0; $i -lt $ArgumentsText.Length; $i++) {
|
|
$char = $ArgumentsText[$i]
|
|
|
|
if ($char -eq "'" -and -not $inDoubleQuote) {
|
|
[void]$builder.Append($char)
|
|
if ($inSingleQuote -and $i + 1 -lt $ArgumentsText.Length -and $ArgumentsText[$i + 1] -eq "'") {
|
|
$i++
|
|
[void]$builder.Append($ArgumentsText[$i])
|
|
continue
|
|
}
|
|
|
|
$inSingleQuote = -not $inSingleQuote
|
|
continue
|
|
}
|
|
|
|
if ($char -eq '"' -and -not $inSingleQuote) {
|
|
$inDoubleQuote = -not $inDoubleQuote
|
|
[void]$builder.Append($char)
|
|
continue
|
|
}
|
|
|
|
if (-not $inSingleQuote -and -not $inDoubleQuote) {
|
|
if ($char -eq '(') {
|
|
$depth++
|
|
}
|
|
elseif ($char -eq ')') {
|
|
$depth--
|
|
}
|
|
elseif ($char -eq ',' -and $depth -eq 0) {
|
|
$arguments.Add($builder.ToString().Trim())
|
|
[void]$builder.Clear()
|
|
continue
|
|
}
|
|
}
|
|
|
|
[void]$builder.Append($char)
|
|
}
|
|
|
|
if ($builder.Length -gt 0 -or $ArgumentsText.Trim().Length -gt 0) {
|
|
$arguments.Add($builder.ToString().Trim())
|
|
}
|
|
|
|
return $arguments.ToArray()
|
|
}
|
|
|
|
hidden [System.Object] ResolveExpressionToken([string]$Token, $Parameters, $Variables, [System.Collections.Generic.List[string]]$ResolutionStack) {
|
|
$trimmedToken = $Token.Trim()
|
|
if ([string]::IsNullOrWhiteSpace($trimmedToken)) {
|
|
return ''
|
|
}
|
|
|
|
if ($this.IsTemplateExpression($trimmedToken)) {
|
|
return $this.EvaluateTemplateExpression($trimmedToken.Substring(1, $trimmedToken.Length - 2), $Parameters, $Variables, $ResolutionStack)
|
|
}
|
|
|
|
if ($this.IsFunctionInvocation($trimmedToken)) {
|
|
return $this.EvaluateTemplateExpression($trimmedToken, $Parameters, $Variables, $ResolutionStack)
|
|
}
|
|
|
|
if (($trimmedToken.StartsWith("'") -and $trimmedToken.EndsWith("'")) -or ($trimmedToken.StartsWith('"') -and $trimmedToken.EndsWith('"'))) {
|
|
return $this.UnquoteString($trimmedToken)
|
|
}
|
|
|
|
if ($trimmedToken -match '^\$?true$') {
|
|
return $true
|
|
}
|
|
|
|
if ($trimmedToken -match '^\$?false$') {
|
|
return $false
|
|
}
|
|
|
|
if ($trimmedToken -match '^\$?null$') {
|
|
return $null
|
|
}
|
|
|
|
if ($trimmedToken -match '^-?\d+$') {
|
|
return [int]$trimmedToken
|
|
}
|
|
|
|
if ($trimmedToken -match '^-?\d+\.\d+$') {
|
|
return [double]$trimmedToken
|
|
}
|
|
|
|
return $trimmedToken
|
|
}
|
|
|
|
hidden [string] UnquoteString([string]$Value) {
|
|
if ($Value.StartsWith("'") -and $Value.EndsWith("'")) {
|
|
return ($Value.Substring(1, $Value.Length - 2) -replace "''", "'")
|
|
}
|
|
|
|
if ($Value.StartsWith('"') -and $Value.EndsWith('"')) {
|
|
return $Value.Substring(1, $Value.Length - 2)
|
|
}
|
|
|
|
return $Value
|
|
}
|
|
|
|
hidden [System.Object] GetParameterValue([string]$ParameterName, $Parameters) {
|
|
if ($null -eq $Parameters -or -not $Parameters.Contains($ParameterName)) {
|
|
throw "Parameter '$ParameterName' nicht gefunden"
|
|
}
|
|
|
|
$parameter = $Parameters[$ParameterName]
|
|
if ($parameter -is [System.Collections.IDictionary]) {
|
|
if ($parameter.Contains('Value') -and $null -ne $parameter.Value) {
|
|
return $parameter.Value
|
|
}
|
|
|
|
if ($parameter.Contains('DefaultValue')) {
|
|
return $parameter.DefaultValue
|
|
}
|
|
}
|
|
|
|
return $parameter
|
|
}
|
|
|
|
hidden [System.Object] GetVariableValue([string]$VariableName, $Parameters, $Variables, [System.Collections.Generic.List[string]]$ResolutionStack) {
|
|
if ($null -eq $Variables -or -not $Variables.Contains($VariableName)) {
|
|
throw "Variable '$VariableName' nicht gefunden"
|
|
return $null
|
|
}
|
|
|
|
if ($ResolutionStack.Contains($VariableName)) {
|
|
$cycle = @($ResolutionStack.ToArray()) + $VariableName
|
|
throw "Zirkuläre Variablenreferenz erkannt: $($cycle -join ' -> ')"
|
|
return $null
|
|
}
|
|
|
|
$ResolutionStack.Add($VariableName)
|
|
$resolvedValue = $null
|
|
try {
|
|
$resolvedValue = $this.ResolveValueInternal($Variables[$VariableName], $Parameters, $Variables, $ResolutionStack)
|
|
}
|
|
finally {
|
|
[void]$ResolutionStack.Remove($VariableName)
|
|
}
|
|
|
|
return $resolvedValue
|
|
}
|
|
}
|
|
|
|
class TabControlBuilder : BaseComponent{
|
|
[System.Windows.Forms.TabControl] $control
|
|
|
|
TabControlBuilder() {
|
|
$this.control = New-Object System.Windows.Forms.TabControl
|
|
}
|
|
|
|
[TabControlBuilder] SetDock([System.String]$dock) {
|
|
$this.control.Dock = [System.Windows.Forms.DockStyle]::$dock
|
|
return $this
|
|
}
|
|
|
|
[TabControlBuilder] SetWidth([Int]$width) {
|
|
$this.control.Width = $width
|
|
return $this
|
|
}
|
|
|
|
[TabControlBuilder] SetVisible([Boolean]$visible) {
|
|
$this.control.Visible = $visible
|
|
return $this
|
|
}
|
|
|
|
[TabControlBuilder] SetSelectedIndex([int]$index) {
|
|
$this.control.SelectedIndex = $index
|
|
return $this
|
|
}
|
|
|
|
[TabControlBuilder] AddTabPage([System.Windows.Forms.TabPage]$tabPage) {
|
|
$this.control.TabPages.Add($tabPage) | Out-Null
|
|
return $this
|
|
}
|
|
|
|
[System.Windows.Forms.TabControl] Build() {
|
|
return $this.control
|
|
}
|
|
}
|
|
|
|
class TabPageBuilder : BaseComponent{
|
|
[System.Windows.Forms.TabPage]$control
|
|
|
|
TabPageBuilder([System.String]$text) {
|
|
$this.control = New-Object System.Windows.Forms.TabPage
|
|
$this.control.Text = $text
|
|
}
|
|
|
|
[TabPageBuilder] SetPadding([int]$all) {
|
|
$this.control.Padding = New-Object System.Windows.Forms.Padding($all)
|
|
return $this
|
|
}
|
|
|
|
[TabPageBuilder] AddControl([System.Windows.Forms.Control]$childControl) {
|
|
$this.control.Controls.Add($childControl)
|
|
return $this
|
|
}
|
|
|
|
[void] AddTo([System.Windows.Forms.Control]$parent) {
|
|
$parent.Controls.Add($this.control)
|
|
}
|
|
|
|
[System.Windows.Forms.TabPage] Build() {
|
|
return $this.control
|
|
}
|
|
}
|
|
|
|
class ListViewBuilder : BaseComponent {
|
|
[System.Windows.Forms.ListView]$control
|
|
|
|
ListViewBuilder() {
|
|
$this.control = New-Object System.Windows.Forms.ListView
|
|
$this.control.View = 'Details'
|
|
}
|
|
|
|
[ListViewBuilder] SetDock([System.String]$dock) {
|
|
$this.control.Dock = [System.Windows.Forms.DockStyle]::$dock
|
|
return $this
|
|
}
|
|
|
|
[ListViewBuilder] SetView([System.String]$view) {
|
|
$this.control.View = [System.Windows.Forms.View]::$view
|
|
return $this
|
|
}
|
|
|
|
[ListViewBuilder] SetFullRowSelect([bool]$select) {
|
|
$this.control.FullRowSelect = $select
|
|
return $this
|
|
}
|
|
|
|
[ListViewBuilder] SetGridLines([bool]$gridLines) {
|
|
$this.control.GridLines = $gridLines
|
|
return $this
|
|
}
|
|
|
|
[ListViewBuilder] AddColumn([System.String]$text, [int]$width) {
|
|
$this.control.Columns.Add($text, $width) | Out-Null
|
|
return $this
|
|
}
|
|
|
|
[ListViewBuilder] AddDoubleClickHandler([scriptblock]$handler) {
|
|
$this.control.Add_DoubleClick($handler)
|
|
return $this
|
|
}
|
|
|
|
[System.Windows.Forms.ListView] Build() {
|
|
return $this.control
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
Add-Type -AssemblyName System.Windows.Forms
|
|
Add-Type -AssemblyName System.Drawing
|
|
|
|
$settingsManager = [SettingsManager]::new("DSC Tool")
|
|
|
|
# Verwendung
|
|
$logManager = [LogManager]::new("DSC Tool")
|
|
$logManager.Info("Anwendung gestartet")
|
|
|
|
[BaseComponent]::InitializeShared($settingsManager, $logManager)
|
|
|
|
foreach($function in $(Get-ChildItem -Path $settingsManager.Get("FunctionsPath") -Recurse -Filter "*.ps1" -File)){
|
|
$logManager.Info("Lade Funktion: $($function.FullName)")
|
|
try{
|
|
. $function.FullName
|
|
}catch{
|
|
$logManager.Error("Fehler beim Laden: $_")
|
|
}
|
|
}
|
|
|
|
$stateManager = [StateManager]::new()
|
|
$stateManager.SetStates(@{
|
|
hasSelection = $false
|
|
isMerged = $false
|
|
isResolved = $false
|
|
})
|
|
|
|
# Menü erstellen
|
|
$menuBuilder = (
|
|
[MenuBuilder]::new().
|
|
BuildFromStructure($settingsManager.GetMenuStructure()).
|
|
WithStateManager($stateManager)
|
|
)
|
|
|
|
$menuHandlers = @{
|
|
"Import" = @{
|
|
Handler = {
|
|
Import-ConfigurationData
|
|
$statusBar.SetText("Status", "Deployment importiert.")
|
|
}
|
|
Condition = {
|
|
-not $stateManager.GetState("isMerged")
|
|
}
|
|
}
|
|
"Export" = @{
|
|
Handler = {
|
|
Export-ConfigurationData
|
|
$statusBar.SetText("Status", "Deployment exportiert.")
|
|
}
|
|
Condition = {
|
|
$stateManager.GetState("isMerged") -eq $true
|
|
}
|
|
}
|
|
"Refresh" = @{
|
|
Handler = {
|
|
|
|
$statusBar.SetText("Status", "Wird aktualisiert...")
|
|
}
|
|
}
|
|
"Exit" = {
|
|
$form.Form.Close()
|
|
}
|
|
"OpenFolder" = @{
|
|
Handler = {
|
|
$result = [DialogBuilder]::SelectFolder().
|
|
SetDescription("Wählen Sie den Root-Ordner für Templates").
|
|
SetSelectedPath($settingsManager.Get("RootPath", "C:\")).
|
|
SetShowNewFolderButton($true).
|
|
SetUseDescriptionForTitle($true).
|
|
Show()
|
|
|
|
if ($result.Result) {
|
|
$settingsManager.Set("RootPath", $result.SelectedPath)
|
|
$statusBar.SetText("Status", "Ordner gesetzt: $($result.SelectedPath)")
|
|
#Load-Templates
|
|
}
|
|
}
|
|
}
|
|
"ResetMenu" = {
|
|
$result = [System.Windows.Forms.MessageBox]::Show(
|
|
"Möchten Sie das Menü auf die Standardeinstellungen zurücksetzen?`n`nDie Anwendung wird danach neu gestartet.",
|
|
"Menü zurücksetzen",
|
|
[System.Windows.Forms.MessageBoxButtons]::YesNo,
|
|
[System.Windows.Forms.MessageBoxIcon]::Question
|
|
)
|
|
|
|
if ($result -eq 'Yes') {
|
|
$settingsManager.ResetMenuStructure()
|
|
[System.Windows.Forms.MessageBox]::Show(
|
|
"Menü wurde zurückgesetzt. Bitte starten Sie die Anwendung neu.",
|
|
"Erfolg",
|
|
[System.Windows.Forms.MessageBoxButtons]::OK,
|
|
[System.Windows.Forms.MessageBoxIcon]::Information
|
|
)
|
|
$form.Form.Close()
|
|
}
|
|
}
|
|
"About" = {
|
|
[System.Windows.Forms.MessageBox]::Show(
|
|
"DSC Tool v1.0`n`nEin modernes Tool zur Verwaltung von DSC-Konfigurationen.`n`n© 2024",
|
|
"Über DSC Tool",
|
|
[System.Windows.Forms.MessageBoxButtons]::OK,
|
|
[System.Windows.Forms.MessageBoxIcon]::Information
|
|
)
|
|
}
|
|
}
|
|
|
|
# Handler setzen
|
|
$menuBuilder.SetClickHandlersWithConditions($menuHandlers)
|
|
|
|
# StatusBar erstellen
|
|
$statusBar = [StatusStripBuilder]::new()
|
|
|
|
# FlowLayoutPanel erstellen
|
|
$flow = (
|
|
[FlowLayoutPanelBuilder]::new().
|
|
SetPadding(6).
|
|
Build()
|
|
)
|
|
|
|
## Rechte Seite
|
|
# Rechtes Label
|
|
|
|
$tabControl = (
|
|
[TabControlBuilder]::new().
|
|
SetDock("Fill").
|
|
Build()
|
|
)
|
|
|
|
$buttonClear = (
|
|
[ButtonBuilder]::new().
|
|
SetFluentIcon([char]0xed62).
|
|
SetToolTip("Clear").
|
|
Build()
|
|
)
|
|
|
|
$tabControlButtonPanel = (
|
|
[FlowLayoutPanelBuilder]::new().
|
|
SetDock("Right").
|
|
SetPadding(6).
|
|
SetWidth(52).
|
|
SetFlowDirection("TopDown").
|
|
SetWrapContents($false).
|
|
AddControls(@($buttonClear)).
|
|
Build()
|
|
)
|
|
|
|
$tabPanel = (
|
|
[PanelBuilder]::new().
|
|
SetDock("Top").
|
|
SetHeight(200).
|
|
BindEnabled({
|
|
$stateManager.GetState("isResolved") -eq $true
|
|
}, $stateManager).
|
|
AddControls(@($tabControl,$tabControlButtonPanel)).
|
|
Build()
|
|
)
|
|
|
|
$rightLabel = (
|
|
[LabelBuilder]::new("Datei-Inhalt / Details").
|
|
SetDock('Top').
|
|
SetHeight(24).
|
|
SetFont("Segoe UI", 9, [System.Drawing.FontStyle]::Bold).
|
|
SetTextAlign([System.Drawing.ContentAlignment]::MiddleLeft).
|
|
SetPadding(5, 0, 0, 0).
|
|
Build()
|
|
)
|
|
|
|
# TreeView
|
|
$treeView = (
|
|
[TreeViewBuilder]::new().
|
|
SetFont("Consolas", 10).
|
|
AddNode("Keine Auswahl").
|
|
Build()
|
|
)
|
|
|
|
$buttonImport = (
|
|
[ButtonBuilder]::new().
|
|
SetFluentIcon([char]0xed25).
|
|
SetToolTip("Import - Datei laden").
|
|
BindEnabled({
|
|
-not $stateManager.GetState("isMerged")
|
|
}, $stateManager).
|
|
SetClickHandler({
|
|
Import-ConfigurationData
|
|
}).
|
|
Build()
|
|
)
|
|
|
|
$buttonMerge = (
|
|
[ButtonBuilder]::new().
|
|
SetFluentIcon([char]0xe9f5).
|
|
SetToolTip("Merge - Ausgewählte Dateien zusammenführen").
|
|
BindEnabled({
|
|
$selectionList.Items.Count -gt 0 -and $stateManager.GetState("isMerged") -eq $false
|
|
}, $stateManager).
|
|
SetClickHandler({
|
|
param($s, $e)
|
|
|
|
if($selectionList.Items.Count -gt 0){
|
|
Merge-Templates
|
|
$stateManager.SetState("isResolved",$true)
|
|
}else{
|
|
[System.Windows.Forms.MessageBox]::Show("Keine Einträge vorhanden","Info",[System.Windows.Forms.MessageBoxButtons]::OK,[System.Windows.Forms.MessageBoxIcon]::Information)
|
|
}
|
|
}).
|
|
Build()
|
|
)
|
|
|
|
$buttonClear = (
|
|
[ButtonBuilder]::new().
|
|
SetFluentIcon([char]0xed62).
|
|
SetToolTip("Clear - TreeView leeren").
|
|
BindEnabled({
|
|
$treeView.Nodes.Count -gt 0
|
|
}, $stateManager).
|
|
SetClickHandler({
|
|
$treeView.Nodes.Clear()
|
|
$treeView.Nodes.Add("Keine Auswahl") | Out-Null
|
|
$statusBar.SetText("Status", "TreeView geleert")
|
|
$stateManager.SetStates(@{
|
|
"isMerged" = $false
|
|
"isResolved" = $false
|
|
})
|
|
}).
|
|
Build()
|
|
)
|
|
|
|
$buttonExport = (
|
|
[ButtonBuilder]::new().
|
|
SetFluentIcon([char]0xe74e).
|
|
SetToolTip("Export - Als PSD1 speichern").
|
|
BindEnabled({
|
|
$stateManager.GetState("isResolved") -eq $true
|
|
}, $stateManager).
|
|
SetClickHandler({
|
|
Export-ConfigurationData
|
|
}).
|
|
Build()
|
|
)
|
|
|
|
$treeButtonPanel = (
|
|
[FlowLayoutPanelBuilder]::new().
|
|
SetDock("Right").
|
|
SetPadding(6).
|
|
SetWidth(52).
|
|
SetFlowDirection("TopDown").
|
|
SetWrapContents($false).
|
|
AddControls(@($buttonImport, $buttonMerge, $buttonClear, $buttonExport)).
|
|
Build()
|
|
)
|
|
|
|
$treeViewPanel = (
|
|
[PanelBuilder]::new().
|
|
SetDock("Fill").
|
|
AddControls(@($treeView,$treeButtonPanel)).
|
|
Build()
|
|
)
|
|
|
|
$selectionLabel = (
|
|
[LabelBuilder]::new("Ausgewählte Dateien").
|
|
SetHeight(20).
|
|
SetDock("Bottom").
|
|
Build()
|
|
)
|
|
|
|
$selectionList = (
|
|
[ListBoxBuilder]::new().
|
|
SetFont("Segoe UI", 9).
|
|
SetDock('Fill'). # Füllt die GroupBox aus
|
|
SetHeight(120).
|
|
Build()
|
|
)
|
|
|
|
$buttonMoveUp = (
|
|
[ButtonBuilder]::new().
|
|
SetFluentIcon([char]0xe74a).
|
|
SetToolTip("Element nach oben verschieben").
|
|
BindEnabled({
|
|
$selectionList.Items.Count -gt 1
|
|
}, $stateManager).
|
|
SetClickHandler({
|
|
$SelectedIndex = $selectionList.SelectedIndex
|
|
if ($SelectedIndex -gt 0) {
|
|
$item = $selectionList.Items[$SelectedIndex]
|
|
$selectionList.Items.RemoveAt($SelectedIndex)
|
|
$selectionList.Items.Insert($SelectedIndex-1, $item)
|
|
$selectionList.SelectedIndex = $SelectedIndex-1
|
|
$stateManager.SetState("isMerged",$false)
|
|
}
|
|
}).
|
|
Build()
|
|
)
|
|
|
|
$buttonRemoveSelection = (
|
|
[ButtonBuilder]::new().
|
|
SetFluentIcon([char]0xe894).
|
|
SetToolTip("Element löschen").
|
|
BindEnabled({
|
|
$selectionList.Items.Count -gt 0
|
|
}, $stateManager).
|
|
SetClickHandler({
|
|
$SelectedIndex = $selectionList.SelectedIndex
|
|
if ($SelectedIndex -ge 0) {
|
|
$removed = $selectionList.Items[$SelectedIndex]
|
|
$resp = [System.Windows.Forms.MessageBox]::Show("Eintrag wirklich löschen?`r`n$($removed.FullName)","Bestätigen",[System.Windows.Forms.MessageBoxButtons]::YesNo,[System.Windows.Forms.MessageBoxIcon]::Question)
|
|
if ($resp -eq [System.Windows.Forms.DialogResult]::Yes) {
|
|
$selectionList.Items.RemoveAt($SelectedIndex)
|
|
$stateManager.SetState("hasSelection", $selectionList.Items.Count -gt 0)
|
|
$stateManager.UpdateAllButtons()
|
|
$statusBar.SetText("Status","Eintrag entfernt: $($removed.FullName)")
|
|
if ($selectionList.Items.Count -eq 0) {
|
|
Update-TreeView
|
|
} else {
|
|
Merge-Templates
|
|
}
|
|
}
|
|
} else {
|
|
[System.Windows.Forms.MessageBox]::Show("Kein Eintrag ausgewählt","Info",[System.Windows.Forms.MessageBoxButtons]::OK,[System.Windows.Forms.MessageBoxIcon]::Information)
|
|
}
|
|
}).
|
|
Build()
|
|
)
|
|
|
|
$buttonClearSelection = (
|
|
[ButtonBuilder]::new().
|
|
SetFluentIcon([char]0xe74d).
|
|
SetToolTip("Element löschen").
|
|
BindEnabled({
|
|
$selectionList.Items.Count -gt 0
|
|
}, $stateManager).
|
|
SetClickHandler({
|
|
if ($SelectedIndex -ge 0) {
|
|
$selectionList.Items.Clear()
|
|
} else {
|
|
[System.Windows.Forms.MessageBox]::Show("Kein Eintrag vorhanden","Info",[System.Windows.Forms.MessageBoxButtons]::OK,[System.Windows.Forms.MessageBoxIcon]::Information)
|
|
}
|
|
Update-TreeView
|
|
}).
|
|
Build()
|
|
)
|
|
|
|
$buttonMoveDown = (
|
|
[ButtonBuilder]::new().
|
|
SetFluentIcon([char]0xe74b).
|
|
SetToolTip("Element nach unten verschieben").
|
|
BindEnabled({
|
|
$selectionList.Items.Count -gt 1
|
|
}, $stateManager).
|
|
SetClickHandler({
|
|
$SelectedIndex = $selectionList.SelectedIndex
|
|
if ($SelectedIndex -ge 0 -and $SelectedIndex -lt ($selectionList.Items.Count - 1)) {
|
|
$item = $selectionList.Items[$SelectedIndex]
|
|
$selectionList.Items.RemoveAt($SelectedIndex)
|
|
$selectionList.Items.Insert($SelectedIndex+1, $item)
|
|
$selectionList.SelectedIndex = $SelectedIndex+1
|
|
$stateManager.SetState("isMerged",$false)
|
|
}
|
|
}).
|
|
Build()
|
|
)
|
|
|
|
$selectionButtonPanel = (
|
|
[FlowLayoutPanelBuilder]::new().
|
|
SetDock("Right").
|
|
SetPadding(6).
|
|
SetWidth(48).
|
|
SetFlowDirection("TopDown").
|
|
SetWrapContents($false).
|
|
AddControls(@($buttonMoveUp,$buttonRemoveSelection,$buttonClearSelection,$buttonMoveDown)).
|
|
Build()
|
|
)
|
|
|
|
$selectionBottomPanel = (
|
|
[PanelBuilder]::new().
|
|
SetDock('Bottom').
|
|
SetHeight(200).
|
|
AddControls(@($selectionList,$selectionButtonPanel)).
|
|
Build()
|
|
)
|
|
|
|
# SplitPanel erstellen
|
|
$splitPanel = (
|
|
[SplitPanelBuilder]::new('Vertical', 0.30, 100, 150).
|
|
AddToPanel1($flow).
|
|
ClearPanel2().
|
|
AddToPanel2($treeViewPanel).
|
|
AddToPanel2($rightLabel).
|
|
AddToPanel2($selectionLabel).
|
|
AddToPanel2($selectionBottomPanel).
|
|
AddToPanel2($tabPanel)
|
|
)
|
|
|
|
# Form erstellen
|
|
$form = (
|
|
[FormBuilder]::new("Test").
|
|
SetSize(
|
|
$settingsManager.Get("WindowWidth", 1024),
|
|
$settingsManager.Get("WindowHeight", 768)
|
|
).
|
|
AddMenu($menuBuilder).
|
|
AddStatusBar($statusBar).
|
|
AddSplitPanel($splitPanel).
|
|
AddKeyDownHandler({
|
|
param($s, $e)
|
|
|
|
# Ctrl+S für Export
|
|
if ($e.Control -and $e.KeyCode -eq 'S') {
|
|
if ($stateManager.GetState("isMerged")) {
|
|
Export-ConfigurationData
|
|
}
|
|
$e.Handled = $true
|
|
}
|
|
|
|
# Ctrl+O für Import
|
|
if ($e.Control -and $e.KeyCode -eq 'O') {
|
|
$buttonImport.PerformClick()
|
|
$e.Handled = $true
|
|
}
|
|
|
|
# F5 für Refresh
|
|
if ($e.KeyCode -eq 'F5') {
|
|
Load-Templates
|
|
$e.Handled = $true
|
|
}
|
|
|
|
# Ctrl+M für Merge
|
|
if ($e.Control -and $e.KeyCode -eq 'M') {
|
|
if ($selectionList.Items.Count -gt 0) {
|
|
Merge-Templates
|
|
}
|
|
$e.Handled = $true
|
|
}
|
|
}).
|
|
AddLoadHandler({
|
|
# Beim Laden der Form
|
|
$rootPath = $settingsManager.Get("RootPath")
|
|
if ($rootPath -and (Test-Path $rootPath)) {
|
|
$statusBar.AddLabel("Status", "Lade gespeicherten Pfad: $rootPath")
|
|
}
|
|
|
|
Load-Templates
|
|
|
|
# Registriere Layout-Container für automatisches Resize
|
|
[BaseComponent]::AccessibilityManager.RegisterLayoutContainer($flow)
|
|
|
|
# Registriere alle Controls für Accessibility
|
|
$form.RegisterAllAccessibleControls() | Out-Null
|
|
}).
|
|
AddFormClosedHandler({
|
|
# Settings speichern
|
|
$settingsManager.Set("WindowWidth", $form.Form.Width)
|
|
$settingsManager.Set("WindowHeight", $form.Form.Height)
|
|
$settingsManager.Set("SplitterDistance", $splitPanel.SplitContainer.SplitterDistance)
|
|
|
|
# Ressourcen freigeben
|
|
$treeView.Dispose()
|
|
$selectionList.Dispose()
|
|
$flow.Dispose()
|
|
}).
|
|
AddShownHandler({
|
|
# ZUERST: SplitPanel initialisieren
|
|
$splitPanel.InitializeAfterShown($form.Form)
|
|
|
|
# DANN: Padding setzen
|
|
$splitPanel.SetPanelPaddingWithMenu(1, $menuBuilder.GetMenuStrip(), 6, 6, 6)
|
|
$splitPanel.SetPanelPaddingWithMenu(2, $menuBuilder.GetMenuStrip(), 6, 6, $($statusBar.GetStatusStrip().Height + 6))
|
|
|
|
foreach($Groupbox in $flow.Controls){
|
|
# GroupBox-Breite anpassen
|
|
$Groupbox.Width = $flow.ClientSize.Width - 20
|
|
}
|
|
|
|
$splitPanel.AutoSizeSplitterToPanel1Content()
|
|
|
|
# Focus setzen
|
|
$treeView.Focus()
|
|
|
|
# StatusBar Update
|
|
$statusBar.SetText("Status", "Initialisierung abgeschlossen")
|
|
})
|
|
)
|
|
|
|
# Initial alle Button-States aktualisieren
|
|
$stateManager.UpdateAllButtons()
|
|
|
|
$form.Show()
|