813 lines
28 KiB
C#
813 lines
28 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.ComponentModel;
|
|||
|
using System.Data;
|
|||
|
using System.Drawing;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Windows.Forms;
|
|||
|
using MathNet.Numerics.LinearAlgebra;
|
|||
|
|
|||
|
namespace MatrixCalculator
|
|||
|
{
|
|||
|
public partial class MainWindow : Form
|
|||
|
{
|
|||
|
private WorksheetFile worksheet = new WorksheetFile();
|
|||
|
private List<Matrix<double>> matrices = new List<Matrix<double>>();
|
|||
|
private Matrix<double> matrixA, matrixB, matrixResult;
|
|||
|
|
|||
|
#region Matrix properties
|
|||
|
private Matrix<double> MatrixA {
|
|||
|
get { return matrixA; }
|
|||
|
set {
|
|||
|
matrixA = value;
|
|||
|
GridViewHelper.PutMatrix(matrixA, dataMatrixA);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private Matrix<double> MatrixB
|
|||
|
{
|
|||
|
get { return matrixB; }
|
|||
|
set
|
|||
|
{
|
|||
|
matrixB = value;
|
|||
|
GridViewHelper.PutMatrix(matrixB, dataMatrixB);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private Matrix<double> MatrixResult
|
|||
|
{
|
|||
|
get { return matrixResult; }
|
|||
|
set
|
|||
|
{
|
|||
|
matrixResult = value;
|
|||
|
GridViewHelper.PutMatrix(matrixResult, dataResult);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private Matrix<double> MatrixPreview
|
|||
|
{
|
|||
|
get {
|
|||
|
if (listMatrices.SelectedItems.Count == 1)
|
|||
|
return matrices[listMatrices.SelectedIndices[0]];
|
|||
|
else return null;
|
|||
|
}
|
|||
|
set {
|
|||
|
GridViewHelper.PutMatrix(value, dataPreview);
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Constructor
|
|||
|
|
|||
|
public MainWindow()
|
|||
|
{
|
|||
|
InitializeComponent();
|
|||
|
ResetAll();
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region User interface
|
|||
|
|
|||
|
#region Menus
|
|||
|
private void menuFileNew_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!ShowSaveWarningDialog()) return;
|
|||
|
|
|||
|
ResetAll();
|
|||
|
worksheet = new WorksheetFile();
|
|||
|
}
|
|||
|
|
|||
|
private void menuFileOpen_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!ShowSaveWarningDialog()) return;
|
|||
|
|
|||
|
// Open file dialog
|
|||
|
string file;
|
|||
|
if (!OpenDialog("Open worksheet...", MatrixCalculator.Properties.Resources.WorksheetFormatFilter, out file)) return;
|
|||
|
|
|||
|
// Open the file
|
|||
|
DataTable data = new DataTable();
|
|||
|
try {
|
|||
|
worksheet = new WorksheetFile(file);
|
|||
|
data = worksheet.Read();
|
|||
|
}
|
|||
|
|
|||
|
catch (Exception ex) {
|
|||
|
MessageBox.Show("Error:" + ex.Message, "Error!");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Load data
|
|||
|
ResetAll();
|
|||
|
AddMatrices(data);
|
|||
|
}
|
|||
|
|
|||
|
private void menuFileSave_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (worksheet.FileName == "")
|
|||
|
{
|
|||
|
string file;
|
|||
|
if (!SaveDialog("Save worksheet...", MatrixCalculator.Properties.Resources.WorksheetFormatFilter, out file)) return;
|
|||
|
|
|||
|
worksheet.FileName = file;
|
|||
|
}
|
|||
|
|
|||
|
try { worksheet.Save(); }
|
|||
|
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message, "Error!"); }
|
|||
|
}
|
|||
|
|
|||
|
private void menuFileSaveAs_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
string file;
|
|||
|
if (!SaveDialog("Save worksheet...", MatrixCalculator.Properties.Resources.WorksheetFormatFilter, out file)) return;
|
|||
|
|
|||
|
try { worksheet.SaveAs(file); }
|
|||
|
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message, "Error!"); }
|
|||
|
}
|
|||
|
|
|||
|
private void menuFileImportCsv_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
string file;
|
|||
|
if (!OpenDialog("Open CSV file...", MatrixCalculator.Properties.Resources.CsvFormatFilter, out file))
|
|||
|
return;
|
|||
|
|
|||
|
ImportCsvWindow wind = new ImportCsvWindow();
|
|||
|
try { wind.LoadFile(file); }
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
MessageBox.Show("Error: " + ex.Message, "Error!");
|
|||
|
}
|
|||
|
|
|||
|
if (wind.ShowDialog() != System.Windows.Forms.DialogResult.OK)
|
|||
|
return;
|
|||
|
|
|||
|
AddMatrix(wind.Matrix, wind.MatrixName, "", true);
|
|||
|
}
|
|||
|
|
|||
|
private void menuFileImportWorksheet_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
string file;
|
|||
|
if (!OpenDialog("Open worksheet...", MatrixCalculator.Properties.Resources.WorksheetFormatFilter, out file))
|
|||
|
return;
|
|||
|
|
|||
|
ImportWorksheetWindow wind = new ImportWorksheetWindow();
|
|||
|
try { wind.LoadFile(file); }
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
MessageBox.Show("Error: " + ex.Message, "Error!");
|
|||
|
}
|
|||
|
|
|||
|
if (wind.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
|
|||
|
AddMatrices(wind.Data);
|
|||
|
}
|
|||
|
|
|||
|
private void menuFilePreferences_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
new SettingsWindow().ShowDialog();
|
|||
|
}
|
|||
|
|
|||
|
private void menuFileExit_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
this.Close();
|
|||
|
}
|
|||
|
|
|||
|
private void menuMatrixNew_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
Editor edit = new Editor();
|
|||
|
edit.Text = "New matrix...";
|
|||
|
|
|||
|
if (edit.ShowDialog() != System.Windows.Forms.DialogResult.OK)
|
|||
|
return;
|
|||
|
|
|||
|
AddMatrix(edit.Matrix, edit.MatrixName, edit.MatrixDescription, true);
|
|||
|
}
|
|||
|
|
|||
|
private void menuMatrixEdit_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (listMatrices.SelectedItems.Count != 1) return;
|
|||
|
|
|||
|
string old_name, new_name, desc;
|
|||
|
Matrix<double> matrix;
|
|||
|
// Set up variables
|
|||
|
|
|||
|
Editor edit = new Editor();
|
|||
|
edit.Text = "Edit matrix...";
|
|||
|
old_name = edit.MatrixName = listMatrices.SelectedItems[0].Text;
|
|||
|
edit.MatrixDescription = listMatrices.SelectedItems[0].SubItems[1].Text;
|
|||
|
edit.Matrix = matrices[listMatrices.SelectedIndices[0]];
|
|||
|
|
|||
|
// Dialog
|
|||
|
if (edit.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
|
|||
|
|
|||
|
// Update new stuff
|
|||
|
new_name = listMatrices.SelectedItems[0].Text = edit.MatrixName;
|
|||
|
desc = listMatrices.SelectedItems[0].SubItems[1].Text = edit.MatrixDescription;
|
|||
|
matrix = matrices[listMatrices.SelectedIndices[0]] = edit.Matrix;
|
|||
|
|
|||
|
// Update in file
|
|||
|
worksheet.ModifyMatrix(old_name, new_name, CsvParser.ToCSV(matrix), desc);
|
|||
|
|
|||
|
// Update preview
|
|||
|
listMatrices_SelectedIndexChanged(this, new EventArgs());
|
|||
|
}
|
|||
|
|
|||
|
private void menuMatrixDelete_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
foreach (int i in listMatrices.SelectedIndices)
|
|||
|
{
|
|||
|
worksheet.DeleteMatrix(listMatrices.Items[i].Text);
|
|||
|
listMatrices.Items.RemoveAt(i);
|
|||
|
matrices.RemoveAt(i);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void menuMatrixDuplicate_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (listMatrices.SelectedItems.Count != 1) return;
|
|||
|
|
|||
|
// Set up variables
|
|||
|
Editor edit = new Editor();
|
|||
|
edit.Text = "New matrix...";
|
|||
|
edit.MatrixName = listMatrices.SelectedItems[0].Text;
|
|||
|
edit.MatrixDescription = listMatrices.SelectedItems[0].SubItems[1].Text;
|
|||
|
edit.Matrix = matrices[listMatrices.SelectedIndices[0]];
|
|||
|
|
|||
|
// Dialog
|
|||
|
if (edit.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
|
|||
|
|
|||
|
// Update new stuff
|
|||
|
AddMatrix(edit.Matrix, edit.MatrixName, edit.MatrixDescription, true);
|
|||
|
}
|
|||
|
|
|||
|
private void menuMatrixInsertA_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (listMatrices.SelectedIndices.Count == 1)
|
|||
|
MatrixA = matrices[listMatrices.SelectedIndices[0]];
|
|||
|
}
|
|||
|
|
|||
|
private void menuMatrixInsertB_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (listMatrices.SelectedIndices.Count == 1)
|
|||
|
MatrixB = matrices[listMatrices.SelectedIndices[0]];
|
|||
|
}
|
|||
|
|
|||
|
private void menuMatrixCopy_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (listMatrices.SelectedIndices.Count != 1) return;
|
|||
|
|
|||
|
string csv = CsvParser.ToCSV(matrices[listMatrices.SelectedIndices[0]]);
|
|||
|
Clipboard.SetText(csv, TextDataFormat.CommaSeparatedValue);
|
|||
|
}
|
|||
|
|
|||
|
private void menuMatrixPaste_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
// Get data
|
|||
|
string csv = "";
|
|||
|
if (Clipboard.ContainsText(TextDataFormat.CommaSeparatedValue))
|
|||
|
csv = Clipboard.GetText(TextDataFormat.CommaSeparatedValue);
|
|||
|
else return;
|
|||
|
|
|||
|
// Put it in a matrix
|
|||
|
Editor edit = new Editor();
|
|||
|
edit.Text = "Paste matrix...";
|
|||
|
edit.Matrix = MatrixConverter.FromTable(CsvParser.GetTable(csv, ",;\t".ToArray()));
|
|||
|
edit.MatrixName = "Pasted matrix";
|
|||
|
|
|||
|
if (edit.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
|
|||
|
|
|||
|
// Get data
|
|||
|
AddMatrix(edit.Matrix, edit.MatrixName, edit.MatrixDescription, true);
|
|||
|
}
|
|||
|
|
|||
|
private void menuMatrixPasteSpecial_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
// Get data
|
|||
|
string csv = "";
|
|||
|
if (Clipboard.ContainsText(TextDataFormat.CommaSeparatedValue))
|
|||
|
csv = Clipboard.GetText(TextDataFormat.CommaSeparatedValue);
|
|||
|
else if (Clipboard.ContainsText())
|
|||
|
csv = Clipboard.GetText();
|
|||
|
else return;
|
|||
|
|
|||
|
// Use CSV importer
|
|||
|
ImportCsvWindow wind = new ImportCsvWindow();
|
|||
|
wind.Csv = csv;
|
|||
|
|
|||
|
if (wind.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
|
|||
|
|
|||
|
AddMatrix(wind.Matrix, wind.MatrixName, "", true);
|
|||
|
}
|
|||
|
|
|||
|
private void menuHelpAbout_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
DynamicLink.Launcher.About();
|
|||
|
}
|
|||
|
|
|||
|
private void menuHelpHelp_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
DynamicLink.Launcher.StartModule("Help", "matrixcalc");
|
|||
|
}
|
|||
|
|
|||
|
private void contextMenuDataAdd_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
var item = sender as ToolStripMenuItem;
|
|||
|
var menu = item.Owner as ContextMenuStrip;
|
|||
|
var grid = menu.SourceControl as DataGridView;
|
|||
|
if (grid == null) return;
|
|||
|
|
|||
|
// Create editor window
|
|||
|
Editor editwindow = new Editor();
|
|||
|
editwindow.Text = "New matrix...";
|
|||
|
editwindow.Matrix = GridViewHelper.GetMatrix(grid);
|
|||
|
|
|||
|
if (editwindow.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
|||
|
AddMatrix(editwindow.Matrix, editwindow.MatrixName, editwindow.MatrixDescription, true);
|
|||
|
}
|
|||
|
|
|||
|
private void contextMenuDataClear_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
var item = sender as ToolStripMenuItem;
|
|||
|
var menu = item.Owner as ContextMenuStrip;
|
|||
|
var grid = menu.SourceControl as DataGridView;
|
|||
|
if (grid == null) return;
|
|||
|
|
|||
|
if (grid == dataMatrixA) matrixA = null;
|
|||
|
else if (grid == dataMatrixB) matrixB = null;
|
|||
|
|
|||
|
grid.Rows.Clear();
|
|||
|
grid.Columns.Clear();
|
|||
|
}
|
|||
|
|
|||
|
private void contextMenuDataCopy_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
var item = sender as ToolStripMenuItem;
|
|||
|
var menu = item.Owner as ContextMenuStrip;
|
|||
|
var grid = menu.SourceControl as DataGridView;
|
|||
|
if (grid == null) return;
|
|||
|
|
|||
|
string csv = CsvParser.ToCSV(grid);
|
|||
|
Clipboard.SetText(csv, TextDataFormat.CommaSeparatedValue);
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Calculator buttons
|
|||
|
private void buttonAdd_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 1, 1, 1, 0, 0)) return;
|
|||
|
|
|||
|
try { MatrixResult = matrixA + matrixB; }
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
textOutput.Text = "Error: " + ex.Message;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void buttonSub_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 1, 1, 1, 0, 0)) return;
|
|||
|
|
|||
|
try { MatrixResult = matrixA - matrixB; }
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
textOutput.Text = "Error: " + ex.Message;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void buttonMul_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 1, 1, 0, 1, 0)) return;
|
|||
|
|
|||
|
try { MatrixResult = matrixA * matrixB; }
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
textOutput.Text = "Error: " + ex.Message;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void buttonAddNum_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 0, 0, 0, 0, 0)) return;
|
|||
|
|
|||
|
// Get a number
|
|||
|
NumericInput input = new NumericInput(NumericInput.NumberType.Real);
|
|||
|
if (input.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
|
|||
|
double number = input.NumberReal;
|
|||
|
|
|||
|
// Now add it
|
|||
|
Matrix<double> m = Matrix<double>.Build.Dense(matrixA.RowCount, matrixA.ColumnCount, number);
|
|||
|
MatrixResult = matrixA + m;
|
|||
|
}
|
|||
|
|
|||
|
private void buttonSubNum_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 0, 0, 0, 0, 0)) return;
|
|||
|
|
|||
|
// Get a number
|
|||
|
NumericInput input = new NumericInput(NumericInput.NumberType.Real);
|
|||
|
if (input.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
|
|||
|
double number = input.NumberReal;
|
|||
|
|
|||
|
// Now add it
|
|||
|
Matrix<double> m = Matrix<double>.Build.Dense(matrixA.RowCount, matrixA.ColumnCount, number);
|
|||
|
MatrixResult = matrixA - m;
|
|||
|
}
|
|||
|
|
|||
|
private void buttonMulNum_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 0, 0, 0, 0, 0)) return;
|
|||
|
|
|||
|
// Get a number
|
|||
|
NumericInput input = new NumericInput(NumericInput.NumberType.Real);
|
|||
|
if (input.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
|
|||
|
double number = input.NumberReal;
|
|||
|
|
|||
|
// Now add it
|
|||
|
MatrixResult = matrixA * number;
|
|||
|
}
|
|||
|
|
|||
|
private void buttonInv_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 0, 0, 0, 0, 0)) return;
|
|||
|
|
|||
|
try { MatrixResult = matrixA.Inverse(); }
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
textOutput.Text = "Error: " + ex.Message;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void buttonPow_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 0, 0, 0, 0, 0)) return;
|
|||
|
|
|||
|
// Get a number
|
|||
|
NumericInput input = new NumericInput(NumericInput.NumberType.Integer);
|
|||
|
if (input.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
|
|||
|
int number = input.NumberInt;
|
|||
|
|
|||
|
// Calculate
|
|||
|
try { MatrixResult = MatrixHelper.Power (matrixA, number); }
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
textOutput.Text = "Error: " + ex.Message;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void buttonTransp_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 0, 0, 0, 0, 0)) return;
|
|||
|
|
|||
|
try { MatrixResult = matrixA.Transpose(); }
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
textOutput.Text = "Error: " + ex.Message;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void buttonTrace_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 0, 0, 0, 0, 0)) return;
|
|||
|
|
|||
|
if (MatrixCalculator.Properties.Settings.Default.NumberResultAsMatrix)
|
|||
|
MatrixResult = Matrix<double>.Build.Dense(1, 1, matrixA.Trace());
|
|||
|
|
|||
|
else textOutput.Text = MyDouble.String(matrixA.Trace());
|
|||
|
}
|
|||
|
|
|||
|
private void buttonRank_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 0, 0, 0, 0, 0)) return;
|
|||
|
|
|||
|
if (MatrixCalculator.Properties.Settings.Default.NumberResultAsMatrix)
|
|||
|
MatrixResult = Matrix<double>.Build.Dense(1, 1, Convert.ToDouble(matrixA.Rank()));
|
|||
|
|
|||
|
else textOutput.Text = matrixA.Rank().ToString();
|
|||
|
}
|
|||
|
|
|||
|
private void buttonDet_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 0, 0, 0, 0, 1)) return;
|
|||
|
|
|||
|
if (MatrixCalculator.Properties.Settings.Default.NumberResultAsMatrix)
|
|||
|
MatrixResult = Matrix<double>.Build.Dense(1, 1, matrixA.Determinant());
|
|||
|
|
|||
|
else textOutput.Text = MyDouble.String(matrixA.Determinant());
|
|||
|
}
|
|||
|
|
|||
|
private void buttonMin_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 0, 0, 0, 0, 0)) return;
|
|||
|
|
|||
|
if (MatrixCalculator.Properties.Settings.Default.NumberResultAsMatrix)
|
|||
|
MatrixResult = Matrix<double>.Build.Dense(1, 1, MatrixHelper.Min(matrixA));
|
|||
|
|
|||
|
else textOutput.Text = MyDouble.String(MatrixHelper.Min(matrixA));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private void buttonMax_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!VerifyConditions(1, 0, 0, 0, 0, 0)) return;
|
|||
|
|
|||
|
if (MatrixCalculator.Properties.Settings.Default.NumberResultAsMatrix)
|
|||
|
MatrixResult = Matrix<double>.Build.Dense(1, 1, MatrixHelper.Max(matrixA));
|
|||
|
|
|||
|
else textOutput.Text = MyDouble.String(MatrixHelper.Max(matrixA));
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Drag & drop
|
|||
|
private void dataMatrix_DragEnter(object sender, DragEventArgs e)
|
|||
|
{
|
|||
|
if (e.Data.GetDataPresent(typeof(ListViewItem))) e.Effect = DragDropEffects.Move;
|
|||
|
else e.Effect = DragDropEffects.None;
|
|||
|
}
|
|||
|
|
|||
|
private void dataMatrix_DragDrop(object sender, DragEventArgs e)
|
|||
|
{
|
|||
|
ListViewItem data = e.Data.GetData(typeof(ListViewItem)) as ListViewItem;
|
|||
|
var send = sender as DataGridView;
|
|||
|
if (data == null || send == null) return;
|
|||
|
|
|||
|
if (send == dataMatrixA) MatrixA = matrices[data.Index];
|
|||
|
else if (send == dataMatrixB) MatrixB = matrices[data.Index];
|
|||
|
}
|
|||
|
|
|||
|
private void listMatrices_DragOver(object sender, DragEventArgs e)
|
|||
|
{
|
|||
|
e.Effect = DragDropEffects.Move;
|
|||
|
}
|
|||
|
|
|||
|
private void listMatrices_MouseDown(object sender, MouseEventArgs e)
|
|||
|
{
|
|||
|
if (listMatrices.SelectedItems.Count == 1 && e.Button == System.Windows.Forms.MouseButtons.Left)
|
|||
|
listMatrices.DoDragDrop(listMatrices.SelectedItems[0], DragDropEffects.Move);
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region List Matrices Selected Index Changed
|
|||
|
private void EnableMenus(int insA, int insB, int copy, int edit, int del, int dupl)
|
|||
|
{
|
|||
|
menuMatrixInsertA.Enabled = contextMenuListInsertA.Enabled = (insA != 0);
|
|||
|
menuMatrixInsertB.Enabled = contextMenuListInsertB.Enabled = (insB != 0);
|
|||
|
menuMatrixCopy.Enabled = contextMenuListCopy.Enabled = (copy != 0);
|
|||
|
menuMatrixEdit.Enabled = contextMenuListEdit.Enabled = (edit != 0);
|
|||
|
menuMatrixDelete.Enabled = contextMenuListDelete.Enabled = (del != 0);
|
|||
|
menuMatrixDuplicate.Enabled = contextMenuListDuplicate.Enabled = (dupl != 0);
|
|||
|
}
|
|||
|
|
|||
|
private void listMatrices_SelectedIndexChanged(object sender, EventArgs e)
|
|||
|
{
|
|||
|
switch (listMatrices.SelectedIndices.Count)
|
|||
|
{
|
|||
|
case 0: EnableMenus(0, 0, 0, 0, 0, 0); break;
|
|||
|
case 1:
|
|||
|
this.labelPreviewName.Text = "Name: " + listMatrices.SelectedItems[0].Text;
|
|||
|
this.labelPreviewDesc.Text = "Description: " + listMatrices.SelectedItems[0].SubItems[1].Text;
|
|||
|
MatrixPreview = matrices[listMatrices.SelectedIndices[0]];
|
|||
|
|
|||
|
EnableMenus(1, 1, 1, 1, 1, 1);
|
|||
|
break;
|
|||
|
default: EnableMenus(0, 0, 0, 0, 1, 0); break;
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Painting
|
|||
|
protected override void OnPaintBackground(PaintEventArgs e)
|
|||
|
{
|
|||
|
DynamicLink.Controls.BackgroundGradient.Paint(e.Graphics, new Rectangle(-1, -1, this.Width, this.Height));
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Others
|
|||
|
private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
|
|||
|
{
|
|||
|
if (!ShowSaveWarningDialog()) e.Cancel = true;
|
|||
|
|
|||
|
if (!e.Cancel) MatrixCalculator.Properties.Settings.Default.Save();
|
|||
|
}
|
|||
|
|
|||
|
private void textOutput_TextChanged(object sender, EventArgs e)
|
|||
|
{
|
|||
|
toolTip.SetToolTip(textOutput, textOutput.Text);
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Additional routines
|
|||
|
private string MakeUnique(string name)
|
|||
|
{
|
|||
|
List<string> probl = new List<string>();
|
|||
|
|
|||
|
// Test name uniqueness
|
|||
|
bool unique = true;
|
|||
|
foreach (ListViewItem i in this.listMatrices.Items)
|
|||
|
{
|
|||
|
if (i.Text == name) unique = false;
|
|||
|
if (i.Text.StartsWith(name)) probl.Add(i.Text);
|
|||
|
}
|
|||
|
|
|||
|
// If not unique, generate a unique name
|
|||
|
if (!unique)
|
|||
|
{
|
|||
|
int n = 0;
|
|||
|
while (probl.Contains(name + n.ToString()) && n < 10000) n++;
|
|||
|
name += n.ToString();
|
|||
|
}
|
|||
|
|
|||
|
return name;
|
|||
|
}
|
|||
|
|
|||
|
private void AddMatrix(Matrix<double> m, string name, string desc, bool inFile = false)
|
|||
|
{
|
|||
|
matrices.Add(m);
|
|||
|
name = MakeUnique(name);
|
|||
|
|
|||
|
// Add it
|
|||
|
ListViewItem item = listMatrices.Items.Add(name);
|
|||
|
item.SubItems.Add(desc);
|
|||
|
|
|||
|
// To file?
|
|||
|
if (inFile) worksheet.AddMatrix(name, CsvParser.ToCSV(m), desc);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private void AddMatrices(DataTable data, bool infile = false)
|
|||
|
{
|
|||
|
AddMatrices(data, infile, false, MatrixCalculator.Properties.Settings.Default.InternalCsvSeparators.ToArray());
|
|||
|
}
|
|||
|
|
|||
|
private void AddMatrices(DataTable data, bool infile, bool combine, params char[] separs)
|
|||
|
{
|
|||
|
foreach (DataRow i in data.Rows)
|
|||
|
{
|
|||
|
try {
|
|||
|
string name = i["name"].ToString();
|
|||
|
string desc = i["description"].ToString();
|
|||
|
string csv = i["csv"].ToString();
|
|||
|
DataTable dt = CsvParser.GetTable(csv, separs, combine);
|
|||
|
|
|||
|
AddMatrix(MatrixConverter.FromTable(dt), name, desc, infile);
|
|||
|
}
|
|||
|
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
MessageBox.Show("Error: " + e.Message, "Error!");
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void ResetAll()
|
|||
|
{
|
|||
|
matrices.Clear();
|
|||
|
listMatrices.Items.Clear();
|
|||
|
|
|||
|
AddMatrix(Matrix<double>.Build.Dense(7, 7, 0), "Zero", "Zero matrix");
|
|||
|
AddMatrix(Matrix<double>.Build.DenseIdentity(7, 7), "One", "Identity matrix");
|
|||
|
}
|
|||
|
|
|||
|
private bool ShowSaveWarningDialog()
|
|||
|
{
|
|||
|
// Nothing to do
|
|||
|
if (worksheet.IsQueueEmpty) return true;
|
|||
|
|
|||
|
// Show dialog
|
|||
|
switch (MessageBox.Show("All the unsaved changes will be lost. Do you want to save the current worksheet?",
|
|||
|
"Save?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question))
|
|||
|
{
|
|||
|
|
|||
|
case System.Windows.Forms.DialogResult.Cancel: return false;
|
|||
|
case System.Windows.Forms.DialogResult.Yes:
|
|||
|
menuFileSave_Click(this, new EventArgs());
|
|||
|
break;
|
|||
|
|
|||
|
case System.Windows.Forms.DialogResult.No:
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
private bool OpenDialog(string title, string filter, out string filename)
|
|||
|
{
|
|||
|
bool result;
|
|||
|
|
|||
|
// Initialize dialog
|
|||
|
OpenFileDialog open = new OpenFileDialog();
|
|||
|
open.Title = title;
|
|||
|
open.Filter = filter;
|
|||
|
|
|||
|
// Show
|
|||
|
if (open.ShowDialog() == System.Windows.Forms.DialogResult.OK) result = true;
|
|||
|
else result = false;
|
|||
|
|
|||
|
// Output
|
|||
|
filename = open.FileName;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
private bool SaveDialog(string title, string filter, out string filename)
|
|||
|
{
|
|||
|
bool result;
|
|||
|
|
|||
|
// Initialize dialog
|
|||
|
SaveFileDialog save = new SaveFileDialog();
|
|||
|
save.Title = title;
|
|||
|
save.Filter = filter;
|
|||
|
|
|||
|
// Show
|
|||
|
if (save.ShowDialog() == System.Windows.Forms.DialogResult.OK) result = true;
|
|||
|
else result = false;
|
|||
|
|
|||
|
// Output
|
|||
|
filename = save.FileName;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Additional calculator routines
|
|||
|
bool VerifyConditions(int includeA, int includeB, int changeSpecial, int checkSum, int checkMul, int checkSq)
|
|||
|
{
|
|||
|
// Verify matrix A
|
|||
|
if (includeA != 0 && matrixA == null)
|
|||
|
{
|
|||
|
textOutput.Text = "Error: Missing matrix A!";
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// Verify matrix B
|
|||
|
if (includeB != 0 && matrixB == null)
|
|||
|
{
|
|||
|
textOutput.Text = "Error: Missing matrix B!";
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// Replace special matrix types (0 and identity)
|
|||
|
if (changeSpecial != 0)
|
|||
|
{
|
|||
|
// Matrix A
|
|||
|
if (MatrixHelper.Equal(matrixA, Matrix<double>.Build.Dense(7, 7, 0)))
|
|||
|
{
|
|||
|
if (checkSum != 0) matrixA = Matrix<double>.Build.Dense(matrixB.RowCount, matrixB.ColumnCount, 0.0);
|
|||
|
if (checkMul != 0) matrixA = Matrix<double>.Build.Dense(matrixB.ColumnCount, matrixB.ColumnCount, 0.0);
|
|||
|
}
|
|||
|
|
|||
|
if (MatrixHelper.Equal(matrixA, Matrix<double>.Build.DenseIdentity(7, 7)))
|
|||
|
{
|
|||
|
if (checkSum != 0) matrixA = Matrix<double>.Build.DenseIdentity(matrixB.RowCount, matrixB.ColumnCount);
|
|||
|
if (checkMul != 0) matrixA = Matrix<double>.Build.DenseIdentity(matrixB.ColumnCount, matrixB.ColumnCount);
|
|||
|
}
|
|||
|
|
|||
|
// Matrix B
|
|||
|
if (MatrixHelper.Equal(matrixB, Matrix<double>.Build.Dense(7, 7, 0)))
|
|||
|
{
|
|||
|
if (checkSum != 0) matrixB = Matrix<double>.Build.Dense(matrixA.RowCount, matrixA.ColumnCount, 0.0);
|
|||
|
if (checkMul != 0) matrixB = Matrix<double>.Build.Dense(matrixA.ColumnCount, matrixA.ColumnCount, 0.0);
|
|||
|
}
|
|||
|
|
|||
|
if (MatrixHelper.Equal(matrixB, Matrix<double>.Build.DenseIdentity(7, 7)))
|
|||
|
{
|
|||
|
if (checkSum != 0) matrixB = Matrix<double>.Build.DenseIdentity(matrixA.RowCount, matrixA.ColumnCount);
|
|||
|
if (checkMul != 0) matrixB = Matrix<double>.Build.DenseIdentity(matrixA.ColumnCount, matrixA.ColumnCount);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// If sum, make sure sizes match
|
|||
|
if (checkSum != 0 && (matrixA.RowCount != matrixB.RowCount || matrixA.ColumnCount != matrixB.ColumnCount))
|
|||
|
{
|
|||
|
textOutput.Text = "Error: Incompatible matrices.";
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// If multiplication, check A's width = B's height
|
|||
|
if (checkMul != 0 && (matrixA.ColumnCount != matrixB.RowCount))
|
|||
|
{
|
|||
|
textOutput.Text = "Error: Incompatible matrices.";
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// If matrix A must be square
|
|||
|
if (checkSq != 0 && (matrixA.ColumnCount != matrixA.RowCount))
|
|||
|
{
|
|||
|
textOutput.Text = "Error: Invalid matrix.";
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
}
|