TreeControl/SRxXmlTreeControl.ps1
|
class SRxXmlTreeControl : SRxTreeControl { [bool] $Verbose = $false hidden [System.Collections.Hashtable] $_byXPath = @{} SRxXmlTreeControl() : base() { $this.SetSideBorder( [SRxBorderSides]::Right, [System.Drawing.SystemColors]::ControlDark, [float]1.0 ) $this.Padding = [System.Windows.Forms.Padding]::new(0, 0, 1, 0) } [void] LoadFromXml($xmlElement, [string]$rootXPath, $xPathFn) { try { $this.ClearModel() $this._byXPath.Clear() if ($null -eq $xmlElement) { $this.SyncToUI(); return } $rootId = $this.reserveId($rootXPath) $this.AddNode($rootId, "", $this.headText($xmlElement, $true), ( $this.newTag($rootXPath, $xmlElement))) $this.addXmlChildren($xmlElement, $rootXPath, $rootId, $xPathFn) $this.SyncToUI() if ($this.Verbose) { Write-Host ("SRxXmlTreeControl - model built: {0} nodes" -f $this.Count()) } } catch { Write-Host "SRxXmlTreeControl.LoadFromXml - FAILED (model is PARTIAL): $($_.Exception.Message)" try { $this.SyncToUI() } catch { } } } hidden [void] addXmlChildren($xElement, [string]$parentXPath, [string]$parentId, $xPathFn) { foreach ($xEl in $xElement.ChildNodes) { if ($xEl.NodeType -ne [System.Xml.XmlNodeType]::Element) { continue } $xPth = "" if ($null -ne $xPathFn) { try { $xPth = [string](& $xPathFn $xEl $parentXPath) } catch { $xPth = "" } } if ([string]::IsNullOrEmpty($xPth)) { $xPth = ($parentXPath + "/" + [string]$xEl.LocalName) } $hasKids = $false try { $hasKids = [bool]$xEl.HasChildNodes } catch { $hasKids = $false } $id = $this.reserveId($xPth) $this.AddNode($id, $parentId, $this.headText($xEl, $hasKids), ($this.newTag($xPth, $xEl))) if ($hasKids) { $this.addXmlChildren($xEl, $xPth, $id, $xPathFn) } } } hidden [string] headText($xEl, [bool]$hasKids) { try { $outer = [string]$xEl.OuterXml if ($hasKids) { return ($outer.Split(">")[0] + ">") } return $outer } catch { return "" } } hidden [object] newTag([string]$xPth, $xEl) { $outer = "" try { $outer = [string]$xEl.OuterXml } catch { } return (New-Object PSObject -Property @{ xPath = $xPth Filter = @{} SavedFilter = @{} ActiveScopeChanges = @{} ActiveScopeFilter = @{} OuterXml = $outer DeprecatedOnScope_In = -1 }) } hidden [string] reserveId([string]$xPth) { $id = $xPth if ($this._byXPath.ContainsKey($xPth)) { $n = [int]$this._byXPath[$xPth] $n++ $this._byXPath[$xPth] = $n $id = ("{0}#{1}" -f $xPth, $n) } else { $this._byXPath[$xPth] = 0 } return $id } [string] GetXPath([string]$id) { $n = $this.GetNode($id) if ($null -eq $n -or $null -eq $n.Tag) { return "" } try { return [string]$n.Tag.xPath } catch { return "" } } [string] IdForXPath([string]$xPth) { if ($this.GetNode($xPth)) { return $xPth } foreach ($id in $this.AllIds()) { if ($this.GetXPath($id) -eq $xPth) { return $id } } return "" } [string[]] AllIds() { $out = New-Object System.Collections.ArrayList foreach ($rid in $this.RootIds()) { $this.collectIds($rid, $out) } return @($out) } hidden [void] collectIds([string]$id, $acc) { [void]$acc.Add($id) foreach ($c in $this.ChildIds($id)) { $this.collectIds($c, $acc) } } [object] SelectedTag() { $id = $this.SelectedId() if ([string]::IsNullOrEmpty($id)) { return $null } $n = $this.GetNode($id) if ($null -eq $n) { return $null } return $n.Tag } [object] FindUiNode([string]$id) { try { $found = $this.InnerTree().Nodes.Find($id, $true) if ($found.Count -gt 0) { return $found[0] } } catch { } return $null } [void] ApplyCustomizationOverlay([hashtable]$styleById) { try { $this.PushOverlay('customizations') $this.ClearOverlayStyles('customizations') if ($null -ne $styleById) { foreach ($id in $styleById.Keys) { $this.SetOverlayStyle('customizations', [string]$id, [hashtable]$styleById[$id]) } } $this.applyAppearance() } catch { Write-Host "ApplyCustomizationOverlay - $($_.Exception.Message)" } } [void] ClearCustomizationOverlay() { $this.PopOverlay('customizations') } [void] ExpandRoot() { try { $roots = $this.RootIds() if ($roots.Count -eq 0) { return } $ui = $this.FindUiNode([string]$roots[0]) if ($null -ne $ui -and -not $ui.IsExpanded) { $ui.Expand() } } catch { Write-Host "ExpandRoot - $($_.Exception.Message)" } } } |