diff options
author | Jeffrey Stedfast <jeff@xamarin.com> | 2011-12-24 02:11:10 +0400 |
---|---|---|
committer | Jeffrey Stedfast <jeff@xamarin.com> | 2011-12-24 02:11:10 +0400 |
commit | 04e415d2c4e75d418a1ec2f642a85152406c9436 (patch) | |
tree | 8f19a639a1d8c7d0bb9329b7426e8a7c0a8eae35 | |
parent | 791f2e1ac5b97f5a82a26170ec353114963e868a (diff) |
[Ide] Escape Solution Tree View label names.
Fixes bug #420.
14 files changed, 93 insertions, 15 deletions
diff --git a/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/ExtensionNodeBuilder.cs b/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/ExtensionNodeBuilder.cs index c5c2fa6fdc..4095a15a48 100644 --- a/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/ExtensionNodeBuilder.cs +++ b/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/ExtensionNodeBuilder.cs @@ -64,7 +64,7 @@ namespace MonoDevelop.AddinAuthoring.NodeBuilders public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Pixbuf icon, ref Pixbuf closedIcon) { Extension ext = (Extension) dataObject; - label = Util.GetDisplayName (ext); + label = EscapeTextForMarkup (Util.GetDisplayName (ext)); icon = Context.GetIcon ("md-extension"); } diff --git a/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/ExtensionPointNodeBuilder.cs b/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/ExtensionPointNodeBuilder.cs index 76446829e1..2e7cfa5693 100644 --- a/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/ExtensionPointNodeBuilder.cs +++ b/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/ExtensionPointNodeBuilder.cs @@ -71,7 +71,7 @@ namespace MonoDevelop.AddinAuthoring.NodeBuilders public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Pixbuf icon, ref Pixbuf closedIcon) { ExtensionPoint ep = (ExtensionPoint) dataObject; - label = !string.IsNullOrEmpty (ep.Name) ? ep.Name : ep.Path; + label = EscapeTextForMarkup (!string.IsNullOrEmpty (ep.Name) ? ep.Name : ep.Path); icon = Context.GetIcon ("md-extension-point"); } diff --git a/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/SolutionNodeBuilder.cs b/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/SolutionNodeBuilder.cs index 0df58e778f..0382b13032 100644 --- a/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/SolutionNodeBuilder.cs +++ b/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/SolutionNodeBuilder.cs @@ -71,7 +71,7 @@ namespace MonoDevelop.AddinAuthoring.NodeBuilders public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon) { Solution sol = (Solution) dataObject; - label = sol.Name; + label = EscapeTextForMarkup (sol.Name); icon = Context.GetIcon (MonoDevelop.Ide.Gui.Stock.Solution); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/NodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/NodeBuilder.cs index 16b91b950c..84a4cb1f0b 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/NodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/NodeBuilder.cs @@ -27,6 +27,9 @@ // using System; +using System.Text; +using System.Collections.Generic; + using MonoDevelop.Core; namespace MonoDevelop.Ide.Gui.Components @@ -145,5 +148,74 @@ namespace MonoDevelop.Ide.Gui.Components return (nodeAttr & attr) != 0; } + + + static Dictionary<char, string> MarkupSpecials; + + static NodeBuilder () + { + byte c; + + MarkupSpecials = new Dictionary<char, string> (); + MarkupSpecials.Add ('\'', "'"); + MarkupSpecials.Add ('"', """); + MarkupSpecials.Add ('&', "&"); + MarkupSpecials.Add ('<', "<"); + MarkupSpecials.Add ('>', ">"); + + // Escape control characters. + for (c = 0x1; c <= 0x8; c++) + MarkupSpecials.Add ((char) c, string.Format ("�x{0:x};", c)); + for (c = 0xb; c <= 0xc; c++) + MarkupSpecials.Add ((char) c, string.Format ("�x{0:x};", c)); + for (c = 0xe; c <= 0x1f; c++) + MarkupSpecials.Add ((char) c, string.Format ("�x{0:x};", c)); + for (c = 0x7f; c <= 0x84; c++) + MarkupSpecials.Add ((char) c, string.Format ("�x{0:x};", c)); + for (c = 0x86; c <= 0x9f; c++) + MarkupSpecials.Add ((char) c, string.Format ("�x{0:x};", c)); + } + + static int EscapedLength (string text, out int first) + { + int length = text.Length; + string escaped; + + first = -1; + + for (int i = 0; i < text.Length; i++) { + if (MarkupSpecials.TryGetValue (text[i], out escaped)) { + if (first == -1) + first = i; + + length += escaped.Length; + } + } + + return length; + } + + protected static string EscapeTextForMarkup (string text) + { + StringBuilder sb; + int length, i; + + if ((length = EscapedLength (text, out i)) == text.Length) + return text; + + sb = new StringBuilder (text, 0, i, length); + while (i < text.Length) { + string escaped; + + if (MarkupSpecials.TryGetValue (text[i], out escaped)) + sb.Append (escaped); + else + sb.Append (text[i]); + + i++; + } + + return sb.ToString (); + } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/TreeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/TreeBuilder.cs index f7296152b0..0d27654db0 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/TreeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/TreeBuilder.cs @@ -153,10 +153,12 @@ namespace MonoDevelop.Ide.Gui.Components } return ats; } + static int NullSortFunc (Gtk.TreeModel model, Gtk.TreeIter a, Gtk.TreeIter b) { return 0; } + public void AddChildren (IEnumerable dataObjects) { NodeBuilder[] chain = null; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs index c6d9d740ca..cba2856f1b 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs @@ -73,7 +73,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad { ProjectFile file = (ProjectFile) dataObject; - label = file.Link.IsNullOrEmpty ? file.FilePath.FileName : file.Link.FileName; + label = EscapeTextForMarkup (file.Link.IsNullOrEmpty ? file.FilePath.FileName : file.Link.FileName); if (!File.Exists (file.FilePath)) { label = "<span foreground='red'>" + label + "</span>"; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFolderNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFolderNodeBuilder.cs index fe22add135..54697fc392 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFolderNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFolderNodeBuilder.cs @@ -125,7 +125,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad ProjectFolder folder = (ProjectFolder) dataObject; - label = folder.Name; + label = EscapeTextForMarkup (folder.Name); icon = folderOpenIcon; closedIcon = folderClosedIcon; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectNodeBuilder.cs index d400ed7001..fb952fa75f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectNodeBuilder.cs @@ -113,19 +113,21 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad Project p = dataObject as Project; + string escapedProjectName = EscapeTextForMarkup (p.Name); string iconName; + if (p is DotNetProject && ((DotNetProject)p).LanguageBinding == null) { iconName = Gtk.Stock.DialogError; - label = GettextCatalog.GetString ("{0} <span foreground='red' size='small'>(Unknown language '{1}')</span>", p.Name, ((DotNetProject)p).LanguageName); + label = GettextCatalog.GetString ("{0} <span foreground='red' size='small'>(Unknown language '{1}')</span>", escapedProjectName, ((DotNetProject)p).LanguageName); } else if (p is UnknownProject) { iconName = Gtk.Stock.DialogError; - label = GettextCatalog.GetString ("{0} <span foreground='red' size='small'>(Unknown project type)</span>", p.Name); + label = GettextCatalog.GetString ("{0} <span foreground='red' size='small'>(Unknown project type)</span>", escapedProjectName); } else { iconName = p.StockIcon; if (p.ParentSolution != null && p.ParentSolution.SingleStartup && p.ParentSolution.StartupItem == p) - label = "<b>" + p.Name + "</b>"; + label = "<b>" + escapedProjectName + "</b>"; else - label = p.Name; + label = escapedProjectName; } icon = Context.GetIcon (iconName); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectReferenceFolderNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectReferenceFolderNodeBuilder.cs index cb6e3d25bd..e708277929 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectReferenceFolderNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectReferenceFolderNodeBuilder.cs @@ -73,7 +73,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon) { - label = GettextCatalog.GetString ("References"); + label = EscapeTextForMarkup (GettextCatalog.GetString ("References")); icon = Context.GetIcon (Stock.OpenReferenceFolder); closedIcon = Context.GetIcon (Stock.ClosedReferenceFolder); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectReferenceNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectReferenceNodeBuilder.cs index 5c825ca0a8..0829cf52c9 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectReferenceNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectReferenceNodeBuilder.cs @@ -77,6 +77,8 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad icon = Context.GetIcon (Stock.Reference); break; } + + label = EscapeTextForMarkup (label); if (!pref.IsValid) { label = "<span color='red'>" + label + "</span>"; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionFolderNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionFolderNodeBuilder.cs index 46108ab3cf..271f2ac781 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionFolderNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionFolderNodeBuilder.cs @@ -78,7 +78,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon) { SolutionFolder combine = dataObject as SolutionFolder; - label = combine.Name; + label = EscapeTextForMarkup (combine.Name); icon = Context.GetIcon (Stock.SolutionFolderOpen); closedIcon = Context.GetIcon (Stock.SolutionFolderClosed); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionNodeBuilder.cs index c8e9511efd..f935786e63 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionNodeBuilder.cs @@ -92,7 +92,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon) { Solution solution = dataObject as Solution; - label = GettextCatalog.GetString ("Solution {0}", solution.Name); + label = EscapeTextForMarkup (GettextCatalog.GetString ("Solution {0}", solution.Name)); icon = Context.GetIcon (Stock.Solution); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SystemFileNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SystemFileNodeBuilder.cs index eda6dda4be..da8c253351 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SystemFileNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SystemFileNodeBuilder.cs @@ -65,7 +65,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon) { SystemFile file = (SystemFile) dataObject; - label = file.Name; + label = EscapeTextForMarkup (file.Name); icon = DesktopService.GetPixbufForFile (file.Path, Gtk.IconSize.Menu); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/UnknownEntryNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/UnknownEntryNodeBuilder.cs index bf6bebe050..fe4d794750 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/UnknownEntryNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/UnknownEntryNodeBuilder.cs @@ -53,7 +53,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad if (entry.LoadError.Length > 0) { icon = Context.GetIcon (Gtk.Stock.DialogError); - label = GettextCatalog.GetString ("{0} <span foreground='red' size='small'>(Load failed)</span>", entry.Name); + label = GettextCatalog.GetString ("{0} <span foreground='red' size='small'>(Load failed)</span>", EscapeTextForMarkup (entry.Name)); } else { icon = Context.GetIcon (MonoDevelop.Ide.Gui.Stock.Project); Gdk.Pixbuf gicon = Context.GetComposedIcon (icon, "fade"); @@ -62,7 +62,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad Context.CacheComposedIcon (icon, "fade", gicon); } icon = gicon; - label = entry.Name; + label = EscapeTextForMarkup (entry.Name); } } |