Browse Source

Ported ResourceToolkit to ITextEditor.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4970 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Christian Hornung 16 years ago
parent
commit
b3e15c91cb
  1. 3
      src/AddIns/Misc/ResourceToolkit/Project/Hornung.ResourceToolkit.addin
  2. 27
      src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj
  3. 15
      src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/AbstractNRefactoryResourceCodeCompletionBinding.cs
  4. 15
      src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreResourceCodeCompletionBinding.cs
  5. 84
      src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionDataProvider.cs
  6. 37
      src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionItemList.cs
  7. 63
      src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionData.cs
  8. 50
      src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionItem.cs
  9. 66
      src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionData.cs
  10. 72
      src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionDataProvider.cs
  11. 58
      src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItem.cs
  12. 59
      src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItemList.cs
  13. 82
      src/AddIns/Misc/ResourceToolkit/Project/Src/Commands/TextEditorContextMenuBuilder.cs
  14. 9
      src/AddIns/Misc/ResourceToolkit/Test/AbstractResourceResolverTestFixture.cs
  15. 4
      src/AddIns/Misc/ResourceToolkit/Test/ResourceToolkit.Tests.csproj

3
src/AddIns/Misc/ResourceToolkit/Project/Hornung.ResourceToolkit.addin

@ -38,7 +38,7 @@ @@ -38,7 +38,7 @@
<!-- Context menus -->
<Path name = "/SharpDevelop/ViewContent/DefaultTextEditor/ContextMenu">
<Path name = "/SharpDevelop/ViewContent/TextEditor/ContextMenu">
<MenuItem id = "StringResources" insertbefore = "Refactoring" type = "Builder" class = "Hornung.ResourceToolkit.Commands.TextEditorContextMenuBuilder" />
</Path>
@ -134,6 +134,7 @@ @@ -134,6 +134,7 @@
<String id="Alternative1" text="..\Startup\Project\Resources"/>
<String id="Alternative2" text="..\Startup\Resources"/>
<String id="ICSharpCodeCoreDemo" text="..\Startup"/>
<String id="SharpDevelop4" text="..\data\resources"/>
</Path>
<Path name="/AddIns/ResourceToolkit/ICSharpCodeCoreResourceResolver/LocalResourcesLocations">

27
src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj

@ -39,6 +39,12 @@ @@ -39,6 +39,12 @@
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="PresentationFramework">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@ -49,14 +55,17 @@ @@ -49,14 +55,17 @@
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Src\CodeCompletion\AbstractNRefactoryResourceCodeCompletionBinding.cs" />
<Compile Include="Src\CodeCompletion\CSharpResourceCodeCompletionBinding.cs" />
<Compile Include="Src\CodeCompletion\ICSharpCodeCoreResourceCodeCompletionBinding.cs" />
<Compile Include="Src\CodeCompletion\NewResourceCodeCompletionData.cs" />
<Compile Include="Src\CodeCompletion\ResourceCodeCompletionData.cs" />
<Compile Include="Src\CodeCompletion\ResourceCodeCompletionDataProvider.cs" />
<Compile Include="Src\CodeCompletion\NewResourceCodeCompletionItem.cs" />
<Compile Include="Src\CodeCompletion\ResourceCodeCompletionItem.cs" />
<Compile Include="Src\CodeCompletion\ResourceCodeCompletionItemList.cs" />
<Compile Include="Src\CodeCompletion\VBNetResourceCodeCompletionBinding.cs" />
<Compile Include="Src\Commands\RefactoringCommands.cs" />
<Compile Include="Src\Commands\TextEditorContextMenuBuilder.cs" />
@ -103,9 +112,14 @@ @@ -103,9 +112,14 @@
<EmbeddedResource Include="Resources\EditStringResourceDialog.xfrm" />
<Compile Include="Src\Resolver\MemberFindAstVisitor.cs" />
<Compile Include="Src\Resolver\MemberEqualityComparer.cs" />
<Compile Include="Src\CodeCompletion\ICSharpCodeCoreTagCompletionDataProvider.cs" />
<Compile Include="Src\CodeCompletion\ICSharpCodeCoreTagCompletionItemList.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Main\ICSharpCode.Core.Presentation\ICSharpCode.Core.Presentation.csproj">
<Project>{7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}</Project>
<Name>ICSharpCode.Core.Presentation</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Main\ICSharpCode.Core.WinForms\ICSharpCode.Core.WinForms.csproj">
<Project>{857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}</Project>
<Name>ICSharpCode.Core.WinForms</Name>
@ -139,11 +153,6 @@ @@ -139,11 +153,6 @@
<Folder Include="Src\ToolTips" />
<Folder Include="Resources" />
<Folder Include="Configuration" />
<ProjectReference Include="..\..\..\..\Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj">
<Project>{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}</Project>
<Name>ICSharpCode.TextEditor</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Libraries\NRefactory\Project\NRefactory.csproj">
<Project>{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}</Project>
<Name>NRefactory</Name>

