From b3e15c91cb1a55de208688e2e123b363b7175225 Mon Sep 17 00:00:00 2001 From: Christian Hornung Date: Sat, 19 Sep 2009 13:18:03 +0000 Subject: [PATCH] Ported ResourceToolkit to ITextEditor. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4970 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Hornung.ResourceToolkit.addin | 3 +- .../Project/ResourceToolkit.csproj | 27 ++++-- ...NRefactoryResourceCodeCompletionBinding.cs | 15 ++-- ...rpCodeCoreResourceCodeCompletionBinding.cs | 15 ++-- ...CSharpCodeCoreTagCompletionDataProvider.cs | 84 ------------------- .../ICSharpCodeCoreTagCompletionItemList.cs | 37 ++++++++ .../NewResourceCodeCompletionData.cs | 63 -------------- .../NewResourceCodeCompletionItem.cs | 50 +++++++++++ .../ResourceCodeCompletionData.cs | 66 --------------- .../ResourceCodeCompletionDataProvider.cs | 72 ---------------- .../ResourceCodeCompletionItem.cs | 58 +++++++++++++ .../ResourceCodeCompletionItemList.cs | 59 +++++++++++++ .../Commands/TextEditorContextMenuBuilder.cs | 82 ++++++++++-------- .../AbstractResourceResolverTestFixture.cs | 9 +- .../Test/ResourceToolkit.Tests.csproj | 4 - 15 files changed, 294 insertions(+), 350 deletions(-) delete mode 100644 src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionDataProvider.cs create mode 100644 src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionItemList.cs delete mode 100644 src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionData.cs create mode 100644 src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionItem.cs delete mode 100644 src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionData.cs delete mode 100644 src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionDataProvider.cs create mode 100644 src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItem.cs create mode 100644 src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItemList.cs diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Hornung.ResourceToolkit.addin b/src/AddIns/Misc/ResourceToolkit/Project/Hornung.ResourceToolkit.addin index 8ef15a4e39..e5699bc4e4 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Hornung.ResourceToolkit.addin +++ b/src/AddIns/Misc/ResourceToolkit/Project/Hornung.ResourceToolkit.addin @@ -38,7 +38,7 @@ - + @@ -134,6 +134,7 @@ + diff --git a/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj b/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj index bf6160a7e6..d22c99a109 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj +++ b/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj @@ -39,6 +39,12 @@ False + + 3.0 + + + 3.0 + 3.5 @@ -49,14 +55,17 @@ 3.5 + + 3.0 + - - - + + + @@ -103,9 +112,14 @@ - + + + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9} + ICSharpCode.Core.Presentation + False + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288} ICSharpCode.Core.WinForms @@ -139,11 +153,6 @@ - - {2D18BE89-D210-49EB-A9DD-2246FBB3DF6D} - ICSharpCode.TextEditor - False - {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} NRefactory diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/AbstractNRefactoryResourceCodeCompletionBinding.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/AbstractNRefactoryResourceCodeCompletionBinding.cs index ea8c478f58..a88c43b9f6 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/AbstractNRefactoryResourceCodeCompletionBinding.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/AbstractNRefactoryResourceCodeCompletionBinding.cs @@ -5,22 +5,21 @@ // $Revision$ // -using ICSharpCode.SharpDevelop.Editor.CodeCompletion; using System; using Hornung.ResourceToolkit.Resolver; using Hornung.ResourceToolkit.ResourceFileContent; using ICSharpCode.NRefactory.PrettyPrinter; using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; namespace Hornung.ResourceToolkit.CodeCompletion { /// /// Provides a base class for code completion for inserting resource keys using NRefactory. /// - public abstract class AbstractNRefactoryResourceCodeCompletionBinding : DefaultCodeCompletionBinding + public abstract class AbstractNRefactoryResourceCodeCompletionBinding : ICodeCompletionBinding { - - public override CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch) + public CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch) { if (this.CompletionPossible(editor, ch)) { @@ -41,7 +40,7 @@ namespace Hornung.ResourceToolkit.CodeCompletion } } - editor.ShowCompletionWindow(new ResourceCodeCompletionDataProvider(content, this.OutputVisitor, result.CallingClass != null ? result.CallingClass.Name+"." : null), ch); + editor.ShowCompletionWindow(new ResourceCodeCompletionItemList(content, this.OutputVisitor, result.CallingClass != null ? result.CallingClass.Name+"." : null)); return CodeCompletionKeyPressResult.Completed; } } @@ -51,6 +50,11 @@ namespace Hornung.ResourceToolkit.CodeCompletion return CodeCompletionKeyPressResult.None; } + public bool CtrlSpace(ITextEditor editor) + { + return false; + } + // ******************************************************************************************************************************** /// @@ -64,6 +68,5 @@ namespace Hornung.ResourceToolkit.CodeCompletion protected abstract IOutputAstVisitor OutputVisitor { get; } - } } diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreResourceCodeCompletionBinding.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreResourceCodeCompletionBinding.cs index b2df761f90..92246720f1 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreResourceCodeCompletionBinding.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreResourceCodeCompletionBinding.cs @@ -5,12 +5,12 @@ // $Revision$ // -using ICSharpCode.SharpDevelop.Editor.CodeCompletion; using System; using Hornung.ResourceToolkit.Resolver; using Hornung.ResourceToolkit.ResourceFileContent; using ICSharpCode.Core; using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; namespace Hornung.ResourceToolkit.CodeCompletion { @@ -18,10 +18,9 @@ namespace Hornung.ResourceToolkit.CodeCompletion /// Provides code completion for inserting resource keys /// for ICSharpCode.Core resources references ("${res: ... }"). /// - public class ICSharpCodeCoreResourceCodeCompletionBinding : DefaultCodeCompletionBinding + public class ICSharpCodeCoreResourceCodeCompletionBinding : ICodeCompletionBinding { - - public override CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch) + public CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch) { if (ch == ':') { @@ -48,7 +47,7 @@ namespace Hornung.ResourceToolkit.CodeCompletion } if (content != null) { - editor.ShowCompletionWindow(new ResourceCodeCompletionDataProvider(content, null, null), ch); + editor.ShowCompletionWindow(new ResourceCodeCompletionItemList(content, null, null)); return CodeCompletionKeyPressResult.Completed; } @@ -61,7 +60,7 @@ namespace Hornung.ResourceToolkit.CodeCompletion if (ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreHostResourceSet(editor.FileName).ResourceFileContent != null || ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreLocalResourceSet(editor.FileName).ResourceFileContent != null) { - editor.ShowCompletionWindow(new ICSharpCodeCoreTagCompletionDataProvider(), ch); + editor.ShowCompletionWindow(new ICSharpCodeCoreTagCompletionItemList(editor)); return CodeCompletionKeyPressResult.Completed; } @@ -71,5 +70,9 @@ namespace Hornung.ResourceToolkit.CodeCompletion return CodeCompletionKeyPressResult.None; } + public bool CtrlSpace(ITextEditor editor) + { + return false; + } } } diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionDataProvider.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionDataProvider.cs deleted file mode 100644 index 2df19f4699..0000000000 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionDataProvider.cs +++ /dev/null @@ -1,84 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; -using ICSharpCode.TextEditor; -using ICSharpCode.TextEditor.Gui.CompletionWindow; - -namespace Hornung.ResourceToolkit.CodeCompletion -{ - /// - /// Provides code completion data for the ${res tag. - /// - public class ICSharpCodeCoreTagCompletionDataProvider : AbstractCompletionDataProvider - { - int startOffset; - TextArea textArea; - bool nonMatchingCharTyped; - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "ICSharpCode.TextEditor.Gui.CompletionWindow.DefaultCompletionData.#ctor(System.String,System.String,System.Int32)")] - public override ICompletionData[] GenerateCompletionData(string fileName, TextArea textArea, char charTyped) - { - this.textArea = textArea; - this.startOffset = textArea.Caret.Offset; - this.nonMatchingCharTyped = false; - this.DefaultIndex = 0; - return new ICompletionData[] { new DefaultCompletionData("{res", null, ClassBrowserIconService.GotoArrow.ImageIndex) }; - } - - public override CompletionDataProviderKeyResult ProcessKey(char key) - { - // Return NormalKey as long as: - // - the typed string matches the ${res tag - // - ':' is not pressed - // Return InsertionKey when: - // - ':' is pressed and the typed string matches the ${res tag - // - the typed string does not match the ${res tag and more than one - // character has already been typed (to close the completion window) - - string typedTag = this.GetTypedText(); - if (key != ':') { - typedTag += key; - } - - bool match = "${res:".StartsWith(typedTag, StringComparison.OrdinalIgnoreCase); - - if (key == ':') { - if (match || this.nonMatchingCharTyped) { - return CompletionDataProviderKeyResult.InsertionKey; - } else { - this.nonMatchingCharTyped = true; - return CompletionDataProviderKeyResult.NormalKey; - } - } else { - if (match) { - this.nonMatchingCharTyped = false; - return CompletionDataProviderKeyResult.NormalKey; - } else { - if (this.nonMatchingCharTyped) { - return CompletionDataProviderKeyResult.InsertionKey; - } else { - this.nonMatchingCharTyped = true; - return CompletionDataProviderKeyResult.NormalKey; - } - } - } - } - - string GetTypedText() - { - if (this.textArea == null) { - return String.Empty; - } - - int offset = Math.Max(this.startOffset, 0); - return this.textArea.Document.GetText(offset, Math.Min(Math.Max(this.textArea.Caret.Offset - offset, 0), this.textArea.Document.TextLength - offset)); - } - } -} diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionItemList.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionItemList.cs new file mode 100644 index 0000000000..ae71177988 --- /dev/null +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionItemList.cs @@ -0,0 +1,37 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; + +namespace Hornung.ResourceToolkit.CodeCompletion +{ + /// + /// Provides code completion data for the ${res tag. + /// + public sealed class ICSharpCodeCoreTagCompletionItemList : DefaultCompletionItemList + { + public ICSharpCodeCoreTagCompletionItemList(ITextEditor editor) + : base() + { + var item = new DefaultCompletionItem("{res") { Image = ClassBrowserIconService.Keyword }; + this.Items.Add(item); + this.SuggestedItem = item; + } + + public override CompletionItemListKeyResult ProcessInput(char key) + { + if (key == ':' || key == '}' || Char.IsWhiteSpace(key)) { + return CompletionItemListKeyResult.InsertionKey; + } else { + return CompletionItemListKeyResult.NormalKey; + } + } + } +} diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionData.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionData.cs deleted file mode 100644 index adf93845b3..0000000000 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionData.cs +++ /dev/null @@ -1,63 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Globalization; -using System.Windows.Forms; - -using Hornung.ResourceToolkit.Gui; -using Hornung.ResourceToolkit.ResourceFileContent; -using ICSharpCode.Core; -using ICSharpCode.NRefactory.PrettyPrinter; -using ICSharpCode.SharpDevelop.Gui; -using ICSharpCode.TextEditor; - -namespace Hornung.ResourceToolkit.CodeCompletion -{ - /// - /// Provides a code completion entry used to add a new string resource. - /// - public class NewResourceCodeCompletionData : ResourceCodeCompletionData - { - - readonly IResourceFileContent content; - readonly string preEnteredName; - - public NewResourceCodeCompletionData(IResourceFileContent content, IOutputAstVisitor outputVisitor, string preEnteredName) - : base(StringParser.Parse("${res:Hornung.ResourceToolkit.CodeCompletion.AddNewEntry}"), String.Format(CultureInfo.CurrentCulture, StringParser.Parse("${res:Hornung.ResourceToolkit.CodeCompletion.AddNewDescription}"), content.FileName), outputVisitor) - { - this.content = content; - this.preEnteredName = preEnteredName; - } - - /// - /// Present a form to the user where he enters the name for the new - /// string resource and then insert the key value into the text editor. - /// - /// TextArea to insert the completion data in. - /// Character that should be inserted after the completion data. - /// \0 when no character should be inserted. - /// Returns true when the insert action has processed the character - /// ; false when the character was not processed. - public override bool InsertAction(TextArea textArea, char ch) - { - - EditStringResourceDialog dialog = new EditStringResourceDialog(this.content, this.preEnteredName, null, true); - dialog.Text = this.Description; - if (dialog.ShowDialog(WorkbenchSingleton.MainWin32Window) != DialogResult.OK) { - return false; - } - - this.Text = dialog.Key; - - this.content.Add(dialog.Key, dialog.Value); - - return base.InsertAction(textArea, ch); - } - - } -} diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionItem.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionItem.cs new file mode 100644 index 0000000000..d4c4bb51c5 --- /dev/null +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionItem.cs @@ -0,0 +1,50 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Globalization; +using System.Windows.Forms; + +using Hornung.ResourceToolkit.Gui; +using Hornung.ResourceToolkit.ResourceFileContent; +using ICSharpCode.Core; +using ICSharpCode.NRefactory.PrettyPrinter; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; +using ICSharpCode.SharpDevelop.Gui; + +namespace Hornung.ResourceToolkit.CodeCompletion +{ + /// + /// Provides a code completion item used to add a new string resource. + /// + public sealed class NewResourceCodeCompletionItem : ResourceCodeCompletionItem + { + readonly IResourceFileContent content; + readonly string preEnteredName; + + public NewResourceCodeCompletionItem(IResourceFileContent content, IOutputAstVisitor outputVisitor, string preEnteredName) + : base(StringParser.Parse("${res:Hornung.ResourceToolkit.CodeCompletion.AddNewEntry}"), String.Format(CultureInfo.CurrentCulture, StringParser.Parse("${res:Hornung.ResourceToolkit.CodeCompletion.AddNewDescription}"), content.FileName), outputVisitor) + { + this.content = content; + this.preEnteredName = preEnteredName; + } + + public override void Complete(CompletionContext context) + { + using (EditStringResourceDialog dialog = new EditStringResourceDialog(this.content, this.preEnteredName, null, true)) { + dialog.Text = this.Description; + if (dialog.ShowDialog(WorkbenchSingleton.MainWin32Window) != DialogResult.OK) { + return; + } + + this.content.Add(dialog.Key, dialog.Value); + + this.CompleteInternal(context, dialog.Key); + } + } + } +} diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionData.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionData.cs deleted file mode 100644 index 7318d6dcd2..0000000000 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionData.cs +++ /dev/null @@ -1,66 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using ICSharpCode.NRefactory.Ast; -using ICSharpCode.NRefactory.PrettyPrinter; -using ICSharpCode.SharpDevelop; -using ICSharpCode.TextEditor; -using ICSharpCode.TextEditor.Gui.CompletionWindow; - -namespace Hornung.ResourceToolkit.CodeCompletion -{ - /// - /// Represents a code completion data entry for resource keys. - /// - public class ResourceCodeCompletionData : DefaultCompletionData - { - - readonly IOutputAstVisitor outputVisitor; - - /// - /// Initializes a new instance of the class. - /// - /// The resource key. - /// The resource description. - /// The NRefactory output visitor to be used to generate the inserted code. If null, the key is inserted literally. - public ResourceCodeCompletionData(string key, string description, IOutputAstVisitor outputVisitor) - : base(key, description, ClassBrowserIconService.GotoArrow.ImageIndex) - { - this.outputVisitor = outputVisitor; - } - - /// - /// Insert the element represented by the completion data into the text - /// editor. - /// - /// TextArea to insert the completion data in. - /// Character that should be inserted after the completion data. - /// \0 when no character should be inserted. - /// Returns true when the insert action has processed the character - /// ; false when the character was not processed. - public override bool InsertAction(TextArea textArea, char ch) - { - string insertString; - - if (this.outputVisitor != null) { - PrimitiveExpression pre = new PrimitiveExpression(this.Text, this.Text); - pre.AcceptVisitor(this.outputVisitor, null); - insertString = this.outputVisitor.Text; - } else { - insertString = this.Text; - } - - textArea.InsertString(insertString); - if (ch == insertString[insertString.Length - 1]) { - return true; - } - return false; - } - - } -} diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionDataProvider.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionDataProvider.cs deleted file mode 100644 index 3d28bed6d3..0000000000 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionDataProvider.cs +++ /dev/null @@ -1,72 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections.Generic; -using Hornung.ResourceToolkit.ResourceFileContent; -using ICSharpCode.NRefactory.PrettyPrinter; -using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; -using ICSharpCode.TextEditor.Gui.CompletionWindow; - -namespace Hornung.ResourceToolkit.CodeCompletion -{ - /// - /// Provides code completion data for resource keys. - /// - public class ResourceCodeCompletionDataProvider : AbstractCompletionDataProvider - { - readonly IResourceFileContent content; - readonly IOutputAstVisitor outputVisitor; - readonly string preEnteredName; - - /// - /// Initializes a new instance of the class. - /// - /// The resource file content to be presented to the user. - /// The NRefactory output visitor to be used to generate the inserted code. If null, the key is inserted literally. - /// The type name which should be pre-entered in the 'add new' dialog box if the user selects the 'add new' entry. - public ResourceCodeCompletionDataProvider(IResourceFileContent content, IOutputAstVisitor outputVisitor, string preEnteredName) - { - if (content == null) { - throw new ArgumentNullException("content"); - } - this.content = content; - this.outputVisitor = outputVisitor; - this.preEnteredName = preEnteredName; - this.InsertSpace = false; - } - - /// - /// Generates the completion data. This method is called by the text editor control. - /// - public override ICompletionData[] GenerateCompletionData(string fileName, ICSharpCode.TextEditor.TextArea textArea, char charTyped) - { - List list = new List(); - - list.Add(new NewResourceCodeCompletionData(this.content, this.outputVisitor, this.preEnteredName)); - - foreach (KeyValuePair entry in this.content.Data) { - list.Add(new ResourceCodeCompletionData(entry.Key, ResourceResolverService.FormatResourceDescription(this.content, entry.Key), this.outputVisitor)); - } - - return list.ToArray(); - } - - /// - /// Gets if pressing 'key' should trigger the insertion of the currently selected element. - /// - public override CompletionDataProviderKeyResult ProcessKey(char key) - { - if (key == '.') { - // don't auto-complete on pressing '.' (this character is commonly used in resource key names) - return CompletionDataProviderKeyResult.NormalKey; - } - return base.ProcessKey(key); - } - - } -} diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItem.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItem.cs new file mode 100644 index 0000000000..14424604c7 --- /dev/null +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItem.cs @@ -0,0 +1,58 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.NRefactory.Ast; +using ICSharpCode.NRefactory.PrettyPrinter; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; + +namespace Hornung.ResourceToolkit.CodeCompletion +{ + /// + /// Represents a code completion item for resource keys. + /// + public class ResourceCodeCompletionItem : DefaultCompletionItem + { + readonly IOutputAstVisitor outputVisitor; + + /// + /// Initializes a new instance of the class. + /// + /// The resource key. + /// The resource description. + /// The NRefactory output visitor to be used to generate the inserted code. If null, the key is inserted literally. + public ResourceCodeCompletionItem(string key, string description, IOutputAstVisitor outputVisitor) + : base(key) + { + this.Description = description; + this.Image = ClassBrowserIconService.Const; + this.outputVisitor = outputVisitor; + } + + public override void Complete(CompletionContext context) + { + this.CompleteInternal(context, this.Text); + } + + protected void CompleteInternal(CompletionContext context, string key) + { + string insertString; + + if (this.outputVisitor != null) { + PrimitiveExpression pre = new PrimitiveExpression(key, key); + pre.AcceptVisitor(this.outputVisitor, null); + insertString = this.outputVisitor.Text; + } else { + insertString = key; + } + + context.Editor.Document.Replace(context.StartOffset, context.Length, insertString); + context.EndOffset = context.StartOffset + insertString.Length; + } + } +} diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItemList.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItemList.cs new file mode 100644 index 0000000000..246758dfa3 --- /dev/null +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItemList.cs @@ -0,0 +1,59 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; + +using Hornung.ResourceToolkit.ResourceFileContent; +using ICSharpCode.NRefactory.PrettyPrinter; +using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; + +namespace Hornung.ResourceToolkit.CodeCompletion +{ + /// + /// Provides code completion data for resource keys. + /// + public sealed class ResourceCodeCompletionItemList : DefaultCompletionItemList + { + /// + /// Initializes a new instance of the class. + /// + /// The resource file content to be presented to the user. + /// The NRefactory output visitor to be used to generate the inserted code. If null, the key is inserted literally. + /// The type name which should be pre-entered in the 'add new' dialog box if the user selects the 'add new' entry. + public ResourceCodeCompletionItemList(IResourceFileContent content, IOutputAstVisitor outputVisitor, string preEnteredName) + { + if (content == null) { + throw new ArgumentNullException("content"); + } + + this.GenerateCompletionItems(content, outputVisitor, preEnteredName); + } + + /// + /// Generates the completion items. + /// + private void GenerateCompletionItems(IResourceFileContent content, IOutputAstVisitor outputVisitor, string preEnteredName) + { + this.Items.Add(new NewResourceCodeCompletionItem(content, outputVisitor, preEnteredName)); + + foreach (KeyValuePair entry in content.Data) { + this.Items.Add(new ResourceCodeCompletionItem(entry.Key, ResourceResolverService.FormatResourceDescription(content, entry.Key), outputVisitor)); + } + } + + public override CompletionItemListKeyResult ProcessInput(char key) + { + if (key == '.') { + // don't auto-complete on pressing '.' (this character is commonly used in resource key names) + return CompletionItemListKeyResult.NormalKey; + } + return base.ProcessInput(key); + } + } +} diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Commands/TextEditorContextMenuBuilder.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Commands/TextEditorContextMenuBuilder.cs index 0c8d0a02fe..1033278bb2 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Commands/TextEditorContextMenuBuilder.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Commands/TextEditorContextMenuBuilder.cs @@ -5,70 +5,83 @@ // $Revision$ // -using ICSharpCode.SharpDevelop; using System; using System.Collections.Generic; using System.Globalization; +using System.Windows.Controls; using System.Windows.Forms; + using Hornung.ResourceToolkit.Gui; using Hornung.ResourceToolkit.Refactoring; using Hornung.ResourceToolkit.Resolver; using ICSharpCode.Core; -using ICSharpCode.Core.WinForms; +using ICSharpCode.Core.Presentation; +using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Refactoring; -using ICSharpCode.TextEditor; +using MenuItem = System.Windows.Controls.MenuItem; namespace Hornung.ResourceToolkit.Commands { /// /// Builds context menu for editing string resources. /// - public class TextEditorContextMenuBuilder : ISubmenuBuilder + public sealed class TextEditorContextMenuBuilder : IMenuItemBuilder { - public ToolStripItem[] BuildSubmenu(Codon codon, object owner) + static readonly System.Windows.Controls.Control[] EmptyControlArray = new System.Windows.Controls.Control[0]; + + System.Collections.ICollection IMenuItemBuilder.BuildItems(Codon codon, object owner) { - TextEditorControl editor = owner as TextEditorControl; - + ITextEditor editor = owner as ITextEditor; if (editor == null) { - return new ToolStripItem[0]; + ITextEditorProvider provider = owner as ITextEditorProvider; + if (provider == null) { + return EmptyControlArray; + } + editor = provider.TextEditor; } - ResourceResolveResult result = ResourceResolverService.Resolve(new TextEditorAdapter(editor), null); + ResourceResolveResult result = ResourceResolverService.Resolve(editor, null); if (result != null && result.ResourceFileContent != null && result.Key != null) { - List items = new List(); - MenuCommand cmd; + List items = new List(); + MenuItem item = new MenuItem(); // add resource (if key does not exist) / edit resource (if key exists) if (result.ResourceFileContent.ContainsKey(result.Key)) { - cmd = new MenuCommand("${res:Hornung.ResourceToolkit.TextEditorContextMenu.EditResource}", this.EditResource); + item.Header = MenuService.ConvertLabel(StringParser.Parse("${res:Hornung.ResourceToolkit.TextEditorContextMenu.EditResource}")); } else { - cmd = new MenuCommand("${res:Hornung.ResourceToolkit.TextEditorContextMenu.AddResource}", this.EditResource); + item.Header = MenuService.ConvertLabel(StringParser.Parse("${res:Hornung.ResourceToolkit.TextEditorContextMenu.AddResource}")); } - cmd.Tag = result; - items.Add(cmd); + item.Click += this.EditResource; + item.Tag = result; + items.Add(item); // find references - cmd = new MenuCommand("${res:SharpDevelop.Refactoring.FindReferencesCommand}", this.FindReferences); - cmd.Tag = result; - items.Add(cmd); + item = new MenuItem(); + item.Header = MenuService.ConvertLabel(StringParser.Parse("${res:SharpDevelop.Refactoring.FindReferencesCommand}")); + item.Click += this.FindReferences; + item.Tag = result; + items.Add(item); // rename - cmd = new MenuCommand("${res:SharpDevelop.Refactoring.RenameCommand}", this.Rename); - cmd.Tag = result; - items.Add(cmd); + item = new MenuItem(); + item.Header = MenuService.ConvertLabel(StringParser.Parse("${res:SharpDevelop.Refactoring.RenameCommand}")); + item.Click += this.Rename; + item.Tag = result; + items.Add(item); // put the resource menu items into a submenu // with the resource key as title - ToolStripMenuItem subMenu = new ToolStripMenuItem(result.Key); - subMenu.DropDownItems.AddRange(items.ToArray()); - return new ToolStripItem[] { subMenu, new MenuSeparator() }; + item = new MenuItem(); + item.Header = result.Key; + item.ItemsSource = items; + return new System.Windows.Controls.Control[] { item, new Separator() }; } - return new ToolStripItem[0]; + return EmptyControlArray; } // ******************************************************************************************************************************** @@ -76,12 +89,12 @@ namespace Hornung.ResourceToolkit.Commands [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "ICSharpCode.Core.MessageService.ShowWarning(System.String)")] void EditResource(object sender, EventArgs e) { - MenuCommand cmd = sender as MenuCommand; - if (cmd == null) { + MenuItem item = sender as MenuItem; + if (item == null) { return; } - ResourceResolveResult result = cmd.Tag as ResourceResolveResult; + ResourceResolveResult result = item.Tag as ResourceResolveResult; if (result == null) { return; } @@ -117,12 +130,12 @@ namespace Hornung.ResourceToolkit.Commands [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", MessageId = "Body")] void FindReferences(object sender, EventArgs e) { - MenuCommand cmd = sender as MenuCommand; - if (cmd == null) { + MenuItem item = sender as MenuItem; + if (item == null) { return; } - ResourceResolveResult result = cmd.Tag as ResourceResolveResult; + ResourceResolveResult result = item.Tag as ResourceResolveResult; if (result == null) { return; } @@ -137,12 +150,12 @@ namespace Hornung.ResourceToolkit.Commands void Rename(object sender, EventArgs e) { - MenuCommand cmd = sender as MenuCommand; - if (cmd == null) { + MenuItem item = sender as MenuItem; + if (item == null) { return; } - ResourceResolveResult result = cmd.Tag as ResourceResolveResult; + ResourceResolveResult result = item.Tag as ResourceResolveResult; if (result == null) { return; } @@ -151,6 +164,5 @@ namespace Hornung.ResourceToolkit.Commands Application.DoEvents(); ResourceRefactoringService.Rename(result); } - } } diff --git a/src/AddIns/Misc/ResourceToolkit/Test/AbstractResourceResolverTestFixture.cs b/src/AddIns/Misc/ResourceToolkit/Test/AbstractResourceResolverTestFixture.cs index f76390507a..f31678a732 100644 --- a/src/AddIns/Misc/ResourceToolkit/Test/AbstractResourceResolverTestFixture.cs +++ b/src/AddIns/Misc/ResourceToolkit/Test/AbstractResourceResolverTestFixture.cs @@ -11,8 +11,9 @@ using Hornung.ResourceToolkit; using Hornung.ResourceToolkit.Resolver; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Editor.AvalonEdit; using ICSharpCode.SharpDevelop.Refactoring; -using ICSharpCode.TextEditor.Document; using NUnit.Framework; namespace ResourceToolkit.Tests @@ -52,9 +53,9 @@ namespace ResourceToolkit.Tests protected ResourceResolveResult Resolve(string fileName, string code, int caretLine, int caretColumn, char? charTyped, bool parseFile) { this.EnlistTestFile(fileName, code, parseFile); - IDocument doc = new DocumentFactory().CreateDocument(); - doc.TextContent = code; - return ResourceResolverService.Resolve(fileName, new TextEditorDocument(doc), caretLine, caretColumn, charTyped); + IDocument doc = new AvalonEditDocumentAdapter(); + doc.Text = code; + return ResourceResolverService.Resolve(fileName, doc, caretLine, caretColumn, charTyped); } /// diff --git a/src/AddIns/Misc/ResourceToolkit/Test/ResourceToolkit.Tests.csproj b/src/AddIns/Misc/ResourceToolkit/Test/ResourceToolkit.Tests.csproj index fd1744da3e..0932307431 100644 --- a/src/AddIns/Misc/ResourceToolkit/Test/ResourceToolkit.Tests.csproj +++ b/src/AddIns/Misc/ResourceToolkit/Test/ResourceToolkit.Tests.csproj @@ -62,10 +62,6 @@ - - {2D18BE89-D210-49EB-A9DD-2246FBB3DF6D} - ICSharpCode.TextEditor - {2748AD25-9C63-4E12-877B-4DCE96FBED54} ICSharpCode.SharpDevelop