From 17ccf2beef0592caf3aea7a0fd236a8684821fab Mon Sep 17 00:00:00 2001 From: Robin Cornelius Date: Sun, 4 Dec 2016 21:21:00 +0000 Subject: [PATCH] Attempt to Fix #35 * Any changes to an OD entry will change the save button to red and not allow you to switch the OD view until you have saved or allowed the changes to be lost * After saving an OD change, adding a PDO, deleting PDO, editing PDO, or saving Device Info window title for device will go red and you will be prompted to confirm a close or app quit operation * Pressing save to the XML file will reset the dirty flag and make clear the red banner saving the EDS file will not clear the red banner --- EDSTest/DeviceInfoView.cs | 2 + EDSTest/DeviceODView.Designer.cs | 5 ++ EDSTest/DeviceODView.cs | 94 ++++++++++++++++++++++++++++---- EDSTest/DevicePDOView.cs | 11 +++- EDSTest/Form1.Designer.cs | 1 + EDSTest/Form1.cs | 68 ++++++++++++++++++++++- EDSTest/ListViewEx.cs | 6 +- libEDSsharp/Bridge.cs | 6 +- libEDSsharp/eds.cs | 26 ++++++++- 9 files changed, 200 insertions(+), 19 deletions(-) diff --git a/EDSTest/DeviceInfoView.cs b/EDSTest/DeviceInfoView.cs index 8bcbf2a6..3bcd435d 100644 --- a/EDSTest/DeviceInfoView.cs +++ b/EDSTest/DeviceInfoView.cs @@ -160,6 +160,8 @@ private void button_update_devfile_info_Click(object sender, EventArgs e) //These are read only and auto calculated //textBox_rxpdos.Text = eds.di.NrOfRXPDO.ToString(); //textBox_txpdos.Text = eds.di.NrOfTXPDO.ToString(); + + eds.dirty = true; } catch (Exception ex) { diff --git a/EDSTest/DeviceODView.Designer.cs b/EDSTest/DeviceODView.Designer.cs index 9e18fa8a..71027e2f 100644 --- a/EDSTest/DeviceODView.Designer.cs +++ b/EDSTest/DeviceODView.Designer.cs @@ -510,6 +510,7 @@ private void InitializeComponent() // // comboBox_memory // + this.comboBox_memory.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBox_memory.FormattingEnabled = true; this.comboBox_memory.Location = new System.Drawing.Point(320, 219); this.comboBox_memory.Name = "comboBox_memory"; @@ -570,6 +571,7 @@ private void InitializeComponent() // // comboBox_objecttype // + this.comboBox_objecttype.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBox_objecttype.Enabled = false; this.comboBox_objecttype.FormattingEnabled = true; this.comboBox_objecttype.Location = new System.Drawing.Point(108, 169); @@ -588,6 +590,7 @@ private void InitializeComponent() // // comboBox_datatype // + this.comboBox_datatype.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBox_datatype.FormattingEnabled = true; this.comboBox_datatype.Location = new System.Drawing.Point(108, 195); this.comboBox_datatype.Name = "comboBox_datatype"; @@ -623,6 +626,7 @@ private void InitializeComponent() // // comboBox_accesstype // + this.comboBox_accesstype.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBox_accesstype.FormattingEnabled = true; this.comboBox_accesstype.Location = new System.Drawing.Point(108, 221); this.comboBox_accesstype.Name = "comboBox_accesstype"; @@ -656,6 +660,7 @@ private void InitializeComponent() // // comboBox_pdomap // + this.comboBox_pdomap.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBox_pdomap.FormattingEnabled = true; this.comboBox_pdomap.Location = new System.Drawing.Point(108, 248); this.comboBox_pdomap.Name = "comboBox_pdomap"; diff --git a/EDSTest/DeviceODView.cs b/EDSTest/DeviceODView.cs index c1f01f54..b9dcedd2 100644 --- a/EDSTest/DeviceODView.cs +++ b/EDSTest/DeviceODView.cs @@ -38,6 +38,7 @@ public partial class DeviceODView : MyTabUserControl public EDSsharp eds = null; ODentry selectedobject; + ODentry lastselectedobject; ListViewItem selecteditem; ListViewItem selecteditemsub; @@ -45,22 +46,16 @@ public DeviceODView() { InitializeComponent(); - comboBox_datatype.Items.Add(""); - foreach (DataType foo in Enum.GetValues(typeof(DataType))) { comboBox_datatype.Items.Add(foo.ToString()); } - comboBox_objecttype.Items.Add(""); - foreach (ObjectType foo in Enum.GetValues(typeof(ObjectType))) { comboBox_objecttype.Items.Add(foo.ToString()); } - comboBox_accesstype.Items.Add(""); - foreach (EDSsharp.AccessType foo in Enum.GetValues(typeof(EDSsharp.AccessType))) { comboBox_accesstype.Items.Add(foo.ToString()); @@ -68,15 +63,11 @@ public DeviceODView() comboBox_accesstype.Items.Add("0x1003 rw/ro"); - - comboBox_memory.Items.Add(""); - foreach (StorageLocation foo in Enum.GetValues(typeof(StorageLocation))) { comboBox_memory.Items.Add(foo.ToString()); } - comboBox_pdomap.Items.Add(""); comboBox_pdomap.Items.Add("no"); comboBox_pdomap.Items.Add("optional"); @@ -85,14 +76,40 @@ public DeviceODView() listView_optional_objects.DoubleBuffering(true); listViewDetails.DoubleBuffering(true); + foreach(Control c in splitContainer4.Panel2.Controls) + { + if (c is CheckBox) + { + ((CheckBox)c).CheckedChanged += DataDirty; + } + else + { + c.TextChanged += DataDirty; + } + } + } + + bool updating = false; + + private void DataDirty(object sender, EventArgs e) + { + if (updating == true) + return; + + button_save_changes.BackColor = Color.Red; + + } - private void button_save_changes_Click(object sender, EventArgs e) { if (selectedobject == null) return; + eds.dirty = true; + + button_save_changes.BackColor = default(Color); + //Allow everything to be updated and control what is allowed via enable/disable for the control selectedobject.parameter_name = textBox_name.Text; @@ -132,6 +149,7 @@ private void button_save_changes_Click(object sender, EventArgs e) selectedobject.Disabled = !checkBox_enabled.Checked; selectedobject.location = (StorageLocation)Enum.Parse(typeof(StorageLocation), comboBox_memory.SelectedItem.ToString()); + } if(selectedobject.parent == null && selectedobject.objecttype == ObjectType.ARRAY) @@ -183,9 +201,15 @@ public void updatedetailslist() public void validateanddisplaydata() { + if (selectedobject == null) return; + lastselectedobject = selectedobject; + + updating = true; + + ODentry od = (ODentry)selectedobject; @@ -265,6 +289,7 @@ public void validateanddisplaydata() textBox_defaultvalue.Enabled = false; } + updating = false; return; //nothing else to do at this point } @@ -301,6 +326,8 @@ public void validateanddisplaydata() } + updating = false; + return; } @@ -412,6 +439,8 @@ private void listView_mandatory_objects_MouseClick(object sender, MouseEventArgs ListViewItem lvi = listView_mandatory_objects.SelectedItems[0]; + if (checkdirty()) + return; UInt16 idx = Convert.ToUInt16(lvi.Text, 16); updateselectedindexdisplay(idx); @@ -429,6 +458,9 @@ private void list_mouseclick(ListView listview, MouseEventArgs e) if (listview.SelectedItems.Count == 0) return; + if (checkdirty()) + return; + ListViewItem lvi = listview.SelectedItems[0]; UInt16 idx = Convert.ToUInt16(lvi.Text, 16); @@ -469,6 +501,8 @@ private void list_mouseclick(ListView listview, MouseEventArgs e) private void listView_MouseDown(ListView listview, MouseEventArgs e) { + + ListViewHitTestInfo HI = listview.HitTest(e.Location); if (e.Button == MouseButtons.Right) { @@ -516,6 +550,9 @@ private void listViewDetails_MouseClick(object sender, MouseEventArgs e) if (listViewDetails.SelectedItems.Count == 0) return; + if (checkdirty()) + return; + selecteditemsub = lvi; ODentry od = (ODentry)lvi.Tag; @@ -645,6 +682,8 @@ private void addNewObjectToolStripMenuItem_Click(object sender, EventArgs e) if (ni.ShowDialog() == DialogResult.OK) { + eds.dirty = true; + ODentry od = new ODentry(); od.objecttype = ni.ot; @@ -744,13 +783,15 @@ private void deleteObjectToolStripMenuItem_Click(object sender, EventArgs e) } } + } } - if (MessageBox.Show(string.Format("Really delete index 0x{0:x4} ?", od.index), "Are you sure?", MessageBoxButtons.YesNo) == DialogResult.Yes) + if (MessageBox.Show(string.Format("Really delete index 0x{0:x4} ?", od.index), "Are you sure?", MessageBoxButtons.YesNo) == DialogResult.Yes) { + eds.dirty = true; eds.ods.Remove(od.index); populateindexlists(); } @@ -765,6 +806,7 @@ private void disableObjectToolStripMenuItem_Click(object sender, EventArgs e) ODentry od = (ODentry)item.Tag; + eds.dirty = true; od.Disabled = !od.Disabled; populateindexlists(); @@ -819,6 +861,7 @@ private void addSubItemToolStripMenuItem_Click(object sender, EventArgs e) } } + eds.dirty = true; updateselectedindexdisplay(selectedobject.index); validateanddisplaydata(); @@ -855,6 +898,7 @@ private void removeSubItemToolStripMenuItem_Click(object sender, EventArgs e) od.parent.subobjects = newlist; + eds.dirty = true; updateselectedindexdisplay(selectedobject.index); validateanddisplaydata(); } @@ -930,12 +974,38 @@ private void listViewDetails_SelectedIndexChanged(object sender, EventArgs e) if (listViewDetails.SelectedItems.Count == 0) return; + if (checkdirty()) + return; + + ListViewItem lvi = listViewDetails.SelectedItems[0]; selecteditemsub = lvi; selectedobject = (ODentry)lvi.Tag; validateanddisplaydata(); } + + private bool checkdirty() + { + + if (button_save_changes.BackColor == Color.Red) + { + if (button_save_changes.BackColor == Color.Red) + { + if (MessageBox.Show(String.Format("Unsaved changes on Index 0x{0:x4}/{1:x2}\nDo you wish to change objects and loose your changes", lastselectedobject.index, lastselectedobject.subindex), "Unsaved changes",MessageBoxButtons.YesNo) == DialogResult.No) + { + return true; + } + else + { + button_save_changes.BackColor = default(Color); + } + + } + } + + return false; + } } public static class ControlExtensions diff --git a/EDSTest/DevicePDOView.cs b/EDSTest/DevicePDOView.cs index e5dce73f..a63d29b8 100644 --- a/EDSTest/DevicePDOView.cs +++ b/EDSTest/DevicePDOView.cs @@ -308,10 +308,10 @@ void updatePDOTXslot(ODentry od , int row) void listView_TXCOBmap_onComboBoxIndexChanged(int row, int col, string Text) { - - //row+0x1a00 will be the slot to adjust + //row+0x1a00 will be the slot to adjust + eds.dirty = true; UInt16 slot = (UInt16)(0x200 + Convert.ToUInt16(listView_TXCOBmap.Items[row].SubItems[1].Text, 16)); ODentry slotod = eds.ods[slot]; @@ -486,6 +486,7 @@ private void button_addPDO_Click(object sender, EventArgs e) } + eds.dirty = true; } @@ -506,7 +507,9 @@ private void button_deletePDO_Click(object sender, EventArgs e) doUpdatePDOs(); doUpdateOD(); } - + + eds.dirty = true; + } catch (Exception ex) { @@ -585,6 +588,8 @@ private void button_savepdochanges_Click(object sender, EventArgs e) doUpdatePDOs(); doUpdateOD(); + + eds.dirty = true; } catch (Exception ex) { diff --git a/EDSTest/Form1.Designer.cs b/EDSTest/Form1.Designer.cs index bf5024b7..a7c8a47e 100644 --- a/EDSTest/Form1.Designer.cs +++ b/EDSTest/Form1.Designer.cs @@ -291,6 +291,7 @@ private void InitializeComponent() this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Name = "ODEditor_MainForm"; this.Text = "Object Dictionary Editor v0.5"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ODEditor_MainForm_FormClosing); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ODEditor_MainForm_FormClosed); this.Load += new System.EventHandler(this.ODEditor_MainForm_Load); this.menuStrip1.ResumeLayout(false); diff --git a/EDSTest/Form1.cs b/EDSTest/Form1.cs index a916dd84..401b407b 100644 --- a/EDSTest/Form1.cs +++ b/EDSTest/Form1.cs @@ -137,6 +137,8 @@ private void openEDSfile(string path) DeviceView device = new DeviceView(); + eds.onDataDirty += Eds_onDataDirty; + device.eds = eds; tabControl1.TabPages.Add(eds.di.ProductName); tabControl1.TabPages[tabControl1.TabPages.Count - 1].Controls.Add(device); @@ -231,6 +233,8 @@ private void openXMLfile(string path) DeviceView device = new DeviceView(); + eds.onDataDirty += Eds_onDataDirty; + device.eds = eds; tabControl1.TabPages[tabControl1.TabPages.Count - 1].Controls.Add(device); device.Dock = DockStyle.Fill; @@ -253,6 +257,30 @@ private void openXMLfile(string path) } + private void Eds_onDataDirty(bool dirty, EDSsharp sender) + { + foreach(TabPage page in tabControl1.TabPages) + { + foreach(Control c in page.Controls) + { + if(c.GetType() == typeof(DeviceView)) + { + DeviceView d = (DeviceView)c; + if (d.eds.dirty == true) + { + page.BackColor = Color.Red; + } + else + { + page.BackColor = default(Color); + } + } + + } + + } + + } private void tabControl1_DrawItem(Object sender, System.Windows.Forms.DrawItemEventArgs e) { @@ -295,6 +323,13 @@ private void closeFileToolStripMenuItem_Click(object sender, EventArgs e) // tabControl1.TabPages[tabControl1.TabPages.Count - 1].Controls.Add(device); DeviceView device = (DeviceView)tabControl1.SelectedTab.Controls[0]; + + if(device.eds.dirty==true) + { + if (MessageBox.Show( "All usaved changes will be lost\n continue?", "Unsaved changes", MessageBoxButtons.YesNo) == DialogResult.No) + return; + } + network.Remove(device.eds); tabControl1.TabPages.Remove(tabControl1.SelectedTab); @@ -304,7 +339,7 @@ private void closeFileToolStripMenuItem_Click(object sender, EventArgs e) private void quitToolStripMenuItem_Click(object sender, EventArgs e) { - Close(); + Close(); } private void saveEDSToolStripMenuItem_Click(object sender, EventArgs e) @@ -352,6 +387,8 @@ private void saveProjectXMLToolStripMenuItem_Click(object sender, EventArgs e) coxml.dev = d; coxml.writeXML(sfd.FileName); + + dv.eds.dirty = false; } @@ -368,6 +405,8 @@ private void newToolStripMenuItem_Click(object sender, EventArgs e) DeviceView device = new DeviceView(); device.eds = eds; + eds.onDataDirty += Eds_onDataDirty; + tabControl1.TabPages[tabControl1.TabPages.Count - 1].Controls.Add(device); device.Dock = DockStyle.Fill; @@ -543,6 +582,7 @@ private void openNetworkfile(string file) device.Dock = DockStyle.Fill; network.Add(eds); + eds.onDataDirty += Eds_onDataDirty; device.dispatch_updateOD(); @@ -656,6 +696,32 @@ private void saveExportAllToolStripMenuItem_Click(object sender, EventArgs e) + } + } + + private void ODEditor_MainForm_FormClosing(object sender, FormClosingEventArgs e) + { + + foreach (TabPage page in tabControl1.TabPages) + { + foreach (Control c in page.Controls) + { + if (c.GetType() == typeof(DeviceView)) + { + DeviceView d = (DeviceView)c; + if (d.eds.dirty == true) + { + if(MessageBox.Show("Warning you have unsaved changes\n Do you wish to continue","Unsaved changes",MessageBoxButtons.YesNo)==DialogResult.No) + { + e.Cancel = true; + return; + } + } + + } + + } + } } } diff --git a/EDSTest/ListViewEx.cs b/EDSTest/ListViewEx.cs index 719536a4..9037d3f0 100644 --- a/EDSTest/ListViewEx.cs +++ b/EDSTest/ListViewEx.cs @@ -346,7 +346,9 @@ private void ShowComboBox(Point location, Size sz, StringCollection data) combo.Items.Add(text); } // Set the current text, take it from the current listview cell + noevent = true; combo.Text = this.Items[row].SubItems[col].Text; + noevent = false; // Calculate and set drop down width combo.DropDownWidth = this.GetDropDownWidth(data); // Show the combo @@ -596,6 +598,8 @@ private void textBox_Leave(object sender, EventArgs e) /// /// /// + /// + bool noevent = false; private void combo_SelectedIndexChanged(object sender, EventArgs e) { try @@ -605,7 +609,7 @@ private void combo_SelectedIndexChanged(object sender, EventArgs e) this.Items[row].SubItems[col].Text = this.combo.Text; this.combo.Visible = !this.hideComboAfterSelChange; - if (onComboBoxIndexChanged != null) + if (noevent==false && onComboBoxIndexChanged != null) onComboBoxIndexChanged(row, col, combo.Text); } } diff --git a/libEDSsharp/Bridge.cs b/libEDSsharp/Bridge.cs index 9c3cd856..8bdeb35c 100644 --- a/libEDSsharp/Bridge.cs +++ b/libEDSsharp/Bridge.cs @@ -23,6 +23,7 @@ You should have received a copy of the GNU General Public License using System.Text; using System.Threading.Tasks; using Xml2CSharp; +using System.Text.RegularExpressions; /* I know i'm going to regret this * @@ -215,7 +216,10 @@ public EDSsharp convert(Device dev) if (coo.AccessType != null) { string at = coo.AccessType; - at = at.Replace("cons", "const"); // predicted regression from #23 + + Regex reg = new Regex(@"^cons$"); + at = reg.Replace(at,"const"); + entry.accesstype = (EDSsharp.AccessType)Enum.Parse(typeof(EDSsharp.AccessType), at); } diff --git a/libEDSsharp/eds.cs b/libEDSsharp/eds.cs index 1d55f9ba..06850f31 100644 --- a/libEDSsharp/eds.cs +++ b/libEDSsharp/eds.cs @@ -961,6 +961,23 @@ public enum AccessType public string edsfilename = null; public string xmlfilename = null; + //property to indicate unsaved data; + private bool _dirty; + public bool dirty + { + get + { + return _dirty; + } + set + { + _dirty = value; + if (onDataDirty != null) + onDataDirty(_dirty,this); + + } + } + Dictionary> eds; public SortedDictionary ods; public SortedDictionary dummy_ods; @@ -975,11 +992,13 @@ public enum AccessType public UInt16 NodeId = 0; - + public delegate void DataDirty(bool dirty, EDSsharp sender); + public event DataDirty onDataDirty; public EDSsharp() { + eds = new Dictionary>(); ods = new SortedDictionary(); dummy_ods = new SortedDictionary(); @@ -1023,6 +1042,11 @@ public EDSsharp() } + public void setdirty() + { + + } + string sectionname = ""; public void parseline(string linex)