~halega/+junk/sharpdevelop

« back to all changes in this revision

Viewing changes to src/AddIns/Analysis/Profiler/Frontend/Controls/CallTreeNodeViewModel.cs

  • Committer: sk
  • Date: 2011-09-10 05:17:57 UTC
  • Revision ID: halega@halega.com-20110910051757-qfouz1llya9m6boy
4.1.0.7915 Release Candidate 1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
 
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
 
3
 
 
4
using System;
 
5
using System.Collections.Generic;
 
6
using System.Collections.ObjectModel;
 
7
using System.ComponentModel;
 
8
using System.Linq;
 
9
using System.Windows;
 
10
using System.Windows.Controls;
 
11
using System.Windows.Documents;
 
12
 
 
13
using ICSharpCode.Profiler.Controller.Data;
 
14
 
 
15
namespace ICSharpCode.Profiler.Controls
 
16
{
 
17
        public class CallTreeNodeViewModel : IViewModel<CallTreeNodeViewModel>, INotifyPropertyChanged
 
18
        {
 
19
                #region INotifyPropertyChanged Member
 
20
 
 
21
                public event PropertyChangedEventHandler PropertyChanged;
 
22
 
 
23
                protected void OnPropertyChanged(string name)
 
24
                {
 
25
                        if (this.PropertyChanged != null)
 
26
                        {
 
27
                                PropertyChanged(this, new PropertyChangedEventArgs(name));
 
28
                        }
 
29
                }
 
30
 
 
31
                #endregion
 
32
 
 
33
                ReadOnlyCollection<CallTreeNodeViewModel> children;
 
34
                protected readonly CallTreeNode node;
 
35
                CallTreeNodeViewModel parent;
 
36
                protected int level;
 
37
                
 
38
                public CallTreeNode Node { get { return node; } }
 
39
                
 
40
                public event EventHandler<NodeEventArgs<CallTreeNodeViewModel>> VisibleChildExpandedChanged;
 
41
                public event EventHandler<NodeEventArgs<CallTreeNodeViewModel>> RequestBringIntoView;
 
42
                
 
43
                protected virtual void OnRequestBringIntoView(NodeEventArgs<CallTreeNodeViewModel> e)
 
44
                {
 
45
                        if (RequestBringIntoView != null) {
 
46
                                RequestBringIntoView(this, e);
 
47
                        }
 
48
                }
 
49
                
 
50
                protected virtual void OnVisibleChildExpandedChanged(NodeEventArgs<CallTreeNodeViewModel> e)
 
51
                {
 
52
                        if (VisibleChildExpandedChanged != null) {
 
53
                                VisibleChildExpandedChanged(this, e);
 
54
                        }
 
55
                }
 
56
                
 
57
                public void BringIntoView()
 
58
                {
 
59
                        BringIntoView(this);
 
60
                }
 
61
                
 
62
                void BringIntoView(CallTreeNodeViewModel item)
 
63
                {
 
64
                        if (this.parent != null) {
 
65
                                parent.BringIntoView(item);
 
66
                                return;
 
67
                        }
 
68
                        OnRequestBringIntoView(new NodeEventArgs<CallTreeNodeViewModel>(item));
 
69
                }
 
70
                
 
71
                public int Level
 
72
                {
 
73
                        get { return level; }
 
74
                        set { level = value; }
 
75
                }
 
76
                
 
77
                public CallTreeNodeViewModel Parent
 
78
                {
 
79
                        get { return parent; }
 
80
                }
 
81
 
 
82
                public virtual long CpuCyclesSpent
 
83
                {
 
84
                        get {
 
85
                                return node.CpuCyclesSpent;
 
86
                        }
 
87
                }
 
88
                
 
89
                public virtual double TimePercentageOfParent
 
90
                {
 
91
                        get {
 
92
                                if (this.parent == null)
 
93
                                        return 1;
 
94
                                else
 
95
                                        return (double)this.node.CpuCyclesSpent / (double)this.parent.node.CpuCyclesSpent;
 
96
                        }
 
97
                }
 
98
                
 
99
                public Visibility HotPathIndicatorVisibility {
 
100
                        get {
 
101
                                if (TimePercentageOfParent >= 0.2)
 
102
                                        return Visibility.Visible;
 
103
                                
 
104
                                return Visibility.Collapsed;
 
105
                        }
 
106
                }
 
107
                
 
108
                public virtual string TimePercentageOfParentAsText
 
109
                {
 
110
                        get {
 
111
                                return (TimePercentageOfParent * 100).ToString("0.00") + "%";
 
112
                        }
 
113
                }
 
114
                
 
115
                public virtual object ToolTip
 
116
                {
 
117
                        get { return CreateShortToolTip(); }
 
118
                }
 
119
                
 
120
                object CreateShortToolTip()
 
121
                {
 
122
                        if (level == 0)
 
123
                                return null; // no tooltip for root
 
124
                        if (node.IsThread)
 
125
                                return Name;
 
126
 
 
127
                        TextBlock text = new TextBlock {
 
128
                                Inlines = {
 
129
                                        ((!string.IsNullOrEmpty(node.ReturnType)) ? node.ReturnType + " " : ""),
 
130
                                        new Bold { Inlines = { node.Name } },
 
131
                                        "(" + ((node.Parameters.Count > 0) ? string.Join(", ", node.Parameters.ToArray()) : "") + ")"
 
132
                                }
 
133
                        };
 
134
 
 
135
                        return text;
 
136
                }
 
137
 
 
138
                public object CreateToolTip(ControlsTranslation translation)
 
139
                {
 
140
                        if (node.IsThread)
 
141
                                return Name; // only name for threads
 
142
 
 
143
                        TextBlock text = new TextBlock
 
144
                        {
 
145
                                Inlines = {
 
146
                                        ((!string.IsNullOrEmpty(node.ReturnType)) ? node.ReturnType + " " : ""),
 
147
                                        new Bold { Inlines = { node.Name } },
 
148
                                        "(" + ((node.Parameters.Count > 0) ? string.Join(", ", node.Parameters.ToArray()) : "") + ")\n",
 
149
                                        new Bold { Inlines = { translation.CpuCyclesText } },
 
150
                                        " " + node.CpuCyclesSpent + "\n",
 
151
                                        new Bold { Inlines = { translation.TimeText } },
 
152
                                        " " + node.TimeSpent.ToString("f6") + "ms\n",
 
153
                                        new Bold { Inlines = { translation.CallsText } },
 
154
                                        " " + node.CallCount.ToString()
 
155
                                }
 
156
                        };
 
157
 
 
158
                        return text;
 
159
                }
 
160
                
 
161
                public string GetSignature()
 
162
                {
 
163
                        if (node.IsThread)
 
164
                                return Name;
 
165
                        return node.Signature;
 
166
                }
 
167
 
 
168
                public ReadOnlyCollection<string> Parameters
 
169
                {
 
170
                        get {
 
171
                                return new ReadOnlyCollection<string>(this.node.Parameters);
 
172
                        }
 
173
                }
 
174
 
 
175
                public CallTreeNodeViewModel(CallTreeNode node, CallTreeNodeViewModel parent)
 
176
                {
 
177
                        if (node == null)
 
178
                                throw new ArgumentNullException("node");
 
179
                        this.node = node;
 
180
                        this.parent = parent;
 
181
                        this.level = (this.parent == null) ? 1 : this.parent.level + 1;
 
182
                }
 
183
 
 
184
                public bool IsAncestorOf(CallTreeNodeViewModel descendant)
 
185
                {
 
186
                        if (this != descendant) {
 
187
                                if (descendant == null)
 
188
                                        return false;
 
189
 
 
190
                                return IsAncestorOf(descendant.Parent);
 
191
                        }
 
192
                        
 
193
                        return true;
 
194
                }
 
195
 
 
196
                public virtual ReadOnlyCollection<CallTreeNodeViewModel> Children {
 
197
                        get {
 
198
                                lock (this) {
 
199
                                        if (this.children == null) {
 
200
                                                
 
201
                                                this.children = this.node.Children
 
202
                                                        .Select(c => new CallTreeNodeViewModel(c, this))
 
203
                                                        .ToList()
 
204
                                                        .AsReadOnly();
 
205
                                        }
 
206
                                        
 
207
                                        return this.children;
 
208
                                }
 
209
                        }
 
210
                }
 
211
 
 
212
                public virtual string Name
 
213
                {
 
214
                        get {
 
215
                                return this.node.Name ?? string.Empty;
 
216
                        }
 
217
                }
 
218
 
 
219
                public virtual string FullyQualifiedClassName
 
220
                {
 
221
                        get {
 
222
                                string nodeName = this.node.Name;
 
223
                                if (string.IsNullOrEmpty(nodeName))
 
224
                                        return null;
 
225
                                if (!nodeName.Contains("."))
 
226
                                        return null;
 
227
                                int index = nodeName.LastIndexOf('.');
 
228
                                if (nodeName[index - 1] == '.')
 
229
                                        index--;
 
230
                                return nodeName.Substring(0, index);
 
231
                        }
 
232
                }
 
233
 
 
234
                public virtual string MethodName
 
235
                {
 
236
                        get {
 
237
                                string nodeName = this.node.Name;
 
238
                                if (string.IsNullOrEmpty(nodeName))
 
239
                                        return null;
 
240
                                if (!nodeName.Contains("."))
 
241
                                        return null;
 
242
                                int index = nodeName.LastIndexOf('.');
 
243
                                if (nodeName[index - 1] == '.')
 
244
                                        index--;
 
245
                                return nodeName.Substring(index + 1);
 
246
                        }
 
247
                }
 
248
                
 
249
                public virtual string ShortName
 
250
                {
 
251
                        get {
 
252
                                string className = this.FullyQualifiedClassName;
 
253
                                if (className == null)
 
254
                                        return this.Name;
 
255
                                int index = className.LastIndexOf('.');
 
256
                                return className.Substring(index + 1) + "." + MethodName;
 
257
                        }
 
258
                }
 
259
                
 
260
                bool isExpanded;
 
261
                
 
262
                public bool IsExpanded {
 
263
                        get { return isExpanded; }
 
264
                        set {
 
265
                                if (isExpanded != value) {
 
266
                                        isExpanded = value;
 
267
                                        OnPropertyChanged("IsExpanded");
 
268
                                        this.IsExpandedChanged(new NodeEventArgs<CallTreeNodeViewModel>(this));
 
269
                                        
 
270
                                        if (isExpanded) {
 
271
                                                DeselectChildren(children);
 
272
                                        }
 
273
                                }
 
274
                        }
 
275
                }
 
276
 
 
277
                void DeselectChildren(IList<CallTreeNodeViewModel> children)
 
278
                {
 
279
                        foreach (CallTreeNodeViewModel item in children) {
 
280
                                item.IsSelected = false;
 
281
                                if (item.isExpanded)
 
282
                                        DeselectChildren(item.Children);
 
283
                        }
 
284
                }
 
285
                
 
286
                void IsExpandedChanged(NodeEventArgs<CallTreeNodeViewModel> e)
 
287
                {
 
288
                        this.visibleElementCount = 1 + (IsExpanded ? Children.Sum(c => c.VisibleElementCount) : 0);
 
289
                        OnVisibleChildExpandedChanged(e);
 
290
                        
 
291
                        if (Parent != null && Parent.IsExpanded) {
 
292
                                Parent.IsExpandedChanged(e);
 
293
                        }
 
294
                }
 
295
 
 
296
                /*void IsSelectedChanged(CallTreeNodeViewModel item)
 
297
                {
 
298
                        if (Parent != null)
 
299
                                Parent.IsSelectedChanged(item);
 
300
                        else
 
301
                                OnChildSelectedChanged(new CallTreeNodeViewModelEventArgs(item));
 
302
                }
 
303
 
 
304
                protected virtual void OnChildSelectedChanged(CallTreeNodeViewModelEventArgs eventArgs)
 
305
                {
 
306
                        if (ChildSelectedChanged != null)
 
307
                                ChildSelectedChanged(this, eventArgs);
 
308
                }*/
 
309
                
 
310
                bool isSelected;
 
311
                
 
312
                public bool IsSelected {
 
313
                        get { return isSelected; }
 
314
                        set {
 
315
                                if (isSelected != value) {
 
316
                                        isSelected = value;
 
317
                                        OnPropertyChanged("IsSelected");
 
318
                                        //this.IsSelectedChanged(this);
 
319
                                        
 
320
                                        if (isSelected) {
 
321
                                                CallTreeNodeViewModel node = this.Parent;
 
322
                                                while (node != null) {
 
323
                                                        node.IsExpanded = true;
 
324
                                                        node = node.Parent;
 
325
                                                }
 
326
                                        }
 
327
                                }
 
328
                        }
 
329
                }
 
330
                
 
331
                public string TimeSpent {
 
332
                        get {
 
333
                                if (!node.IsThread)
 
334
                                        return node.TimeSpent.ToString("f6") + "ms";
 
335
                                else
 
336
                                        return null;
 
337
                        }
 
338
                }
 
339
                
 
340
                public string TimeSpentSelf {
 
341
                        get {
 
342
                                if (!node.IsThread)
 
343
                                        return node.TimeSpentSelf.ToString("f6") + "ms";
 
344
                                else
 
345
                                        return null;
 
346
                        }
 
347
                }
 
348
                
 
349
                public string TimeSpentSelfPerCall {
 
350
                        get {
 
351
                                if (!node.IsThread)
 
352
                                        return (node.TimeSpentSelf / node.CallCount).ToString("f6") + "ms";
 
353
                                else
 
354
                                        return null;
 
355
                        }
 
356
                }
 
357
                
 
358
                public string TimeSpentPerCall {
 
359
                        get {
 
360
                                if (!node.IsThread)
 
361
                                        return (node.TimeSpent / node.CallCount).ToString("f6") + "ms";
 
362
                                else
 
363
                                        return null;
 
364
                        }
 
365
                }
 
366
                
 
367
                public string CallCount {
 
368
                        get {
 
369
                                if (!node.IsThread)
 
370
                                        return node.CallCount.ToString();
 
371
                                else
 
372
                                        return null;
 
373
                        }
 
374
                }
 
375
                
 
376
                public Visibility CheckBoxVisibility
 
377
                {
 
378
                        get {
 
379
                                if (node.HasChildren)
 
380
                                        return Visibility.Visible;
 
381
                                else
 
382
                                        return Visibility.Hidden;
 
383
                        }
 
384
                }
 
385
                
 
386
                public override string ToString()
 
387
                {
 
388
                        return "[" + Name + "]";
 
389
                }
 
390
 
 
391
                #region IViewModel<CallTreeNodeViewModel> Member
 
392
                int visibleElementCount = 1;
 
393
 
 
394
                public virtual int VisibleElementCount
 
395
                {
 
396
                        get {
 
397
                                return this.visibleElementCount;
 
398
                        }
 
399
                }
 
400
                
 
401
                public virtual Thickness IndentationMargin {
 
402
                        get {
 
403
                                return new Thickness((level - 1) * 12, 0, 2, 0);
 
404
                        }
 
405
                }
 
406
                #endregion
 
407
        }
 
408
}