forked from chuongmep/CadPythonShell
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathObjectDiff.cs
More file actions
502 lines (441 loc) · 16.7 KB
/
ObjectDiff.cs
File metadata and controls
502 lines (441 loc) · 16.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
// (C) Copyright 2004 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using MgdDbg.CompBuilder;
using MgdDbg.Utils;
using System;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using AcadApp = Autodesk.AutoCAD.ApplicationServices;
namespace MgdDbg.ObjTests.Forms
{
public partial class ObjectDiff : Form
{
private Database m_db = null;
private TransactionHelper m_trHlpr = null;
private Object m_tmpObj = null;
private Object m_obj1 = null;
private Object m_obj2 = null;
private ObjectCompare m_compareObjs;
public ObjectDiff(TransactionHelper trHlpr)
{
InitializeComponent();
m_db = MgdDbg.Utils.Db.GetCurDwg();
m_trHlpr = trHlpr;
InitializeTreeView();
}
/// <summary>
/// Initialise tree with all symbol tables and NOD
/// </summary>
private void InitializeTreeView()
{
m_treeView.BeginUpdate();
AddSymbolTableToTree("Block Table", m_db.BlockTableId);
AddSymbolTableToTree("Dimension Style Table", m_db.DimStyleTableId);
AddSymbolTableToTree("Layer Table", m_db.LayerTableId);
AddSymbolTableToTree("Linetype Table", m_db.LinetypeTableId);
AddSymbolTableToTree("Reg App Table", m_db.RegAppTableId);
AddSymbolTableToTree("Text Style Table", m_db.TextStyleTableId);
AddSymbolTableToTree("View Table", m_db.ViewTableId);
AddSymbolTableToTree("Viewport Table", m_db.ViewportTableId);
AddSymbolTableToTree("UCS Table", m_db.UcsTableId);
TreeNode rootNode = new TreeNode("Named Objects Dictionary");
rootNode.Tag = m_db.NamedObjectsDictionaryId;
m_treeView.Nodes.Add(rootNode);
AddDictionaryToTree(m_db.NamedObjectsDictionaryId, rootNode, m_trHlpr.Transaction);
m_treeView.Sorted = true;
m_treeView.EndUpdate();
}
/// <summary>
/// Add a single Symbol Table to the tree and iterate over all its SymbolTableRecords,
/// adding each one of them as a sub-node
/// </summary>
/// <param name="tblName">Name of the table</param>
/// <param name="tblId">ObjectId of the table</param>
private void
AddSymbolTableToTree(string tblName, ObjectId tblId)
{
DBObject tmpObj = m_trHlpr.Transaction.GetObject(tblId, OpenMode.ForRead);
SymbolTable tbl = tmpObj as SymbolTable;
if (tbl != null)
{
TreeNode mainTblNode = new TreeNode(tblName);
mainTblNode.Tag = tblId;
m_treeView.Nodes.Add(mainTblNode);
// iterate over each TblRec in the SymbolTable
foreach (ObjectId tblRecId in tbl)
{
TreeNode recNode = new TreeNode(m_trHlpr.SymbolIdToName(tblRecId));
recNode.Tag = tblRecId;
mainTblNode.Nodes.Add(recNode);
}
}
}
private void
AddDictionaryToTree(ObjectId dictId, TreeNode parentNode, Transaction tr)
{
// NOTE: when recursively processing items in a dictionary
// we may encounter things that are not derived from DBDictionary.
// In that case, the cast to type DBDictionary will fail and
// we'll just return without adding any nested items.
DBObject tmpObj = tr.GetObject(dictId, OpenMode.ForRead);
DBDictionary dbDict = tmpObj as DBDictionary;
if (dbDict != null)
{
foreach (DictionaryEntry curEntry in dbDict)
{
TreeNode newNode = new TreeNode((string)curEntry.Key);
newNode.Tag = curEntry.Value;
parentNode.Nodes.Add(newNode);
// if this is a dictionary, it will recursively add
// all of its children to the tree
AddDictionaryToTree((ObjectId)curEntry.Value, newNode, tr);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void
m_treeView_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Node.Tag != null)
{
m_tmpObj = m_trHlpr.Transaction.GetObject((ObjectId)e.Node.Tag, OpenMode.ForRead);
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void
addAsComparerToolStripMenuItem_Click(object sender, EventArgs e)
{
m_obj1 = m_tmpObj;
PopulateCompareBox(m_compareBx1, (ObjectId)m_treeView.SelectedNode.Tag, m_treeView.SelectedNode.Text);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void
addAsCompareeToolStripMenuItem_Click(object sender, EventArgs e)
{
m_obj2 = m_tmpObj;
PopulateCompareBox(m_compareBx2, (ObjectId)m_treeView.SelectedNode.Tag, m_treeView.SelectedNode.Text);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void
m_btmCompare_Click(object sender, EventArgs e)
{
if (m_obj1 == null || m_obj2 == null)
{
MessageBox.Show("Please choose two objects to compare");
return;
}
Compare();
}
/// <summary>
///
/// </summary>
private void
Compare()
{
m_compareObjs = new ObjectCompare(m_obj1, m_obj2);
PopulateListView();
}
/// <summary>
/// Get the common hierarchy of the 2 objects
/// and then get the properties at each level
/// </summary>
private void
PopulateListView()
{
m_listView.Items.Clear();
ArrayList hierarchy = m_compareObjs.CommonHierarchy;
foreach (Object typeObj in hierarchy)
{
Type type = typeObj as Type;
Hashtable propsTable = m_compareObjs.GetPropsAtLevel(type);
/// display it
DisplayDiff(type.Name, propsTable);
}
}
/// <summary>
/// Drill down
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void
DataItemSelected(object sender, System.EventArgs e)
{
Debug.Assert((m_listView.SelectedItems.Count > 1) == false);
if (m_listView.SelectedItems.Count != 0)
{
ListViewItem item = m_listView.SelectedItems[0];
if (item.SubItems.Count != 3)
return;
Object[] objs = new Object[2];
objs[0] = item.SubItems[1].Tag;
objs[1] = item.SubItems[2].Tag;
if (objs[0] == null || objs[1] == null)
return;
EntityDiff dbox = new EntityDiff(objs[0], objs[1]);
AcadApp.Application.ShowModalDialog(dbox);
}
}
/// <summary>
/// Display the diff between the properties
/// of the two objects
/// </summary>
/// <param name="listViewItem">class separator string</param>
/// <param name="propTable">
/// key --> property name
/// value --> an arraylist of 2 items, each item containing
/// the value of the current property for the respective object
/// </param>
public void
DisplayDiff(string listViewItem, Hashtable propTable)
{
if (propTable == null)
return;
m_listView.BeginUpdate();
System.Drawing.Font boldFont = new System.Drawing.Font(m_listView.Font, System.Drawing.FontStyle.Bold);
string text = string.Format("--- {0} ---", listViewItem);
ListViewItem lvItemSeparator = new ListViewItem(text);
/// show class separator
lvItemSeparator.BackColor = Color.LightBlue;
m_listView.Items.Add(lvItemSeparator);
IDictionaryEnumerator iDictEnum = propTable.GetEnumerator();
while (iDictEnum.MoveNext())
{
DictionaryEntry dictEntry = (DictionaryEntry)iDictEnum.Current;
string key = dictEntry.Key as string;
ArrayList arrList = dictEntry.Value as ArrayList;
object obj1 = arrList[0];
object obj2 = arrList[1];
ListViewItem lvItem = new ListViewItem(key);
ListViewItem.ListViewSubItem lvsItem1 = new ListViewItem.ListViewSubItem();
lvsItem1.Text = obj1.ToString();
ListViewItem.ListViewSubItem lvsItem2 = new ListViewItem.ListViewSubItem();
lvsItem2.Text = obj2.ToString();
lvItem.SubItems.Add(lvsItem1);
lvItem.SubItems.Add(lvsItem2);
Type type = null;
if (obj1.GetType() == typeof(System.DBNull))
{
type = obj2.GetType();
}
else
type = obj1.GetType();
/// provide a drill down only on worthwhile data
if (IsDrillDown(type))
{
lvsItem1.Tag = obj1;
lvsItem2.Tag = obj2;
/// visual cue to drill down
lvItem.Font = boldFont;
}
/// this may happen when there is a collection object comparison
if (obj1.GetType() != obj2.GetType())
{
/// we know this is diff., so highlight it
lvItem.BackColor = Color.Red;
}
else
{
/// regular occurence of unequal objects
if (!obj1.Equals(obj2))
{
/// we know this is diff., so highlight it
lvItem.BackColor = Color.Red;
}
}
m_listView.Items.Add(lvItem);
}
m_listView.EndUpdate();
}
/// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private Boolean
IsDrillDown(Type type)
{
if (type.IsPrimitive == false &&
type.IsEnum == false &&
type != typeof(String) &&
type != typeof(DBNull))
{
return true;
}
return false;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void
m_btnEntChoose_Click(object sender, EventArgs e)
{
Editor ed = AcadApp.Application.DocumentManager.MdiActiveDocument.Editor;
EditorUserInteraction userInteraction = ed.StartUserInteraction(this);
try
{
PromptEntityResult res = ed.GetEntity("\nSelect first entity");
if (res.Status != PromptStatus.OK)
return;
ObjectId objId1 = res.ObjectId;
res = ed.GetEntity("\nSelect second entity");
if (res.Status != PromptStatus.OK)
return;
ObjectId objId2 = res.ObjectId;
m_obj1 = m_trHlpr.Transaction.GetObject(objId1, OpenMode.ForRead);
m_obj2 = m_trHlpr.Transaction.GetObject(objId2, OpenMode.ForRead);
PopulateCompareBox(m_compareBx1, objId1, string.Empty);
PopulateCompareBox(m_compareBx2, objId2, string.Empty);
Compare();
}
/// dont leave editor paralysed if user cancels out
finally
{
userInteraction.End();
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void
m_treeView_ItemDrag(object sender, ItemDragEventArgs e)
{
DoDragDrop(e.Item, DragDropEffects.Move);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void
m_compareBx1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void
m_compareBx1_DragDrop(object sender, DragEventArgs e)
{
TreeNode treeNode = e.Data.GetData(typeof(TreeNode)) as TreeNode;
if (treeNode != null)
{
m_obj1 = m_trHlpr.Transaction.GetObject((ObjectId)treeNode.Tag, OpenMode.ForRead);
PopulateCompareBox(m_compareBx1, (ObjectId)treeNode.Tag, treeNode.Text);
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void
m_compareBx2_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void
m_compareBx2_DragDrop(object sender, DragEventArgs e)
{
TreeNode treeNode = e.Data.GetData(typeof(TreeNode)) as TreeNode;
if (treeNode != null)
{
m_obj2 = m_trHlpr.Transaction.GetObject((ObjectId)treeNode.Tag, OpenMode.ForRead);
PopulateCompareBox(m_compareBx2, (ObjectId)treeNode.Tag, treeNode.Text);
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void
m_treeView_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
TreeNode treeNode = m_treeView.GetNodeAt(e.Location);
if (treeNode.Tag != null)
{
m_treeView.SelectedNode = treeNode;
}
}
}
/// <summary>
///
/// </summary>
/// <param name="compareBox"></param>
/// <param name="objId"></param>
/// <param name="name"></param>
private void
PopulateCompareBox(object compareBox, ObjectId objId, string name)
{
DBObject tempObj = m_trHlpr.Transaction.GetObject(objId, OpenMode.ForRead);
String type = String.Format("Type : {0}", tempObj.GetType().Name);
String id = String.Format("ObjectId : {0}", objId.ToString());
if (compareBox == m_compareBx1)
{
m_compareBx1.Items.Clear();
m_compareBx1.Items.Add(name);
m_compareBx1.Items.Add(type);
m_compareBx1.Items.Add(id);
}
if (compareBox == m_compareBx2)
{
m_compareBx2.Items.Clear();
m_compareBx2.Items.Add(name);
m_compareBx2.Items.Add(type);
m_compareBx2.Items.Add(id);
}
}
}
}