15
src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/AbstractNRefactoryResourceCodeCompletionBinding.cs

@ -5,22 +5,21 @@ @@ -5,22 +5,21 @@
// <version>$Revision$</version>
// </file>
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
{
/// <summary>
/// Provides a base class for code completion for inserting resource keys using NRefactory.
/// </summary>
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 @@ -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 @@ -51,6 +50,11 @@ namespace Hornung.ResourceToolkit.CodeCompletion
return CodeCompletionKeyPressResult.None;
}
public bool CtrlSpace(ITextEditor editor)
{
return false;
}
// ********************************************************************************************************************************
/// <summary>
@ -64,6 +68,5 @@ namespace Hornung.ResourceToolkit.CodeCompletion @@ -64,6 +68,5 @@ namespace Hornung.ResourceToolkit.CodeCompletion
protected abstract IOutputAstVisitor OutputVisitor {
get;
}
}
}

15
src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreResourceCodeCompletionBinding.cs

@ -5,12 +5,12 @@ @@ -5,12 +5,12 @@
// <version>$Revision$</version>
// </file>
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 @@ -18,10 +18,9 @@ namespace Hornung.ResourceToolkit.CodeCompletion
/// Provides code completion for inserting resource keys
/// for ICSharpCode.Core resources references ("${res: ... }").
/// </summary>
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 @@ -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 @@ -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 @@ -71,5 +70,9 @@ namespace Hornung.ResourceToolkit.CodeCompletion
return CodeCompletionKeyPressResult.None;
}
public bool CtrlSpace(ITextEditor editor)
{
return false;
}
}
}

84
src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionDataProvider.cs

@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Christian Hornung" email=""/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Gui.CompletionWindow;
namespace Hornung.ResourceToolkit.CodeCompletion
{
/// <summary>
/// Provides code completion data for the ${res tag.
/// </summary>
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));
}
}
}

37
src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreTagCompletionItemList.cs

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Christian Hornung" email=""/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
namespace Hornung.ResourceToolkit.CodeCompletion
{
/// <summary>
/// Provides code completion data for the ${res tag.
/// </summary>
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;
}
}
}
}

63
src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionData.cs

@ -1,63 +0,0 @@ @@ -1,63 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Christian Hornung" email=""/>
// <version>$Revision$</version>
// </file>
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
{
/// <summary>
/// Provides a code completion entry used to add a new string resource.
/// </summary>
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;
}
/// <summary>
/// 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.
/// </summary>
/// <param name="textArea">TextArea to insert the completion data in.</param>
/// <param name="ch">Character that should be inserted after the completion data.
/// \0 when no character should be inserted.</param>
/// <returns>Returns true when the insert action has processed the character
/// <paramref name="ch"/>; false when the character was not processed.</returns>
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);
}
}
}

50
src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/NewResourceCodeCompletionItem.cs

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Christian Hornung" email=""/>
// <version>$Revision$</version>
// </file>
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
{
/// <summary>
/// Provides a code completion item used to add a new string resource.
/// </summary>
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);
}
}
}
}

66
src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionData.cs

@ -1,66 +0,0 @@ @@ -1,66 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Christian Hornung" email=""/>
// <version>$Revision$</version>
// </file>
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
{
/// <summary>
/// Represents a code completion data entry for resource keys.
/// </summary>
public class ResourceCodeCompletionData : DefaultCompletionData
{
readonly IOutputAstVisitor outputVisitor;
/// <summary>
/// Initializes a new instance of the <see cref="ResourceCodeCompletionData" /> class.
/// </summary>
/// <param name="key">The resource key.</param>
/// <param name="description">The resource description.</param>
/// <param name="outputVisitor">The NRefactory output visitor to be used to generate the inserted code. If <c>null</c>, the key is inserted literally.</param>
public ResourceCodeCompletionData(string key, string description, IOutputAstVisitor outputVisitor)
: base(key, description, ClassBrowserIconService.GotoArrow.ImageIndex)
{
this.outputVisitor = outputVisitor;
}
/// <summary>
/// Insert the element represented by the completion data into the text
/// editor.
/// </summary>
/// <param name="textArea">TextArea to insert the completion data in.</param>
/// <param name="ch">Character that should be inserted after the completion data.
/// \0 when no character should be inserted.</param>
/// <returns>Returns true when the insert action has processed the character
/// <paramref name="ch"/>; false when the character was not processed.</returns>
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;
}
}
}

72
src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionDataProvider.cs

