/// <summary> /// update the SVG DOM and the grid /// </summary> void UpdateData() { var alinks = svg.Descendants(ns + "a"); ALinksGrid.CellValueChanged -= ALinksGrid_CellValueChanged; List <DataGridViewRow> toDelete = new List <DataGridViewRow>(); foreach (DataGridViewRow row in ALinksGrid.Rows) { XElement alink = svg.Descendants().First(el => (el.Attribute("id") != null) && (el.Attribute("id").Value == (string)row.Cells["ID"].Value)); if (alink.Name.LocalName != "a") { alink = alink.Parent; } if (alink == null) { throw new Exception(String.Format("Cannot find the <a> tag for the current row with href=\"{0}\"", row.Cells["id"].Value)); } // delete <a> from SVG DOM if specified, including any <title> or <desc> in it if ((bool)row.Cells["Delete"].Value) { XElement parent = alink.Parent; alink.Remove(); foreach (XElement title in alink.Elements(ns + "title")) { title.Remove(); } foreach (XElement desc in alink.Elements(ns + "desc")) { desc.Remove(); } parent.Elements().ElementAt(alink.ElementsBeforeSelf().Count()).AddBeforeSelf(alink.Elements()); //add the <a>'s children back toDelete.Add(row); continue; } alink.Descendants(ns + "title").First().Value = (string)row.Cells["Title"].Value; // update <title> alink.Descendants(ns + "desc").First().Value = (string)row.Cells["Desc"].Value; // update <desc> alink.Attribute("tabindex").Value = (string)row.Cells["TabIndex"].Value; // update tabindex="#" } // remove deleted links from the grid ALinksGrid.Visible = false; foreach (var row in toDelete) { ALinksGrid.Rows.Remove(row); } ALinksGrid.Refresh(); ALinksGrid.Visible = true; ALinksGrid.CellValueChanged += ALinksGrid_CellValueChanged; }
/// <summary> /// open an SVG file, process it, and populate the grid /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ButtonOpen_Click(object sender, EventArgs e) { // Check if current file is dirty if (isGridDirty) { if (MessageBox.Show("You have unsaved changes in the current SVG file. If you click OK, any unsaved changes will be discarded", "Unsaved Changes", MessageBoxButtons.OKCancel) != DialogResult.OK) { return; } } ALinksGrid.Visible = false; // Open file OpenFileDialog openFile1 = new OpenFileDialog(); openFile1.Filter = "SVG Files|*.svg"; if (openFile1.ShowDialog() != DialogResult.OK || openFile1.FileName == "") { return; } svg = XDocument.Load(openFile1.FileName); // Process SVG DOM and populate the grid if (!svg.Root.Element(ns + "style").Value.Contains(".hover_group")) { svg.Root.Element(ns + "style").Value += hoverText; } ALinksGrid.AutoGenerateColumns = false; ALinksGrid.Rows.Clear(); foreach (XElement alink in svg.Descendants(ns + "a")) { alink.SetAttributeValue("cursor", "pointer"); // set cursor="pointer" alink.SetAttributeValue("target", "_blank"); // set target="_blank" if (alink.Attribute("tabindex") == null) // set tabindex="0" if not exist { alink.SetAttributeValue("tabindex", "0"); } // set class="hover_group" for all groups with <a> as immediate parent foreach (XElement group in alink.Elements(ns + "g")) { XAttribute attr = group.Attribute("class"); if (attr != null) { attr.Value = "hover_group;" + attr.Value; } else { group.SetAttributeValue("class", "hover_group"); } } // create <title> if not exist in decendents XElement title = null; if (alink.Descendants(ns + "title").Count() > 0) { title = alink.Descendants(ns + "title").First(); } if (title == null) { title = new XElement(ns + "title", ""); alink.Add(title); } // create <desc> if not exist in descendents XElement desc = null; if (alink.Descendants(ns + "desc").Count() > 0) { desc = alink.Descendants(ns + "desc").First(); } if (desc == null) { desc = new XElement(ns + "desc", ""); alink.Add(desc); } // add ids for <title> and <desc> if not exist string titleid, descid; if (title.Attribute("id") == null) { titleid = GenerateId(); title.SetAttributeValue("id", titleid); } else { titleid = title.Attribute("id").Value; } if (desc.Attribute("id") == null) { descid = GenerateId(); desc.SetAttributeValue("id", descid); } else { descid = desc.Attribute("id").Value; } alink.SetAttributeValue("aria-labelledby", titleid + " " + descid); // set aria-labelledby="[titleid] [descid]" // create a new row for the link in the grid ALinksGrid.Rows.Add( alink.DescendantsAndSelf().First(el => el.Attribute("id") != null).Attribute("id").Value, // id alink.Attribute(xlink + "href").Value, // href alink.Descendants(ns + "title").First().Value, // title alink.Descendants(ns + "desc").First().Value, // desc alink.Attribute("tabindex").Value, // tabindex alink.Ancestors(ns + "a").Count() > 0 ? true : false, // nested? false); // delete link? (no by default) } ALinksGrid.Refresh(); ALinksGrid.ColumnHeadersVisible = true; ALinksGrid.Visible = true; ALinksGrid.CellValueChanged += ALinksGrid_CellValueChanged; currentFile = openFile1.FileName; ButtonSave.Enabled = true; ButtonSaveAs.Enabled = true; this.Text = String.Format("{0} - {1}", formTitle, currentFile); isGridDirty = true; }