Skip to content

Commit 7b63a45

Browse files
committed
Added Datamodel comparison mode
Added menu bar Worked around Designer bugs in TreeGridView Improved GUID display
1 parent 2cd21eb commit 7b63a45

12 files changed

+729
-100
lines changed

DmxPad/App.xaml

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<converter:EncodingDisplay x:Key="EncodingDisplay"/>
1818
<converter:AttributeGroupDisplay x:Key="AttributeDisplay"/>
1919
<converter:DatamodelPath x:Key="DatamodelPathConverter"/>
20+
<converter:ComparisonTreeVisibility x:Key="ComparisonTreeVisibility"/>
2021

2122
<l:InspectPaneTemplateSelector x:Key="InspectPaneTemplateSelector"/>
2223
<converter:ValueColumnTemplateSelector x:Key="ValueColumnTemplateSelector"/>
@@ -29,8 +30,7 @@
2930
</DataTemplate>
3031

3132
<DataTemplate DataType="{x:Type dm:Element}">
32-
<!--<Grid AllowDrop="True" Drop="ElementHeader_Drop" MouseDown="ElementHeader_MouseDown" MouseMove="ElementHeader_StartDrag" KeyDown="ElementHeader_KeyDown">-->
33-
<Grid VerticalAlignment="Center">
33+
<Grid VerticalAlignment="Center" ToolTip="{Binding ID}" Background="Transparent">
3434
<ContentControl Content="{Binding Converter={StaticResource AttributeIconConverter}}" IsTabStop="False" VerticalAlignment="Center" HorizontalAlignment="Left"/>
3535
<TextBlock Text="{Binding Name}" Margin="20,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" />
3636
</Grid>
@@ -43,14 +43,47 @@
4343
</Grid>
4444
</DataTemplate>
4545

46+
<DataTemplate DataType="{x:Type l:ComparisonDatamodel+Element}">
47+
<Grid VerticalAlignment="Center" Background="Transparent">
48+
<Grid.ToolTip>
49+
<StackPanel>
50+
<StackPanel.Resources>
51+
<Style TargetType="TextBlock">
52+
<Setter Property="Text">
53+
<Setter.Value>
54+
<MultiBinding StringFormat="{}{0}: {1}">
55+
<Binding Path="Owner.File.Name"/>
56+
<Binding Path="ID"/>
57+
</MultiBinding>
58+
</Setter.Value>
59+
</Setter>
60+
</Style>
61+
</StackPanel.Resources>
62+
63+
<TextBlock DataContext="{Binding Element_Left}" />
64+
<TextBlock DataContext="{Binding Element_Right}" />
65+
</StackPanel>
66+
</Grid.ToolTip>
67+
<ContentControl Content="{Binding Converter={StaticResource AttributeIconConverter}}" IsTabStop="False" VerticalAlignment="Center" HorizontalAlignment="Left"/>
68+
<TextBlock Text="{Binding Element_Left.Name}" Margin="20,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" />
69+
</Grid>
70+
</DataTemplate>
71+
72+
<DataTemplate DataType="{x:Type l:ComparisonDatamodel+Attribute}">
73+
<Grid VerticalAlignment="Center">
74+
<ContentControl Content="{Binding Converter={StaticResource AttributeIconConverter}}" IsTabStop="False" VerticalAlignment="Center" HorizontalAlignment="Left"/>
75+
<TextBlock Text="{Binding Name}" Margin="20,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" />
76+
</Grid>
77+
</DataTemplate>
78+
4679
<DataTemplate x:Key="Attr_Generic">
4780

4881
<TextBox Text="{Binding Path=Value}"/>
4982
</DataTemplate>
5083

5184
<DataTemplate x:Key="Attr_Element">
5285
<Grid VerticalAlignment="Top">
53-
<ContentPresenter Content="{Binding}"/>
86+
<ContentPresenter Content="{Binding Value}" ToolTip="{Binding ID}"/>
5487
<Button Content="Browse..." Command="{x:Static l:App.ChooseElement}" HorizontalAlignment="Right" VerticalAlignment="Center"/>
5588
</Grid>
5689
</DataTemplate>

DmxPad/App.xaml.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,6 @@ protected override void OnExit(ExitEventArgs e)
3131
public static RoutedCommand ChooseElement = new RoutedCommand();
3232
public static RoutedCommand CompareDatamodel = new RoutedCommand("CompareDatamodel", typeof(App),
3333
new InputGestureCollection(new KeyGesture[] { new KeyGesture(Key.D, ModifierKeys.Control) }));
34+
public static RoutedCommand ShowChangesOnly = new RoutedCommand("ShowChangesOnly", typeof(App));
3435
}
3536
}

