|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * |
|
5 * Redistribution and use in source and binary forms, with or without |
|
6 * modification, are permitted provided that the following conditions are met: |
|
7 * |
|
8 * - Redistributions of source code must retain the above copyright notice, |
|
9 * this list of conditions and the following disclaimer. |
|
10 * - Redistributions in binary form must reproduce the above copyright notice, |
|
11 * this list of conditions and the following disclaimer in the documentation |
|
12 * and/or other materials provided with the distribution. |
|
13 * - Neither the name of Nokia Corporation nor the names of its contributors |
|
14 * may be used to endorse or promote products derived from this software |
|
15 * without specific prior written permission. |
|
16 * |
|
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 * POSSIBILITY OF SUCH DAMAGE. |
|
28 * |
|
29 * Initial Contributors: |
|
30 * Nokia Corporation - initial contribution. |
|
31 * |
|
32 * Contributors: |
|
33 * |
|
34 * Description: |
|
35 * |
|
36 */ |
|
37 |
|
38 using System; |
|
39 using System.Collections; |
|
40 using System.ComponentModel; |
|
41 using System.Drawing; |
|
42 using System.Data; |
|
43 using System.Windows.Forms; |
|
44 using System.Text; |
|
45 using SymbianStructuresLib.Debug.Symbols; |
|
46 using HeapLib; |
|
47 using HeapLib.Cells; |
|
48 using HeapLib.Array; |
|
49 using HeapLib.Relationships; |
|
50 using HeapLib.Statistics; |
|
51 |
|
52 namespace HeapUiLib.Controls |
|
53 { |
|
54 public partial class HeapCellRelationshipControl : UserControl |
|
55 { |
|
56 #region Enumerations |
|
57 public enum TListMode |
|
58 { |
|
59 EListModeEmbeddedReferences = 0, |
|
60 EListModeReferencedBy |
|
61 } |
|
62 #endregion |
|
63 |
|
64 #region Constructors & destructor |
|
65 public HeapCellRelationshipControl() |
|
66 { |
|
67 InitializeComponent(); |
|
68 } |
|
69 #endregion |
|
70 |
|
71 #region API |
|
72 public void SetFilter( TFilterType aType ) |
|
73 { |
|
74 SetFilter( aType, null ); |
|
75 } |
|
76 |
|
77 public void SetFilter( TFilterType aType, Symbol aSymbol ) |
|
78 { |
|
79 iFilterType = aType; |
|
80 iFilterSymbol = aSymbol; |
|
81 iCellFilter.FilterType = aType; |
|
82 // |
|
83 UpdateListView(); |
|
84 } |
|
85 |
|
86 public void CopySelectedDataToClipboard() |
|
87 { |
|
88 StringBuilder clipboardText = new StringBuilder(); |
|
89 |
|
90 // Get columns |
|
91 foreach ( XPTable.Models.Column column in iTable.ColumnModel.Columns ) |
|
92 { |
|
93 clipboardText.Append( column.Text + "\t" ); |
|
94 } |
|
95 clipboardText.Append( System.Environment.NewLine ); |
|
96 |
|
97 // Do underline (there must be a better way!) |
|
98 int len = clipboardText.Length; |
|
99 for ( int i = 0; i < len; i++ ) |
|
100 { |
|
101 clipboardText.Append( "=" ); |
|
102 } |
|
103 clipboardText.Append( System.Environment.NewLine ); |
|
104 |
|
105 // Get cell values |
|
106 foreach ( XPTable.Models.Row row in iTable.SelectedItems ) |
|
107 { |
|
108 foreach ( XPTable.Models.Cell cell in row.Cells ) |
|
109 { |
|
110 string text = cell.Text; |
|
111 clipboardText.Append( text + "\t" ); |
|
112 } |
|
113 // |
|
114 clipboardText.Append( System.Environment.NewLine ); |
|
115 } |
|
116 // |
|
117 Clipboard.SetDataObject( clipboardText.ToString(), true ); |
|
118 } |
|
119 #endregion |
|
120 |
|
121 #region Properties |
|
122 [Browsable( false )] |
|
123 public HeapStatistics Statistics |
|
124 { |
|
125 get { return iCellFilter.Statistics; } |
|
126 set { iCellFilter.Statistics = value; } |
|
127 } |
|
128 |
|
129 [Browsable( false )] |
|
130 public HeapCell SelectedCell |
|
131 { |
|
132 get |
|
133 { |
|
134 HeapCell cell = null; |
|
135 // |
|
136 if ( iTable.SelectedItems.Length > 0 ) |
|
137 { |
|
138 int index = iTable.SelectedIndicies[ 0 ]; |
|
139 cell = iTable.TableModel.Rows[ index ].Tag as HeapCell; |
|
140 } |
|
141 // |
|
142 return cell; |
|
143 } |
|
144 set |
|
145 { |
|
146 foreach ( XPTable.Models.Row row in iTable.TableModel.Rows ) |
|
147 { |
|
148 HeapCell cell = (HeapCell) row.Tag; |
|
149 // |
|
150 if ( cell.Address == value.Address ) |
|
151 { |
|
152 iTable.Select(); |
|
153 iTable.Focus(); |
|
154 iTable.TableModel.Selections.Clear(); |
|
155 iTable.TableModel.Selections.AddCell( row.Index, 0 ); |
|
156 iTable.EnsureVisible( row.Index, 0 ); |
|
157 break; |
|
158 } |
|
159 } |
|
160 } |
|
161 } |
|
162 |
|
163 [Browsable( false )] |
|
164 public HeapCellArray Cells |
|
165 { |
|
166 get { return iCells; } |
|
167 set |
|
168 { |
|
169 iCells = value; |
|
170 UpdateListView(); |
|
171 } |
|
172 } |
|
173 |
|
174 public TListMode ListMode |
|
175 { |
|
176 get |
|
177 { |
|
178 TListMode ret = TListMode.EListModeReferencedBy; |
|
179 // |
|
180 if ( iRB_EmbeddedReferencesTo.Checked ) |
|
181 { |
|
182 ret = TListMode.EListModeEmbeddedReferences; |
|
183 } |
|
184 // |
|
185 return ret; |
|
186 } |
|
187 set |
|
188 { |
|
189 if ( value == TListMode.EListModeEmbeddedReferences ) |
|
190 { |
|
191 iRB_EmbeddedReferencesTo.Checked = true; |
|
192 } |
|
193 else |
|
194 { |
|
195 iRB_ReferencedBy.Checked = true; |
|
196 } |
|
197 } |
|
198 } |
|
199 #endregion |
|
200 |
|
201 #region Event handlers |
|
202 private void iTable_DoubleClick( object sender, EventArgs e ) |
|
203 { |
|
204 OnDoubleClick( e ); |
|
205 } |
|
206 |
|
207 private void iTable_PrepareForSort( object sender, XPTable.Events.SortEventArgs e ) |
|
208 { |
|
209 if ( e.Column == iCol_Length ) |
|
210 { |
|
211 e.Comparer = new XPTable.Sorting.NumberComparer( iTable.TableModel, e.Index, e.Column.SortOrder ); |
|
212 } |
|
213 else if ( e.Column == iCol_ReferencedBy ) |
|
214 { |
|
215 e.Comparer = new XPTable.Sorting.NumberComparer( iTable.TableModel, e.Index, e.Column.SortOrder ); |
|
216 } |
|
217 else if ( e.Column == iCol_EmbeddedReferencesTo ) |
|
218 { |
|
219 e.Comparer = new XPTable.Sorting.NumberComparer( iTable.TableModel, e.Index, e.Column.SortOrder ); |
|
220 } |
|
221 else |
|
222 { |
|
223 e.Comparer = new XPTable.Sorting.TextComparer( iTable.TableModel, e.Index, e.Column.SortOrder ); |
|
224 } |
|
225 } |
|
226 |
|
227 private void iTable_SelectionChanged( object sender, XPTable.Events.SelectionEventArgs e ) |
|
228 { |
|
229 if ( e.NewSelectedIndicies.Length > 0 ) |
|
230 { |
|
231 int rowIndex = e.NewSelectedIndicies[ 0 ]; |
|
232 XPTable.Models.Row row = e.TableModel.Rows[ rowIndex ]; |
|
233 HeapCell cell = (HeapCell) row.Tag; |
|
234 UpdateReferenceInfoList( cell ); |
|
235 } |
|
236 } |
|
237 |
|
238 private void iCellFilter_FilterChanged( TFilterType aFilter, Symbol aSymbolOrNull ) |
|
239 { |
|
240 SetFilter( aFilter, aSymbolOrNull ); |
|
241 } |
|
242 |
|
243 private void iRB_Type_CheckedChanged( object sender, EventArgs e ) |
|
244 { |
|
245 if ( iTable.SelectedItems.Length > 0 ) |
|
246 { |
|
247 HeapCell cell = (HeapCell) iTable.SelectedItems[ 0 ].Tag; |
|
248 UpdateReferenceInfoList( cell ); |
|
249 } |
|
250 } |
|
251 #endregion |
|
252 |
|
253 #region Internal methods |
|
254 private void UpdateListView() |
|
255 { |
|
256 iTable.BeginUpdate(); |
|
257 iTable.TableModel.Rows.Clear(); |
|
258 // |
|
259 foreach ( HeapCell cell in Cells ) |
|
260 { |
|
261 // Check whether the filter permits this item to be included. |
|
262 if ( CheckAgainstFilter( cell ) ) |
|
263 { |
|
264 RelationshipManager relManager = cell.RelationshipManager; |
|
265 |
|
266 XPTable.Models.Row row = new XPTable.Models.Row(); |
|
267 row.Tag = cell; |
|
268 // |
|
269 XPTable.Models.Cell cellType = new XPTable.Models.Cell( " " + cell.TypeString ); |
|
270 if ( cell.Type == HeapCell.TType.EAllocated ) |
|
271 { |
|
272 if ( cell.IsDescriptor ) |
|
273 { |
|
274 cellType.ForeColor = Color.DarkGoldenrod; |
|
275 cellType.ToolTipText = "Descriptor"; |
|
276 } |
|
277 else |
|
278 { |
|
279 cellType.ForeColor = Color.Red; |
|
280 } |
|
281 } |
|
282 else if ( cell.Type == HeapCell.TType.EFree ) |
|
283 { |
|
284 cellType.ForeColor = Color.Blue; |
|
285 } |
|
286 row.Cells.Add( cellType ); |
|
287 row.Cells.Add( new XPTable.Models.Cell( "0x" + cell.Address.ToString( "x8" ) ) ); |
|
288 |
|
289 // Must initialise "data" in order for sorting to work (XPTable's numeric sorter relies upon it). |
|
290 XPTable.Models.Cell cellLength = new XPTable.Models.Cell( cell.Length.ToString() ); |
|
291 cellLength.Data = cell.Length; |
|
292 row.Cells.Add( cellLength ); |
|
293 |
|
294 // Reference by |
|
295 XPTable.Models.Cell cellRefBy = new XPTable.Models.Cell( relManager.ReferencedBy.Count.ToString() ); |
|
296 cellRefBy.Data = relManager.ReferencedBy.Count; |
|
297 row.Cells.Add( cellRefBy ); |
|
298 |
|
299 // Embedded references to |
|
300 XPTable.Models.Cell cellEmbeddedRefsTo = new XPTable.Models.Cell( relManager.EmbeddedReferencesTo.Count.ToString() ); |
|
301 cellEmbeddedRefsTo.Data = relManager.EmbeddedReferencesTo.Count; |
|
302 row.Cells.Add( cellEmbeddedRefsTo ); |
|
303 |
|
304 // Payload column |
|
305 if ( cell.IsDescriptor ) |
|
306 { |
|
307 row.Cells.Add( new XPTable.Models.Cell( cell.DescriptorText ) ); |
|
308 } |
|
309 else if ( cell.Symbol != null ) |
|
310 { |
|
311 row.Cells.Add( new XPTable.Models.Cell( cell.SymbolString ) ); |
|
312 } |
|
313 else |
|
314 { |
|
315 row.Cells.Add( new XPTable.Models.Cell( cell.RawItems.FirstLine ) ); |
|
316 } |
|
317 // |
|
318 iTable.TableModel.Rows.Add( row ); |
|
319 } |
|
320 } |
|
321 |
|
322 // Must sort if the user had previously selected a sort column |
|
323 if ( iTable.IsValidColumn( iTable.SortingColumn ) ) |
|
324 { |
|
325 iTable.Sort(); |
|
326 } |
|
327 |
|
328 // Done - end transaction & redraw |
|
329 iTable.EndUpdate(); |
|
330 } |
|
331 |
|
332 private void UpdateReferenceInfoList( HeapCell aCell ) |
|
333 { |
|
334 RelationshipManager relManager = aCell.RelationshipManager; |
|
335 // |
|
336 if ( aCell.Symbol != null ) |
|
337 { |
|
338 iGP_AssociatedWith.Text = "[0x" + aCell.Address + "] " + aCell.SymbolString; |
|
339 } |
|
340 else |
|
341 { |
|
342 iGP_AssociatedWith.Text = "[0x" + aCell.Address + "]"; |
|
343 } |
|
344 |
|
345 // |
|
346 if ( iRB_EmbeddedReferencesTo.Checked ) |
|
347 { |
|
348 HeapCellArray array = new HeapCellArray(); |
|
349 foreach ( RelationshipInfo info in relManager.EmbeddedReferencesTo ) |
|
350 { |
|
351 array.Add( info.ToCell ); |
|
352 } |
|
353 // |
|
354 iAssociatedWith.Cells = array; |
|
355 } |
|
356 else |
|
357 { |
|
358 HeapCellArray array = new HeapCellArray(); |
|
359 foreach ( HeapCell refCell in relManager.ReferencedBy ) |
|
360 { |
|
361 array.Add( refCell ); |
|
362 } |
|
363 // |
|
364 iAssociatedWith.Cells = array; |
|
365 } |
|
366 } |
|
367 |
|
368 private bool CheckAgainstFilter( HeapCell aCell ) |
|
369 { |
|
370 bool ret = false; |
|
371 // |
|
372 if ( iFilterType == TFilterType.EFilterShowAll ) |
|
373 { |
|
374 ret = true; |
|
375 } |
|
376 else if ( iFilterType == TFilterType.EFilterShowCellsFree && aCell.Type == HeapCell.TType.EFree ) |
|
377 { |
|
378 ret = true; |
|
379 } |
|
380 else if ( iFilterType == TFilterType.EFilterShowCellsAllocated && aCell.Type == HeapCell.TType.EAllocated ) |
|
381 { |
|
382 ret = true; |
|
383 } |
|
384 else if ( iFilterType == TFilterType.EFilterShowCellsAllocatedDescriptor && aCell.Type == HeapCell.TType.EAllocated && aCell.IsDescriptor ) |
|
385 { |
|
386 ret = true; |
|
387 } |
|
388 else if ( iFilterType == TFilterType.EFilterShowCellsAllocatedByType && aCell.Type == HeapCell.TType.EAllocated ) |
|
389 { |
|
390 bool noSymbol = ( iFilterSymbol == null || iFilterSymbol.Address == 0 ); |
|
391 bool descriptor = aCell.IsDescriptor; |
|
392 // |
|
393 if ( !descriptor ) |
|
394 { |
|
395 if ( noSymbol && aCell.Symbol == null ) |
|
396 { |
|
397 ret = true; |
|
398 } |
|
399 else if ( iFilterSymbol != null && aCell.Symbol != null ) |
|
400 { |
|
401 ret = ( aCell.Symbol.Address == iFilterSymbol.Address ); |
|
402 } |
|
403 } |
|
404 } |
|
405 // |
|
406 return ret; |
|
407 } |
|
408 #endregion |
|
409 |
|
410 #region Data members |
|
411 private TFilterType iFilterType = TFilterType.EFilterShowAll; |
|
412 private Symbol iFilterSymbol = null; |
|
413 private HeapCellArray iCells = new HeapCellArray(); |
|
414 #endregion |
|
415 } |
|
416 } |