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
 | |
| 
 | |
| 
 | |
|     }
 | |
| }
 |