1308 lines
49 KiB
C#
1308 lines
49 KiB
C#
using bts;
|
|
|
|
using Bts.DataStream;
|
|
using Bts.DataStreamExpressions;
|
|
using Bts.PubSub;
|
|
|
|
using Spark.Core.Disposables;
|
|
using Spark.Core.Reactive;
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reactive;
|
|
using System.Reactive.Linq;
|
|
using System.Reactive.Subjects;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Windows.Forms;
|
|
using BlueOrb.Pubsub.Diagnostics;
|
|
|
|
namespace BCG
|
|
{
|
|
public partial class MainForm : System.Windows.Forms.Form
|
|
{
|
|
private const string LastQueryRegistryKey = "LastQuery";
|
|
private const string RecentSavedFilesRegistryKey = "RecentSavedFiles";
|
|
private const string DateTimeDisplayFormat = "M/d/yyyy h:mm:ss.fff tt";
|
|
private const int MaxRecentSavedFiles = 10;
|
|
private static readonly Color QueryEditorDefaultColor = Color.White;
|
|
private static readonly Color QueryEditorCommentColor = Color.FromArgb(106, 115, 125);
|
|
private static readonly Color QueryEditorOperatorColor = Color.FromArgb(86, 156, 214);
|
|
private static readonly Color QueryEditorAssignmentNameColor = Color.FromArgb(78, 201, 176);
|
|
private static readonly Color GridBackgroundColor = Color.FromArgb(37, 37, 38);
|
|
private static readonly Color GridAltRowColor = Color.FromArgb(43, 43, 48);
|
|
private static readonly Color GridHeaderColor = Color.FromArgb(62, 62, 66);
|
|
private static readonly Color GridGridLineColor = Color.FromArgb(58, 58, 61);
|
|
private static readonly Color GridSelectionColor = Color.FromArgb(9, 71, 113);
|
|
private static readonly Color GridSelectionForeColor = Color.White;
|
|
private static readonly Color GridTimestampColor = Color.FromArgb(206, 215, 222);
|
|
private static readonly Color GridIdentifierColor = Color.FromArgb(156, 163, 175);
|
|
private static readonly Color GridIndicatorColor = Color.FromArgb(156, 220, 254);
|
|
|
|
class PrimitiveTreeNodeComparer : IComparer
|
|
{
|
|
public int Compare(object? x, object? y)
|
|
{
|
|
var left = x as TreeNode;
|
|
var right = y as TreeNode;
|
|
if (left is null || right is null)
|
|
return 0;
|
|
|
|
string left_key = _sort_key(left);
|
|
string right_key = _sort_key(right);
|
|
return StringComparer.OrdinalIgnoreCase.Compare(left_key, right_key);
|
|
}
|
|
|
|
static string _sort_key(TreeNode node)
|
|
{
|
|
if (node.Parent is null)
|
|
return node.Text;
|
|
|
|
if (node.Tag is string primitive_name)
|
|
return primitive_name;
|
|
|
|
return node.Text;
|
|
}
|
|
}
|
|
// static async Task _run() {
|
|
// var login = "bts";
|
|
// var passwd = String.Empty;
|
|
// Console.WriteLine("Starting DSQA... ");
|
|
// // Log.notnull(login);
|
|
// // Log.notnull(passwd);
|
|
// var service_ctx = bts.api.core.ServiceContext.create();
|
|
// await service_ctx.login(login, passwd);
|
|
// }
|
|
private bool myChangeStyle = false;
|
|
private PersistWindowState myWindowState;
|
|
private string? myLastFileName;
|
|
private ViewStream? myCurrentStream;
|
|
private List<ToolStripMenuItem> mySiteItems = new List<ToolStripMenuItem>();
|
|
private readonly List<string> _recent_saved_files = new List<string>();
|
|
private ToolStripSeparator? _recent_saved_files_separator;
|
|
// private string mySite = SitesCore.getMySiteName ();
|
|
private string mySite = "TODO";
|
|
private string myLastClassName = "MyView";
|
|
private ViewStream? myAllTagsStream;
|
|
IBlueRowCollection? tagRows;
|
|
private string myKQ;
|
|
private TextWriter? myConsoleOutput;
|
|
IDataPacket? pendingData;
|
|
IDisposable? titleSub;
|
|
readonly ToolTip _primitive_tool_tip = new ToolTip();
|
|
readonly Dictionary<string, string?> _primitive_source_path_cache = new Dictionary<string, string?>();
|
|
Dictionary<string, string?>? _source_file_index;
|
|
string? _repo_root_path;
|
|
char? _last_primitive_search_char;
|
|
TreeNode? _last_primitive_search_assembly_node;
|
|
bool _is_applying_query_syntax_highlighting;
|
|
HashSet<string>? _dsl_operator_names;
|
|
|
|
public MainForm()
|
|
{
|
|
//Task.Run(async () => await _run());
|
|
InitializeComponent();
|
|
_apply_grid_theme();
|
|
// myKQ = ConfigurationRequester.getApplicationQualifier();
|
|
myKQ = "TODO";
|
|
var handleCreatedSubject = new Subject<bool>();
|
|
HandleCreated += (s, e) => handleCreatedSubject.OnNext(true);
|
|
titleSub = Disposable.Create(
|
|
handleCreatedSubject.SelectSeries(_ =>
|
|
Observable.FromEvent(
|
|
cb => Invoke(() => titleInvalidated += cb),
|
|
cb => Invoke(() => titleInvalidated -= cb))
|
|
.Prepend(Unit.Default)
|
|
.SelectSeries(_ => new PubsubRoutesStream().AsObservable().Take(1)))
|
|
.Subscribe(dp => BeginInvoke(() => refreshTitle(dp.newRows))),
|
|
handleCreatedSubject);
|
|
mySetText();
|
|
|
|
myWindowState = new PersistWindowState();
|
|
myWindowState.parent = this;
|
|
myWindowState.saveState = false;
|
|
myWindowState.LoadState += myLoadPersistedState;
|
|
myWindowState.SaveState += mySavePersistedState;
|
|
|
|
this.Load += new EventHandler(myLoad);
|
|
this.Closing += new CancelEventHandler(myClosing);
|
|
myQueryTextBox.TextChanged += (o, e) => _apply_query_syntax_highlighting();
|
|
}
|
|
|
|
event Action? titleInvalidated;
|
|
|
|
public string query_text
|
|
{
|
|
get { return myQueryTextBox.Text; }
|
|
set
|
|
{
|
|
myQueryTextBox.Text = value;
|
|
_apply_query_syntax_highlighting();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clean up any resources being used.
|
|
/// </summary>
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
Disposable.Dispose(ref titleSub);
|
|
components?.Dispose();
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
private ViewStream myGetAllTagsStream()
|
|
{
|
|
// TODO: Port PublishedTagsStream from edge (then we can uncomment impl below)
|
|
//ViewStream vs = new PubSubServerStateStream();
|
|
ViewStream vs = new PubSubServerStateStream(ViewStreamDatabase.instance);
|
|
return new FilterStream(vs, "tag~='DS_'");
|
|
//return new LiteralStream("tag/String", "DS_table1;DS_table2");
|
|
}
|
|
|
|
private void mySetText()
|
|
{
|
|
titleInvalidated?.Invoke();
|
|
}
|
|
|
|
void refreshTitle(IBlueRowCollection rows)
|
|
{
|
|
string route_txt = String.Empty;
|
|
foreach (IBlueRow r in rows)
|
|
{
|
|
var tag_regexp = r.get<string>("tag_regexp");
|
|
var server_url = r.get<string>("server_url");
|
|
route_txt += $"{tag_regexp} : {server_url},";
|
|
}
|
|
|
|
this.Text = $"Data Stream Query Analyzer | routes: {route_txt}";
|
|
myToolStripStatusLabelTime.Text = "Ready";
|
|
myToolStripStatusLabelRows.Text = string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the data in the form of a multilevel IDictionary
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private IDictionary myGetLibraryData()
|
|
{
|
|
SortedList retVal = new SortedList();
|
|
string[] primitiveNames = PrimitiveManager.instance.get_dsl_op_names();
|
|
foreach (string pName in primitiveNames)
|
|
{
|
|
string aName = PrimitiveManager.instance.get_dslop_assembly_name(pName);
|
|
ICollection cNames = PrimitiveManager.instance.get_dsl_op_cons_args(pName);
|
|
if (!retVal.Contains(aName))
|
|
retVal.Add(aName, new SortedList());
|
|
(retVal[aName] as IDictionary)[pName] = new ArrayList(cNames);
|
|
|
|
}
|
|
foreach (DictionaryEntry outerDe in retVal)
|
|
foreach (DictionaryEntry innerDe in (outerDe.Value as IDictionary))
|
|
(innerDe.Value as ArrayList).Sort();
|
|
return retVal;
|
|
}
|
|
|
|
HashSet<string> _get_dsl_operator_names()
|
|
{
|
|
if (_dsl_operator_names != null)
|
|
return _dsl_operator_names;
|
|
|
|
_dsl_operator_names = new HashSet<string>(
|
|
PrimitiveManager.instance.get_dsl_op_names().Cast<string>(),
|
|
StringComparer.OrdinalIgnoreCase);
|
|
return _dsl_operator_names;
|
|
}
|
|
|
|
void _apply_query_syntax_highlighting()
|
|
{
|
|
if (_is_applying_query_syntax_highlighting || myQueryTextBox.IsDisposed)
|
|
return;
|
|
|
|
_is_applying_query_syntax_highlighting = true;
|
|
try
|
|
{
|
|
int selection_start = myQueryTextBox.SelectionStart;
|
|
int selection_length = myQueryTextBox.SelectionLength;
|
|
|
|
myQueryTextBox.SuspendLayout();
|
|
myQueryTextBox.SelectAll();
|
|
myQueryTextBox.SelectionColor = QueryEditorDefaultColor;
|
|
|
|
foreach (Match match in Regex.Matches(myQueryTextBox.Text, @"^\s*([A-Za-z_]\w*)\s*=", RegexOptions.Multiline))
|
|
{
|
|
Group group = match.Groups[1];
|
|
myQueryTextBox.Select(group.Index, group.Length);
|
|
myQueryTextBox.SelectionColor = QueryEditorAssignmentNameColor;
|
|
}
|
|
|
|
foreach (Match match in Regex.Matches(myQueryTextBox.Text, @"\b([A-Za-z_]\w*)\s*\("))
|
|
{
|
|
Group group = match.Groups[1];
|
|
if (!_get_dsl_operator_names().Contains(group.Value))
|
|
continue;
|
|
myQueryTextBox.Select(group.Index, group.Length);
|
|
myQueryTextBox.SelectionColor = QueryEditorOperatorColor;
|
|
}
|
|
|
|
foreach (Match match in Regex.Matches(myQueryTextBox.Text, @"//.*$", RegexOptions.Multiline))
|
|
{
|
|
myQueryTextBox.Select(match.Index, match.Length);
|
|
myQueryTextBox.SelectionColor = QueryEditorCommentColor;
|
|
}
|
|
|
|
myQueryTextBox.Select(selection_start, selection_length);
|
|
if (selection_length == 0)
|
|
myQueryTextBox.SelectionColor = QueryEditorDefaultColor;
|
|
myQueryTextBox.ResumeLayout();
|
|
}
|
|
finally
|
|
{
|
|
_is_applying_query_syntax_highlighting = false;
|
|
}
|
|
}
|
|
|
|
|
|
private void myLoadAssemblies()
|
|
{
|
|
myTreeView.Nodes.Clear();
|
|
IDictionary libraryData = myGetLibraryData();
|
|
foreach (DictionaryEntry de in libraryData)
|
|
{
|
|
TreeNode assemblyNode = new TreeNode(de.Key as String);
|
|
foreach (DictionaryEntry innerDe in (de.Value as IDictionary))
|
|
{
|
|
string primitive_name = innerDe.Key as string;
|
|
TreeNode primitiveNode = new TreeNode(primitive_name)
|
|
{
|
|
Tag = primitive_name
|
|
};
|
|
foreach (string con in (innerDe.Value as ICollection))
|
|
primitiveNode.Nodes.Add(con);
|
|
assemblyNode.Nodes.Add(primitiveNode);
|
|
}
|
|
myTreeView.Nodes.Add(assemblyNode);
|
|
}
|
|
myTreeView.Sort();
|
|
/*
|
|
myPrimitivesTextBox.Clear ();
|
|
ArrayList al = new ArrayList(PrimitiveManager.instance.getPrimitiveNames());
|
|
al.Sort();
|
|
foreach (string s in al)
|
|
{
|
|
myPrimitivesTextBox.Text += "\n" + s + " (from " + PrimitiveManager.instance.getAssemblyName(s) + ")\n";
|
|
foreach (string desc in PrimitiveManager.instance.getConstructorSigns(s))
|
|
myPrimitivesTextBox.Text += "\t" + desc + "\n";
|
|
}*/
|
|
}
|
|
|
|
private void myHandleTableListChange(object o)
|
|
{
|
|
BeginInvoke(() =>
|
|
{
|
|
tagRows = ((IDataPacket)o).newRows;
|
|
myUpdateTableList();
|
|
});
|
|
}
|
|
|
|
|
|
#region Persistence Keys
|
|
public int textBoxHeight
|
|
{
|
|
get { return myQueryTextBox.Height; }
|
|
set { myQueryTextBox.Height = value; }
|
|
}
|
|
|
|
private void myLoadPersistedState(object sender, BlueRegistry blueReg)
|
|
{
|
|
myQueryTextBox.Text = blueReg.getValue(RegistryRoot.HKCU, LastQueryRegistryKey, string.Empty)?.ToString() ?? string.Empty;
|
|
_load_recent_saved_files(blueReg.getValue(RegistryRoot.HKCU, RecentSavedFilesRegistryKey, string.Empty)?.ToString());
|
|
_refresh_recent_saved_files_menu();
|
|
}
|
|
|
|
private void mySavePersistedState(object sender, BlueRegistry blueReg)
|
|
{
|
|
blueReg.setValue(RegistryRoot.HKCU, LastQueryRegistryKey, myQueryTextBox.Text ?? string.Empty);
|
|
blueReg.setValue(RegistryRoot.HKCU, RecentSavedFilesRegistryKey, string.Join("|", _recent_saved_files));
|
|
}
|
|
#endregion
|
|
|
|
private Stopwatch _stopwatch = new Stopwatch();
|
|
private void myTryExpression(string expStr)
|
|
{
|
|
_stopwatch.Restart();
|
|
myFreezeView(false); // force unfreeze the view
|
|
DataStreamExpression oldExp = myExp;
|
|
try
|
|
{
|
|
var exp = DataStreamExpressionsInterpreter.Evaluate(expStr);
|
|
|
|
if (exp == null)
|
|
throw new Exception("Syntax error. I am afraid I have no further details. Let Pedro know if you are really bothered about it.");
|
|
|
|
myDataGrid.DataSource = null;
|
|
myTabControl.SelectedIndex = 0;
|
|
myErrorTextBox.Text = "";
|
|
// myDataGrid.CaptionText = "";
|
|
|
|
if (myCurrentStream != null)
|
|
myCurrentStream.onChange -= new BCG.DataStream.ChangeDelegate(myCallback);
|
|
myCurrentStream = null;
|
|
|
|
myExp = exp;
|
|
myCrono.Restart();
|
|
|
|
(myCurrentStream = myExp.getView(new Dictionary<string, StatementExpression>(0))).onChange += new DataStream.ChangeDelegate(myCallback);
|
|
myChangeStyle = true;
|
|
//new SimpleBindableStream(myExp.getView(new Hashtable())).onChange += new DataStream.ChangeDelegate(myCallback);
|
|
/*
|
|
if (oldExp != null)
|
|
oldExp.getView(new Hashtable()).onChange -= new DataStream.ChangeDelegate(myCallback);
|
|
*/
|
|
//myQueryTextBox.Text = expStr;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Ui.warn(exc.ToString());
|
|
|
|
myDataGrid.DataSource = null;
|
|
myTabControl.SelectedIndex = 2;
|
|
myExp = oldExp;
|
|
myErrorTextBox.Text = exc.Message + "\n";
|
|
if (exc.InnerException != null)
|
|
myErrorTextBox.Text += "Inner Exception: " + exc.InnerException.Message + "\n";
|
|
myErrorTextBox.Text += "\n" + exc.StackTrace;
|
|
myCSharpText.Text = "";
|
|
}
|
|
}
|
|
|
|
private string myExtractFromClass(TextReader r)
|
|
{
|
|
string line = r.ReadLine();
|
|
while (line != null && line.IndexOf("*Expression*") == -1)
|
|
line = r.ReadLine();
|
|
|
|
if (line == null)
|
|
throw new Exception("Unexpected EOF");
|
|
|
|
r.ReadLine();
|
|
|
|
string result = "";
|
|
line = r.ReadLine();
|
|
|
|
while (line != null && line.IndexOf("----------------------------------------------------------------------") == -1)
|
|
{
|
|
if (line != "")
|
|
result += line.Substring(" ".Length) + "\n";
|
|
line = r.ReadLine();
|
|
}
|
|
if (line == null)
|
|
throw new Exception("Unexpected EOF");
|
|
|
|
return result;
|
|
}
|
|
|
|
public void loadFile(string fileName)
|
|
{
|
|
try
|
|
{
|
|
TextReader r = new StreamReader(fileName);
|
|
try
|
|
{
|
|
myQueryTextBox.Text = myExtractFromClass(r);
|
|
}
|
|
finally
|
|
{
|
|
r.Close();
|
|
}
|
|
myLastFileName = fileName;
|
|
this.Text = fileName;
|
|
_track_recent_saved_file(fileName);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Ui.warn(exc.ToString());
|
|
|
|
myDataGrid.DataSource = null;
|
|
myTabControl.SelectedIndex = 1;
|
|
myErrorTextBox.Text = exc.Message;
|
|
myErrorTextBox.Text += "\n" + exc.StackTrace;
|
|
}
|
|
|
|
}
|
|
|
|
private void myPrintCode(IBlueTableSchema schema, ICollection vars, string code)
|
|
{
|
|
|
|
myCSharpText.Text = "using System;\n\nnamespace BCG\n{";
|
|
|
|
myCSharpText.Text += "\n/*";
|
|
myCSharpText.Text += "\n ----------------------------------------------------------------------";
|
|
myCSharpText.Text += "\n *Expression*";
|
|
myCSharpText.Text += "\n ----------------------------------------------------------------------";
|
|
foreach (string line in myQueryTextBox.Text.Split('\n'))
|
|
myCSharpText.Text += "\n " + line;
|
|
myCSharpText.Text += "\n\n ----------------------------------------------------------------------";
|
|
myCSharpText.Text += "\n *Schema*";
|
|
myCSharpText.Text += "\n ----------------------------------------------------------------------";
|
|
foreach (ColumnInfo ci in schema.columnInfo)
|
|
myCSharpText.Text += "\n " + ci.colName + new string(' ', Math.Max(32 - ci.colName.Length, 1)) + ci.colType.ToString();
|
|
myCSharpText.Text += "\n*/\n";
|
|
|
|
|
|
string lastVar = null;
|
|
string variableDeclarations = "";
|
|
foreach (string var in vars)
|
|
{
|
|
variableDeclarations += " ViewStream " + var + ";\n";
|
|
lastVar = var;
|
|
}
|
|
|
|
|
|
|
|
myLastClassName = null;
|
|
if (lastVar != null)
|
|
myLastClassName = lastVar[0].ToString().ToUpper() + lastVar.Substring(1);
|
|
else
|
|
myLastClassName = "MyView";
|
|
|
|
myCSharpText.Text += "\n\n public class " + myLastClassName + " : ViewStream \n {\n";
|
|
|
|
myCSharpText.Text += " public " + myLastClassName + "() : this(null) {}\n";
|
|
myCSharpText.Text += " public " + myLastClassName + "(ViewStreamDatabase db)\n {\n";
|
|
|
|
myCSharpText.Text += variableDeclarations;
|
|
|
|
if (lastVar != null)
|
|
myCSharpText.Text += "\n";
|
|
myCSharpText.Text += code + "\n";
|
|
if (lastVar != null)
|
|
myCSharpText.Text += " mySetRealSource(" + lastVar + ");\n";
|
|
myCSharpText.Text += " }\n";
|
|
myCSharpText.Text += " }\n";
|
|
myCSharpText.Text += "}";
|
|
}
|
|
|
|
static DataGridViewColumn _column_factory(ColumnInfo ci)
|
|
{
|
|
return new DataGridViewTextBoxColumn
|
|
{
|
|
HeaderText = ci.colName,
|
|
Width = get_col_width(ci)
|
|
};
|
|
|
|
static int get_col_width(ColumnInfo ci)
|
|
{
|
|
const int CHAR_WIDTH = 10;
|
|
const int MIN_WIDTH = 50;
|
|
const int MIN_DATE_WIDTH = 200;
|
|
var header_width = ci.colName.Length * CHAR_WIDTH;
|
|
var min_width = ci.colType == typeof(DateTime) ? MIN_DATE_WIDTH : MIN_WIDTH;
|
|
return Math.Max(header_width, min_width);
|
|
}
|
|
}
|
|
|
|
private void myApplyDateTimeFormatting(IBlueTableSchema schema)
|
|
{
|
|
var dateTimeColumns = new HashSet<string>(
|
|
schema.columnInfo
|
|
.Where(ci => ci.colType == typeof(DateTime))
|
|
.Select(ci => ci.colName));
|
|
|
|
foreach (DataGridViewColumn column in myDataGrid.Columns)
|
|
{
|
|
if (!dateTimeColumns.Contains(column.DataPropertyName) && !dateTimeColumns.Contains(column.Name))
|
|
continue;
|
|
|
|
column.DefaultCellStyle.Format = DateTimeDisplayFormat;
|
|
column.Width = Math.Max(column.Width, 220);
|
|
}
|
|
}
|
|
|
|
void _apply_grid_theme()
|
|
{
|
|
myDataGrid.BackgroundColor = GridBackgroundColor;
|
|
myDataGrid.BorderStyle = BorderStyle.None;
|
|
myDataGrid.EnableHeadersVisualStyles = false;
|
|
myDataGrid.GridColor = GridGridLineColor;
|
|
myDataGrid.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal;
|
|
myDataGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
|
|
myDataGrid.MultiSelect = false;
|
|
myDataGrid.RowHeadersVisible = false;
|
|
myDataGrid.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
|
|
myDataGrid.RowHeadersBorderStyle = DataGridViewHeaderBorderStyle.None;
|
|
myDataGrid.ColumnHeadersHeight = 36;
|
|
myDataGrid.RowTemplate.Height = 24;
|
|
myDataGrid.Font = new Font("Consolas", 9F, FontStyle.Regular, GraphicsUnit.Point);
|
|
|
|
myDataGrid.DefaultCellStyle.BackColor = GridBackgroundColor;
|
|
myDataGrid.DefaultCellStyle.ForeColor = Color.White;
|
|
myDataGrid.DefaultCellStyle.SelectionBackColor = GridSelectionColor;
|
|
myDataGrid.DefaultCellStyle.SelectionForeColor = GridSelectionForeColor;
|
|
myDataGrid.DefaultCellStyle.Padding = new Padding(4, 1, 4, 1);
|
|
|
|
myDataGrid.AlternatingRowsDefaultCellStyle.BackColor = GridAltRowColor;
|
|
myDataGrid.AlternatingRowsDefaultCellStyle.ForeColor = Color.White;
|
|
myDataGrid.AlternatingRowsDefaultCellStyle.SelectionBackColor = GridSelectionColor;
|
|
myDataGrid.AlternatingRowsDefaultCellStyle.SelectionForeColor = GridSelectionForeColor;
|
|
|
|
myDataGrid.ColumnHeadersDefaultCellStyle.BackColor = GridHeaderColor;
|
|
myDataGrid.ColumnHeadersDefaultCellStyle.ForeColor = Color.White;
|
|
myDataGrid.ColumnHeadersDefaultCellStyle.SelectionBackColor = GridHeaderColor;
|
|
myDataGrid.ColumnHeadersDefaultCellStyle.SelectionForeColor = Color.White;
|
|
myDataGrid.ColumnHeadersDefaultCellStyle.Font = new Font("Consolas", 9F, FontStyle.Bold, GraphicsUnit.Point);
|
|
myDataGrid.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
|
|
myDataGrid.ColumnHeadersDefaultCellStyle.Padding = new Padding(6, 2, 6, 2);
|
|
}
|
|
|
|
void _apply_grid_column_styling(IBlueTableSchema schema)
|
|
{
|
|
var column_types = schema.columnInfo.ToDictionary(ci => ci.colName, ci => ci.colType, StringComparer.OrdinalIgnoreCase);
|
|
foreach (DataGridViewColumn column in myDataGrid.Columns)
|
|
{
|
|
if (!column_types.TryGetValue(column.DataPropertyName, out var col_type) &&
|
|
!column_types.TryGetValue(column.Name, out col_type))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
column.SortMode = DataGridViewColumnSortMode.NotSortable;
|
|
|
|
if (_is_numeric_type(col_type))
|
|
{
|
|
column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
|
|
}
|
|
else
|
|
{
|
|
column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
|
|
}
|
|
|
|
if (col_type == typeof(DateTime))
|
|
{
|
|
column.DefaultCellStyle.ForeColor = GridTimestampColor;
|
|
}
|
|
else if (string.Equals(column.HeaderText, "id", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
column.DefaultCellStyle.ForeColor = GridIdentifierColor;
|
|
}
|
|
else if (_looks_like_indicator(column.HeaderText))
|
|
{
|
|
column.DefaultCellStyle.ForeColor = GridIndicatorColor;
|
|
}
|
|
else
|
|
{
|
|
column.DefaultCellStyle.ForeColor = Color.White;
|
|
}
|
|
}
|
|
|
|
static bool _is_numeric_type(Type type)
|
|
{
|
|
return type == typeof(int) ||
|
|
type == typeof(long) ||
|
|
type == typeof(float) ||
|
|
type == typeof(double) ||
|
|
type == typeof(decimal) ||
|
|
type == typeof(short) ||
|
|
type == typeof(uint) ||
|
|
type == typeof(ulong);
|
|
}
|
|
|
|
static bool _looks_like_indicator(string column_name)
|
|
{
|
|
return column_name.Contains("rsi", StringComparison.OrdinalIgnoreCase) ||
|
|
column_name.Contains("macd", StringComparison.OrdinalIgnoreCase) ||
|
|
column_name.Contains("atr", StringComparison.OrdinalIgnoreCase) ||
|
|
column_name.Contains("moving_average", StringComparison.OrdinalIgnoreCase) ||
|
|
column_name.Contains("signal", StringComparison.OrdinalIgnoreCase) ||
|
|
column_name.Contains("histogram", StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
}
|
|
|
|
// this is the stream callback
|
|
private void myCallback(object o)
|
|
{
|
|
var dp = (IDataPacket)o;
|
|
Log.Ui.diag(dp.GetIncrementalIdString());
|
|
Volatile.Write(ref pendingData, dp);
|
|
}
|
|
|
|
private Stopwatch myCrono = new();
|
|
|
|
private DataStreamExpression? myExp;
|
|
|
|
private void myTimer_Tick(object sender, System.EventArgs e)
|
|
{
|
|
var dp = Interlocked.Exchange(ref pendingData, null);
|
|
if (dp is null)
|
|
{
|
|
return;
|
|
}
|
|
_stopwatch.Stop();
|
|
var timer = Stopwatch.StartNew();
|
|
myCrono.Stop();
|
|
myToolStripStatusLabelTime.BackColor = Color.Black;
|
|
myToolStripStatusLabelRows.BackColor = Color.Black;
|
|
myToolStripStatusLabelTime.ForeColor = Color.White;
|
|
myToolStripStatusLabelRows.ForeColor = Color.White;
|
|
string time_text = "Last update: " + DateTime.Now.ToString("hh:mm:ss:fff tt") + $" time: {_stopwatch.ElapsedMilliseconds} msecs\t\t";
|
|
myToolStripStatusLabelTime.Text = time_text;
|
|
myToolStripStatusLabelRows.Text = "New = " + dp.newRows.Count + " Added = " + dp.addedRows.Count + " Deleted = " + dp.deletedRows.Count;
|
|
Log.Ui.diag(Text);
|
|
int hscrollval = myChangeStyle ? 0 : myDataGrid.HorizScrollBarValue;
|
|
|
|
myDataGrid.DataSource = new SimpleBindableCollection(dp.newRows.schema, dp.newRows);
|
|
_apply_grid_theme();
|
|
myApplyDateTimeFormatting(dp.newRows.schema);
|
|
_apply_grid_column_styling(dp.newRows.schema);
|
|
myDataGrid.ClearSelection();
|
|
var force = false;
|
|
if (myChangeStyle && force)
|
|
{
|
|
myChangeStyle = false;
|
|
myDataGrid.Columns.Clear();
|
|
myDataGrid.Columns.AddRange(Array.ConvertAll(dp.Schema.columnInfo, _column_factory));
|
|
}
|
|
myCrono.Restart();
|
|
// myDataGrid.CaptionText = myCrono.time.TotalMilliseconds + " ms ";
|
|
// myDataGrid.CaptionText += dp.newRows.Count.ToString () + " records";
|
|
|
|
|
|
myDataGrid.HorizScrollBarValue = hscrollval;
|
|
|
|
var varNames = new List<string>(0);
|
|
var code = myExp?.print(9, varNames);
|
|
myPrintCode(dp.Schema, varNames, code);
|
|
myConsoleRichTextBox.Clear();
|
|
// this was was very very slow
|
|
//myConsoleRichTextBox.Text = BlueDataUtility.get_printed_rows(dp.newRows, (col) => 30);
|
|
timer.Stop();
|
|
Log.Gen.info(
|
|
$"DSQA MainForm.myCallback table: {dp.Schema.tableName} rows: {dp.newRows.Count} time: {timer.Elapsed.TotalMilliseconds:0.00}ms");
|
|
}
|
|
|
|
class StringWrapper
|
|
{
|
|
public StringWrapper(string s)
|
|
{
|
|
myTableName = s;
|
|
}
|
|
public string tableName
|
|
{
|
|
get { return myTableName; }
|
|
}
|
|
private string myTableName;
|
|
}
|
|
|
|
private void MainForm_Closed(object sender, System.EventArgs e)
|
|
{
|
|
if (myExp != null)
|
|
myExp.getView(new Dictionary<string, StatementExpression>(0)).onChange -= new DataStream.ChangeDelegate(myCallback);
|
|
}
|
|
|
|
private void myMenuItemExecuteQueryClick(object sender, System.EventArgs e)
|
|
{
|
|
myQueryTextBox.SelectionStart = myQueryTextBox.Text.Length;
|
|
myQueryTextBox.SelectionLength = myQueryTextBox.Text.Length;
|
|
myQueryTextBox.SelectionColor = Color.White;
|
|
myQueryTextBox.SelectionLength = 0;
|
|
myTryExpression(myQueryTextBox.Text);
|
|
}
|
|
|
|
private void myToolStripMenuItemExecSel_Click(object sender, EventArgs e)
|
|
{
|
|
// int selstart = myQueryTextBox.SelectionStart;
|
|
// int sellength = myQueryTextBox.SelectionLength;
|
|
// myQueryTextBox.SelectionStart = 0;
|
|
// myQueryTextBox.SelectionLength = myQueryTextBox.Text.Length;
|
|
// myQueryTextBox.SelectionColor = Color.White;
|
|
// myQueryTextBox.SelectionStart = selstart;
|
|
// myQueryTextBox.SelectionLength = sellength;
|
|
// myQueryTextBox.SelectionColor = Color.Crimson;
|
|
// myTryExpression(myQueryTextBox.SelectedText);
|
|
// myQueryTextBox.SelectionStart = myQueryTextBox.Text.Length;
|
|
// myQueryTextBox.SelectionLength = 0;
|
|
// myQueryTextBox.SelectionColor = Color.White;
|
|
}
|
|
|
|
private void myMenuItemOpenClick(object sender, System.EventArgs e)
|
|
{
|
|
OpenFileDialog od = new OpenFileDialog();
|
|
od.Filter = "All files (*.*)|*.*|C# class (*.cs)|*.cs";
|
|
|
|
if (od.ShowDialog() == DialogResult.OK)
|
|
loadFile(od.FileName);
|
|
}
|
|
|
|
private void mySave(string fileName)
|
|
{
|
|
using (TextWriter w = new StreamWriter(fileName))
|
|
w.Write(myCSharpText.Text);
|
|
myLastFileName = fileName;
|
|
this.Text = fileName;
|
|
_track_recent_saved_file(fileName);
|
|
}
|
|
|
|
private void myMenuItemSaveClick(object sender, System.EventArgs e)
|
|
{
|
|
if (myLastFileName == null)
|
|
myMenuItemSaveAsClick(sender, e);
|
|
else
|
|
mySave(myLastFileName);
|
|
}
|
|
|
|
private void myMenuItemSaveAsClick(object sender, System.EventArgs e)
|
|
{
|
|
SaveFileDialog sd = new SaveFileDialog();
|
|
if (myLastFileName != null)
|
|
sd.FileName = myLastFileName;
|
|
else
|
|
sd.FileName = myLastClassName + ".cs";
|
|
|
|
if (sd.ShowDialog() == DialogResult.OK)
|
|
mySave(sd.FileName);
|
|
}
|
|
|
|
private void _load_recent_saved_files(string? serialized_paths)
|
|
{
|
|
_recent_saved_files.Clear();
|
|
if (string.IsNullOrWhiteSpace(serialized_paths))
|
|
return;
|
|
|
|
foreach (string path in serialized_paths.Split('|'))
|
|
{
|
|
if (string.IsNullOrWhiteSpace(path))
|
|
continue;
|
|
if (_recent_saved_files.Contains(path, StringComparer.OrdinalIgnoreCase))
|
|
continue;
|
|
_recent_saved_files.Add(path);
|
|
if (_recent_saved_files.Count >= MaxRecentSavedFiles)
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void _track_recent_saved_file(string file_name)
|
|
{
|
|
_recent_saved_files.RemoveAll(path => string.Equals(path, file_name, StringComparison.OrdinalIgnoreCase));
|
|
_recent_saved_files.Insert(0, file_name);
|
|
if (_recent_saved_files.Count > MaxRecentSavedFiles)
|
|
_recent_saved_files.RemoveRange(MaxRecentSavedFiles, _recent_saved_files.Count - MaxRecentSavedFiles);
|
|
_refresh_recent_saved_files_menu();
|
|
}
|
|
|
|
private void _refresh_recent_saved_files_menu()
|
|
{
|
|
var file_menu = myToolStripMenuItemFile.DropDownItems;
|
|
for (int i = file_menu.Count - 1; i >= 0; i--)
|
|
{
|
|
if (file_menu[i] is ToolStripMenuItem menu_item && Equals(menu_item.Tag, "recent-saved-file"))
|
|
file_menu.RemoveAt(i);
|
|
}
|
|
|
|
if (_recent_saved_files_separator != null)
|
|
{
|
|
file_menu.Remove(_recent_saved_files_separator);
|
|
_recent_saved_files_separator.Dispose();
|
|
_recent_saved_files_separator = null;
|
|
}
|
|
|
|
if (_recent_saved_files.Count == 0)
|
|
return;
|
|
|
|
int insert_index = file_menu.IndexOf(myToolStripMenuItemExit);
|
|
if (insert_index < 0)
|
|
insert_index = file_menu.Count;
|
|
|
|
_recent_saved_files_separator = new ToolStripSeparator();
|
|
file_menu.Insert(insert_index, _recent_saved_files_separator);
|
|
insert_index++;
|
|
|
|
foreach (string path in _recent_saved_files)
|
|
{
|
|
var menu_item = new ToolStripMenuItem(Path.GetFileName(path))
|
|
{
|
|
Tag = "recent-saved-file",
|
|
ToolTipText = path,
|
|
BackColor = Color.FromArgb(36, 36, 49),
|
|
ForeColor = Color.Lime
|
|
};
|
|
menu_item.Click += (_, __) => loadFile(path);
|
|
file_menu.Insert(insert_index, menu_item);
|
|
insert_index++;
|
|
}
|
|
}
|
|
|
|
private void myTableListBox_DoubleClick(object sender, System.EventArgs e)
|
|
{
|
|
if (myTableListBox.SelectedItem != null)
|
|
{
|
|
string tableName = myTableListBox.SelectedItem.ToString();
|
|
myQueryTextBox.Text = myQueryTextBox.Text == "" ? tableName : myQueryTextBox.Text + "\n" + tableName;
|
|
myTryExpression(myQueryTextBox.Text);
|
|
}
|
|
}
|
|
|
|
private void myDataGrid_MouseEnter(object sender, System.EventArgs e)
|
|
{
|
|
//myDataGrid.TableStyles[0].GridLineColor = Color.LightSteelBlue;
|
|
// if (myDataGrid.TableStyles.Count > 0)
|
|
// myDataGrid.TableStyles[0].HeaderBackColor = Color.LightSteelBlue;
|
|
}
|
|
|
|
private void myDataGrid_MouseLeave(object sender, System.EventArgs e)
|
|
{
|
|
//myDataGrid.TableStyles[0].GridLineColor = Color.Gainsboro;
|
|
// if (myDataGrid.TableStyles.Count > 0)
|
|
// myDataGrid.TableStyles[0].HeaderBackColor = Color.Gainsboro;
|
|
}
|
|
|
|
private void myCSharpText_MouseEnter(object sender, System.EventArgs e)
|
|
{
|
|
//myCSharpText.BackColor = Color.Gainsboro;
|
|
myCSharpText.Font = new Font(myCSharpText.Font.Name, myCSharpText.Font.Size, FontStyle.Bold);
|
|
}
|
|
|
|
private void myCSharpText_MouseLeave(object sender, System.EventArgs e)
|
|
{
|
|
//myCSharpText.BackColor = Color.White;
|
|
myCSharpText.Font = new Font(myCSharpText.Font.Name, myCSharpText.Font.Size, FontStyle.Regular);
|
|
}
|
|
|
|
private void myTableListBox_MouseEnter(object sender, System.EventArgs e)
|
|
{
|
|
//myTableListBox.BackColor = Color.Gainsboro;
|
|
myTableListBox.Font = new Font(myTableListBox.Font.Name, myTableListBox.Font.Size, FontStyle.Bold);
|
|
}
|
|
|
|
private void myTableListBox_MouseLeave(object sender, System.EventArgs e)
|
|
{
|
|
//myTableListBox.BackColor = Color.White;
|
|
myTableListBox.Font = new Font(myTableListBox.Font.Name, myTableListBox.Font.Size, FontStyle.Regular);
|
|
}
|
|
|
|
private void myLoad(object sender, EventArgs e)
|
|
{
|
|
myFreezeView(false);
|
|
|
|
myToolStripMenuItemSite.DropDownItems.Clear();
|
|
// foreach (var name in SitesCfg.instance.siteNames)
|
|
// {
|
|
// ToolStripMenuItem mi = new ToolStripMenuItem (name);
|
|
// mi.Click += new EventHandler (myMenuItemSiteClick);
|
|
// mySiteItems.Add (mi);
|
|
// mi.Enabled = true;
|
|
// myToolStripMenuItemSite.DropDownItems.Add (mi);
|
|
|
|
// if (name == mySite)
|
|
// mi.Checked = true;
|
|
// }
|
|
|
|
myConsoleRichTextBox.ReadOnly = true;
|
|
myConsoleOutput = new RichTextBoxStreamWriter(myConsoleRichTextBox);
|
|
Console.SetOut(myConsoleOutput);
|
|
Console.SetError(myConsoleOutput);
|
|
if (BCG.Utilities.Win32.WindowsAPI.SetStdHandle(-11, myConsoleRichTextBox.Handle) == 0) // set stdout
|
|
{
|
|
var ex = new Win32Exception(); // same as new Win32Exception(Marshal.GetLastWin32Error())
|
|
Console.WriteLine(ex.Message);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Set stdout worked.");
|
|
}
|
|
|
|
if (BCG.Utilities.Win32.WindowsAPI.SetStdHandle(-12, myConsoleRichTextBox.Handle) == 0) // set stderr
|
|
{
|
|
var ex = new Win32Exception(); // same as new Win32Exception(Marshal.GetLastWin32Error())
|
|
Console.WriteLine(ex.Message);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Set stderr worked.");
|
|
}
|
|
Console.WriteLine("Redirecting console ouput to this window...");
|
|
|
|
myTreeView.TreeViewNodeSorter = new PrimitiveTreeNodeComparer();
|
|
myLoadAssemblies();
|
|
|
|
// ViewStreamDatabase.instance = new ViewStreamDatabase();
|
|
myAllTagsStream = myGetAllTagsStream();
|
|
myAllTagsStream.onChange += new BCG.DataStream.ChangeDelegate(myHandleTableListChange);
|
|
myTabControl.SelectedIndex = 3;
|
|
myTreeView.AfterSelect += new TreeViewEventHandler(myHandleTreeNodeSelect);
|
|
myTreeView.KeyPress += myHandleTreeViewKeyPress;
|
|
myTreeView.NodeMouseHover += myHandleTreeNodeMouseHover;
|
|
myTreeView.MouseLeave += myHandleTreeViewMouseLeave;
|
|
//do this lazily so we don't have to have bps, etc up to run dsqa
|
|
//_library = new LibraryForm(this);
|
|
}
|
|
|
|
private void myMenuItemSiteClick(object sender, System.EventArgs e)
|
|
{
|
|
ToolStripMenuItem mi = (ToolStripMenuItem)sender;
|
|
|
|
if (mi.Text != mySite)
|
|
{
|
|
mySite = mi.Text;
|
|
foreach (var m in mySiteItems)
|
|
m.Checked = false;
|
|
mi.Checked = true;
|
|
|
|
myAllTagsStream.onChange -= new BCG.DataStream.ChangeDelegate(myHandleTableListChange);
|
|
myTableListBox.Items.Clear();
|
|
|
|
// SitesCore.setMySiteName (mySite);
|
|
|
|
// ViewStreamDatabase.instance = new ViewStreamDatabase();
|
|
myAllTagsStream = myGetAllTagsStream();
|
|
myAllTagsStream.onChange += new BCG.DataStream.ChangeDelegate(myHandleTableListChange);
|
|
|
|
myDataGrid.DataSource = null;
|
|
myTabControl.SelectedIndex = 3;
|
|
mySetText();
|
|
}
|
|
}
|
|
|
|
private void myClosing(object sender, CancelEventArgs e)
|
|
{
|
|
}
|
|
|
|
private void myHandleTreeNodeSelect(object sender, TreeViewEventArgs e)
|
|
{
|
|
if (myTreeView.SelectedNode != null)
|
|
{
|
|
if (myTreeView.SelectedNode.LastNode == null)
|
|
{
|
|
string primitive_name = myTreeView.SelectedNode.Parent.Tag as string ?? myTreeView.SelectedNode.Parent.Text;
|
|
string sn = primitive_name + "()";
|
|
myQueryTextBox.Text = myQueryTextBox.Text == "" ? sn : myQueryTextBox.Text + "\n" + sn;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void myHandleTreeViewKeyPress(object? sender, KeyPressEventArgs e)
|
|
{
|
|
if (!Char.IsLetterOrDigit(e.KeyChar))
|
|
return;
|
|
|
|
char search_char = Char.ToLowerInvariant(e.KeyChar);
|
|
TreeNode? assembly_node = _get_selected_assembly_node();
|
|
if (assembly_node is null)
|
|
return;
|
|
|
|
int start_idx = 0;
|
|
if (_last_primitive_search_char == search_char &&
|
|
ReferenceEquals(_last_primitive_search_assembly_node, assembly_node) &&
|
|
myTreeView.SelectedNode?.Parent == assembly_node)
|
|
{
|
|
start_idx = myTreeView.SelectedNode.Index + 1;
|
|
}
|
|
|
|
TreeNode? match_node = _find_matching_primitive_node(assembly_node, search_char, start_idx) ??
|
|
_find_matching_primitive_node(assembly_node, search_char, 0);
|
|
|
|
if (match_node is not null)
|
|
{
|
|
myTreeView.SelectedNode = match_node;
|
|
match_node.EnsureVisible();
|
|
_last_primitive_search_char = search_char;
|
|
_last_primitive_search_assembly_node = assembly_node;
|
|
e.Handled = true;
|
|
}
|
|
}
|
|
|
|
private TreeNode? _get_selected_assembly_node()
|
|
{
|
|
if (myTreeView.SelectedNode is null)
|
|
return myTreeView.Nodes.Count > 0 ? myTreeView.Nodes[0] : null;
|
|
|
|
return myTreeView.SelectedNode.Parent ?? myTreeView.SelectedNode;
|
|
}
|
|
|
|
private TreeNode? _find_matching_primitive_node(TreeNode assembly_node, char search_char, int start_idx)
|
|
{
|
|
for (int i = start_idx; i < assembly_node.Nodes.Count; i++)
|
|
{
|
|
TreeNode primitive_node = assembly_node.Nodes[i];
|
|
string primitive_name = primitive_node.Tag as string ?? primitive_node.Text;
|
|
if (primitive_name.Length > 0 && Char.ToLowerInvariant(primitive_name[0]) == search_char)
|
|
return primitive_node;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void myHandleTreeNodeMouseHover(object? sender, TreeNodeMouseHoverEventArgs e)
|
|
{
|
|
if (e.Node?.Tag is not string primitive_name)
|
|
{
|
|
_primitive_tool_tip.Hide(myTreeView);
|
|
return;
|
|
}
|
|
|
|
Type? primitive_type = PrimitiveManager.instance.get_dsl_op_type(primitive_name);
|
|
if (primitive_type is null)
|
|
{
|
|
_primitive_tool_tip.Hide(myTreeView);
|
|
return;
|
|
}
|
|
|
|
string tooltip_text = $"Namespace: {primitive_type.Namespace ?? "(none)"}";
|
|
string? source_path = _get_source_file_path(primitive_type);
|
|
if (!String.IsNullOrWhiteSpace(source_path))
|
|
tooltip_text += $"\nSource: {source_path}";
|
|
|
|
Point mouse_point = myTreeView.PointToClient(Cursor.Position);
|
|
_primitive_tool_tip.Show(tooltip_text, myTreeView, mouse_point.X + 12, mouse_point.Y + 12, 8000);
|
|
}
|
|
|
|
private void myHandleTreeViewMouseLeave(object? sender, EventArgs e)
|
|
{
|
|
_primitive_tool_tip.Hide(myTreeView);
|
|
}
|
|
|
|
private string? _get_source_file_path(Type primitive_type)
|
|
{
|
|
string cache_key = primitive_type.FullName ?? primitive_type.Name;
|
|
if (_primitive_source_path_cache.TryGetValue(cache_key, out string? cached_path))
|
|
return cached_path;
|
|
|
|
Dictionary<string, string?> source_file_index = _source_file_index ??= _build_source_file_index();
|
|
if (!source_file_index.TryGetValue(primitive_type.Name, out string? source_path))
|
|
return null;
|
|
_primitive_source_path_cache[cache_key] = source_path;
|
|
return source_path;
|
|
}
|
|
|
|
private Dictionary<string, string?> _build_source_file_index()
|
|
{
|
|
Dictionary<string, string?> source_file_index = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
|
|
string? repo_root = _repo_root_path ??= _find_repo_root();
|
|
if (String.IsNullOrWhiteSpace(repo_root))
|
|
return source_file_index;
|
|
|
|
string source_root = Path.Combine(repo_root, "src", "DataStreamSuite");
|
|
if (!Directory.Exists(source_root))
|
|
return source_file_index;
|
|
|
|
foreach (string file_path in Directory.EnumerateFiles(source_root, "*.cs", SearchOption.AllDirectories))
|
|
{
|
|
string type_name = Path.GetFileNameWithoutExtension(file_path);
|
|
if (!source_file_index.ContainsKey(type_name))
|
|
source_file_index[type_name] = file_path;
|
|
}
|
|
return source_file_index;
|
|
}
|
|
|
|
private string? _find_repo_root()
|
|
{
|
|
string? curr_path = AppDomain.CurrentDomain.BaseDirectory;
|
|
while (!String.IsNullOrWhiteSpace(curr_path))
|
|
{
|
|
if (Directory.Exists(Path.Combine(curr_path, "src", "DataStreamSuite")))
|
|
return curr_path;
|
|
curr_path = Directory.GetParent(curr_path)?.FullName;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void myToolStripMenuItemExit_Click(object sender, EventArgs e)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
private void myToolStripMenuItemFreeze_Click(object sender, EventArgs e)
|
|
{
|
|
myFreezeView(myTimer.Enabled);
|
|
}
|
|
|
|
private void myFreezeView(bool freeze)
|
|
{
|
|
myTimer.Enabled = !freeze;
|
|
myToolStripMenuItemFreeze.Checked = freeze;
|
|
myToolStripMenuItemStep.Enabled = freeze;
|
|
}
|
|
|
|
private void myToolStripMenuItemStep_Click(object sender, EventArgs e)
|
|
{
|
|
ViewStreamDatabase.instance.doWork();
|
|
}
|
|
|
|
private void myToolStripMenuItemLoadAss_Click(object sender, EventArgs e)
|
|
{
|
|
OpenFileDialog ofd = new OpenFileDialog();
|
|
ofd.ShowReadOnly = true;
|
|
DialogResult dr = ofd.ShowDialog(this);
|
|
if (ofd.CheckFileExists && ofd.CheckPathExists && dr == DialogResult.OK)
|
|
{
|
|
PrimitiveManager.instance.load_streams_from_assembly(ofd.FileName);
|
|
myLoadAssemblies();
|
|
}
|
|
}
|
|
|
|
private void myToolStripMenuItemTest_Click(object sender, EventArgs e)
|
|
{
|
|
if (myCurrentStream != null)
|
|
{
|
|
myCurrentStream.onChange -= new DataStream.ChangeDelegate(myCallback);
|
|
myCurrentStream.onChange += new DataStream.ChangeDelegate(myCallback);
|
|
}
|
|
}
|
|
|
|
private void myToolStripMenuItemClearConsole_Click(object sender, EventArgs e)
|
|
{
|
|
myConsoleRichTextBox.Clear();
|
|
Console.WriteLine("Redirecting console ouput to this window...");
|
|
}
|
|
|
|
private void myTableFilterBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
myUpdateTableList();
|
|
}
|
|
|
|
private void myUpdateTableList()
|
|
{
|
|
var rows = tagRows;
|
|
if (rows == null)
|
|
return;
|
|
|
|
|
|
ICollection oldItems = myTableListBox.Items;
|
|
|
|
myTableListBox.BeginUpdate();
|
|
int topindex = myTableListBox.TopIndex;
|
|
string topitem = (myTableListBox.Items.Count > 0) ? myTableListBox.Items[topindex].ToString() : string.Empty;
|
|
|
|
myTableListBox.Items.Clear();
|
|
SortedList<string, bool> sl = new SortedList<string, bool>();
|
|
if (string.IsNullOrEmpty(myTableFilterBox.Text))
|
|
foreach (IBlueRow r in rows)
|
|
{
|
|
sl[r["tag"].ToString().Substring(DSTagManager.get_stream_tag("").Length)] = true;
|
|
}
|
|
else
|
|
{
|
|
Regex tableRegex = new Regex(myTableFilterBox.Text);
|
|
foreach (IBlueRow r in rows)
|
|
{
|
|
string thisTable = r["tag"].ToString().Substring(DSTagManager.get_stream_tag("").Length);
|
|
if (tableRegex.IsMatch(thisTable))
|
|
sl[thisTable] = true;
|
|
}
|
|
}
|
|
string[] list = new string[sl.Keys.Count];
|
|
sl.Keys.CopyTo(list, 0);
|
|
myTableListBox.Items.AddRange(list);
|
|
|
|
int top = sl.IndexOfKey(topitem);
|
|
if (top >= 0)
|
|
myTableListBox.TopIndex = top;
|
|
else
|
|
myTableListBox.TopIndex = Math.Min(sl.Count - 1, topindex);
|
|
myTableListBox.EndUpdate();
|
|
}
|
|
|
|
private void testGridToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var timer = new Stopwatch();
|
|
//while (true)
|
|
//{
|
|
// Random rnd = new Random(DateTime.Now.Millisecond);
|
|
// List<double> rand_nos = new List<double>();
|
|
// for (int i = 0; i < 10000; i++)
|
|
// rand_nos.Add(rnd.NextDouble());
|
|
// timer.start();
|
|
// rand_nos.Sort();
|
|
// timer.stop();
|
|
// BCG.Utilities.BlueEventLog.logEvent(String.Format("nrows = {0} sorting time = {1}", rand_nos.Count, timer.lastIntervalTime), BCG.Utilities.BlueEventLevel.Performance);
|
|
// System.Threading.Thread.Sleep(10);
|
|
//}
|
|
|
|
ViewStream s = new LoaderStream(@"P:\Dropbox\Data\spread_md_esoa_cme");
|
|
s = new MutableAppendStream(s, s);
|
|
s.onChange += OnChange;
|
|
|
|
void OnChange(object? obj)
|
|
{
|
|
s.onChange -= OnChange;
|
|
//s = new MutableAppendStream(s, s);
|
|
var rowCollection = ((IDataPacket)obj!).newRows;
|
|
var rows = new List<IBlueRow>(rowCollection.Count);
|
|
rows.AddRange(rowCollection.Cast<IBlueRow>());
|
|
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
timer.Restart();
|
|
rows.Sort(delegate (IBlueRow r1, IBlueRow r2)
|
|
{
|
|
return _sort_dicts_index(r1, r2, 5, true);
|
|
});
|
|
timer.Stop();
|
|
Log.Ui.diag($"nrows = {rows.Count} sorting time = {timer.Elapsed.TotalMilliseconds:0.00}ms");
|
|
}
|
|
}
|
|
}
|
|
|
|
private static int mySortDictionaries(IBlueRow r1, IBlueRow r2, string column, bool low_to_high)
|
|
{
|
|
if (r1.Contains(column) && r2.Contains(column))
|
|
return compare_send_dontcare_to_last(r1[column], r2[column], low_to_high);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
private static int _sort_dicts_index(IBlueRow r1, IBlueRow r2, int col_no, bool low_to_high)
|
|
{
|
|
//return compare_send_dontcare_to_last(r1[col_no], r2[col_no], low_to_high);
|
|
return ((IComparable)r1[col_no]).CompareTo(r2[col_no]);
|
|
}
|
|
|
|
internal static int compare_send_dontcare_to_last(object o1, object o2, bool low_to_high)
|
|
{
|
|
if (myIsDontCare(o1))
|
|
return myIsDontCare(o2) ? 0 : 1;
|
|
else
|
|
return myIsDontCare(o2) ? -1 : (low_to_high ? ((IComparable)o1).CompareTo(o2)
|
|
: ((IComparable)o2).CompareTo(o1));
|
|
}
|
|
|
|
private static bool myIsDontCare(object o)
|
|
{
|
|
return o == null || o == DBNull.Value ||
|
|
o is string && String.IsNullOrEmpty((string)o) ||
|
|
o is double && (Double.IsInfinity((double)o) || Double.IsNaN((double)o)) ||
|
|
o is float && (Single.IsInfinity((float)o) || Single.IsNaN((float)o));
|
|
}
|
|
|
|
private void _new_grid_form(object args)
|
|
{
|
|
//System.Timers.Timer t = new System.Timers.Timer();
|
|
////t.SynchronizingObject
|
|
//BCG.Utilities.BlueEventLog.logEvent(String.Format("New BTSTabularGridTestForm created on thread {0}", System.Threading.Thread.CurrentThread.ManagedThreadId),
|
|
// "Diagnosis");
|
|
//ViewStream s = args as ViewStream;
|
|
//BTSTabularGridTestForm f = new BTSTabularGridTestForm(s);
|
|
//Application.Run(f);
|
|
}
|
|
|
|
private void libraryToolStripMenuItem_Click(object sender, EventArgs e) { }
|
|
|
|
private void myTableFilterLabel_Click(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void MainForm_Load(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|