-
-
Notifications
You must be signed in to change notification settings - Fork 43
Expand file tree
/
Copy pathStatisticsView.cs
More file actions
297 lines (256 loc) · 9.94 KB
/
Copy pathStatisticsView.cs
File metadata and controls
297 lines (256 loc) · 9.94 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
// Copyright (c) 2015-2017 SIL International
// This software is licensed under the LGPL, version 2.1 or later
// (http://www.gnu.org/licenses/lgpl-2.1.html)
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Xml;
using SIL.FieldWorks.Common.FwUtils;
using SIL.FieldWorks.Common.Widgets;
using SIL.LCModel;
using SIL.LCModel.DomainServices;
using SIL.FieldWorks.XWorks;
using SIL.Utils;
using XCore;
namespace SIL.FieldWorks.IText
{
public partial class StatisticsView : UserControl, IxCoreContentControl
{
private bool _shouldNotCall;
private string _areaName;
private Mediator _mediator;
private PropertyTable _propertyTable;
private LcmCache _cache;
private InterlinearTextsRecordClerk m_clerk;
public StatisticsView()
{
InitializeComponent();
ContextMenu cm = new ContextMenu();
var mi = new MenuItem("Copy");
mi.Click += new EventHandler(mi_Copy);
cm.MenuItems.Add(mi);
statisticsBox.ContextMenu = cm;
}
public string AccName
{
get { return ITextStrings.ksTextAreaStatisticsViewName; }
}
#region Implementation of IxCoreCtrlTabProvider
/// <summary>
/// Gather up suitable targets to Cntrl-(Shift-)Tab into.
/// </summary>
/// <param name="targetCandidates">List of places to move to.</param>
/// <returns>A suitable target for moving to in Ctrl(+Shift)+Tab.
/// This returned value should also have been added to the main list.</returns>
public Control PopulateCtrlTabTargetCandidateList(List<Control> targetCandidates)
{
targetCandidates.Add(this);
return this;
}
#endregion
#region Implementation of IxCoreColleague
public void Init(Mediator mediator, PropertyTable propertyTable, XmlNode configurationParameters)
{
CheckDisposed();
_mediator = mediator; //allows the Cache property to function
_propertyTable = propertyTable;
_cache = _propertyTable.GetValue<LcmCache>("cache");
string name = XmlUtils.GetAttributeValue(configurationParameters, "clerk");
var clerk = RecordClerk.FindClerk(_propertyTable, name);
m_clerk = (clerk == null || clerk is TemporaryRecordClerk) ?
(InterlinearTextsRecordClerk)RecordClerkFactory.CreateClerk(mediator, _propertyTable, configurationParameters, true, true) :
(InterlinearTextsRecordClerk)clerk;
// There's no record bar for it to control, but it should control the staus bar (e.g., it should update if we change
// the set of selected texts).
m_clerk.ActivateUI(true);
_areaName = XmlUtils.GetOptionalAttributeValue(configurationParameters, "area", "unknown");
RebuildStatisticsTable();
//add ourselves so that we can receive messages (related to the text selection currently misnamed AddTexts)
mediator.AddColleague(this);
//add our current state to the history system
string toolName = _propertyTable.GetStringProperty("currentContentControl", "");
mediator.SendMessage("AddContextToHistory", new FwLinkArgs(toolName, Guid.Empty), false);
}
private void RebuildStatisticsTable()
{
statisticsBox.Clear();
// TODO-Linux: SelectionTabs isn't implemented on Mono
statisticsBox.SelectionTabs = new int[] { 10, 300};
//retrieve the default UI font.
var font = FontHeightAdjuster.GetFontForStyle(StyleServices.NormalStyleName,
FontHeightAdjuster.StyleSheetFromPropertyTable(_propertyTable),
Cache.DefaultUserWs, Cache.WritingSystemFactory);
//increase the size of the default UI font and make it bold for the header.
Font headerFont = new Font(font.FontFamily, font.SizeInPoints + 1.0f, FontStyle.Bold, font.Unit, font.GdiCharSet);
//refresh the statisticsDescription (in case of font changes)
statisticsBox.Text = ITextStrings.ksStatisticsView_HeaderText;
int row = 0;
var textList = InterestingTextsDecorator.GetInterestingTextList(_mediator, _propertyTable, Cache.ServiceLocator);
int numberOfSegments = 0;
int wordCount = 0;
int uniqueWords = 0;
Dictionary<int, int> languageCount = new Dictionary<int, int>();
Dictionary<int, HashSet<string>> languageTypeCount = new Dictionary<int, HashSet<string>>();
//for each interesting text
foreach (var text in textList.InterestingTexts)
{
//if a text is deleted in Interlinear there could be a text in this list which has invalid data.
if (text.Hvo < 0)
continue;
//for every paragraph in the interesting text
for (int index = 0; index < text.ParagraphsOS.Count; ++index)
{
//count the segments in this paragraph
numberOfSegments += text[index].SegmentsOS.Count;
//count all the things analyzed as words
var words = new List<IAnalysis>(text[index].Analyses);
var wordForms = new List<IWfiWordform>(words.Where(x => x.Wordform != null && x.Wordform.ShortName != "???").Select(y => y.Wordform));
foreach (var wordForm in wordForms)
{
var valdWSs = wordForm.Form.AvailableWritingSystemIds;
foreach (var ws in valdWSs)
{
// increase the count of words(tokens) for this language
int count = 0;
if (languageCount.TryGetValue(ws, out count))
{
languageCount[ws] = count + 1;
}
else
{
languageCount.Add(ws, 1);
}
//increase the count of unique words(types) for this language
HashSet<string> pair;
if (languageTypeCount.TryGetValue(ws, out pair))
{
//add the string for this writing system in all lower case to the set, unique count is case insensitive
pair.Add(wordForm.Form.get_String(ws).Text.ToLower());
}
else
{
//add the string for this writing system in all lower case to the set, unique count is case insensitive
languageTypeCount.Add(ws, new HashSet<string> {wordForm.Form.get_String(ws).Text.ToLower()});
}
}
}
words.RemoveAll(item => !item.HasWordform);
wordCount += words.Count;
}
}
// insert total word type count
statisticsBox.Text += Environment.NewLine + Environment.NewLine + Environment.NewLine + "\t" + ITextStrings.ksStatisticsViewTotalWordTypesText + "\t"; // Todo: find the right System.?.NewLine constant
++row;
//add one row for the unique words in each language.
foreach (KeyValuePair<int, HashSet<string>> keyValuePair in languageTypeCount)
{
var ws = Cache.WritingSystemFactory.get_EngineOrNull(keyValuePair.Key);
string labText = (ws != null ? ws.ToString() : "#unknown#") + @":";
statisticsBox.Text += Environment.NewLine + Environment.NewLine + "\t" + labText + "\t"; // Todo: find the right System.?.NewLine constant
statisticsBox.Text += "" + keyValuePair.Value.Count;
++row;
uniqueWords += keyValuePair.Value.Count; //increase the total of unique words
}
// next insert the word count.
statisticsBox.Text += Environment.NewLine + Environment.NewLine + Environment.NewLine + "\t" + ITextStrings.ksStatisticsViewTotalWordTokensText + "\t"; // Todo: find the right System.?.NewLine constant
statisticsBox.Text += wordCount;
++row;
//add one row for the token count for each language.
foreach (KeyValuePair<int, int> keyValuePair in languageCount)
{
var ws = Cache.WritingSystemFactory.get_EngineOrNull(keyValuePair.Key);
string labText = (ws != null ? ws.ToString() : "#unknown#") + @":";
statisticsBox.Text += Environment.NewLine + Environment.NewLine + "\t" + labText + "\t"; // Todo: find the right System.?.NewLine constant
statisticsBox.Text += "" + keyValuePair.Value;
++row;
}
statisticsBox.Text += Environment.NewLine + Environment.NewLine + Environment.NewLine + "\t" + ITextStrings.ksStatisticsViewTotalSentencesText + "\t"; // Todo: find the right System.?.NewLine constant
// next insert the sentence count.
statisticsBox.Text += numberOfSegments;
// insert the total word type count into the richTextBox (it wasn't available earlier)
statisticsBox.SelectionStart = statisticsBox.Find(ITextStrings.ksStatisticsViewTotalWordTypesText) +
ITextStrings.ksStatisticsViewTotalWordTypesText.Length;
statisticsBox.SelectionLength = 1;
statisticsBox.SelectedText = "\t" + uniqueWords;
// Set the font for the header. Do this after we add the other stuff to make sure
// it doesn't apply to extra text added adjacent to it.
statisticsBox.Select(0, ITextStrings.ksStatisticsView_HeaderText.Length);
statisticsBox.SelectionFont = headerFont;
statisticsBox.Select(0, 0);
}
public IxCoreColleague[] GetMessageTargets()
{
CheckDisposed();
return new IxCoreColleague[] { this };
}
public bool ShouldNotCall
{
get { return _shouldNotCall; }
}
public int Priority
{
get
{
return (int)ColleaguePriority.Low;
}
}
public bool OnDisplayAddTexts(object commandObject, ref UIItemDisplayProperties display)
{
CheckDisposed();
display.Enabled = m_clerk != null;
display.Visible = display.Enabled;
return true;
}
public bool OnAddTexts(object args)
{
bool result = m_clerk.OnAddTexts(args);
if(result)
{
RebuildStatisticsTable();
}
return result;
}
#endregion
#region Implementation of IxCoreContentControl
public bool PrepareToGoAway()
{
CheckDisposed();
return true;
}
public string AreaName
{
get { return _areaName; }
}
#endregion
/// <summary>
/// This method throws an ObjectDisposedException if IsDisposed returns
/// true. This is the case where a method or property in an object is being
/// used but the object itself is no longer valid.
///
/// This method should be added to all public properties and methods of this
/// object and all other objects derived from it (extensive).
/// </summary>
public void CheckDisposed()
{
if (IsDisposed)
throw new ObjectDisposedException("StatisticsView has been disposed.");
}
/// <summary>
/// FDO cache.
/// </summary>
protected LcmCache Cache
{
get
{
return _cache;
}
}
//Code to add right click
void mi_Copy(object sender, EventArgs e)
{
statisticsBox.Copy();
}
}
}