Skip to content

Commit 56525ff

Browse files
committed
Fix #38: Newer Versions Of Elucidate Skips lines in the "LiveLog" (V19.1.773.27)
- Remove FastColouredTextBox - Remove other entities not needed in the installer - Start to introduce tab Page controls - Explain what Force Sync will be using
1 parent 0805a6f commit 56525ff

18 files changed

Lines changed: 1096 additions & 707 deletions

Elucidate/Elucidate Windows Installer/Elucidate.wxs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,6 @@
7777
<netfx:NativeImage Id="ngen.Exceptionless.Windows" Platform="all" Priority="2" AppBaseDirectory="ClientDIR" />
7878
</File>
7979
</Component>
80-
<Component>
81-
<File Source="$(var.MgtSource)\FastColoredTextBox.dll" KeyPath="yes" >
82-
<netfx:NativeImage Id="ngen.FastColoredTextBox" Platform="all" Priority="2" AppBaseDirectory="ClientDIR" />
83-
</File>
84-
</Component>
8580
<Component>
8681
<File Source="$(var.MgtSource)\GroupControls.dll" KeyPath="yes" >
8782
<netfx:NativeImage Id="ngen.GroupControls" Platform="all" Priority="2" AppBaseDirectory="ClientDIR" />
@@ -103,21 +98,11 @@
10398
<netfx:NativeImage Id="ngen.Navigator" Platform="all" Priority="2" AppBaseDirectory="ClientDIR" />
10499
</File>
105100
</Component>
106-
<Component>
107-
<File Source="$(var.MgtSource)\Krypton Ribbon.dll" KeyPath="yes" >
108-
<netfx:NativeImage Id="ngen.Ribbon" Platform="all" Priority="2" AppBaseDirectory="ClientDIR" />
109-
</File>
110-
</Component>
111101
<Component>
112102
<File Source="$(var.MgtSource)\Krypton Toolkit.dll" KeyPath="yes" >
113103
<netfx:NativeImage Id="ngen.Toolkit" Platform="all" Priority="2" AppBaseDirectory="ClientDIR" />
114104
</File>
115105
</Component>
116-
<Component>
117-
<File Source="$(var.MgtSource)\Krypton Workspace.dll" KeyPath="yes" >
118-
<netfx:NativeImage Id="ngen.Workspace" Platform="all" Priority="2" AppBaseDirectory="ClientDIR" />
119-
</File>
120-
</Component>
121106
<Component>
122107
<File Source="$(var.MgtSource)\Microsoft.Win32.TaskScheduler.dll" KeyPath="yes" >
123108
<netfx:NativeImage Id="ngen.Microsoft.Win32.TaskScheduler" Platform="all" Priority="2" AppBaseDirectory="ClientDIR" />
@@ -147,9 +132,9 @@
147132
<Component>
148133
<File Source="$(sys.SOURCEFILEDIR)GPLv2.rtf" KeyPath="yes" />
149134
</Component>
150-
<Component>
151-
<File Source="$(sys.SOURCEFILEDIR)LGPLv3.0.rtf" KeyPath="yes" /> <!--Used for the FastColouredTextBox-->
152-
</Component>
135+
<!--<Component>
136+
<File Source="$(sys.SOURCEFILEDIR) TODO" KeyPath="yes" /> --><!--Used for the Krypton--><!--
137+
</Component>-->
153138
<Component>
154139
<File Source="$(var.MgtSource)\wyDay.Controls\License.txt" KeyPath="yes" />
155140
</Component>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RAID/@EntryIndexedValue">RAID</s:String>
23
<s:Boolean x:Key="/Default/UserDictionary/Words/=Coghlan/@EntryIndexedValue">True</s:Boolean>
34
<s:Boolean x:Key="/Default/UserDictionary/Words/=smartctl/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
using System;
2+
using System.Collections.Concurrent;
3+
using System.Diagnostics;
4+
using System.Drawing;
5+
using System.Text;
6+
using System.Windows.Forms;
7+
// ReSharper disable MemberCanBePrivate.Global
8+
9+
// ReSharper disable UnusedMember.Global
10+
11+
namespace Elucidate.Controls
12+
{
13+
/// <summary>
14+
/// Stolen from
15+
/// https://stackoverflow.com/questions/2196097/elegant-log-window-in-winforms-c-sharp
16+
/// and then
17+
/// - reformatted to make it work with NLog style levels
18+
/// - Made to work for multi-line
19+
/// - Updates via a timer
20+
/// </summary>
21+
public sealed class ListBoxLog : IDisposable
22+
{
23+
private const int DEFAULT_MAX_LINES_IN_LISTBOX = 2000;
24+
private const int DEFAULT_UPDATE_FREQUENCY_MS = 250;
25+
26+
private bool disposed;
27+
private ListBox listBoxInt;
28+
private readonly int maxEntriesInListBox;
29+
private readonly Timer timer1;
30+
31+
private class LogString
32+
{
33+
public string LevelUppercase;
34+
public string Message;
35+
};
36+
37+
private readonly ConcurrentQueue<LogString> pendingLogMessages = new ConcurrentQueue<LogString>();
38+
private bool alreadyDequing;
39+
40+
public ListBoxLog(ListBox listBox, int maxLinesInListbox = DEFAULT_MAX_LINES_IN_LISTBOX, int defaultUpdateFrequencyms = DEFAULT_UPDATE_FREQUENCY_MS)
41+
{
42+
disposed = false;
43+
timer1 = new Timer
44+
{
45+
Enabled = listBox.IsHandleCreated,
46+
Interval = defaultUpdateFrequencyms,
47+
};
48+
timer1.Tick += timer1_Tick;
49+
50+
listBoxInt = listBox;
51+
maxEntriesInListBox = maxLinesInListbox;
52+
53+
Paused = false;
54+
55+
listBoxInt.SelectionMode = SelectionMode.MultiExtended;
56+
57+
listBoxInt.HandleCreated += OnHandleCreated;
58+
listBoxInt.HandleDestroyed += OnHandleDestroyed;
59+
listBoxInt.DrawItem += DrawItemHandler;
60+
listBoxInt.KeyDown += KeyDownHandler;
61+
listBoxInt.MeasureItem += MeasureItem;
62+
listBoxInt.DrawMode = DrawMode.OwnerDrawVariable;
63+
64+
MenuItem[] menuItems = new[] { new MenuItem("Copy", CopyMenuOnClickHandler) };
65+
listBoxInt.ContextMenu = new ContextMenu(menuItems);
66+
listBoxInt.ContextMenu.Popup += CopyMenuPopupHandler;
67+
68+
}
69+
70+
public void LogMethod(string levelUppercase, string message)
71+
{
72+
pendingLogMessages.Enqueue(new LogString
73+
{
74+
LevelUppercase = levelUppercase,
75+
Message = message + Environment.NewLine
76+
});
77+
}
78+
79+
80+
public bool Paused { get; set; }
81+
82+
~ListBoxLog()
83+
{
84+
if (!disposed)
85+
{
86+
Dispose(false);
87+
disposed = true;
88+
}
89+
}
90+
91+
public void Dispose()
92+
{
93+
if (!disposed)
94+
{
95+
Dispose(true);
96+
GC.SuppressFinalize(this);
97+
disposed = true;
98+
}
99+
}
100+
101+
private void OnHandleCreated(object sender, EventArgs e)
102+
{
103+
timer1.Enabled = true;
104+
}
105+
106+
private void OnHandleDestroyed(object sender, EventArgs e)
107+
{
108+
timer1.Enabled = false;
109+
}
110+
111+
private void MeasureItem(object sender, MeasureItemEventArgs e)
112+
{
113+
if (e.Index >= 0)
114+
{
115+
if (!(((ListBox)sender).Items[e.Index] is LogString logEvent))
116+
{
117+
logEvent = new LogString
118+
{
119+
LevelUppercase = @"FATAL",
120+
Message = ((ListBox)sender).Items[e.Index].ToString()
121+
};
122+
}
123+
124+
e.ItemHeight = (int) (e.Graphics.MeasureString(logEvent.Message, listBoxInt.Font).Height + 2);
125+
}
126+
}
127+
128+
129+
private void DrawItemHandler(object sender, DrawItemEventArgs e)
130+
{
131+
if (e.Index >= 0)
132+
{
133+
e.DrawBackground();
134+
e.DrawFocusRectangle();
135+
136+
// SafeGuard against wrong configuration of list box
137+
if (!(((ListBox)sender).Items[e.Index] is LogString logEvent))
138+
{
139+
logEvent = new LogString
140+
{
141+
LevelUppercase = @"FATAL",
142+
Message = ((ListBox) sender).Items[e.Index].ToString()
143+
};
144+
}
145+
146+
Brush color;
147+
switch (logEvent.LevelUppercase)
148+
{
149+
case @"FATAL":
150+
color = Brushes.White;
151+
break;
152+
case @"ERROR":
153+
color = Brushes.Red;
154+
break;
155+
case @"WARNING":
156+
color = Brushes.Goldenrod;
157+
break;
158+
case @"INFO":
159+
color = Brushes.Black;
160+
break;
161+
case @"DEBUG":
162+
color = Brushes.Gray;
163+
break;
164+
case @"TRACE":
165+
color = Brushes.DarkGray;
166+
break;
167+
default:
168+
color = Brushes.Black;
169+
break;
170+
}
171+
172+
if (logEvent.LevelUppercase == @"FATAL")
173+
{
174+
e.Graphics.FillRectangle(Brushes.Red, e.Bounds);
175+
}
176+
177+
e.Graphics.DrawString(logEvent.Message, listBoxInt.Font, color, e.Bounds);
178+
}
179+
}
180+
181+
private void KeyDownHandler(object sender, KeyEventArgs e)
182+
{
183+
if (e.Modifiers == Keys.Control)
184+
{
185+
if (e.KeyCode == Keys.C)
186+
{
187+
CopyToClipboard();
188+
}
189+
else if (e.KeyCode == Keys.C)
190+
{
191+
listBoxInt.BeginUpdate();
192+
for (int i = listBoxInt.Items.Count - 1; i >= 0; i--)
193+
{
194+
listBoxInt.SetSelected(i, true);
195+
}
196+
listBoxInt.EndUpdate();
197+
}
198+
}
199+
}
200+
201+
private void CopyMenuOnClickHandler(object sender, EventArgs e)
202+
{
203+
CopyToClipboard();
204+
}
205+
206+
private void CopyMenuPopupHandler(object sender, EventArgs e)
207+
{
208+
if (sender is ContextMenu menu)
209+
{
210+
menu.MenuItems[0].Enabled = (listBoxInt.SelectedItems.Count > 0);
211+
}
212+
}
213+
214+
private void timer1_Tick(object sender, EventArgs e)
215+
{
216+
try
217+
{
218+
if (alreadyDequing
219+
|| pendingLogMessages.IsEmpty)
220+
{
221+
return;
222+
}
223+
224+
alreadyDequing = true;
225+
// Now lock in case the timer is overlapping !
226+
//BeginInvoke((MethodInvoker)delegate
227+
{
228+
//some stuffs for best performance
229+
listBoxInt.BeginUpdate();
230+
231+
// find the style to use
232+
while (pendingLogMessages.TryDequeue(out LogString log))
233+
{
234+
listBoxInt.Items.Add(log);
235+
}
236+
237+
if (listBoxInt.Items.Count > maxEntriesInListBox)
238+
{
239+
listBoxInt.Items.RemoveAt(0);
240+
}
241+
242+
if (!Paused)
243+
{
244+
listBoxInt.TopIndex = listBoxInt.Items.Count - 1;
245+
}
246+
247+
listBoxInt.EndUpdate();
248+
//}
249+
alreadyDequing = false;
250+
}
251+
//);
252+
}
253+
catch (Exception ex)
254+
{
255+
Debug.Fail(ex.Message);
256+
}
257+
}
258+
259+
private void CopyToClipboard()
260+
{
261+
if (listBoxInt.SelectedItems.Count > 0)
262+
{
263+
StringBuilder selectedItemsAsRtfText = new StringBuilder();
264+
//selectedItemsAsRtfText.AppendLine(@"{\rtf1\ansi\deff0{\fonttbl{\f0\fcharset0 Courier;}}");
265+
//selectedItemsAsRtfText.AppendLine(
266+
// @"{\colortbl;\red255\green255\blue255;\red255\green0\blue0;\red218\green165\blue32;\red0\green128\blue0;\red0\green0\blue255;\red0\green0\blue0}");
267+
foreach (LogString logEvent in listBoxInt.SelectedItems)
268+
{
269+
//selectedItemsAsRtfText.AppendFormat(@"{{\f0\fs16\chshdng0\chcbpat{0}\cb{0}\cf{1} ",
270+
// (logEvent.LevelUppercase == @"FATAL") ? 2 : 1,
271+
// (logEvent.LevelUppercase == @"FATAL") ? 1 :
272+
// ((int)logEvent.Level > 5) ? 6 : ((int)logEvent.Level) + 1);
273+
//selectedItemsAsRtfText.Append(FormatALogEventMessage(logEvent, messageFormat));
274+
//selectedItemsAsRtfText.AppendLine(@"\par}");
275+
selectedItemsAsRtfText.Append(logEvent.Message);
276+
}
277+
278+
//selectedItemsAsRtfText.AppendLine(@"}");
279+
//Clipboard.SetData(DataFormats.Rtf, selectedItemsAsRtfText.ToString());
280+
Clipboard.SetData(DataFormats.UnicodeText, selectedItemsAsRtfText.ToString());
281+
}
282+
283+
}
284+
285+
286+
private void Dispose(bool disposing)
287+
{
288+
if (listBoxInt != null)
289+
{
290+
timer1.Enabled = false;
291+
292+
listBoxInt.HandleCreated -= OnHandleCreated;
293+
listBoxInt.HandleCreated -= OnHandleDestroyed;
294+
listBoxInt.DrawItem -= DrawItemHandler;
295+
listBoxInt.KeyDown -= KeyDownHandler;
296+
297+
listBoxInt.ContextMenu.MenuItems.Clear();
298+
listBoxInt.ContextMenu.Popup -= CopyMenuPopupHandler;
299+
listBoxInt.ContextMenu = null;
300+
301+
listBoxInt.Items.Clear();
302+
listBoxInt.DrawMode = DrawMode.Normal;
303+
listBoxInt = null;
304+
}
305+
}
306+
}
307+
}

0 commit comments

Comments
 (0)