@ -1,72 +0,0 @@ @@ -1,72 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Christian Hornung" email=""/>
// <version>$Revision$</version>
// </file>
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
{
/// <summary>
/// Provides code completion data for resource keys.
/// </summary>
public class ResourceCodeCompletionDataProvider : AbstractCompletionDataProvider
{
readonly IResourceFileContent content;
readonly IOutputAstVisitor outputVisitor;
readonly string preEnteredName;
/// <summary>
/// Initializes a new instance of the <see cref="ResourceCodeCompletionDataProvider" /> class.
/// </summary>
/// <param name="content">The resource file content to be presented to the user.</param>
/// <param name="outputVisitor">The NRefactory output visitor to be used to generate the inserted code. If <c>null</c>, the key is inserted literally.</param>
/// <param name="preEnteredName">The type name which should be pre-entered in the 'add new' dialog box if the user selects the 'add new' entry.</param>
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;
}
/// <summary>
/// Generates the completion data. This method is called by the text editor control.
/// </summary>
public override ICompletionData[] GenerateCompletionData(string fileName, ICSharpCode.TextEditor.TextArea textArea, char charTyped)
{
List<ICompletionData> list = new List<ICompletionData>();
list.Add(new NewResourceCodeCompletionData(this.content, this.outputVisitor, this.preEnteredName));
foreach (KeyValuePair<string, object> entry in this.content.Data) {
list.Add(new ResourceCodeCompletionData(entry.Key, ResourceResolverService.FormatResourceDescription(this.content, entry.Key), this.outputVisitor));
}
return list.ToArray();
}
/// <summary>
/// Gets if pressing 'key' should trigger the insertion of the currently selected element.
/// </summary>
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);
}
}
}

58
src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItem.cs

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Christian Hornung" email=""/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.PrettyPrinter;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
namespace Hornung.ResourceToolkit.CodeCompletion
{
/// <summary>
/// Represents a code completion item for resource keys.
/// </summary>
public class ResourceCodeCompletionItem : DefaultCompletionItem
{
readonly IOutputAstVisitor outputVisitor;
/// <summary>
/// Initializes a new instance of the <see cref="ResourceCodeCompletionItem" /> class.
/// </summary>
/// <param name="key">The resource key.</param>
/// <param name="description">The resource description.</param>
/// <param name="outputVisitor">The NRefactory output visitor to be used to generate the inserted code. If <c>null</c>, the key is inserted literally.</param>
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;
}
}
}

59
src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ResourceCodeCompletionItemList.cs

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Christian Hornung" email=""/>
// <version>$Revision$</version>
// </file>
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
{
/// <summary>
/// Provides code completion data for resource keys.
/// </summary>
public sealed class ResourceCodeCompletionItemList : DefaultCompletionItemList
{
/// <summary>
/// Initializes a new instance of the <see cref="ResourceCodeCompletionItemList" /> class.
/// </summary>
/// <param name="content">The resource file content to be presented to the user.</param>
/// <param name="outputVisitor">The NRefactory output visitor to be used to generate the inserted code. If <c>null</c>, the key is inserted literally.</param>
/// <param name="preEnteredName">The type name which should be pre-entered in the 'add new' dialog box if the user selects the 'add new' entry.</param>
public ResourceCodeCompletionItemList(IResourceFileContent content, IOutputAstVisitor outputVisitor, string preEnteredName)
{
if (content == null) {
throw new ArgumentNullException("content");
}
this.GenerateCompletionItems(content, outputVisitor, preEnteredName);
}
/// <summary>
/// Generates the completion items.
/// </summary>
private void GenerateCompletionItems(IResourceFileContent content, IOutputAstVisitor outputVisitor, string preEnteredName)
{
this.Items.Add(new NewResourceCodeCompletionItem(content, outputVisitor, preEnteredName));
foreach (KeyValuePair<string, object> 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);
}
}
}

82
src/AddIns/Misc/ResourceToolkit/Project/Src/Commands/TextEditorContextMenuBuilder.cs

@ -5,70 +5,83 @@ @@ -5,70 +5,83 @@
// <version>$Revision$</version>
// </file>
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
{
/// <summary>
/// Builds context menu for editing string resources.
/// </summary>
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<ToolStripItem> items = new List<ToolStripItem>();
MenuCommand cmd;
List<MenuItem> items = new List<MenuItem>();
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 @@ -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 @@ -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 @@ -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 @@ -151,6 +164,5 @@ namespace Hornung.ResourceToolkit.Commands
Application.DoEvents();
ResourceRefactoringService.Rename(result);
}
}
}

9
src/AddIns/Misc/ResourceToolkit/Test/AbstractResourceResolverTestFixture.cs

@ -11,8 +11,9 @@ using Hornung.ResourceToolkit; @@ -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 @@ -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);
}
/// <summary>

4
src/AddIns/Misc/ResourceToolkit/Test/ResourceToolkit.Tests.csproj

@ -62,10 +62,6 @@ @@ -62,10 +62,6 @@
<Compile Include="VBNet\BclNRefactoryResourceResolverTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj">
<Project>{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}</Project>
<Name>ICSharpCode.TextEditor</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj">
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project>
<Name>ICSharpCode.SharpDevelop</Name>

Loading…
Cancel
Save