diff options
author | Lluis Sanchez <lluis@novell.com> | 2010-03-24 20:07:14 +0300 |
---|---|---|
committer | Lluis Sanchez <lluis@novell.com> | 2010-03-24 20:07:14 +0300 |
commit | 047d32932a5f27f98fbd2dfc04d9aaa293cfe16e (patch) | |
tree | 789319afe26143bf830b49f387caab16a582adcf /main | |
parent | 6aaef4412d971d46af58c93aabf68cd04d74db26 (diff) |
* MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs: Don't
save the file if nothing has been replaced.
* MonoDevelop.Ide/MonoDevelop.Ide.Templates/SingleFileDescriptionTemplate.cs:
* MonoDevelop.Ide/MonoDevelop.Ide.Templates/CodeTranslationFileDescriptionTemplate.cs:
HashtableToStringArray is not necessary. The string parser service
can directly handle a string dictionary.
* MonoDevelop.Ide/Makefile.am:
* MonoDevelop.Ide/gtk-gui/gui.stetic:
* MonoDevelop.Ide/gtk-gui/objects.xml:
* MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs:
* MonoDevelop.Ide/MonoDevelop.Ide.csproj:
* MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs:
* MonoDevelop.Ide/MonoDevelop.Ide.Commands/ToolsCommands.cs:
* MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalTool.cs:
* MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolPanel.cs:
* MonoDevelop.Ide/MonoDevelop.Ide.Commands/CustomStringTagProvider.cs:
* MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/StringTagSelectorButton.cs:
* MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanel.cs:
* MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandWidget.cs:
* MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.ExternalTools.ExternalToolPanelWidget.cs:
* MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanelWidget.cs:
* MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Gui.Components.StringTagSelectorButton.cs:
* MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CustomCommandWidget.cs:
Use the new string tag model. Added a new StringTagSelectorButton
class.
* MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineConfigurationPanel.cs:
Sort the configurations list.
* MonoDevelop.Core/Makefile.am:
* MonoDevelop.Core/MonoDevelop.Core.csproj:
* MonoDevelop.Core/MonoDevelop.Core.StringParsing:
* MonoDevelop.Core/MonoDevelop.Projects/Project.cs:
* MonoDevelop.Core/MonoDevelop.Projects/Solution.cs:
* MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs:
* MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs:
* MonoDevelop.Core/MonoDevelop.Projects/CustomCommand.cs:
* MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs:
* MonoDevelop.Core/MonoDevelop.Core/StringParserService.cs:
* MonoDevelop.Core/MonoDevelop.Projects/SolutionEntityItem.cs:
* MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs:
* MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagModel.cs:
* MonoDevelop.Core/MonoDevelop.Core.StringParsing/IStringTagModel.cs:
* MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectConfiguration.cs:
* MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagProvider.cs:
* MonoDevelop.Core/MonoDevelop.Core.StringParsing/IStringTagProvider.cs:
* MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagDescription.cs:
* MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagModelDescription.cs:
Reworked the string parser service. Added an extension point for
registering tag providers. Added StringTagModel and
StringTagModelDescription classes.
svn path=/trunk/monodevelop/; revision=154152
Diffstat (limited to 'main')
41 files changed, 1311 insertions, 607 deletions
diff --git a/main/src/core/MonoDevelop.Core/ChangeLog b/main/src/core/MonoDevelop.Core/ChangeLog index 11fd02207a..43b4f1cbee 100644 --- a/main/src/core/MonoDevelop.Core/ChangeLog +++ b/main/src/core/MonoDevelop.Core/ChangeLog @@ -1,3 +1,28 @@ +2010-03-24 Lluis Sanchez Gual <lluis@novell.com> + + * Makefile.am: + * MonoDevelop.Core.csproj: + * MonoDevelop.Core.StringParsing: + * MonoDevelop.Projects/Project.cs: + * MonoDevelop.Projects/Solution.cs: + * MonoDevelop.Projects/SolutionItem.cs: + * MonoDevelop.Projects/WorkspaceItem.cs: + * MonoDevelop.Projects/CustomCommand.cs: + * MonoDevelop.Projects/ProjectService.cs: + * MonoDevelop.Core/StringParserService.cs: + * MonoDevelop.Projects/SolutionEntityItem.cs: + * MonoDevelop.Projects/ProjectConfiguration.cs: + * MonoDevelop.Core.StringParsing/StringTagModel.cs: + * MonoDevelop.Core.StringParsing/IStringTagModel.cs: + * MonoDevelop.Projects/DotNetProjectConfiguration.cs: + * MonoDevelop.Core.StringParsing/StringTagProvider.cs: + * MonoDevelop.Core.StringParsing/IStringTagProvider.cs: + * MonoDevelop.Core.StringParsing/StringTagDescription.cs: + * MonoDevelop.Core.StringParsing/StringTagModelDescription.cs: + Reworked the string parser service. Added an extension point + for registering tag providers. Added StringTagModel and + StringTagModelDescription classes. + 2010-03-23 Mike Krüger <mkrueger@novell.com> * MonoDevelop.Projects.Dom/INode.cs: Added some node types. diff --git a/main/src/core/MonoDevelop.Core/Makefile.am b/main/src/core/MonoDevelop.Core/Makefile.am index 79079bfee4..b3baa87096 100644 --- a/main/src/core/MonoDevelop.Core/Makefile.am +++ b/main/src/core/MonoDevelop.Core/Makefile.am @@ -129,6 +129,12 @@ FILES = \ MonoDevelop.Core.Serialization/XmlDataSerializer.cs \ MonoDevelop.Core.Serialization/XmlElementDataType.cs \ MonoDevelop.Core.Serialization/XmlMapAttributeProvider.cs \ + MonoDevelop.Core.StringParsing/IStringTagModel.cs \ + MonoDevelop.Core.StringParsing/IStringTagProvider.cs \ + MonoDevelop.Core.StringParsing/StringTagDescription.cs \ + MonoDevelop.Core.StringParsing/StringTagModel.cs \ + MonoDevelop.Core.StringParsing/StringTagModelDescription.cs \ + MonoDevelop.Core.StringParsing/StringTagProvider.cs \ MonoDevelop.Core/ClrVersion.cs \ MonoDevelop.Core/ComponentModelLocalization.cs \ MonoDevelop.Core/DefaultAddinLocalizer.cs \ diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/IStringTagModel.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/IStringTagModel.cs new file mode 100644 index 0000000000..5726650b2d --- /dev/null +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/IStringTagModel.cs @@ -0,0 +1,55 @@ +// +// StringTagModel.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; + +namespace MonoDevelop.Core.StringParsing +{ + public interface IStringTagModel + { + object GetValue (string name); + } + + class DictionaryStringTagModel<T>: IStringTagModel + { + Dictionary<string,T> dict; + + public DictionaryStringTagModel (Dictionary<string, T> dict) + { + this.dict = dict; + } + + public object GetValue (string name) + { + T val; + if (dict.TryGetValue (name, out val)) + return val; + else + return null; + } + } +} diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/IStringTagProvider.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/IStringTagProvider.cs new file mode 100644 index 0000000000..08ea45e49f --- /dev/null +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/IStringTagProvider.cs @@ -0,0 +1,49 @@ +// +// StringTagModel.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; + +namespace MonoDevelop.Core.StringParsing +{ + [Mono.Addins.TypeExtensionPoint(Name="String providers")] + public interface IStringTagProvider + { + /// <summary> + /// Returns a list of tags that this provider can extract from objects + /// of the provided type. If the provided type can be null, in which + /// case it must return global tags (that is, tags which are not attached + /// to a particular object). + /// </summary> + IEnumerable<StringTagDescription> GetTags (Type type); + + /// <summary> + /// Returns the value of a tag. The instance is an object of a type supported + /// by the provider, that is, the GetTags method returned tags for the object type. + /// </summary> + object GetTagValue (object instance, string tag); + } +} diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagDescription.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagDescription.cs new file mode 100644 index 0000000000..c1cadb6558 --- /dev/null +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagDescription.cs @@ -0,0 +1,76 @@ +// +// StringTagModel.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; + +namespace MonoDevelop.Core.StringParsing +{ + public class StringTagDescription + { + string name; + string description; + bool important = true; + + IStringTagProvider provider; + object instance; + + public StringTagDescription (string name, string description) + { + this.name = name; + this.description = description; + } + + public StringTagDescription (string name, string description, bool important) + { + this.name = name; + this.description = description; + this.important = important; + } + + internal void SetSource (IStringTagProvider provider, object instance) + { + this.provider = provider; + this.instance = instance; + } + + internal object GetValue () + { + return provider.GetTagValue (instance, name.ToUpperInvariant ()); + } + + public string Name { + get { return this.name; } + } + + public string Description { + get { return this.description; } + } + + public bool Important { + get { return this.important; } + } + } +} diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagModel.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagModel.cs new file mode 100644 index 0000000000..025afe0c75 --- /dev/null +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagModel.cs @@ -0,0 +1,108 @@ +// +// StringTagModel.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; + +namespace MonoDevelop.Core.StringParsing +{ + public class StringTagModel: IStringTagModel + { + Dictionary<string,StringTagDescription> tags = new Dictionary<string, StringTagDescription> (StringComparer.InvariantCultureIgnoreCase); + List<object> objects = new List<object> (); + bool initialized; + + public void Add (object obj) + { + objects.Add (obj); + initialized = false; + } + + public void Add (StringTagModel source) + { + objects.Add (source); + initialized = false; + } + + public void Remove (object obj) + { + objects.Remove (obj); + initialized = false; + } + + void Initialize () + { + initialized = true; + tags.Clear (); + foreach (IStringTagProvider provider in StringParserService.GetProviders ()) { + foreach (object obj in objects) { + if (obj is StringTagModel) + continue; + foreach (StringTagDescription tag in provider.GetTags (obj.GetType ())) { + if (!tags.ContainsKey (tag.Name)) { + tag.SetSource (provider, obj); + tags.Add (tag.Name, tag); + } + } + } + foreach (StringTagDescription tag in provider.GetTags (null)) { + if (!tags.ContainsKey (tag.Name)) { + tag.SetSource (provider, null); + tags.Add (tag.Name, tag); + } + } + } + foreach (object obj in objects) { + StringTagModel source = obj as StringTagModel; + if (source == null) + continue; + foreach (var tag in source.Tags.Values) { + if (!tags.ContainsKey (tag.Name)) { + tags.Add (tag.Name, tag); + } + } + } + } + + Dictionary<string,StringTagDescription> Tags { + get { + if (!initialized) + Initialize (); + return tags; + } + } + + public object GetValue (string name) + { + StringTagDescription td; + if (Tags.TryGetValue (name, out td)) + return td.GetValue (); + else + return null; + } + } +} + diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagModelDescription.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagModelDescription.cs new file mode 100644 index 0000000000..8a65f0833b --- /dev/null +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagModelDescription.cs @@ -0,0 +1,101 @@ +// +// StringTagModel.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; + +namespace MonoDevelop.Core.StringParsing +{ + public class StringTagModelDescription + { + List<List<StringTagDescription>> tags = new List<List<StringTagDescription>> (); + HashSet<string> tagNames = new HashSet<string> (StringComparer.InvariantCultureIgnoreCase); + List<Type> types = new List<Type> (); + List<StringTagModelDescription> models = new List<StringTagModelDescription> (); + bool initialized; + + public void Add (Type type) + { + types.Add (type); + initialized = false; + } + + public void Add (StringTagModelDescription model) + { + models.Add (model); + initialized = false; + } + + void Initialize () + { + initialized = true; + tags.Clear (); + foreach (Type type in types) { + var localTags = new List<StringTagDescription> (); + foreach (IStringTagProvider provider in StringParserService.GetProviders ()) { + foreach (StringTagDescription tag in provider.GetTags (type)) { + if (tagNames.Add (tag.Name)) + localTags.Add (tag); + } + foreach (StringTagDescription tag in provider.GetTags (null)) { + if (tagNames.Add (tag.Name)) + localTags.Add (tag); + } + } + tags.Add (localTags); + } + + foreach (StringTagModelDescription model in models) { + foreach (var modelTags in model.GetTagsGrouped ()) { + var localTags = new List<StringTagDescription> (); + foreach (var tag in modelTags) { + if (tagNames.Add (tag.Name)) + localTags.Add (tag); + } + tags.Add (localTags); + } + } + } + + public IEnumerable<StringTagDescription> GetTags () + { + if (!initialized) + Initialize (); + foreach (var list in tags) { + foreach (var tag in list) + yield return tag; + } + } + + public IEnumerable<StringTagDescription[]> GetTagsGrouped () + { + if (!initialized) + Initialize (); + foreach (var list in tags) + yield return list.ToArray (); + } + } +} diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagProvider.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagProvider.cs new file mode 100644 index 0000000000..ff0bd466a6 --- /dev/null +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.StringParsing/StringTagProvider.cs @@ -0,0 +1,51 @@ +// +// StringTagModel.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; + +namespace MonoDevelop.Core.StringParsing +{ + public abstract class StringTagProvider<T>: IStringTagProvider + { + IEnumerable<StringTagDescription> IStringTagProvider.GetTags (Type type) + { + if (typeof(T).IsAssignableFrom (type)) + return GetTags (); + else + return new StringTagDescription [0]; + } + + object IStringTagProvider.GetTagValue (object instance, string tag) + { + return GetTagValue ((T) instance, tag); + } + + public abstract object GetTagValue (T instance, string tag); + + public abstract IEnumerable<StringTagDescription> GetTags (); + } +} diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj index d5cb8b7dd7..a6831a356b 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj @@ -470,6 +470,12 @@ <Compile Include="MonoDevelop.Projects.Text\IPrettyPrinter.cs" /> <Compile Include="MonoDevelop.Projects.Text\Formatter.cs" /> <Compile Include="MonoDevelop.Projects.Utility\DiffUtility.cs" /> + <Compile Include="MonoDevelop.Core.StringParsing\IStringTagProvider.cs" /> + <Compile Include="MonoDevelop.Core.StringParsing\StringTagProvider.cs" /> + <Compile Include="MonoDevelop.Core.StringParsing\StringTagDescription.cs" /> + <Compile Include="MonoDevelop.Core.StringParsing\StringTagModel.cs" /> + <Compile Include="MonoDevelop.Core.StringParsing\StringTagModelDescription.cs" /> + <Compile Include="MonoDevelop.Core.StringParsing\IStringTagModel.cs" /> </ItemGroup> <ItemGroup> <None Include="ChangeLog" /> @@ -520,6 +526,7 @@ <Folder Include="MonoDevelop.Core.Assemblies\" /> <Folder Include="frameworks\" /> <Folder Include="MonoDevelop.Core.Instrumentation\" /> + <Folder Include="MonoDevelop.Core.StringParsing\" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\..\contrib\Mono.Cecil\Mono.Cecil.csproj"> diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringParserService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringParserService.cs index cac9ce312a..7788072362 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringParserService.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringParserService.cs @@ -33,17 +33,20 @@ using System.Collections.Generic; using System.Text; using MonoDevelop.Core; +using Mono.Addins; +using MonoDevelop.Core.StringParsing; namespace MonoDevelop.Core { public static class StringParserService { - static Dictionary<string, string> properties = new Dictionary<string, string> (StringComparer.InvariantCultureIgnoreCase); + static Dictionary<string, object> properties = new Dictionary<string, object> (StringComparer.InvariantCultureIgnoreCase); static Dictionary<string, GenerateString> stringGenerators = new Dictionary<string, GenerateString> (StringComparer.InvariantCultureIgnoreCase); + static StringTagModel DefaultStringTagModel = new StringTagModel (); delegate string GenerateString (string tag, string format); - public static Dictionary<string, string> Properties { + public static Dictionary<string, object> Properties { get { return properties; } @@ -76,7 +79,7 @@ namespace MonoDevelop.Core public static string Parse (string input) { - return Parse (input, (string[,])null); + return Parse (input, DefaultStringTagModel); } public static void Parse (ref string[] inputs) @@ -85,23 +88,8 @@ namespace MonoDevelop.Core inputs[i] = Parse (inputs[i], (string[,])null); } - public static void RegisterStringTagProvider (IStringTagProvider tagProvider) + static string Replace (string tag, IStringTagModel customTags) { - foreach (string providedTag in tagProvider.Tags) { - stringGenerators [providedTag] = delegate (string tag, string format) { - return tagProvider.Convert (tag, format); - }; - } - } - - static string Replace (string tag, Dictionary<string, string> customTags) - { - if (customTags.ContainsKey(tag)) - return customTags[tag]; - if (properties.ContainsKey (tag)) - return properties [tag]; - - GenerateString genString; string tname, tformat; int n = tag.IndexOf (':'); if (n != -1) { @@ -111,6 +99,16 @@ namespace MonoDevelop.Core tname = tag; tformat = string.Empty; } + + tag = tag.ToUpperInvariant (); + object val = customTags.GetValue (tag); + if (val != null) + return FormatValue (val, tformat); + + if (properties.ContainsKey (tag)) + return FormatValue (properties [tag], tformat); + + GenerateString genString; if (stringGenerators.TryGetValue (tname, out genString)) return genString (tname, tformat); @@ -130,7 +128,51 @@ namespace MonoDevelop.Core return null; } - public static string Parse (string input, Dictionary<string, string> customTags) + static string FormatValue (object val, string format) + { + if (format.Length == 0) + return val.ToString (); + if (val is DateTime) + return ((DateTime)val).ToString (format); + else if (val is int) + return ((int)val).ToString (format); + else if (val is uint) + return ((uint)val).ToString (format); + else if (val is long) + return ((long)val).ToString (format); + else if (val is ulong) + return ((ulong)val).ToString (format); + else if (val is short) + return ((short)val).ToString (format); + else if (val is ushort) + return ((ushort)val).ToString (format); + else if (val is byte) + return ((byte)val).ToString (format); + else if (val is sbyte) + return ((sbyte)val).ToString (format); + else if (val is decimal) + return ((decimal)val).ToString (format); + else + return val.ToString (); + } + + public static string Parse<T> (string input, Dictionary<string,T> customTags) + { + return Parse (input, new DictionaryStringTagModel<T> (customTags)); + } + + public static string Parse (string input, string[,] customTags) + { + Dictionary<string, object> tags = new Dictionary<string, object> (StringComparer.InvariantCultureIgnoreCase); + if (customTags != null) { + for (int i = 0; i < customTags.GetLength (0); ++i) { + tags.Add (customTags[i, 0].ToUpper (), customTags[i, 1]); + } + } + return Parse (input, tags); + } + + public static string Parse (string input, IStringTagModel customTags) { StringBuilder result = new StringBuilder (input.Length); int i = 0; @@ -156,143 +198,10 @@ namespace MonoDevelop.Core return result.ToString (); } - public static string Parse (string input, string[,] customTags) - { - Dictionary<string, string> tags = new Dictionary<string, string> (StringComparer.InvariantCultureIgnoreCase); - if (customTags != null) { - for (int i = 0; i < customTags.GetLength (0); ++i) { - tags.Add (customTags[i, 0].ToUpper (), customTags[i, 1]); - } - } - return Parse (input, tags); - } - - public static string Parse (string input, CustomTagStore customTags) - { - return Parse (input, customTags.ToDictionary ()); - } - - public interface IStringTagProvider - { - IEnumerable<string> Tags { - get; - } - string Convert (string tag, string format); - } - } - - public class CustomTagStore - { - Dictionary<string,CustomTag> tags = new Dictionary<string, CustomTag> (); - Dictionary<string,string> aliases = new Dictionary<string, string> (); - List<CustomTagStore> stores; - - public void Add (string tag, string value) + public static IEnumerable<IStringTagProvider> GetProviders () { - Add (tag, value); - } - - public void Add (string tag, string value, string description) - { - tags [tag] = new CustomTag (tag, value, description); - } - - public void AddAlias (string tag, params string[] aliases) - { - CustomTag ct; - if (!tags.TryGetValue (tag, out ct)) - throw new InvalidOperationException ("Tag not registered: " + tag); - foreach (string t in aliases) - this.aliases [t] = ct.Value; - } - - public void Add (CustomTagStore store) - { - if (stores == null) - stores = new List<CustomTagStore> (); - stores.Add (store); - } - - public IEnumerable<CustomTag> Tags { - get { - foreach (CustomTag t in tags.Values) - yield return t; - if (stores != null) { - foreach (CustomTagStore s in stores) { - foreach (CustomTag t in s.Tags) - yield return t; - } - } - } - } - - public Dictionary<string,string> ToDictionary () - { - if (stores != null) { - foreach (CustomTagStore s in stores) { - foreach (KeyValuePair<string,string> ct in s.ToDictionary ()) { - if (!aliases.ContainsKey (ct.Key)) - aliases [ct.Key] = ct.Value; - } - } - } - foreach (CustomTag t in tags.Values) - aliases [t.Tag] = t.Value; - return aliases; - } - - public string Parse (string input) - { - return StringParserService.Parse (input, this); - } - } - - public class CustomTag - { - string tag; - string value; - string description; - ValueGenerator valueGenerator; - - public delegate string ValueGenerator (string tag); - - public CustomTag (string tag, string value): this (tag, value, null) - { - } - - public CustomTag (string tag, string value, string description) - { - this.tag = tag; - this.value = value; - this.description = description; - } - - public CustomTag (string tag, ValueGenerator valueGenerator): this (tag, valueGenerator, null) - { - } - - public CustomTag (string tag, ValueGenerator valueGenerator, string description) - { - this.tag = tag; - this.valueGenerator = valueGenerator; - this.description = description; - } - - public string Tag { - get { return this.tag; } - } - - public string Value { - get { - if (valueGenerator != null) - return valueGenerator (tag); - else - return this.value; - } - } - - public string Description { - get { return this.description; } + foreach (IStringTagProvider provider in AddinManager.GetExtensionObjects (typeof(IStringTagProvider))) + yield return provider; } } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CustomCommand.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CustomCommand.cs index 3574b75707..fca1618cce 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CustomCommand.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CustomCommand.cs @@ -31,6 +31,7 @@ using System.IO; using MonoDevelop.Core.Serialization; using MonoDevelop.Core; using MonoDevelop.Core.Execution; +using MonoDevelop.Core.StringParsing; namespace MonoDevelop.Projects { @@ -114,13 +115,14 @@ namespace MonoDevelop.Projects public void Execute (IProgressMonitor monitor, IWorkspaceObject entry, ExecutionContext context, ConfigurationSelector configuration) { - string [,] customtags = null; + StringTagModel tagSource; - CustomTagStore tagStore = null; if (entry is SolutionItem) - tagStore = ((SolutionItem)entry).GetCustomTags (configuration); + tagSource = ((SolutionItem)entry).GetStringTagModel (configuration); else if (entry is WorkspaceItem) - tagStore = ((WorkspaceItem)entry).GetCustomTags (); + tagSource = ((WorkspaceItem)entry).GetStringTagModel (); + else + tagSource = new StringTagModel (); if (string.IsNullOrEmpty (command)) return; @@ -133,15 +135,12 @@ namespace MonoDevelop.Projects args = string.Empty; } else { exe = command.Substring (0, i); - if (tagStore != null) - args = StringParserService.Parse (command.Substring (i + 1), tagStore); - else - args = command.Substring (i + 1); + args = StringParserService.Parse (command.Substring (i + 1), tagSource); } monitor.Log.WriteLine (GettextCatalog.GetString ("Executing: {0} {1}", exe, args));
- FilePath dir = (string.IsNullOrEmpty (workingdir) ? entry.BaseDirectory : (FilePath) StringParserService.Parse (workingdir, customtags));
+ FilePath dir = (string.IsNullOrEmpty (workingdir) ? entry.BaseDirectory : (FilePath) StringParserService.Parse (workingdir, tagSource));
FilePath localPath = entry.BaseDirectory.Combine (exe); if (File.Exists (localPath)) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectConfiguration.cs index 0a1393a143..57ca1808b1 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectConfiguration.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectConfiguration.cs @@ -32,6 +32,8 @@ using System.IO; using MonoDevelop.Core; using MonoDevelop.Core.Serialization; using MonoDevelop.Core.Assemblies; +using MonoDevelop.Core.StringParsing; +using System.Collections.Generic; namespace MonoDevelop.Projects { @@ -189,4 +191,34 @@ namespace MonoDevelop.Projects get { return table; } } } + + [Mono.Addins.Extension] + class ProjectTagProvider: StringTagProvider<DotNetProjectConfiguration>, IStringTagProvider + { + public override IEnumerable<StringTagDescription> GetTags () + { + yield return new StringTagDescription ("ProjectConfig", GettextCatalog.GetString ("Project Configuration")); + yield return new StringTagDescription ("ProjectConfigName", GettextCatalog.GetString ("Project Configuration Name")); + yield return new StringTagDescription ("ProjectConfigPlat", GettextCatalog.GetString ("Project Configuration Platform")); + yield return new StringTagDescription ("TargetFile", GettextCatalog.GetString ("Target File")); + yield return new StringTagDescription ("TargetName", GettextCatalog.GetString ("Target Name")); + yield return new StringTagDescription ("TargetDir", GettextCatalog.GetString ("Target Directory")); + yield return new StringTagDescription ("TargetExt", GettextCatalog.GetString ("Target Extension")); + } + + public override object GetTagValue (DotNetProjectConfiguration conf, string tag) + { + switch (tag) { + case "TARGETPATH": + case "TARGETFILE": return conf.CompiledOutputName; + case "TARGETNAME": return conf.CompiledOutputName.FileName; + case "TARGETDIR": return conf.CompiledOutputName.ParentDirectory; + case "TARGETEXT": return conf.CompiledOutputName.Extension; + case "PROJECTCONFIG": return conf.Name + "." + conf.Platform; + case "PROJECTCONFIGNAME": return conf.Name; + case "PROJECTCONFIGPLAT": return conf.Platform; + } + throw new NotSupportedException (); + } + } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs index 8b3a43576b..08c63d20c3 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs @@ -190,16 +190,6 @@ namespace MonoDevelop.Projects return BuildAction.StandardActions; } - public override CustomTagStore GetCustomTags (ConfigurationSelector conf) - { - CustomTagStore tagStore = base.GetCustomTags (conf); - FilePath outputFile = GetOutputFileName (conf); - tagStore.Add ("TargetFile", outputFile, GettextCatalog.GetString ("Target File")); - tagStore.Add ("TargetName", outputFile.FileName, GettextCatalog.GetString ("Target Name")); - tagStore.Add ("TargetDir", outputFile.ParentDirectory, GettextCatalog.GetString ("Target Directory")); - return tagStore; - } - public static Project LoadProject (string filename, IProgressMonitor monitor) { Project prj = Services.ProjectService.ReadSolutionItem (monitor, filename) as Project; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs index 11a40f7b56..746c5cfda0 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs @@ -31,6 +31,7 @@ using MonoDevelop.Core; using System.IO; using MonoDevelop.Core.Serialization; using System.Collections.Generic; +using MonoDevelop.Core.StringParsing; namespace MonoDevelop.Projects { @@ -93,11 +94,11 @@ namespace MonoDevelop.Projects { if (ParentItem == null) return environmentVariables; - - CustomTagStore tags = ParentItem.GetCustomTags (Selector); + + StringTagModel tagSource = ParentItem.GetStringTagModel (Selector); Dictionary<string, string> vars = new Dictionary<string, string> (); foreach (var v in environmentVariables) - vars [v.Key] = tags.Parse (v.Value); + vars [v.Key] = StringParserService.Parse (v.Value, tagSource); return vars; } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs index 6515d99d58..4af3fd2124 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs @@ -45,6 +45,7 @@ using MonoDevelop.Core.Assemblies; using MonoDevelop.Core.Instrumentation; using MonoDevelop.Projects.Extensions; using Mono.Unix; +using MonoDevelop.Core.StringParsing; namespace MonoDevelop.Projects { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs index 61cf593004..f211619a7b 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs @@ -33,6 +33,7 @@ using System.Threading; using MonoDevelop.Core.Serialization; using MonoDevelop.Core; using MonoDevelop.Core.ProgressMonitoring; +using MonoDevelop.Core.StringParsing; namespace MonoDevelop.Projects { @@ -190,15 +191,6 @@ namespace MonoDevelop.Projects } } - public override CustomTagStore GetCustomTags () - { - CustomTagStore tags = new CustomTagStore (); - tags.Add ("SolutionName", Name, GettextCatalog.GetString ("Solution name")); - tags.Add ("SolutionFile", FileName, GettextCatalog.GetString ("Solution file")); - tags.Add ("SolutionDir", BaseDirectory, GettextCatalog.GetString ("Solution directory")); - return tags; - } - public override void LoadUserProperties () { base.LoadUserProperties (); @@ -763,4 +755,26 @@ namespace MonoDevelop.Projects public event SolutionItemEventHandler EntrySaved; public event EventHandler<SolutionItemEventArgs> ItemReloadRequired; } + + [Mono.Addins.Extension] + class SolutionTagProvider: StringTagProvider<Solution>, IStringTagProvider + { + public override IEnumerable<StringTagDescription> GetTags () + { + yield return new StringTagDescription ("SolutionFile", GettextCatalog.GetString ("Solution File")); + yield return new StringTagDescription ("SolutionName", GettextCatalog.GetString ("Solution Name")); + yield return new StringTagDescription ("SolutionDir", GettextCatalog.GetString ("Solution Directory")); + } + + public override object GetTagValue (Solution sol, string tag) + { + switch (tag) { + case "SOLUTIONNAME": return sol.Name; + case "COMBINEFILENAME": + case "SOLUTIONFILE": return sol.FileName; + case "SOLUTIONDIR": return sol.BaseDirectory; + } + throw new NotSupportedException (); + } + } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionEntityItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionEntityItem.cs index 62296acc49..7db08cf6cd 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionEntityItem.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionEntityItem.cs @@ -40,6 +40,7 @@ using MonoDevelop.Core; using MonoDevelop.Projects; using MonoDevelop.Core.Serialization; using MonoDevelop.Projects.Extensions; +using MonoDevelop.Core.StringParsing; namespace MonoDevelop.Projects { @@ -289,15 +290,6 @@ namespace MonoDevelop.Projects return col; } - public override CustomTagStore GetCustomTags (ConfigurationSelector conf) - { - CustomTagStore tagStore = base.GetCustomTags (conf); - tagStore.Add ("ItemFile", Name, GettextCatalog.GetString ("Project File")); - tagStore.AddAlias ("ItemFile", "ProjectFile"); - return tagStore; - } - - protected override void OnNameChanged (SolutionItemRenamedEventArgs e) { Solution solution = this.ParentSolution; @@ -426,6 +418,26 @@ namespace MonoDevelop.Projects ConfigurationsChanged (this, EventArgs.Empty); } + public override StringTagModelDescription GetStringTagModelDescription (ConfigurationSelector conf) + { + StringTagModelDescription model = base.GetStringTagModelDescription (conf); + SolutionItemConfiguration config = GetConfiguration (conf); + if (config != null) + model.Add (config.GetType ()); + else + model.Add (typeof(SolutionItemConfiguration)); + return model; + } + + public override StringTagModel GetStringTagModel (ConfigurationSelector conf) + { + StringTagModel source = base.GetStringTagModel (conf); + SolutionItemConfiguration config = GetConfiguration (conf); + if (config != null) + source.Add (config); + return source; + } + internal protected virtual void OnItemAdded (object obj) { } @@ -464,4 +476,24 @@ namespace MonoDevelop.Projects remove { fileStatusTracker.ReloadRequired -= value; } } */ } + + [Mono.Addins.Extension] + class SolutionEntityItemTagProvider: StringTagProvider<SolutionEntityItem>, IStringTagProvider + { + public override IEnumerable<StringTagDescription> GetTags () + { + yield return new StringTagDescription ("ProjectFile", "Project File"); + } + + public override object GetTagValue (SolutionEntityItem item, string tag) + { + switch (tag) { + case "ITEMFILE": + case "PROJECTFILE": + case "PROJECTFILENAME": + return item.FileName; + } + throw new NotSupportedException (); + } + } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs index f39ac7fc58..5d51380671 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs @@ -35,6 +35,7 @@ using MonoDevelop.Core; using MonoDevelop.Core.Serialization; using MonoDevelop.Projects.Extensions;
using MonoDevelop.Core.Collections; +using MonoDevelop.Core.StringParsing; namespace MonoDevelop.Projects { @@ -373,16 +374,21 @@ namespace MonoDevelop.Projects internalChildren.Items.Remove (item); } - public virtual CustomTagStore GetCustomTags (ConfigurationSelector conf) + public virtual StringTagModelDescription GetStringTagModelDescription (ConfigurationSelector conf) { - CustomTagStore tagStore = new CustomTagStore (); - tagStore.Add ("ItemName", Name, GettextCatalog.GetString ("Project Name")); - tagStore.AddAlias ("ItemName", "ProjectName"); - tagStore.Add ("ItemDir", BaseDirectory, GettextCatalog.GetString ("Project Directory")); - tagStore.AddAlias ("ItemDir", "ProjectDir"); + StringTagModelDescription model = new StringTagModelDescription (); + model.Add (GetType ()); + model.Add (typeof(Solution)); + return model; + } + + public virtual StringTagModel GetStringTagModel (ConfigurationSelector conf) + { + StringTagModel source = new StringTagModel (); + source.Add (this); if (ParentSolution != null) - tagStore.Add (ParentSolution.GetCustomTags ()); - return tagStore; + source.Add (ParentSolution.GetStringTagModel ()); + return source; } public static ReadOnlyCollection<T> TopologicalSort<T> (IEnumerable<T> items, ConfigurationSelector configuration) where T: SolutionItem @@ -494,4 +500,27 @@ namespace MonoDevelop.Projects public event SolutionItemRenamedEventHandler NameChanged; public event SolutionItemModifiedEventHandler Modified; } + + [Mono.Addins.Extension] + class SolutionItemTagProvider: StringTagProvider<SolutionItem>, IStringTagProvider + { + public override IEnumerable<StringTagDescription> GetTags () + { + yield return new StringTagDescription ("ProjectName", "Project Name"); + yield return new StringTagDescription ("ProjectDir", "Project Directory"); + } + + public override object GetTagValue (SolutionItem item, string tag) + { + switch (tag) { + case "ITEMNAME": + case "PROJECTNAME": + return item.Name; + case "ITEMDIR": + case "PROJECTDIR": + return item.BaseDirectory; + } + throw new NotSupportedException (); + } + } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs index 86c5c3db6e..d5cd1ad392 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs @@ -38,6 +38,7 @@ using System.CodeDom.Compiler; using MonoDevelop.Core; using MonoDevelop.Projects; using MonoDevelop.Core.Serialization; +using MonoDevelop.Core.StringParsing; namespace MonoDevelop.Projects { @@ -489,13 +490,18 @@ namespace MonoDevelop.Projects return FileName.ChangeExtension (".userprefs"); } - public virtual CustomTagStore GetCustomTags () + public virtual StringTagModelDescription GetStringTagModelDescription () { - CustomTagStore tags = new CustomTagStore (); - tags.Add ("WorkspaceName", Name, GettextCatalog.GetString ("Workspace name")); - tags.Add ("WorkspaceFile", FileName, GettextCatalog.GetString ("Workspace file")); - tags.Add ("WorkspaceDir", BaseDirectory, GettextCatalog.GetString ("Workspace directory")); - return tags; + StringTagModelDescription model = new StringTagModelDescription (); + model.Add (GetType ()); + return model; + } + + public virtual StringTagModel GetStringTagModel () + { + StringTagModel source = new StringTagModel (); + source.Add (this); + return source; } public FilePath GetAbsoluteChildPath (FilePath relPath) @@ -735,4 +741,29 @@ namespace MonoDevelop.Projects reloadRequired (this, args); } } + + [Mono.Addins.Extension] + class WorkspaceItemTagProvider: IStringTagProvider + { + public IEnumerable<StringTagDescription> GetTags (Type type) + { + if (typeof(WorkspaceItem).IsAssignableFrom (type) && !typeof(Solution).IsAssignableFrom (type)) { + // Solutions have its own provider + yield return new StringTagDescription ("WorkspaceFile", GettextCatalog.GetString ("Workspace File")); + yield return new StringTagDescription ("WorkspaceName", GettextCatalog.GetString ("Workspace Name")); + yield return new StringTagDescription ("WorkspaceDir", GettextCatalog.GetString ("Workspace Directory")); + } + } + + public object GetTagValue (object obj, string tag) + { + WorkspaceItem item = (WorkspaceItem) obj; + switch (tag) { + case "WORKSPACENAME": return item.Name; + case "WORKSPACEFILE": return item.FileName; + case "WORKSPACEDIR": return item.BaseDirectory; + } + throw new NotSupportedException (); + } + } } diff --git a/main/src/core/MonoDevelop.Ide/ChangeLog b/main/src/core/MonoDevelop.Ide/ChangeLog index 67c7416e57..d5a7342032 100644 --- a/main/src/core/MonoDevelop.Ide/ChangeLog +++ b/main/src/core/MonoDevelop.Ide/ChangeLog @@ -1,3 +1,36 @@ +2010-03-24 Lluis Sanchez Gual <lluis@novell.com> + + * MonoDevelop.Ide.FindInFiles/FileProvider.cs: Don't save the + file if nothing has been replaced. + + * MonoDevelop.Ide.Templates/SingleFileDescriptionTemplate.cs: + * MonoDevelop.Ide.Templates/CodeTranslationFileDescriptionTemplate.cs: + HashtableToStringArray is not necessary. The string parser + service can directly handle a string dictionary. + + * Makefile.am: + * gtk-gui/gui.stetic: + * gtk-gui/objects.xml: + * MonoDevelop.Ide/Ide.cs: + * MonoDevelop.Ide.csproj: + * MonoDevelop.Ide.Gui/Workbench.cs: + * MonoDevelop.Ide.Commands/ToolsCommands.cs: + * MonoDevelop.Ide.ExternalTools/ExternalTool.cs: + * MonoDevelop.Ide.ExternalTools/ExternalToolPanel.cs: + * MonoDevelop.Ide.Commands/CustomStringTagProvider.cs: + * MonoDevelop.Ide.Gui.Components/StringTagSelectorButton.cs: + * MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanel.cs: + * MonoDevelop.Ide.Projects.OptionPanels/CustomCommandWidget.cs: + * gtk-gui/MonoDevelop.Ide.ExternalTools.ExternalToolPanelWidget.cs: + * MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanelWidget.cs: + * gtk-gui/MonoDevelop.Ide.Gui.Components.StringTagSelectorButton.cs: + * gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CustomCommandWidget.cs: + Use the new string tag model. Added a new + StringTagSelectorButton class. + + * MonoDevelop.Ide.Projects.OptionPanels/CombineConfigurationPanel.cs: + Sort the configurations list. + 2010-03-23 Michael Hutchinson <mhutchinson@novell.com> * MonoDevelop.Ide/MessageService.cs: Use 'Ok' in error dialogs diff --git a/main/src/core/MonoDevelop.Ide/Makefile.am b/main/src/core/MonoDevelop.Ide/Makefile.am index a99e3b00d3..794e854838 100644 --- a/main/src/core/MonoDevelop.Ide/Makefile.am +++ b/main/src/core/MonoDevelop.Ide/Makefile.am @@ -40,6 +40,7 @@ FILES = \ gtk-gui/MonoDevelop.Ide.FindInFiles.FindInFilesDialog.cs \ gtk-gui/MonoDevelop.Ide.FindInFiles.SearchResultWidget.cs \ gtk-gui/MonoDevelop.Ide.Gui.Components.ExecutionModeComboBox.cs \ + gtk-gui/MonoDevelop.Ide.Gui.Components.StringTagSelectorButton.cs \ gtk-gui/MonoDevelop.Ide.Gui.Dialogs.AddinLoadErrorDialog.cs \ gtk-gui/MonoDevelop.Ide.Gui.Dialogs.ErrorDialog.cs \ gtk-gui/MonoDevelop.Ide.Gui.Dialogs.GoToDialog.cs \ @@ -385,6 +386,7 @@ FILES = \ MonoDevelop.Ide.Gui.Components/NodeState.cs \ MonoDevelop.Ide.Gui.Components/PadTreeView.cs \ MonoDevelop.Ide.Gui.Components/ProjectFileEntry.cs \ + MonoDevelop.Ide.Gui.Components/StringTagSelectorButton.cs \ MonoDevelop.Ide.Gui.Components/TransactedTreeBuilder.cs \ MonoDevelop.Ide.Gui.Components/TreeBuilder.cs \ MonoDevelop.Ide.Gui.Components/TreeNodeNavigator.cs \ diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/CustomStringTagProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/CustomStringTagProvider.cs index cab5e3912b..b81558b7ef 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/CustomStringTagProvider.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/CustomStringTagProvider.cs @@ -31,117 +31,80 @@ using MonoDevelop.Core; using MonoDevelop.Ide.Gui; using System.IO; using System.Collections.Generic; +using MonoDevelop.Core.StringParsing; namespace MonoDevelop.Ide.Commands { - class DefaultStringTagProvider : StringParserService.IStringTagProvider + // The path name should not be required here. This is a workaround to a Mono.Addins bug (fixed in the last version) + [Mono.Addins.Extension ("/MonoDevelop.Core/TypeExtensions/MonoDevelop.Core.StringParsing.IStringTagProvider")] + class DefaultStringTagProvider : StringTagProvider<Workbench> { - public IEnumerable<string> Tags { - get { - return new String[] { - "ITEMPATH", - "ITEMDIR", - "ITEMFILENAME", - "ITEMEXT", - "TARGETPATH", - "TARGETDIR", - "TARGETNAME", - "TARGETEXT", - "PROJECTDIR", - "PROJECTFILENAME", - "SOLUTIONDIR", - "SOLUTIONFILE", - "COMBINEDIR", - "COMBINEFILENAME" - }; - } - } - - public string Convert (string tag, string format) - { - try { - switch (tag.ToUpperInvariant ()) { - case "ITEMPATH": - if (IdeApp.Workbench.ActiveDocument != null) - return (IdeApp.Workbench.ActiveDocument.IsViewOnly) ? String.Empty : IdeApp.Workbench.ActiveDocument.Name; - return String.Empty; - - case "ITEMDIR": - if (IdeApp.Workbench.ActiveDocument != null) - return (IdeApp.Workbench.ActiveDocument.IsViewOnly) ? String.Empty : (string)IdeApp.Workbench.ActiveDocument.FileName.ParentDirectory; - return String.Empty; - - case "ITEMFILENAME": - if (IdeApp.Workbench.ActiveDocument != null) - return (IdeApp.Workbench.ActiveDocument.IsViewOnly) ? String.Empty : IdeApp.Workbench.ActiveDocument.FileName.FileName; - return String.Empty; - - case "ITEMEXT": - if (IdeApp.Workbench.ActiveDocument != null) - return (IdeApp.Workbench.ActiveDocument.IsViewOnly) ? String.Empty : IdeApp.Workbench.ActiveDocument.FileName.Extension; - return String.Empty; - - case "TARGETPATH": - if (IdeApp.ProjectOperations.CurrentSelectedProject != null) - return IdeApp.ProjectOperations.CurrentSelectedProject.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration); - else - if ((IdeApp.Workbench.ActiveDocument != null) && (IdeApp.Workbench.ActiveDocument.Project != null)) - return IdeApp.Workbench.ActiveDocument.Project.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration); - return String.Empty; - - case "TARGETDIR": - if(IdeApp.ProjectOperations.CurrentSelectedProject != null) - return Path.GetDirectoryName (IdeApp.ProjectOperations.CurrentSelectedProject.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration)); - else - if((IdeApp.Workbench.ActiveDocument != null) && (IdeApp.Workbench.ActiveDocument.Project != null)) - return Path.GetDirectoryName (IdeApp.Workbench.ActiveDocument.Project.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration)); - return String.Empty; - - case "TARGETNAME": - if(IdeApp.ProjectOperations.CurrentSelectedProject != null) - return Path.GetFileName (IdeApp.ProjectOperations.CurrentSelectedProject.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration)); - else - if((IdeApp.Workbench.ActiveDocument != null) && (IdeApp.Workbench.ActiveDocument.Project != null)) - return Path.GetFileName (IdeApp.Workbench.ActiveDocument.Project.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration)); - return String.Empty; - - case "TARGETEXT": - if(IdeApp.ProjectOperations.CurrentSelectedProject != null) - return Path.GetExtension (IdeApp.ProjectOperations.CurrentSelectedProject.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration)); - else - if((IdeApp.Workbench.ActiveDocument != null) && (IdeApp.Workbench.ActiveDocument.Project != null)) - return Path.GetExtension (IdeApp.Workbench.ActiveDocument.Project.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration)); - return String.Empty; - - case "PROJECTDIR": - if((IdeApp.Workbench.ActiveDocument != null) && (IdeApp.Workbench.ActiveDocument.Project != null)) - return IdeApp.Workbench.ActiveDocument.Project.FileName.ParentDirectory.FullPath; - return String.Empty; - - case "PROJECTFILENAME": - if((IdeApp.Workbench.ActiveDocument != null) && (IdeApp.Workbench.ActiveDocument.Project != null)) - return IdeApp.Workbench.ActiveDocument.Project.FileName.FileName; - return String.Empty; - - case "SOLUTIONDIR": - case "COMBINEDIR": - if(IdeApp.ProjectOperations.CurrentSelectedSolutionItem != null) - return IdeApp.ProjectOperations.CurrentSelectedSolutionItem.ParentSolution.FileName.ParentDirectory.FullPath; - return String.Empty; - - case "SOLUTIONFILE": - case "COMBINEFILENAME": - if(IdeApp.ProjectOperations.CurrentSelectedSolutionItem != null) - return IdeApp.ProjectOperations.CurrentSelectedSolutionItem.ParentSolution.FileName.FileName; - return String.Empty; - - default: - return String.Empty; - } - } - catch { - return String.Empty; + public override IEnumerable<StringTagDescription> GetTags () + { + yield return new StringTagDescription ("FilePath", "File Path"); + yield return new StringTagDescription ("FileDir", "File Directory"); + yield return new StringTagDescription ("FileName", "File Name"); + yield return new StringTagDescription ("FileExt", "File Extension"); + yield return new StringTagDescription ("CurLine", "Cursor Line", false); + yield return new StringTagDescription ("CurColumn", "Cursor Column", false); + yield return new StringTagDescription ("CurOffset", "Cursor Offset", false); + yield return new StringTagDescription ("CurText", "Selected Editor Text", false); + yield return new StringTagDescription ("EditorText", "Editor Text", false); + yield return new StringTagDescription ("StartupPath", "MonoDevelop Startup Directory", false); + } + + public override object GetTagValue (Workbench wb, string tag) + { + switch (tag) { + case "FILEPATH": + if (wb.ActiveDocument != null) + return !wb.ActiveDocument.IsFile ? String.Empty : wb.ActiveDocument.Name; + return null; + + case "FILEDIR": + if (wb.ActiveDocument != null) + return !wb.ActiveDocument.IsFile ? FilePath.Empty : wb.ActiveDocument.FileName.ParentDirectory; + return null; + + case "FILENAME": + if (wb.ActiveDocument != null) + return !wb.ActiveDocument.IsFile ? String.Empty : wb.ActiveDocument.FileName.FileName; + return null; + + case "FILEEXT": + if (wb.ActiveDocument != null) + return !wb.ActiveDocument.IsFile ? String.Empty : wb.ActiveDocument.FileName.Extension; + return null; + + case "CURLINE": + if (wb.ActiveDocument != null && wb.ActiveDocument.TextEditor != null) + return wb.ActiveDocument.TextEditor.CursorLine; + return null; + + case "CURCOLUMN": + if (wb.ActiveDocument != null && wb.ActiveDocument.TextEditor != null) + return wb.ActiveDocument.TextEditor.CursorColumn; + return null; + + case "CUROFFSET": + if (wb.ActiveDocument != null && wb.ActiveDocument.TextEditor != null) + return wb.ActiveDocument.TextEditor.CursorPosition; + return null; + + case "CURTEXT": + if (wb.ActiveDocument != null && wb.ActiveDocument.TextEditor != null) + return wb.ActiveDocument.TextEditor.SelectedText; + return null; + + case "EDITORTEXT": + if (wb.ActiveDocument != null && wb.ActiveDocument.TextEditor != null) + return wb.ActiveDocument.TextEditor.Text; + return null; + + case "STARTUPPATH": + return AppDomain.CurrentDomain.BaseDirectory; } + throw new NotSupportedException (); } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/ToolsCommands.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/ToolsCommands.cs index 87acfdd1fd..a8972e81dd 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/ToolsCommands.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/ToolsCommands.cs @@ -69,7 +69,7 @@ namespace MonoDevelop.Ide.Commands { ExternalTools.ExternalTool tool = (ExternalTools.ExternalTool)dataItem; - string argumentsTool = StringParserService.Parse (tool.Arguments); + string argumentsTool = StringParserService.Parse (tool.Arguments, IdeApp.Workbench.GetStringTagModel ()); //Save current file checkbox if (tool.SaveCurrentFile && IdeApp.Workbench.ActiveDocument != null) @@ -78,7 +78,7 @@ namespace MonoDevelop.Ide.Commands if (tool.PromptForArguments) { string customerArguments = MessageService.GetTextResponse (GettextCatalog.GetString ("Enter any arguments you want to use while launching tool, {0}:", tool.MenuCommand), GettextCatalog.GetString ("Command Arguments for {0}", tool.MenuCommand), ""); if (customerArguments != String.Empty) - argumentsTool = StringParserService.Parse (customerArguments); + argumentsTool = StringParserService.Parse (customerArguments, IdeApp.Workbench.GetStringTagModel ()); } DispatchService.BackgroundDispatch (delegate { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalTool.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalTool.cs index 39721e0f86..3481572852 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalTool.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalTool.cs @@ -41,7 +41,7 @@ namespace MonoDevelop.Ide.ExternalTools string arguments; string initialDirectory; bool promptForArguments; - bool useOutputPad; + bool useOutputPad = true; bool saveCurrentFile; public string MenuCommand { @@ -154,8 +154,22 @@ namespace MonoDevelop.Ide.ExternalTools if (!String.IsNullOrEmpty (reader.GetAttribute (saveCurrentFileAttribute))) result.saveCurrentFile = Boolean.Parse (reader.GetAttribute (saveCurrentFileAttribute)); + // Some tag names have changed. Update them now. + + result.arguments = UpgradeTags (result.arguments); + result.initialDirectory = UpgradeTags (result.initialDirectory); + return result; } + + static string UpgradeTags (string s) + { + s = s.Replace ("${ItemPath}","${FilePath}"); + s = s.Replace ("${ItemDir}","${FileDir}"); + s = s.Replace ("${ItemFileName}","${FileName}"); + s = s.Replace ("${ItemExt}","${FileExt}"); + return s; + } #endregion } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolPanel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolPanel.cs index 7cba4e0869..abe5dbccf6 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolPanel.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolPanel.cs @@ -62,43 +62,6 @@ namespace MonoDevelop.Ide.ExternalTools public partial class ExternalToolPanelWidget : Gtk.Bin { - static string[,] argumentQuickInsertMenu = new string[,] { - {GettextCatalog.GetString ("Item Path"), "${ItemPath}"}, - {GettextCatalog.GetString ("_Item Directory"), "${ItemDir}"}, - {GettextCatalog.GetString ("Item file name"), "${ItemFileName}"}, - {GettextCatalog.GetString ("Item extension"), "${ItemExt}"}, - {"-", ""}, - {GettextCatalog.GetString ("Current line"), "${CurLine}"}, - {GettextCatalog.GetString ("Current column"), "${CurCol}"}, - {GettextCatalog.GetString ("Current text"), "${CurText}"}, - {"-", ""}, - {GettextCatalog.GetString ("Target Path"), "${TargetPath}"}, - {GettextCatalog.GetString ("_Target Directory"), "${TargetDir}"}, - {GettextCatalog.GetString ("Target Name"), "${TargetName}"}, - {GettextCatalog.GetString ("Target Extension"), "${TargetExt}"}, - {"-", ""}, - {GettextCatalog.GetString ("_Project Directory"), "${ProjectDir}"}, - {GettextCatalog.GetString ("Project file name"), "${ProjectFileName}"}, - {"-", ""}, - {GettextCatalog.GetString ("_Solution Directory"), "${SolutionDir}"}, - {GettextCatalog.GetString ("Solution File Name"), "${SolutionFile}"}, - {"-", ""}, - {GettextCatalog.GetString ("MonoDevelop Startup Directory"), "${StartupPath}"}, - }; - - static string[,] workingDirInsertMenu = new string[,] { - {GettextCatalog.GetString ("_Item Directory"), "${ItemDir}"}, - {"-", ""}, - {GettextCatalog.GetString ("_Target Directory"), "${TargetDir}"}, - {GettextCatalog.GetString ("Target Name"), "${TargetName}"}, - {"-", ""}, - {GettextCatalog.GetString ("_Project Directory"), "${ProjectDir}"}, - {"-", ""}, - {GettextCatalog.GetString ("_Solution Directory"), "${SolutionDir}"}, - {"-", ""}, - {GettextCatalog.GetString ("MonoDevelop Startup Directory"), "${StartupPath}"}, - }; - // gtk controls ListStore toolListBoxStore; @@ -119,8 +82,8 @@ namespace MonoDevelop.Ide.ExternalTools titleTextBox, argumentTextBox, workingDirTextBox, promptArgsCheckBox, useOutputPadCheckBox, titleLabel, argumentLabel, commandLabel, - workingDirLabel, browseButton, argumentQuickInsertButton, - workingDirQuickInsertButton, moveUpButton, moveDownButton, + workingDirLabel, browseButton, + moveUpButton, moveDownButton, saveCurrentFileCheckBox }; @@ -136,8 +99,11 @@ namespace MonoDevelop.Ide.ExternalTools toolListBox.AppendColumn (GettextCatalog.GetString ("Tools"), new CellRendererText (), "text", 0); - new MenuButtonEntry (argumentTextBox, argumentQuickInsertButton, argumentQuickInsertMenu); - new MenuButtonEntry (workingDirTextBox, workingDirQuickInsertButton, workingDirInsertMenu); + tagSelectorArgs.TagModel = IdeApp.Workbench.GetStringTagModelDescription (); + tagSelectorArgs.TargetEntry = argumentTextBox; + + tagSelectorPath.TagModel = IdeApp.Workbench.GetStringTagModelDescription (); + tagSelectorPath.TargetEntry = workingDirTextBox; toolListBox.Selection.Changed += SelectionChanged; removeButton.Clicked += RemoveButtonClicked; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs index 44bf97cd59..3dcb293322 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs @@ -95,8 +95,11 @@ namespace MonoDevelop.Ide.FindInFiles Document document; StringBuilder buffer = null; + bool somethingReplaced; + public void BeginReplace () { + somethingReplaced = false; TextReader reader = Open (); buffer = new StringBuilder (reader.ReadToEnd ()); reader.Close (); @@ -111,6 +114,7 @@ namespace MonoDevelop.Ide.FindInFiles public void Replace (int offset, int length, string replacement) { + somethingReplaced = true; buffer.Remove (offset, length); buffer.Insert (offset, replacement); if (this.document != null) { @@ -128,12 +132,12 @@ namespace MonoDevelop.Ide.FindInFiles Gtk.Application.Invoke (delegate { document.TextEditor.EndAtomicUndo (); }); return; } - if (buffer != null) { + if (buffer != null && somethingReplaced) { object attributes = DesktopService.GetFileAttributes (FileName); File.WriteAllText (FileName, buffer.ToString ()); DesktopService.SetFileAttributes (FileName, attributes); - buffer = null; } + buffer = null; } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/StringTagSelectorButton.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/StringTagSelectorButton.cs new file mode 100644 index 0000000000..0ab40cfff0 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/StringTagSelectorButton.cs @@ -0,0 +1,153 @@ +// +// StringTagSelectorButton.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using MonoDevelop.Core.StringParsing; +using Gtk; +using MonoDevelop.Core; + +namespace MonoDevelop.Ide.Gui.Components +{ + [System.ComponentModel.ToolboxItem(true)] + public partial class StringTagSelectorButton : Gtk.Bin + { + bool isOpen; + + public StringTagSelectorButton () + { + this.Build (); + } + + public StringTagModelDescription TagModel { get; set; } + + public Entry TargetEntry { get; set; } + + void InsertTag (string tag) + { + if (TargetEntry != null) { + int tempInt = TargetEntry.Position; + TargetEntry.DeleteSelection(); + TargetEntry.InsertText ("${" + tag + "}", ref tempInt); + } + } + + Menu CreateMenu (bool importantOnly) + { + if (TagModel != null) { + Menu menu = new Menu (); + + bool itemsAdded = false; + bool extraItemsAdded = false; + + foreach (StringTagDescription[] tags in TagModel.GetTagsGrouped ()) { + if (itemsAdded) { + SeparatorMenuItem sep = new SeparatorMenuItem (); + menu.Add (sep); + } + foreach (StringTagDescription tag in tags) { + if (tag.Important != importantOnly) + continue; + MenuItem item = new MenuItem (tag.Description); + string tagString = tag.Name; + item.ButtonPressEvent += delegate { + InsertTag (tagString); + }; + menu.Add (item); + itemsAdded = true; + } + } + if (importantOnly) { + Menu subMenu = CreateMenu (false); + if (subMenu.Children.Length > 0) { + SeparatorMenuItem sep = new SeparatorMenuItem (); + menu.Add (sep); + MenuItem item = new MenuItem (GettextCatalog.GetString ("More")); + item.Submenu = subMenu; + menu.Add (item); + } + } + menu.ShowAll (); + return menu; + } + return null; + } + + protected virtual void OnButtonClicked (object sender, System.EventArgs e) + { + Menu menu = CreateMenu (true); + + if (menu != null) { + isOpen = true; + + //make sure the button looks depressed + ReliefStyle oldRelief = button.Relief; + button.Relief = ReliefStyle.Normal; + + //clean up after the menu's done + menu.Hidden += delegate { + button.Relief = oldRelief ; + isOpen = false; + button.State = StateType.Normal; + + //FIXME: for some reason the menu's children don't get activated if we destroy + //directly here, so use a timeout to delay it + GLib.Timeout.Add (100, delegate { + menu.Destroy (); + return false; + }); + }; + menu.Popup (null, null, PositionFunc, 0, Gtk.Global.CurrentEventTime); + } + } + + protected override void OnStateChanged(StateType previous_state) + { + base.OnStateChanged (previous_state); + + //while the menu's open, make sure the button looks depressed + if (isOpen && button.State != StateType.Active) + button.State = StateType.Active; + } + + void PositionFunc (Menu mn, out int x, out int y, out bool push_in) + { + button.GdkWindow.GetOrigin (out x, out y); + Gdk.Rectangle rect = button.Allocation; + x += rect.X; + y += rect.Y + rect.Height; + + //if the menu would be off the bottom of the screen, "drop" it upwards + if (y + mn.Requisition.Height > button.Screen.Height) { + y -= mn.Requisition.Height; + y -= rect.Height; + } + + //let GTK reposition the button if it still doesn't fit on the screen + push_in = true; + } + } +} + diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs index 74a02eecb1..2b4931bbeb 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs @@ -45,6 +45,7 @@ using MonoDevelop.Ide.Gui.Dialogs; using MonoDevelop.Ide.Desktop; using Mono.Addins; using MonoDevelop.Ide.Projects; +using MonoDevelop.Core.StringParsing; namespace MonoDevelop.Ide.Gui { @@ -526,6 +527,27 @@ namespace MonoDevelop.Ide.Gui } } + public StringTagModelDescription GetStringTagModelDescription () + { + StringTagModelDescription model = new StringTagModelDescription (); + model.Add (typeof (Project)); + model.Add (typeof (Solution)); + model.Add (typeof (DotNetProjectConfiguration)); + model.Add (typeof (Workbench)); + return model; + } + + public StringTagModel GetStringTagModel () + { + StringTagModel source = new StringTagModel (); + source.Add (this); + if (IdeApp.ProjectOperations.CurrentSelectedSolutionItem != null) + source.Add (IdeApp.ProjectOperations.CurrentSelectedSolutionItem.GetStringTagModel (IdeApp.Workspace.ActiveConfiguration)); + else if (IdeApp.ProjectOperations.CurrentSelectedWorkspaceItem != null) + source.Add (IdeApp.ProjectOperations.CurrentSelectedWorkspaceItem.GetStringTagModel ()); + return source; + } + internal void ShowNext () { // Shows the next item in a pad that implements ILocationListPad. diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineConfigurationPanel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineConfigurationPanel.cs index 4a1ea2eb9d..93bfaaf5b7 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineConfigurationPanel.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineConfigurationPanel.cs @@ -59,7 +59,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels partial class CombineConfigurationPanelWidget : Gtk.Bin { - TreeStore store; + ListStore store; SolutionConfiguration configuration; MultiConfigItemOptionsDialog parentDialog; @@ -68,7 +68,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels Build (); this.parentDialog = parentDialog; - store = new TreeStore (typeof(object), typeof(string), typeof(bool)); + store = new ListStore (typeof(object), typeof(string), typeof(bool)); configsList.Model = store; configsList.HeadersVisible = true; @@ -79,6 +79,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels col.AddAttribute (sr, "text", 1); col.Title = GettextCatalog.GetString ("Solution Item"); configsList.AppendColumn (col); + col.SortColumnId = 1; CellRendererToggle tt = new CellRendererToggle (); tt.Activatable = true; @@ -88,6 +89,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels CellRendererComboBox comboCell = new CellRendererComboBox (); comboCell.Changed += new ComboSelectionChangedHandler (OnConfigSelectionChanged); configsList.AppendColumn (GettextCatalog.GetString ("Configuration"), comboCell, new TreeCellDataFunc (OnSetConfigurationsData)); + store.SetSortColumnId (1, SortType.Ascending); } public void Load (SolutionConfiguration config) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanel.cs index e12eaac575..89d69ada0c 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanel.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanel.cs @@ -45,7 +45,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels public override void LoadConfigData () { - widget.Load (ConfiguredSolutionItem, CurrentConfiguration.CustomCommands); + widget.Load (ConfiguredSolutionItem, CurrentConfiguration.CustomCommands, CurrentConfiguration.Selector); } public override void ApplyChanges () diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanelWidget.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanelWidget.cs index 90f29579b7..a6639bb7f8 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanelWidget.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandPanelWidget.cs @@ -38,16 +38,18 @@ namespace MonoDevelop.Ide.Projects.OptionPanels CustomCommandCollection commands; CustomCommandWidget lastSlot; SolutionEntityItem entry; + ConfigurationSelector configSelector; public CustomCommandPanelWidget () { this.Build(); } - public void Load (SolutionEntityItem entry, CustomCommandCollection commands) + public void Load (SolutionEntityItem entry, CustomCommandCollection commands, ConfigurationSelector configSelector) { this.entry = entry; this.commands = commands; + this.configSelector = configSelector; // Clean the list foreach (CustomCommandWidget ccw in vboxCommands.Children) { @@ -66,7 +68,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels void AddCommandSlot (CustomCommand cmd) { - CustomCommandWidget widget = new CustomCommandWidget (entry, cmd); + CustomCommandWidget widget = new CustomCommandWidget (entry, cmd, configSelector); vboxCommands.PackStart (widget, false, false, 0); widget.CommandCreated += OnCommandCreated; widget.CommandRemoved += OnCommandRemoved; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandWidget.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandWidget.cs index a0974f89f9..3cdb8b3099 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandWidget.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CustomCommandWidget.cs @@ -30,6 +30,7 @@ using System; using MonoDevelop.Core; using MonoDevelop.Projects; using MonoDevelop.Components; +using MonoDevelop.Core.StringParsing; namespace MonoDevelop.Ide.Projects.OptionPanels { @@ -41,64 +42,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels IWorkspaceObject entry; bool updating; - // snatched from MonoDevelop.Ide.Gui.OptionPanels/ExternalToolPanel.cs - // a lot of these probably don't apply to custom build commands (e.g. ItemPath -- path of current open doc) -// static string[,] argumentQuickInsertMenu = new string[,] { -// {GettextCatalog.GetString ("Item Path"), "${ItemPath}"}, -// {GettextCatalog.GetString ("_Item Directory"), "${ItemDir}"}, -// {GettextCatalog.GetString ("Item file name"), "${ItemFileName}"}, -// {GettextCatalog.GetString ("Item extension"), "${ItemExt}"}, -// {"-", ""}, -// {GettextCatalog.GetString ("Current line"), "${CurLine}"}, -// {GettextCatalog.GetString ("Current column"), "${CurCol}"}, -// {GettextCatalog.GetString ("Current text"), "${CurText}"}, -// {"-", ""}, -// {GettextCatalog.GetString ("Target Path"), "${TargetPath}"}, -// {GettextCatalog.GetString ("_Target Directory"), "${TargetDir}"}, -// {GettextCatalog.GetString ("Target Name"), "${TargetName}"}, -// {GettextCatalog.GetString ("Target Extension"), "${TargetExt}"}, -// {"-", ""}, -// {GettextCatalog.GetString ("_Project Directory"), "${ProjectDir}"}, -// {GettextCatalog.GetString ("Project file name"), "${ProjectFileName}"}, -// {"-", ""}, -// {GettextCatalog.GetString ("_Solution Directory"), "${CombineDir}"}, -// {GettextCatalog.GetString ("Solution File Name"), "${CombineFileName}"}, -// {"-", ""}, -// {GettextCatalog.GetString ("MonoDevelop Startup Directory"), "${StartupPath}"}, -// }; - - static string[,] projectWorkingDirInsertMenu = new string[,] { - // Keep in sync with CustomCommand.cs - {GettextCatalog.GetString ("_Target Directory"), "${TargetDir}"}, - {GettextCatalog.GetString ("Target _Name"), "${TargetName}"}, - {"-", ""}, - {GettextCatalog.GetString ("_Project Directory"), "${ProjectDir}"}, - {GettextCatalog.GetString ("P_roject Name"), "${ProjectName}"}, - {GettextCatalog.GetString ("Project _File"), "${ProjectFile}"}, - {"-", ""}, - {GettextCatalog.GetString ("_Solution Directory"), "${SolutionDir}"}, - {GettextCatalog.GetString ("So_lution Name"), "${SolutionName}"}, - {GettextCatalog.GetString ("Solution F_ile"), "${SolutionFile}"}, - }; - - static string[,] entryWorkingDirInsertMenu = new string[,] { - // Keep in sync with CustomCommand.cs - {GettextCatalog.GetString ("Solution _Item Directory"), "${ItemDir}"}, - {GettextCatalog.GetString ("Solution Item _Name"), "${ItemName}"}, - {GettextCatalog.GetString ("Solution Item _File"), "${ItemFile}"}, - {"-", ""}, - {GettextCatalog.GetString ("_Solution Directory"), "${SolutionDir}"}, - {GettextCatalog.GetString ("So_lution Name"), "${SolutionName}"}, - {GettextCatalog.GetString ("Solution F_ile"), "${SolutionFile}"}, - }; - - static string[,] solutionWorkingDirInsertMenu = new string[,] { - // Keep in sync with CustomCommand.cs - {GettextCatalog.GetString ("_Solution Directory"), "${SolutionDir}"}, - {GettextCatalog.GetString ("So_lution Name"), "${SolutionName}"}, - }; - - public CustomCommandWidget (IWorkspaceObject entry, CustomCommand cmd) + public CustomCommandWidget (IWorkspaceObject entry, CustomCommand cmd, ConfigurationSelector configSelector) { this.Build(); this.cmd = cmd; @@ -112,15 +56,19 @@ namespace MonoDevelop.Ide.Projects.OptionPanels UpdateControls (); this.WidgetFlags |= Gtk.WidgetFlags.NoShowAll; - string[,] workingDirInsertMenu; - if (entry is Project) - workingDirInsertMenu = projectWorkingDirInsertMenu; - else if (entry is SolutionEntityItem) - workingDirInsertMenu = entryWorkingDirInsertMenu; + StringTagModelDescription tagModel; + if (entry is SolutionItem) + tagModel = ((SolutionItem)entry).GetStringTagModelDescription (configSelector); + else if (entry is WorkspaceItem) + tagModel = ((WorkspaceItem)entry).GetStringTagModelDescription (); else - workingDirInsertMenu = solutionWorkingDirInsertMenu; + tagModel = new StringTagModelDescription (); + + tagSelectorDirectory.TagModel = tagModel; + tagSelectorDirectory.TargetEntry = workingdirEntry; - new MenuButtonEntry (workingdirEntry, workingdirQuickInsertButton, workingDirInsertMenu); + tagSelectorCommand.TagModel = tagModel; + tagSelectorCommand.TargetEntry = entryCommand; } public CustomCommand CustomCommand { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/CodeTranslationFileDescriptionTemplate.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/CodeTranslationFileDescriptionTemplate.cs index c4cbf4502f..da09f14b02 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/CodeTranslationFileDescriptionTemplate.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/CodeTranslationFileDescriptionTemplate.cs @@ -151,8 +151,7 @@ namespace MonoDevelop.Ide.Templates //This is a bit hacky doing it here instead of in CreateContent, but need to //substitute all tags in code before language is translated, because language //translation gets confused by unsubstituted substitution tokens. - string [,] tagsArr = HashtableToStringArray (tags); - tempSubstitutedContent = StringParserService.Parse (content, tagsArr); + tempSubstitutedContent = StringParserService.Parse (content, tags); } private System.CodeDom.Compiler.CodeDomProvider GetCodeDomProvider (string language) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SingleFileDescriptionTemplate.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SingleFileDescriptionTemplate.cs index a4c81325e2..67d4fd27ce 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SingleFileDescriptionTemplate.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SingleFileDescriptionTemplate.cs @@ -117,7 +117,7 @@ namespace MonoDevelop.Ide.Templates if (!string.IsNullOrEmpty (dependsOn)) { Dictionary<string,string> tags = new Dictionary<string,string> (); ModifyTags (policyParent, project, language, null, generatedFile, ref tags); - string parsedDepName = StringParserService.Parse (dependsOn, HashtableToStringArray (tags)); + string parsedDepName = StringParserService.Parse (dependsOn, tags); if (projectFile.DependsOn != parsedDepName) projectFile.DependsOn = parsedDepName; } @@ -210,7 +210,7 @@ namespace MonoDevelop.Ide.Templates if ((name != null) && (name.Length > 0)) { Dictionary<string,string> tags = new Dictionary<string,string> (); ModifyTags (policyParent, project, language, entryName ?? name, null, ref tags); - fileName = StringParserService.Parse (name, HashtableToStringArray (tags)); + fileName = StringParserService.Parse (name, tags); } if (fileName == null) @@ -371,18 +371,5 @@ namespace MonoDevelop.Ide.Templates throw new InvalidOperationException ("Language '" + language + "' not found"); return binding; } - - protected string[,] HashtableToStringArray (Dictionary<string,string> tags) - { - string[,] tagsArr = new string [tags.Count, 2]; - int i = 0; - foreach (string key in tags.Keys) { - tagsArr [i, 0] = key; - tagsArr [i, 1] = tags [key]; - i++; - } - - return tagsArr; - } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj index 53a22b9e12..d4e4ff26a5 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj @@ -1349,6 +1349,8 @@ <Compile Include="MonoDevelop.Ide.Extensions\OptionsDialogSection.cs" /> <Compile Include="MonoDevelop.Ide.Extensions\OptionsPanelNode.cs" /> <Compile Include="MonoDevelop.Ide.Extensions\StockIconCodon.cs" /> + <Compile Include="MonoDevelop.Ide.Gui.Components\StringTagSelectorButton.cs" /> + <Compile Include="gtk-gui\MonoDevelop.Ide.Gui.Components.StringTagSelectorButton.cs" /> </ItemGroup> <ItemGroup> <None Include="ChangeLog" /> diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs index ec14dc1831..414cdda612 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs @@ -168,9 +168,6 @@ namespace MonoDevelop.Ide workbench.Initialize (monitor); monitor.Step (1); - // register string tag provider (TODO: move to add-in tree :) - StringParserService.RegisterStringTagProvider (new MonoDevelop.Ide.Commands.DefaultStringTagProvider ()); - InternalLog.EnableErrorNotification (); monitor.Step (1); diff --git a/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.ExternalTools.ExternalToolPanelWidget.cs b/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.ExternalTools.ExternalToolPanelWidget.cs index 5bb9d7d538..50d06b67c4 100644 --- a/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.ExternalTools.ExternalToolPanelWidget.cs +++ b/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.ExternalTools.ExternalToolPanelWidget.cs @@ -34,13 +34,13 @@ namespace MonoDevelop.Ide.ExternalTools private global::Gtk.Table table3; - private global::Gtk.Button argumentQuickInsertButton; - private global::Gtk.Entry argumentTextBox; + private global::MonoDevelop.Ide.Gui.Components.StringTagSelectorButton tagSelectorArgs; + private global::Gtk.Table table4; - private global::Gtk.Button workingDirQuickInsertButton; + private global::MonoDevelop.Ide.Gui.Components.StringTagSelectorButton tagSelectorPath; private global::Gtk.Entry workingDirTextBox; @@ -198,24 +198,23 @@ namespace MonoDevelop.Ide.ExternalTools this.table3.RowSpacing = ((uint)(6)); this.table3.ColumnSpacing = ((uint)(4)); // Container child table3.Gtk.Table+TableChild - this.argumentQuickInsertButton = new global::Gtk.Button (); - this.argumentQuickInsertButton.Name = "argumentQuickInsertButton"; - this.argumentQuickInsertButton.UseUnderline = true; - this.argumentQuickInsertButton.Label = " > "; - this.table3.Add (this.argumentQuickInsertButton); - global::Gtk.Table.TableChild w13 = ((global::Gtk.Table.TableChild)(this.table3[this.argumentQuickInsertButton])); - w13.LeftAttach = ((uint)(1)); - w13.RightAttach = ((uint)(2)); - w13.XOptions = ((global::Gtk.AttachOptions)(0)); - w13.YOptions = ((global::Gtk.AttachOptions)(0)); - // Container child table3.Gtk.Table+TableChild this.argumentTextBox = new global::Gtk.Entry (); this.argumentTextBox.Name = "argumentTextBox"; this.argumentTextBox.IsEditable = true; this.argumentTextBox.InvisibleChar = '●'; this.table3.Add (this.argumentTextBox); - global::Gtk.Table.TableChild w14 = ((global::Gtk.Table.TableChild)(this.table3[this.argumentTextBox])); - w14.YOptions = ((global::Gtk.AttachOptions)(0)); + global::Gtk.Table.TableChild w13 = ((global::Gtk.Table.TableChild)(this.table3[this.argumentTextBox])); + w13.YOptions = ((global::Gtk.AttachOptions)(0)); + // Container child table3.Gtk.Table+TableChild + this.tagSelectorArgs = new global::MonoDevelop.Ide.Gui.Components.StringTagSelectorButton (); + this.tagSelectorArgs.Events = ((global::Gdk.EventMask)(256)); + this.tagSelectorArgs.Name = "tagSelectorArgs"; + this.table3.Add (this.tagSelectorArgs); + global::Gtk.Table.TableChild w14 = ((global::Gtk.Table.TableChild)(this.table3[this.tagSelectorArgs])); + w14.LeftAttach = ((uint)(1)); + w14.RightAttach = ((uint)(2)); + w14.XOptions = ((global::Gtk.AttachOptions)(4)); + w14.YOptions = ((global::Gtk.AttachOptions)(4)); this.table2.Add (this.table3); global::Gtk.Table.TableChild w15 = ((global::Gtk.Table.TableChild)(this.table2[this.table3])); w15.TopAttach = ((uint)(2)); @@ -229,16 +228,15 @@ namespace MonoDevelop.Ide.ExternalTools this.table4.RowSpacing = ((uint)(6)); this.table4.ColumnSpacing = ((uint)(4)); // Container child table4.Gtk.Table+TableChild - this.workingDirQuickInsertButton = new global::Gtk.Button (); - this.workingDirQuickInsertButton.Name = "workingDirQuickInsertButton"; - this.workingDirQuickInsertButton.UseUnderline = true; - this.workingDirQuickInsertButton.Label = " > "; - this.table4.Add (this.workingDirQuickInsertButton); - global::Gtk.Table.TableChild w16 = ((global::Gtk.Table.TableChild)(this.table4[this.workingDirQuickInsertButton])); + this.tagSelectorPath = new global::MonoDevelop.Ide.Gui.Components.StringTagSelectorButton (); + this.tagSelectorPath.Events = ((global::Gdk.EventMask)(256)); + this.tagSelectorPath.Name = "tagSelectorPath"; + this.table4.Add (this.tagSelectorPath); + global::Gtk.Table.TableChild w16 = ((global::Gtk.Table.TableChild)(this.table4[this.tagSelectorPath])); w16.LeftAttach = ((uint)(1)); w16.RightAttach = ((uint)(2)); - w16.XOptions = ((global::Gtk.AttachOptions)(0)); - w16.YOptions = ((global::Gtk.AttachOptions)(0)); + w16.XOptions = ((global::Gtk.AttachOptions)(4)); + w16.YOptions = ((global::Gtk.AttachOptions)(4)); // Container child table4.Gtk.Table+TableChild this.workingDirTextBox = new global::Gtk.Entry (); this.workingDirTextBox.Name = "workingDirTextBox"; diff --git a/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Gui.Components.StringTagSelectorButton.cs b/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Gui.Components.StringTagSelectorButton.cs new file mode 100644 index 0000000000..e221925cb8 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Gui.Components.StringTagSelectorButton.cs @@ -0,0 +1,34 @@ + +// This file has been generated by the GUI designer. Do not modify. +namespace MonoDevelop.Ide.Gui.Components +{ + public partial class StringTagSelectorButton + { + private global::Gtk.Button button; + + private global::Gtk.Arrow arrow1; + + protected virtual void Build () + { + global::Stetic.Gui.Initialize (this); + // Widget MonoDevelop.Ide.Gui.Components.StringTagSelectorButton + global::Stetic.BinContainer.Attach (this); + this.Name = "MonoDevelop.Ide.Gui.Components.StringTagSelectorButton"; + // Container child MonoDevelop.Ide.Gui.Components.StringTagSelectorButton.Gtk.Container+ContainerChild + this.button = new global::Gtk.Button (); + this.button.CanFocus = true; + this.button.Name = "button"; + // Container child button.Gtk.Container+ContainerChild + this.arrow1 = new global::Gtk.Arrow (((global::Gtk.ArrowType)(1)), ((global::Gtk.ShadowType)(2))); + this.arrow1.Name = "arrow1"; + this.button.Add (this.arrow1); + this.button.Label = null; + this.Add (this.button); + if ((this.Child != null)) { + this.Child.ShowAll (); + } + this.Hide (); + this.button.Clicked += new global::System.EventHandler (this.OnButtonClicked); + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CustomCommandWidget.cs b/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CustomCommandWidget.cs index 9a5791b952..ada0c11025 100644 --- a/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CustomCommandWidget.cs +++ b/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CustomCommandWidget.cs @@ -16,15 +16,19 @@ namespace MonoDevelop.Ide.Projects.OptionPanels private global::Gtk.Table tableData; - private global::Gtk.Button buttonBrowse; - private global::Gtk.Entry entryCommand; private global::Gtk.Entry entryName; private global::Gtk.HBox hbox2; - private global::Gtk.Button workingdirQuickInsertButton; + private global::MonoDevelop.Ide.Gui.Components.StringTagSelectorButton tagSelectorDirectory; + + private global::Gtk.HBox hbox3; + + private global::Gtk.Button buttonBrowse; + + private global::MonoDevelop.Ide.Gui.Components.StringTagSelectorButton tagSelectorCommand; private global::Gtk.Label label1; @@ -111,32 +115,18 @@ namespace MonoDevelop.Ide.Projects.OptionPanels this.tableData.RowSpacing = ((uint)(6)); this.tableData.ColumnSpacing = ((uint)(6)); // Container child tableData.Gtk.Table+TableChild - this.buttonBrowse = new global::Gtk.Button (); - this.buttonBrowse.CanFocus = true; - this.buttonBrowse.Name = "buttonBrowse"; - this.buttonBrowse.UseUnderline = true; - this.buttonBrowse.Label = global::MonoDevelop.Core.GettextCatalog.GetString ("Browse..."); - this.tableData.Add (this.buttonBrowse); - global::Gtk.Table.TableChild w5 = ((global::Gtk.Table.TableChild)(this.tableData[this.buttonBrowse])); - w5.TopAttach = ((uint)(1)); - w5.BottomAttach = ((uint)(2)); - w5.LeftAttach = ((uint)(2)); - w5.RightAttach = ((uint)(3)); - w5.XOptions = ((global::Gtk.AttachOptions)(4)); - w5.YOptions = ((global::Gtk.AttachOptions)(4)); - // Container child tableData.Gtk.Table+TableChild this.entryCommand = new global::Gtk.Entry (); this.entryCommand.CanFocus = true; this.entryCommand.Name = "entryCommand"; this.entryCommand.IsEditable = true; this.entryCommand.InvisibleChar = '●'; this.tableData.Add (this.entryCommand); - global::Gtk.Table.TableChild w6 = ((global::Gtk.Table.TableChild)(this.tableData[this.entryCommand])); - w6.TopAttach = ((uint)(1)); - w6.BottomAttach = ((uint)(2)); - w6.LeftAttach = ((uint)(1)); - w6.RightAttach = ((uint)(2)); - w6.YOptions = ((global::Gtk.AttachOptions)(4)); + global::Gtk.Table.TableChild w5 = ((global::Gtk.Table.TableChild)(this.tableData[this.entryCommand])); + w5.TopAttach = ((uint)(1)); + w5.BottomAttach = ((uint)(2)); + w5.LeftAttach = ((uint)(1)); + w5.RightAttach = ((uint)(2)); + w5.YOptions = ((global::Gtk.AttachOptions)(4)); // Container child tableData.Gtk.Table+TableChild this.entryName = new global::Gtk.Entry (); this.entryName.CanFocus = true; @@ -144,63 +134,94 @@ namespace MonoDevelop.Ide.Projects.OptionPanels this.entryName.IsEditable = true; this.entryName.InvisibleChar = '●'; this.tableData.Add (this.entryName); - global::Gtk.Table.TableChild w7 = ((global::Gtk.Table.TableChild)(this.tableData[this.entryName])); - w7.LeftAttach = ((uint)(1)); - w7.RightAttach = ((uint)(2)); - w7.YOptions = ((global::Gtk.AttachOptions)(4)); + global::Gtk.Table.TableChild w6 = ((global::Gtk.Table.TableChild)(this.tableData[this.entryName])); + w6.LeftAttach = ((uint)(1)); + w6.RightAttach = ((uint)(2)); + w6.YOptions = ((global::Gtk.AttachOptions)(4)); // Container child tableData.Gtk.Table+TableChild this.hbox2 = new global::Gtk.HBox (); this.hbox2.Name = "hbox2"; this.hbox2.Spacing = 6; // Container child hbox2.Gtk.Box+BoxChild - this.workingdirQuickInsertButton = new global::Gtk.Button (); - this.workingdirQuickInsertButton.Name = "workingdirQuickInsertButton"; - this.workingdirQuickInsertButton.UseUnderline = true; - this.workingdirQuickInsertButton.Label = " > "; - this.hbox2.Add (this.workingdirQuickInsertButton); - global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.hbox2[this.workingdirQuickInsertButton])); - w8.Position = 0; - w8.Expand = false; - w8.Fill = false; + this.tagSelectorDirectory = new global::MonoDevelop.Ide.Gui.Components.StringTagSelectorButton (); + this.tagSelectorDirectory.Events = ((global::Gdk.EventMask)(256)); + this.tagSelectorDirectory.Name = "tagSelectorDirectory"; + this.hbox2.Add (this.tagSelectorDirectory); + global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.hbox2[this.tagSelectorDirectory])); + w7.Position = 0; + w7.Expand = false; + w7.Fill = false; this.tableData.Add (this.hbox2); - global::Gtk.Table.TableChild w9 = ((global::Gtk.Table.TableChild)(this.tableData[this.hbox2])); - w9.TopAttach = ((uint)(2)); - w9.BottomAttach = ((uint)(3)); - w9.LeftAttach = ((uint)(2)); - w9.RightAttach = ((uint)(3)); - w9.XOptions = ((global::Gtk.AttachOptions)(4)); - w9.YOptions = ((global::Gtk.AttachOptions)(4)); + global::Gtk.Table.TableChild w8 = ((global::Gtk.Table.TableChild)(this.tableData[this.hbox2])); + w8.TopAttach = ((uint)(2)); + w8.BottomAttach = ((uint)(3)); + w8.LeftAttach = ((uint)(2)); + w8.RightAttach = ((uint)(3)); + w8.XOptions = ((global::Gtk.AttachOptions)(4)); + w8.YOptions = ((global::Gtk.AttachOptions)(4)); + // Container child tableData.Gtk.Table+TableChild + this.hbox3 = new global::Gtk.HBox (); + this.hbox3.Name = "hbox3"; + this.hbox3.Spacing = 6; + // Container child hbox3.Gtk.Box+BoxChild + this.buttonBrowse = new global::Gtk.Button (); + this.buttonBrowse.CanFocus = true; + this.buttonBrowse.Name = "buttonBrowse"; + this.buttonBrowse.UseUnderline = true; + this.buttonBrowse.Label = global::MonoDevelop.Core.GettextCatalog.GetString ("Browse..."); + this.hbox3.Add (this.buttonBrowse); + global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.hbox3[this.buttonBrowse])); + w9.Position = 0; + w9.Expand = false; + w9.Fill = false; + // Container child hbox3.Gtk.Box+BoxChild + this.tagSelectorCommand = new global::MonoDevelop.Ide.Gui.Components.StringTagSelectorButton (); + this.tagSelectorCommand.Events = ((global::Gdk.EventMask)(256)); + this.tagSelectorCommand.Name = "tagSelectorCommand"; + this.hbox3.Add (this.tagSelectorCommand); + global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(this.hbox3[this.tagSelectorCommand])); + w10.Position = 1; + w10.Expand = false; + w10.Fill = false; + this.tableData.Add (this.hbox3); + global::Gtk.Table.TableChild w11 = ((global::Gtk.Table.TableChild)(this.tableData[this.hbox3])); + w11.TopAttach = ((uint)(1)); + w11.BottomAttach = ((uint)(2)); + w11.LeftAttach = ((uint)(2)); + w11.RightAttach = ((uint)(3)); + w11.XOptions = ((global::Gtk.AttachOptions)(4)); + w11.YOptions = ((global::Gtk.AttachOptions)(4)); // Container child tableData.Gtk.Table+TableChild this.label1 = new global::Gtk.Label (); this.label1.Name = "label1"; this.label1.Xalign = 0f; this.label1.LabelProp = global::MonoDevelop.Core.GettextCatalog.GetString ("Working Directory:"); this.tableData.Add (this.label1); - global::Gtk.Table.TableChild w10 = ((global::Gtk.Table.TableChild)(this.tableData[this.label1])); - w10.TopAttach = ((uint)(2)); - w10.BottomAttach = ((uint)(3)); - w10.XOptions = ((global::Gtk.AttachOptions)(4)); - w10.YOptions = ((global::Gtk.AttachOptions)(4)); + global::Gtk.Table.TableChild w12 = ((global::Gtk.Table.TableChild)(this.tableData[this.label1])); + w12.TopAttach = ((uint)(2)); + w12.BottomAttach = ((uint)(3)); + w12.XOptions = ((global::Gtk.AttachOptions)(4)); + w12.YOptions = ((global::Gtk.AttachOptions)(4)); // Container child tableData.Gtk.Table+TableChild this.label3 = new global::Gtk.Label (); this.label3.Name = "label3"; this.label3.Xalign = 0f; this.label3.LabelProp = global::MonoDevelop.Core.GettextCatalog.GetString ("Command:"); this.tableData.Add (this.label3); - global::Gtk.Table.TableChild w11 = ((global::Gtk.Table.TableChild)(this.tableData[this.label3])); - w11.TopAttach = ((uint)(1)); - w11.BottomAttach = ((uint)(2)); - w11.XOptions = ((global::Gtk.AttachOptions)(4)); - w11.YOptions = ((global::Gtk.AttachOptions)(4)); + global::Gtk.Table.TableChild w13 = ((global::Gtk.Table.TableChild)(this.tableData[this.label3])); + w13.TopAttach = ((uint)(1)); + w13.BottomAttach = ((uint)(2)); + w13.XOptions = ((global::Gtk.AttachOptions)(4)); + w13.YOptions = ((global::Gtk.AttachOptions)(4)); // Container child tableData.Gtk.Table+TableChild this.labelName = new global::Gtk.Label (); this.labelName.Name = "labelName"; this.labelName.Xalign = 0f; this.labelName.LabelProp = global::MonoDevelop.Core.GettextCatalog.GetString ("Name:"); this.tableData.Add (this.labelName); - global::Gtk.Table.TableChild w12 = ((global::Gtk.Table.TableChild)(this.tableData[this.labelName])); - w12.XOptions = ((global::Gtk.AttachOptions)(4)); - w12.YOptions = ((global::Gtk.AttachOptions)(4)); + global::Gtk.Table.TableChild w14 = ((global::Gtk.Table.TableChild)(this.tableData[this.labelName])); + w14.XOptions = ((global::Gtk.AttachOptions)(4)); + w14.YOptions = ((global::Gtk.AttachOptions)(4)); // Container child tableData.Gtk.Table+TableChild this.workingdirEntry = new global::Gtk.Entry (); this.workingdirEntry.CanFocus = true; @@ -208,17 +229,17 @@ namespace MonoDevelop.Ide.Projects.OptionPanels this.workingdirEntry.IsEditable = true; this.workingdirEntry.InvisibleChar = '●'; this.tableData.Add (this.workingdirEntry); - global::Gtk.Table.TableChild w13 = ((global::Gtk.Table.TableChild)(this.tableData[this.workingdirEntry])); - w13.TopAttach = ((uint)(2)); - w13.BottomAttach = ((uint)(3)); - w13.LeftAttach = ((uint)(1)); - w13.RightAttach = ((uint)(2)); - w13.YOptions = ((global::Gtk.AttachOptions)(4)); + global::Gtk.Table.TableChild w15 = ((global::Gtk.Table.TableChild)(this.tableData[this.workingdirEntry])); + w15.TopAttach = ((uint)(2)); + w15.BottomAttach = ((uint)(3)); + w15.LeftAttach = ((uint)(1)); + w15.RightAttach = ((uint)(2)); + w15.YOptions = ((global::Gtk.AttachOptions)(4)); this.vbox1.Add (this.tableData); - global::Gtk.Box.BoxChild w14 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.tableData])); - w14.Position = 2; - w14.Expand = false; - w14.Fill = false; + global::Gtk.Box.BoxChild w16 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.tableData])); + w16.Position = 2; + w16.Expand = false; + w16.Fill = false; // Container child vbox1.Gtk.Box+BoxChild this.boxData = new global::Gtk.HBox (); this.boxData.Name = "boxData"; @@ -231,10 +252,10 @@ namespace MonoDevelop.Ide.Projects.OptionPanels this.checkExternalCons.DrawIndicator = true; this.checkExternalCons.UseUnderline = true; this.boxData.Add (this.checkExternalCons); - global::Gtk.Box.BoxChild w15 = ((global::Gtk.Box.BoxChild)(this.boxData[this.checkExternalCons])); - w15.Position = 0; - w15.Expand = false; - w15.Fill = false; + global::Gtk.Box.BoxChild w17 = ((global::Gtk.Box.BoxChild)(this.boxData[this.checkExternalCons])); + w17.Position = 0; + w17.Expand = false; + w17.Fill = false; // Container child boxData.Gtk.Box+BoxChild this.checkPauseCons = new global::Gtk.CheckButton (); this.checkPauseCons.CanFocus = true; @@ -243,15 +264,15 @@ namespace MonoDevelop.Ide.Projects.OptionPanels this.checkPauseCons.DrawIndicator = true; this.checkPauseCons.UseUnderline = true; this.boxData.Add (this.checkPauseCons); - global::Gtk.Box.BoxChild w16 = ((global::Gtk.Box.BoxChild)(this.boxData[this.checkPauseCons])); - w16.Position = 1; - w16.Expand = false; - w16.Fill = false; + global::Gtk.Box.BoxChild w18 = ((global::Gtk.Box.BoxChild)(this.boxData[this.checkPauseCons])); + w18.Position = 1; + w18.Expand = false; + w18.Fill = false; this.vbox1.Add (this.boxData); - global::Gtk.Box.BoxChild w17 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.boxData])); - w17.Position = 3; - w17.Expand = false; - w17.Fill = false; + global::Gtk.Box.BoxChild w19 = ((global::Gtk.Box.BoxChild)(this.vbox1[this.boxData])); + w19.Position = 3; + w19.Expand = false; + w19.Fill = false; this.Add (this.vbox1); if ((this.Child != null)) { this.Child.ShowAll (); @@ -260,9 +281,9 @@ namespace MonoDevelop.Ide.Projects.OptionPanels this.comboType.Changed += new global::System.EventHandler (this.OnComboTypeChanged); this.buttonRemove.Clicked += new global::System.EventHandler (this.OnButtonRemoveClicked); this.workingdirEntry.Changed += new global::System.EventHandler (this.OnWorkingdirEntryChanged); + this.buttonBrowse.Clicked += new global::System.EventHandler (this.OnButtonBrowseClicked); this.entryName.Changed += new global::System.EventHandler (this.OnEntryNameChanged); this.entryCommand.Changed += new global::System.EventHandler (this.OnEntryCommandChanged); - this.buttonBrowse.Clicked += new global::System.EventHandler (this.OnButtonBrowseClicked); this.checkExternalCons.Clicked += new global::System.EventHandler (this.OnCheckExternalConsClicked); this.checkPauseCons.Clicked += new global::System.EventHandler (this.OnCheckPauseConsClicked); } diff --git a/main/src/core/MonoDevelop.Ide/gtk-gui/gui.stetic b/main/src/core/MonoDevelop.Ide/gtk-gui/gui.stetic index 8486a04494..2fc6ab2304 100644 --- a/main/src/core/MonoDevelop.Ide/gtk-gui/gui.stetic +++ b/main/src/core/MonoDevelop.Ide/gtk-gui/gui.stetic @@ -1131,6 +1131,7 @@ <widget class="MonoDevelop.Components.MenuButton" id="conflicButton"> <property name="MemberName" /> <property name="CanFocus">True</property> + <property name="Type">Custom</property> <property name="Label">View Conflicts</property> <property name="UseMarkup">False</property> </widget> @@ -1819,7 +1820,7 @@ </widget> </child> </widget> - <widget class="Gtk.Bin" id="MonoDevelop.Ide.ExternalTools.ExternalToolPanelWidget" design-size="482 442"> + <widget class="Gtk.Bin" id="MonoDevelop.Ide.ExternalTools.ExternalToolPanelWidget" design-size="805 442"> <property name="MemberName" /> <child> <widget class="Gtk.VBox" id="vbox32"> @@ -2015,20 +2016,16 @@ <property name="RowSpacing">6</property> <property name="ColumnSpacing">4</property> <child> - <widget class="Gtk.Button" id="argumentQuickInsertButton"> + <widget class="Gtk.Entry" id="argumentTextBox"> <property name="MemberName" /> - <property name="Type">TextOnly</property> - <property name="Label"> > </property> - <property name="UseUnderline">True</property> + <property name="IsEditable">True</property> + <property name="InvisibleChar">●</property> </widget> <packing> - <property name="LeftAttach">1</property> - <property name="RightAttach">2</property> <property name="AutoSize">False</property> - <property name="XOptions">0</property> <property name="YOptions">0</property> - <property name="XExpand">False</property> - <property name="XFill">False</property> + <property name="XExpand">True</property> + <property name="XFill">True</property> <property name="XShrink">False</property> <property name="YExpand">False</property> <property name="YFill">False</property> @@ -2036,19 +2033,21 @@ </packing> </child> <child> - <widget class="Gtk.Entry" id="argumentTextBox"> + <widget class="MonoDevelop.Ide.Gui.Components.StringTagSelectorButton" id="tagSelectorArgs"> <property name="MemberName" /> - <property name="IsEditable">True</property> - <property name="InvisibleChar">●</property> + <property name="Events">ButtonPressMask</property> </widget> <packing> - <property name="AutoSize">False</property> - <property name="YOptions">0</property> - <property name="XExpand">True</property> + <property name="LeftAttach">1</property> + <property name="RightAttach">2</property> + <property name="AutoSize">True</property> + <property name="XOptions">Fill</property> + <property name="YOptions">Fill</property> + <property name="XExpand">False</property> <property name="XFill">True</property> <property name="XShrink">False</property> <property name="YExpand">False</property> - <property name="YFill">False</property> + <property name="YFill">True</property> <property name="YShrink">False</property> </packing> </child> @@ -2075,23 +2074,21 @@ <property name="RowSpacing">6</property> <property name="ColumnSpacing">4</property> <child> - <widget class="Gtk.Button" id="workingDirQuickInsertButton"> + <widget class="MonoDevelop.Ide.Gui.Components.StringTagSelectorButton" id="tagSelectorPath"> <property name="MemberName" /> - <property name="Type">TextOnly</property> - <property name="Label"> > </property> - <property name="UseUnderline">True</property> + <property name="Events">ButtonPressMask</property> </widget> <packing> <property name="LeftAttach">1</property> <property name="RightAttach">2</property> - <property name="AutoSize">False</property> - <property name="XOptions">0</property> - <property name="YOptions">0</property> + <property name="AutoSize">True</property> + <property name="XOptions">Fill</property> + <property name="YOptions">Fill</property> <property name="XExpand">False</property> - <property name="XFill">False</property> + <property name="XFill">True</property> <property name="XShrink">False</property> <property name="YExpand">False</property> - <property name="YFill">False</property> + <property name="YFill">True</property> <property name="YShrink">False</property> </packing> </child> @@ -8024,23 +8021,21 @@ Custom Command</property> <placeholder /> </child> <child> - <widget class="Gtk.Button" id="buttonBrowse"> + <widget class="Gtk.Entry" id="entryCommand"> <property name="MemberName" /> <property name="CanFocus">True</property> - <property name="Type">TextOnly</property> - <property name="Label" translatable="yes">Browse...</property> - <property name="UseUnderline">True</property> - <signal name="Clicked" handler="OnButtonBrowseClicked" /> + <property name="IsEditable">True</property> + <property name="InvisibleChar">●</property> + <signal name="Changed" handler="OnEntryCommandChanged" /> </widget> <packing> <property name="TopAttach">1</property> <property name="BottomAttach">2</property> - <property name="LeftAttach">2</property> - <property name="RightAttach">3</property> + <property name="LeftAttach">1</property> + <property name="RightAttach">2</property> <property name="AutoSize">True</property> - <property name="XOptions">Fill</property> <property name="YOptions">Fill</property> - <property name="XExpand">False</property> + <property name="XExpand">True</property> <property name="XFill">True</property> <property name="XShrink">False</property> <property name="YExpand">False</property> @@ -8049,16 +8044,14 @@ Custom Command</property> </packing> </child> <child> - <widget class="Gtk.Entry" id="entryCommand"> + <widget class="Gtk.Entry" id="entryName"> <property name="MemberName" /> <property name="CanFocus">True</property> <property name="IsEditable">True</property> <property name="InvisibleChar">●</property> - <signal name="Changed" handler="OnEntryCommandChanged" /> + <signal name="Changed" handler="OnEntryNameChanged" /> </widget> <packing> - <property name="TopAttach">1</property> - <property name="BottomAttach">2</property> <property name="LeftAttach">1</property> <property name="RightAttach">2</property> <property name="AutoSize">True</property> @@ -8072,19 +8065,31 @@ Custom Command</property> </packing> </child> <child> - <widget class="Gtk.Entry" id="entryName"> + <widget class="Gtk.HBox" id="hbox2"> <property name="MemberName" /> - <property name="CanFocus">True</property> - <property name="IsEditable">True</property> - <property name="InvisibleChar">●</property> - <signal name="Changed" handler="OnEntryNameChanged" /> + <property name="Spacing">6</property> + <child> + <widget class="MonoDevelop.Ide.Gui.Components.StringTagSelectorButton" id="tagSelectorDirectory"> + <property name="MemberName" /> + <property name="Events">ButtonPressMask</property> + </widget> + <packing> + <property name="Position">0</property> + <property name="AutoSize">True</property> + <property name="Expand">False</property> + <property name="Fill">False</property> + </packing> + </child> </widget> <packing> - <property name="LeftAttach">1</property> - <property name="RightAttach">2</property> + <property name="TopAttach">2</property> + <property name="BottomAttach">3</property> + <property name="LeftAttach">2</property> + <property name="RightAttach">3</property> <property name="AutoSize">True</property> + <property name="XOptions">Fill</property> <property name="YOptions">Fill</property> - <property name="XExpand">True</property> + <property name="XExpand">False</property> <property name="XFill">True</property> <property name="XShrink">False</property> <property name="YExpand">False</property> @@ -8093,15 +8098,17 @@ Custom Command</property> </packing> </child> <child> - <widget class="Gtk.HBox" id="hbox2"> + <widget class="Gtk.HBox" id="hbox3"> <property name="MemberName" /> <property name="Spacing">6</property> <child> - <widget class="Gtk.Button" id="workingdirQuickInsertButton"> + <widget class="Gtk.Button" id="buttonBrowse"> <property name="MemberName" /> + <property name="CanFocus">True</property> <property name="Type">TextOnly</property> - <property name="Label"> > </property> + <property name="Label" translatable="yes">Browse...</property> <property name="UseUnderline">True</property> + <signal name="Clicked" handler="OnButtonBrowseClicked" /> </widget> <packing> <property name="Position">0</property> @@ -8110,10 +8117,22 @@ Custom Command</property> <property name="Fill">False</property> </packing> </child> + <child> + <widget class="MonoDevelop.Ide.Gui.Components.StringTagSelectorButton" id="tagSelectorCommand"> + <property name="MemberName" /> + <property name="Events">ButtonPressMask</property> + </widget> + <packing> + <property name="Position">1</property> + <property name="AutoSize">True</property> + <property name="Expand">False</property> + <property name="Fill">False</property> + </packing> + </child> </widget> <packing> - <property name="TopAttach">2</property> - <property name="BottomAttach">3</property> + <property name="TopAttach">1</property> + <property name="BottomAttach">2</property> <property name="LeftAttach">2</property> <property name="RightAttach">3</property> <property name="AutoSize">True</property> @@ -11288,4 +11307,22 @@ Visual Studio generates a default ID for embedded resources, instead of simply u </widget> </child> </widget> + <widget class="Gtk.Bin" id="MonoDevelop.Ide.Gui.Components.StringTagSelectorButton" design-size="27 27"> + <property name="MemberName" /> + <property name="Visible">False</property> + <child> + <widget class="Gtk.Button" id="button"> + <property name="MemberName" /> + <property name="CanFocus">True</property> + <property name="Type">Custom</property> + <signal name="Clicked" handler="OnButtonClicked" /> + <child> + <widget class="Gtk.Arrow" id="arrow1"> + <property name="MemberName" /> + <property name="ArrowType">Down</property> + </widget> + </child> + </widget> + </child> + </widget> </stetic-interface>
\ No newline at end of file diff --git a/main/src/core/MonoDevelop.Ide/gtk-gui/objects.xml b/main/src/core/MonoDevelop.Ide/gtk-gui/objects.xml index 8ad2071023..b1465c12f6 100644 --- a/main/src/core/MonoDevelop.Ide/gtk-gui/objects.xml +++ b/main/src/core/MonoDevelop.Ide/gtk-gui/objects.xml @@ -171,4 +171,8 @@ <itemgroups /> <signals /> </object> + <object type="MonoDevelop.Ide.Gui.Components.StringTagSelectorButton" palette-category="General" allow-children="false" base-type="Gtk.Bin"> + <itemgroups /> + <signals /> + </object> </objects>
\ No newline at end of file |