DmxPad/ComparisonDatamodel.cs

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Collections.Specialized;
5+
using System.Linq;
6+
using System.Text;
7+
8+
using Datamodel;
9+
10+
namespace DmxPad
11+
{
12+
public class ComparisonDatamodel
13+
{
14+
#region Properties
15+
16+
public Datamodel.Datamodel Datamodel_Left
17+
{
18+
get { return _Datamodel_Left; }
19+
private set { _Datamodel_Left = value; }
20+
}
21+
Datamodel.Datamodel _Datamodel_Left;
22+
23+
public Datamodel.Datamodel Datamodel_Right
24+
{
25+
get { return _Datamodel_Right; }
26+
private set { _Datamodel_Right = value; }
27+
}
28+
Datamodel.Datamodel _Datamodel_Right;
29+
30+
public Dictionary<Guid, Element> ComparedElements { get { return _ComparedElements; } }
31+
Dictionary<Guid, Element> _ComparedElements = new Dictionary<Guid, Element>();
32+
33+
public Element Root
34+
{
35+
get { return _Root; }
36+
protected set { _Root = value; }
37+
}
38+
Element _Root;
39+
40+
#endregion
41+
42+
public ComparisonDatamodel(Datamodel.Datamodel dm_left, Datamodel.Datamodel dm_right)
43+
{
44+
Datamodel_Left = dm_left;
45+
Datamodel_Right = dm_right;
46+
Root = new ComparisonDatamodel.Element(this, Datamodel_Left.Root, Datamodel_Right.Root);
47+
}
48+
49+
public enum ComparisonState
50+
{
51+
Unchanged,
52+
ChildChanged,
53+
Changed,
54+
Added,
55+
Removed,
56+
}
57+
58+
public interface IComparisonItem
59+
{
60+
ComparisonState State { get; }
61+
}
62+
63+
public class Element : IComparisonItem, IEnumerable<Attribute>
64+
{
65+
#region Properties
66+
public ComparisonDatamodel Owner
67+
{
68+
get { return _Owner; }
69+
protected set { _Owner = value; }
70+
}
71+
ComparisonDatamodel _Owner;
72+
73+
public ComparisonState State
74+
{
75+
get
76+
{
77+
var state = _State;
78+
if (state == ComparisonState.Unchanged && this.Any(a => a.State != ComparisonState.Unchanged))
79+
state = ComparisonState.ChildChanged;
80+
return state;
81+
}
82+
protected set { _State = value; }
83+
}
84+
ComparisonState _State = ComparisonState.Unchanged;
85+
86+
public Datamodel.Element Element_Left
87+
{
88+
get { return _Element_Left; }
89+
protected set { _Element_Left = value; }
90+
}
91+
Datamodel.Element _Element_Left;
92+
93+
public Datamodel.Element Element_Right
94+
{
95+
get { return _Element_Right; }
96+
protected set { _Element_Right = value; }
97+
}
98+
Datamodel.Element _Element_Right;
99+
100+
OrderedDictionary Attributes = new OrderedDictionary();
101+
102+
public string ClassName
103+
{
104+
get { return Element_Right != null ? Element_Right.ClassName : Element_Left.ClassName; }
105+
}
106+
#endregion
107+
108+
public Element(ComparisonDatamodel owner, Datamodel.Element elem_left, Datamodel.Element elem_right)
109+
{
110+
Owner = owner;
111+
Element_Left = elem_left;
112+
Element_Right = elem_right;
113+
114+
if (Element_Left == null)
115+
State = ComparisonState.Added;
116+
else if (Element_Right == null)
117+
State = ComparisonState.Removed;
118+
else if (Element_Left.Name != Element_Right.Name ||
119+
Element_Left.ID != Element_Right.ID ||
120+
Element_Left.ClassName != Element_Right.ClassName ||
121+
Element_Left.Stub != Element_Right.Stub
122+
|| !Enumerable.SequenceEqual(Element_Left.Select(a => a.Name), Element_Right.Select(a => a.Name)))
123+
State = ComparisonState.Changed;
124+
125+
if (Element_Right != null)
126+
{
127+
Owner.ComparedElements[Element_Right.ID] = this;
128+
foreach (var attr_right in Element_Right.Where(a => Element_Left != null && !Element_Left.Contains(a.Name)))
129+
Attributes.Add(attr_right.Name, new Attribute(this, null, attr_right));
130+
}
131+
132+
if (Element_Left != null)
133+
{
134+
Owner.ComparedElements[Element_Left.ID] = this;
135+
foreach (var attr_left in Element_Left)
136+
{
137+
Datamodel.Attribute attr_right = null;
138+
try { attr_right = Element_Right.GetAttribute(attr_left.Name); }
139+
catch { }
140+
141+
Attributes.Add(attr_left.Name, new Attribute(this, attr_left, attr_right));
142+
}
143+
}
144+
}
145+
146+
public IEnumerator<Attribute> GetEnumerator()
147+
{
148+
foreach (var attr in Attributes)
149+
{
150+
var entry = (DictionaryEntry)attr;
151+
yield return (Attribute)entry.Value;
152+
}
153+
}
154+
155+
IEnumerator IEnumerable.GetEnumerator()
156+
{
157+
return (IEnumerator)GetEnumerator();
158+
}
159+
}
160+
161+
public class Attribute : IComparisonItem
162+
{
163+
#region Properties
164+
public Element Owner
165+
{
166+
get { return _Owner; }
167+
protected set { _Owner = value; }
168+
}
169+
Element _Owner;
170+
171+
public string Name
172+
{
173+
get { return _Name; }
174+
protected set { _Name = value; }
175+
}
176+
string _Name;
177+
178+
public ComparisonState State
179+
{
180+
get
181+
{
182+
var state = _State;
183+
if (state == ComparisonState.Unchanged)
184+
{
185+
var elem = Value_Combined as Element;
186+
if (elem != null)
187+
{
188+
if (elem.State != ComparisonState.Unchanged)
189+
state = ComparisonState.ChildChanged;
190+
}
191+
else
192+
{
193+
var array = Value_Combined as IList<Element>;
194+
if (array != null && array.Any(e => e.State != ComparisonState.Unchanged))
195+
state = ComparisonState.ChildChanged;
196+
}
197+
}
198+
return state;
199+
}
200+
protected set { _State = value; }
201+
}
202+
ComparisonState _State = ComparisonState.Unchanged;
203+
204+
public Datamodel.Attribute Attribute_Left
205+
{
206+
get { return _Attribute_Left; }
207+
set { _Attribute_Left = value; }
208+
}
209+
Datamodel.Attribute _Attribute_Left;
210+
211+
public Datamodel.Attribute Attribute_Right
212+
{
213+
get { return _Attribute_Right; }
214+
set { _Attribute_Right = value; }
215+
}
216+
Datamodel.Attribute _Attribute_Right;
217+
218+
public object Value_Combined
219+
{
220+
get { return _Value_Combined; }
221+
protected set { _Value_Combined = value; }
222+
}
223+
object _Value_Combined;
224+
225+
#endregion
226+
227+
public Attribute(Element owner, Datamodel.Attribute attr_left, Datamodel.Attribute attr_right)
228+
{
229+
Owner = owner;
230+
Attribute_Left = attr_left;
231+
Attribute_Right = attr_right;
232+
233+
var cdm = Owner.Owner;
234+
235+
Name = Attribute_Left != null ? Attribute_Left.Name : Attribute_Right.Name;
236+
237+
if (Attribute_Left == null)
238+
State = ComparisonState.Added;
239+
else if (Attribute_Right == null)
240+
State = ComparisonState.Removed;
241+
else
242+
{
243+
var t_left = Attribute_Left.Value == null ? null : Attribute_Left.Value.GetType();
244+
var t_right = Attribute_Right.Value == null ? null : Attribute_Right.Value.GetType();
245+
246+
if (t_left == t_right && t_left != null)
247+
{
248+
var inner = Datamodel.Datamodel.GetArrayInnerType(t_left);
249+
250+
if (inner != null)
251+
{
252+
var array_left = (IList)Attribute_Left.Value;
253+
var array_right = (IList)Attribute_Right.Value;
254+
if (array_left.Count != array_right.Count)
255+
State = ComparisonState.Changed;
256+
else
257+
{
258+
IEqualityComparer comparer = inner == typeof(Datamodel.Element) ? (IEqualityComparer)Datamodel.Element.IDComparer.Default : EqualityComparer<object>.Default;
259+
foreach (int i in Enumerable.Range(0, array_left.Count))
260+
{
261+
if (!comparer.Equals(array_left[i], array_right[i]))
262+
{
263+
State = ComparisonState.Changed;
264+
break;
265+
}
266+
}
267+
}
268+
}
269+
else if (t_left == typeof(Datamodel.Element) && !Datamodel.Element.IDComparer.Default.Equals((Datamodel.Element)Attribute_Left.Value, (Datamodel.Element)Attribute_Right.Value))
270+
{
271+
State = ComparisonState.Changed;
272+
}
273+
274+
if (t_left == typeof(Datamodel.Element))
275+
Value_Combined = new Element(cdm, (Datamodel.Element)Attribute_Left.Value, (Datamodel.Element)Attribute_Right.Value);
276+
277+
else if (inner == typeof(Datamodel.Element))
278+
Value_Combined = ((IList<Datamodel.Element>)Attribute_Left.Value)
279+
.Concat((IList<Datamodel.Element>)Attribute_Right.Value)
280+
.Distinct(Datamodel.Element.IDComparer.Default)
281+
.Select(e => new Element(cdm, cdm.Datamodel_Left.AllElements[e.ID], cdm.Datamodel_Right.AllElements[e.ID])).ToArray();
282+
else
283+
Value_Combined = Attribute_Right.Value;
284+
}
285+
else
286+
State = ComparisonState.Changed;
287+
}
288+
}
289+
}
290+
}
291+
}

0 commit comments

Comments
 (0)