diff --git a/data/resources/image/BitmapResources/BitmapList.txt b/data/resources/image/BitmapResources/BitmapList.txt index ddb63557b2..bf111d6f0d 100644 --- a/data/resources/image/BitmapResources/BitmapList.txt +++ b/data/resources/image/BitmapResources/BitmapList.txt @@ -23,7 +23,7 @@ BitmapResources-data\Icons.16x16.AdjustColor.png BitmapResources-data\Icons.16x16.ArrowDown.png BitmapResources-data\Icons.16x16.ArrowLeftRight.png BitmapResources-data\Icons.16x16.ArrowUp.png -BitmapResources-data\Icons.16x16.Assembly.png +BitmapResources-data\Icons.16x16.Collection.png BitmapResources-data\Icons.16x16.BoldText.png BitmapResources-data\Icons.16x16.BrowserAfter.png BitmapResources-data\Icons.16x16.BrowserBefore.png @@ -85,7 +85,7 @@ BitmapResources-data\Icons.16x16.LowerToUpperCase.png BitmapResources-data\Icons.16x16.MyComputer.png BitmapResources-data\Icons.16x16.NETWORK.png BitmapResources-data\Icons.16x16.OK.png -BitmapResources-data\Icons.16x16.OpenAssembly.png +BitmapResources-data\Icons.16x16.OpenCollection.png BitmapResources-data\Icons.16x16.OutDent.png BitmapResources-data\Icons.16x16.PasteIcon.png BitmapResources-data\Icons.16x16.PersonalFiles.png @@ -140,7 +140,9 @@ SharpQueryIcons\Icons.16x16.SharpQuery.Column.png SharpQueryIcons\Icons.16x16.SharpQuery.NodeError.png SharpQueryIcons\Icons.16x16.SharpQuery.Remove.png SharpQueryIcons\Icons.16x16.SharpQuery.Table.png - +ClassBrowserIcons\Icons.16x16.Workspace.png +ClassBrowserIcons\Icons.16x16.Assembly.png +ClassBrowserIcons\Icons.16x16.AssemblyError.png ------------------------------------------------------------------------------- Copied from the Fugue Icon Library and modified or mashed up with other Fugue @@ -239,6 +241,11 @@ CodeCoverageIcons\CodeCoverage.Icons.16x16.Pad.png CodeCoverageIcons\CodeCoverage.Icons.16x16.Run.png DebuggerIcons\Icons.16x16.Debug.Start.png DebuggerIcons\Icons.16x16.Debug.StartWithoutDebugging.png +DebuggerIcons\Icons.16x16.Debug.Assembly.png +ClassBrowserIcons\Icons.16x16.Module.png +ClassBrowserIcons\Icons.16x16.ModuleError.png +ClassBrowserIcons\Icons.16x16.AssemblyFromFile.png +ClassBrowserIcons\Icons.16x16.AssemblyFromGAC.png NavigationIcons\Icons.16x16.NavigateBack.disabled.png NavigationIcons\Icons.16x16.NavigateBack.png NavigationIcons\Icons.16x16.NavigateForward.png @@ -556,7 +563,6 @@ ClassBrowserIcons\Icons.16x16.Operator.png ClassBrowserIcons\Icons.16x16.Parameter.png ClassBrowserIcons\Icons.16x16.Struct.png - ------------------------------------------------------------------------------- Left original (other source than Fugue Iconlibrary) ------------------------------------------------------------------------------- diff --git a/data/resources/image/BitmapResources/BitmapResources-data/Icons.16x16.Assembly.png b/data/resources/image/BitmapResources/BitmapResources-data/Icons.16x16.Collection.png similarity index 100% rename from data/resources/image/BitmapResources/BitmapResources-data/Icons.16x16.Assembly.png rename to data/resources/image/BitmapResources/BitmapResources-data/Icons.16x16.Collection.png diff --git a/data/resources/image/BitmapResources/BitmapResources-data/Icons.16x16.OpenAssembly.png b/data/resources/image/BitmapResources/BitmapResources-data/Icons.16x16.OpenCollection.png similarity index 100% rename from data/resources/image/BitmapResources/BitmapResources-data/Icons.16x16.OpenAssembly.png rename to data/resources/image/BitmapResources/BitmapResources-data/Icons.16x16.OpenCollection.png diff --git a/data/resources/image/BitmapResources/BitmapResources.res b/data/resources/image/BitmapResources/BitmapResources.res index fbe8c05bb9..7946ddfdb6 100644 --- a/data/resources/image/BitmapResources/BitmapResources.res +++ b/data/resources/image/BitmapResources/BitmapResources.res @@ -86,6 +86,7 @@ Icons.16x16.Debug.Continue = DebuggerIcons\Icons.16x16.Debug.Continue.png Icons.16x16.Debug.StepOver = DebuggerIcons\Icons.16x16.Debug.StepOver.png Icons.16x16.Debug.StepInto = DebuggerIcons\Icons.16x16.Debug.StepInto.png Icons.16x16.Debug.StepOut = DebuggerIcons\Icons.16x16.Debug.StepOut.png +Icons.16x16.Debug.Assembly = DebuggerIcons\Icons.16x16.Debug.Assembly.png # TestRunner Icons.16x16.TestRunner.Yellow = BitmapResources-data\Icons.16x16.TestRunner.Yellow.png @@ -107,7 +108,7 @@ Icons.16x16.AdjustBackgroundColor = BitmapResources-data\Icons.16x16.AdjustB Icons.16x16.HelpOpenFolder = BitmapResources-data\Icons.16x16.HelpOpenFolder.png Icons.16x16.SmallIconsIcon = BitmapResources-data\Icons.16x16.SmallIconsIcon.png Icons.16x16.HtmlElements.AnchorElement = BitmapResources-data\Icons.16x16.HtmlElements.AnchorElement.png -Icons.16x16.Assembly = BitmapResources-data\Icons.16x16.Assembly.png +Icons.16x16.Collection = BitmapResources-data\Icons.16x16.Collection.png Icons.16x16.TipOfTheDay = BitmapResources-data\Icons.16x16.TipOfTheDay.png Icons.16x16.Right = BitmapResources-data\Icons.16x16.Right.png Icons.16x16.CDROM = BitmapResources-data\Icons.16x16.CDROM.png @@ -169,7 +170,7 @@ Icons.16x16.BuildCurrentSelectedProject = BitmapResources-data\Icons.16x16.Bu Icons.16x16.HelpTopic = BitmapResources-data\Icons.16x16.HelpTopic.png Icons.16x16.PrevWindowIcon = BitmapResources-data\Icons.16x16.PrevWindowIcon.png Icons.16x16.HtmlElements.SelectElement = BitmapResources-data\Icons.16x16.HtmlElements.SelectElement.png -Icons.16x16.OpenAssembly = BitmapResources-data\Icons.16x16.OpenAssembly.png +Icons.16x16.OpenCollection = BitmapResources-data\Icons.16x16.OpenCollection.png Icons.16x16.HtmlElements.InputSubmitElement = BitmapResources-data\Icons.16x16.HtmlElements.InputSubmitElement.png Icons.16x16.CancelIcon = BitmapResources-data\Icons.16x16.CancelIcon.png Icons.16x16.ItalicText = BitmapResources-data\Icons.16x16.ItalicText.png @@ -292,6 +293,14 @@ Icons.16x16.SharpQuery.AddConnection = SharpQueryIcons\Icons.16x16.SharpQuery Icons.16x16.SharpQuery.Remove = SharpQueryIcons\Icons.16x16.SharpQuery.Remove.png #ClassBrowser icons +Icons.16x16.AssemblyFromFile = ClassBrowserIcons\Icons.16x16.AssemblyFromFile.png +Icons.16x16.AssemblyFromGAC = ClassBrowserIcons\Icons.16x16.AssemblyFromGAC.png + +Icons.16x16.Workspace = ClassBrowserIcons\Icons.16x16.Workspace.png +Icons.16x16.Assembly = ClassBrowserIcons\Icons.16x16.Assembly.png +Icons.16x16.AssemblyError = ClassBrowserIcons\Icons.16x16.AssemblyError.png +Icons.16x16.Module = ClassBrowserIcons\Icons.16x16.Module.png +Icons.16x16.ModuleError = ClassBrowserIcons\Icons.16x16.ModuleError.png Icons.16x16.NameSpace = ClassBrowserIcons\Icons.16x16.NameSpace.png Icons.16x16.Literal = ClassBrowserIcons\Icons.16x16.Literal.png Icons.16x16.Reference = ClassBrowserIcons\Icons.16x16.Reference.png diff --git a/data/resources/image/BitmapResources/ClassBrowserIcons/AssemblyFromFile.png b/data/resources/image/BitmapResources/ClassBrowserIcons/AssemblyFromFile.png new file mode 100644 index 0000000000..1e33efe252 Binary files /dev/null and b/data/resources/image/BitmapResources/ClassBrowserIcons/AssemblyFromFile.png differ diff --git a/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.Assembly.png b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.Assembly.png new file mode 100644 index 0000000000..d38c058f2f Binary files /dev/null and b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.Assembly.png differ diff --git a/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.AssemblyError.png b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.AssemblyError.png new file mode 100644 index 0000000000..01566b5f5e Binary files /dev/null and b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.AssemblyError.png differ diff --git a/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.AssemblyFromFile.png b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.AssemblyFromFile.png new file mode 100644 index 0000000000..1c4e382bef Binary files /dev/null and b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.AssemblyFromFile.png differ diff --git a/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.AssemblyFromGAC.png b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.AssemblyFromGAC.png new file mode 100644 index 0000000000..d39ab189ee Binary files /dev/null and b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.AssemblyFromGAC.png differ diff --git a/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.Module.png b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.Module.png new file mode 100644 index 0000000000..086da4b455 Binary files /dev/null and b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.Module.png differ diff --git a/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.ModuleError.png b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.ModuleError.png new file mode 100644 index 0000000000..4161b1497b Binary files /dev/null and b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.ModuleError.png differ diff --git a/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.Workspace.png b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.Workspace.png new file mode 100644 index 0000000000..6a27b7c650 Binary files /dev/null and b/data/resources/image/BitmapResources/ClassBrowserIcons/Icons.16x16.Workspace.png differ diff --git a/data/resources/image/BitmapResources/DebuggerIcons/Icons.16x16.Debug.Assembly.png b/data/resources/image/BitmapResources/DebuggerIcons/Icons.16x16.Debug.Assembly.png new file mode 100644 index 0000000000..860aaf96ce Binary files /dev/null and b/data/resources/image/BitmapResources/DebuggerIcons/Icons.16x16.Debug.Assembly.png differ diff --git a/src/AddIns/Analysis/UnitTesting/UnitTesting.addin b/src/AddIns/Analysis/UnitTesting/UnitTesting.addin index 428a3f0785..3b01c2fb29 100644 --- a/src/AddIns/Analysis/UnitTesting/UnitTesting.addin +++ b/src/AddIns/Analysis/UnitTesting/UnitTesting.addin @@ -101,7 +101,7 @@ class="ICSharpCode.UnitTesting.AddNUnitReferenceCommand"/> diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs index e810b5b456..8d25706d93 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs @@ -11,10 +11,9 @@ using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.Completion; using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp.Completion; -using ICSharpCode.NRefactory.CSharp.TypeSystem; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; namespace CSharpBinding.Completion { @@ -127,7 +126,8 @@ namespace CSharpBinding.Completion IEnumerable ICompletionDataFactory.CreateCodeTemplateCompletionData() { - yield break; + return completionContext.Editor.GetSnippets().OfType() + .Select(snippet => new SnippetCompletionData(snippet)); } IEnumerable ICompletionDataFactory.CreatePreProcessorDefinesCompletionData() diff --git a/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingTextEditorViewContent.cs b/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingTextEditorViewContent.cs index 64007d5cde..8774549594 100644 --- a/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingTextEditorViewContent.cs +++ b/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingTextEditorViewContent.cs @@ -29,8 +29,8 @@ namespace ICSharpCode.Scripting void Init(IViewContent view) { this.view = view; - editable = view as IEditable; - textEditor = view.GetService(typeof(ITextEditor)) as ITextEditor; + editable = view.GetService(); + textEditor = view.GetService(); textEditorOptions = textEditor.Options; } diff --git a/src/AddIns/BackendBindings/Scripting/Test/Utils/MockEditableViewContent.cs b/src/AddIns/BackendBindings/Scripting/Test/Utils/MockEditableViewContent.cs index ecbf9e86d5..18727f639f 100644 --- a/src/AddIns/BackendBindings/Scripting/Test/Utils/MockEditableViewContent.cs +++ b/src/AddIns/BackendBindings/Scripting/Test/Utils/MockEditableViewContent.cs @@ -12,7 +12,7 @@ namespace ICSharpCode.Scripting.Tests.Utils /// /// Mock implementation of the IEditable and IViewContent. /// - public class MockEditableViewContent : MockViewContent, IEditable, ITextEditorProvider + public class MockEditableViewContent : MockViewContent, IEditable { public MockTextEditor MockTextEditor = new MockTextEditor(); @@ -37,15 +37,6 @@ namespace ICSharpCode.Scripting.Tests.Utils set { MockTextEditor.MockTextEditorOptions = value; } } - public ITextEditor TextEditor { - get { return MockTextEditor; } - } - - public IDocument GetDocumentForFile(OpenedFile file) - { - throw new NotImplementedException(); - } - public override object GetService(Type serviceType) { if (serviceType == typeof(ITextEditor)) { diff --git a/src/AddIns/BackendBindings/Scripting/Test/Utils/MockTextEditorViewContent.cs b/src/AddIns/BackendBindings/Scripting/Test/Utils/MockTextEditorViewContent.cs index 27f16959c0..018bc4da78 100644 --- a/src/AddIns/BackendBindings/Scripting/Test/Utils/MockTextEditorViewContent.cs +++ b/src/AddIns/BackendBindings/Scripting/Test/Utils/MockTextEditorViewContent.cs @@ -13,7 +13,7 @@ namespace ICSharpCode.Scripting.Tests.Utils /// A mock IViewContent implementation that also implements the /// ITextEditorControlProvider interface. /// - public class MockTextEditorViewContent : MockViewContent, ITextEditorProvider + public class MockTextEditorViewContent : MockViewContent { ITextEditor textEditor; @@ -21,14 +21,5 @@ namespace ICSharpCode.Scripting.Tests.Utils { textEditor = new AvalonEditTextEditorAdapter(new TextEditor()); } - - public ITextEditor TextEditor { - get { return textEditor; } - } - - public IDocument GetDocumentForFile(OpenedFile file) - { - throw new NotImplementedException(); - } } } diff --git a/src/AddIns/BackendBindings/WixBinding/Project/Src/Gui/WixDialogDesigner.cs b/src/AddIns/BackendBindings/WixBinding/Project/Src/Gui/WixDialogDesigner.cs index c1509e44be..efd6148cc7 100644 --- a/src/AddIns/BackendBindings/WixBinding/Project/Src/Gui/WixDialogDesigner.cs +++ b/src/AddIns/BackendBindings/WixBinding/Project/Src/Gui/WixDialogDesigner.cs @@ -83,7 +83,7 @@ namespace ICSharpCode.WixBinding // and text selection operations done by the WiX designer actually // become visible in the text editor. if (!this.SourceCodeStorage.ContainsFile(file)) { - ITextEditor editor = ((ITextEditorProvider)this.PrimaryViewContent).TextEditor; + ITextEditor editor = this.PrimaryViewContent.GetService(); this.SourceCodeStorage.AddFile(file, editor.Document, SD.FileService.DefaultFileEncoding, true); } @@ -224,13 +224,7 @@ namespace ICSharpCode.WixBinding /// Gets the active text area control. /// ITextEditor ActiveTextEditor { - get { - ITextEditorProvider provider = this.PrimaryViewContent as ITextEditorProvider; - if (provider != null) { - return provider.TextEditor; - } - return null; - } + get { return PrimaryViewContent.GetService(); } } void AddToErrorList(XmlException ex) diff --git a/src/AddIns/BackendBindings/WixBinding/Project/Src/Gui/WixDialogDesignerDisplayBinding.cs b/src/AddIns/BackendBindings/WixBinding/Project/Src/Gui/WixDialogDesignerDisplayBinding.cs index 7b26d28b22..413f4ebfb8 100644 --- a/src/AddIns/BackendBindings/WixBinding/Project/Src/Gui/WixDialogDesignerDisplayBinding.cs +++ b/src/AddIns/BackendBindings/WixBinding/Project/Src/Gui/WixDialogDesignerDisplayBinding.cs @@ -37,8 +37,7 @@ namespace ICSharpCode.WixBinding bool IsViewTextEditorProvider(IViewContent view) { - ITextEditorProvider textEditorProvider = view as ITextEditorProvider; - return textEditorProvider != null; + return view.GetService() != null; } } } diff --git a/src/AddIns/BackendBindings/WixBinding/Test/Utils/MockTextEditorViewContent.cs b/src/AddIns/BackendBindings/WixBinding/Test/Utils/MockTextEditorViewContent.cs index 5d7b5545ba..ecbeccbcab 100644 --- a/src/AddIns/BackendBindings/WixBinding/Test/Utils/MockTextEditorViewContent.cs +++ b/src/AddIns/BackendBindings/WixBinding/Test/Utils/MockTextEditorViewContent.cs @@ -11,13 +11,18 @@ namespace WixBinding.Tests.Utils /// /// Mock IViewContent class that implements the ITextEditorProvider interface. /// - public class MockTextEditorViewContent : MockViewContent, ITextEditorProvider + public class MockTextEditorViewContent : MockViewContent { public MockTextEditorViewContent() { } - public ITextEditor TextEditor { get; set; } + ITextEditor textEditor; + + public ITextEditor TextEditor { + get { return textEditor ?? new MockTextEditor(); } + set { textEditor = value; } + } public IDocument GetDocumentForFile(OpenedFile file) { diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs index 7bd1c90b1e..2835db1b27 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs @@ -3,14 +3,10 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.Linq; -using System.Runtime.InteropServices.ComTypes; -using System.Threading; using System.Windows.Media; using ICSharpCode.NRefactory; -using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.TypeSystem; @@ -20,7 +16,6 @@ using ICSharpCode.NRefactory.Xml; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor.CodeCompletion; -using ICSharpCode.SharpDevelop.Parser; namespace ICSharpCode.XamlBinding { diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs index 8c50318b6f..c5214a4641 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Windows; using System.Windows.Controls; @@ -11,16 +10,13 @@ using System.Windows.Media; using System.Xml; using System.Xml.Linq; -using ICSharpCode.AvalonEdit.Document; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.TypeSystem; -using ICSharpCode.NRefactory.Xml; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor.CodeCompletion; -using ICSharpCode.XmlEditor; namespace ICSharpCode.XamlBinding { diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/MarkupExtensionInfo.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/MarkupExtensionInfo.cs index 1f0ee134e5..1a813e4992 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/MarkupExtensionInfo.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/MarkupExtensionInfo.cs @@ -5,9 +5,6 @@ using System; using System.Collections.Generic; using System.Linq; -using ICSharpCode.SharpDevelop; -using ICSharpCode.NRefactory.TypeSystem; -using ICSharpCode.XmlEditor; using System.Text; namespace ICSharpCode.XamlBinding diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/CodeCompletion.xaml.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/CodeCompletion.xaml.cs index 9ed1a2cac6..0b0b7e3bad 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/CodeCompletion.xaml.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/CodeCompletion.xaml.cs @@ -2,14 +2,6 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; -using System.Collections.Generic; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; using ICSharpCode.SharpDevelop.Gui; diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/XamlBindingOptions.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/XamlBindingOptions.cs index c7b1972566..2abe902879 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/XamlBindingOptions.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/XamlBindingOptions.cs @@ -2,7 +2,6 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; -using System.Collections.Generic; using System.Diagnostics; using System.Windows.Media; diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/PropertyPathSegment.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/PropertyPathSegment.cs index ada534d1d7..ffbb7425be 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/PropertyPathSegment.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/PropertyPathSegment.cs @@ -3,7 +3,6 @@ using System; using System.Linq; -using System.Collections.Generic; namespace ICSharpCode.XamlBinding { diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs index 8ab1ff403a..d3f1503425 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Utils.cs @@ -1,18 +1,10 @@ // Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) -using ICSharpCode.NRefactory; using System; using System.Collections.Generic; -using System.Diagnostics; -using System.IO; using System.Linq; -using System.Text.RegularExpressions; -using System.Xml; -using ICSharpCode.Core; -using ICSharpCode.NRefactory.Xml; -using ICSharpCode.SharpDevelop.Editor; -using ICSharpCode.XmlEditor; +using ICSharpCode.NRefactory; namespace ICSharpCode.XamlBinding { diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlAstResolver.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlAstResolver.cs index 9805d23a3a..ea00cddea5 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlAstResolver.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlAstResolver.cs @@ -10,8 +10,6 @@ using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.NRefactory.Xml; -using ICSharpCode.SharpDevelop.Parser; -using ICSharpCode.XmlEditor; namespace ICSharpCode.XamlBinding { diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBehavior.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBehavior.cs index 8504e2bc40..e2dba98a47 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBehavior.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBehavior.cs @@ -6,10 +6,7 @@ using System.Diagnostics; using System.IO; using System.Linq; -using ICSharpCode.AvalonEdit.Document; -using ICSharpCode.Core; using ICSharpCode.NRefactory.TypeSystem; -using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Refactoring; diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs index 4c0983afb7..42e1ebabf8 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs @@ -2,16 +2,13 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; -using System.Collections.Generic; using System.Linq; -using ICSharpCode.SharpDevelop; using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor.CodeCompletion; -using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Project; -using ICSharpCode.XmlEditor; namespace ICSharpCode.XamlBinding { diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs index ab691ea2cf..051973df82 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs @@ -6,15 +6,6 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using System.Threading; -using ICSharpCode.NRefactory; -using ICSharpCode.NRefactory.Semantics; -using ICSharpCode.NRefactory.TypeSystem; -using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Editor; -using ICSharpCode.SharpDevelop.Editor.CodeCompletion; -using ICSharpCode.SharpDevelop.Parser; - namespace ICSharpCode.XamlBinding { /// diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs index ffb8d9f1e6..9ea3a3a926 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs @@ -4,17 +4,11 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.IO; using System.Linq; -using System.Windows.Media; -using System.Xml; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.Xml; -using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Editor; -using ICSharpCode.SharpDevelop.Parser; -using ICSharpCode.XmlEditor; namespace ICSharpCode.XamlBinding { diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs index 5ab19f17cb..7565e4d734 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs @@ -9,7 +9,6 @@ using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Xml; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Editor; -using ICSharpCode.SharpDevelop.Parser; namespace ICSharpCode.XamlBinding { diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlLanguageBinding.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlLanguageBinding.cs index 6a6d26f335..25a695fd09 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlLanguageBinding.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlLanguageBinding.cs @@ -2,7 +2,6 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; -using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Rendering; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Editor; diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs index 39fcb6c32f..e20bab95b9 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs @@ -4,7 +4,6 @@ using System; using System.Windows.Controls; using System.Windows.Input; -using System.Windows.Threading; using ICSharpCode.Core; using ICSharpCode.SharpDevelop; diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs index ff86aecd6b..5c209e9422 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs @@ -4,8 +4,6 @@ using System; using System.Linq; using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; using ICSharpCode.NRefactory.Editor; using ICSharpCode.SharpDevelop.Editor; diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs index 7adf0287c8..02e2b290e5 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs @@ -7,13 +7,11 @@ using System.IO; using System.Linq; using System.Threading; -using ICSharpCode.AvalonEdit.Document; using ICSharpCode.Core; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.TypeSystem; -using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.NRefactory.Utils; using ICSharpCode.NRefactory.Xml; using ICSharpCode.SharpDevelop; @@ -21,7 +19,6 @@ using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor.Search; using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.SharpDevelop.Project; -using ICSharpCode.SharpDevelop.Refactoring; namespace ICSharpCode.XamlBinding { @@ -31,11 +28,6 @@ namespace ICSharpCode.XamlBinding public class XamlParser : IParser { public IReadOnlyList TaskListTokens { get; set; } - -// public LanguageProperties Language -// { -// get { return LanguageProperties.CSharp; } -// } public XamlParser() { diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlSymbolSearch.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlSymbolSearch.cs index 23476b90e4..aa604a7b28 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlSymbolSearch.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlSymbolSearch.cs @@ -3,20 +3,16 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.Core; -using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor.Search; -using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Refactoring; diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlUnresolvedFile.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlUnresolvedFile.cs index 2f4ddbcf4f..e1e4297054 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlUnresolvedFile.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlUnresolvedFile.cs @@ -3,22 +3,13 @@ using System; using System.Collections.Generic; -using System.Collections.Specialized; -using System.IO; using System.Linq; -using System.Threading; -using ICSharpCode.AvalonEdit.Document; using ICSharpCode.Core; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.Editor; -using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.NRefactory.Xml; -using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Parser; -using ICSharpCode.SharpDevelop.Project; -using ICSharpCode.SharpDevelop.Refactoring; namespace ICSharpCode.XamlBinding { @@ -151,10 +142,12 @@ namespace ICSharpCode.XamlBinding AXmlElement rootElement = currentDocument.Children.OfType().FirstOrDefault(); if (rootElement != null) { string className = rootElement.GetAttributeValue(XamlConst.XamlNamespace, "Class"); + string modifier = rootElement.GetAttributeValue(XamlConst.XamlNamespace, "ClassModifier"); if (className != null) { TypeDefinition = new DefaultUnresolvedTypeDefinition(className) { Kind = TypeKind.Class, UnresolvedFile = file, + Accessibility = Accessibility.Public, Region = new DomRegion(file.FileName, textDocument.GetLocation(rootElement.StartOffset), textDocument.GetLocation(rootElement.EndOffset)) }; TypeDefinition.Members.Add( @@ -162,6 +155,35 @@ namespace ICSharpCode.XamlBinding Accessibility = Accessibility.Public, ReturnType = KnownTypeReference.Void }); + TypeDefinition.Members.Add( + new DefaultUnresolvedField(TypeDefinition, "_contentLoaded") { + Accessibility = Accessibility.Private, + ReturnType = KnownTypeReference.Boolean + }); + + var connectMember = + new DefaultUnresolvedMethod(TypeDefinition, "Connect") { + Accessibility = Accessibility.Private, + ReturnType = KnownTypeReference.Void + }; + connectMember.Parameters.Add(new DefaultUnresolvedParameter(KnownTypeReference.Int32, "connectionId")); + connectMember.Parameters.Add(new DefaultUnresolvedParameter(KnownTypeReference.Object, "target")); + TypeDefinition.Members.Add(connectMember); + connectMember.ExplicitInterfaceImplementations.Add( + new DefaultMemberReference(SymbolKind.Method, new GetClassTypeReference(new FullTypeName(typeof(System.Windows.Markup.IComponentConnector).FullName)), "Connect")); + + var browsableAttribute = new DefaultUnresolvedAttribute(new GetClassTypeReference(new FullTypeName(typeof(System.ComponentModel.EditorBrowsableAttribute).FullName))); + + browsableAttribute.PositionalArguments.Add( + new SimpleConstantValue( + new GetClassTypeReference(new FullTypeName(typeof(System.ComponentModel.EditorBrowsableAttribute).FullName)), System.ComponentModel.EditorBrowsableState.Never + )); + + connectMember.Attributes.Add(browsableAttribute); + TypeDefinition.BaseTypes.Add(CreateTypeReference(rootElement.Namespace, rootElement.LocalName)); + TypeDefinition.BaseTypes.Add(new GetClassTypeReference(new FullTypeName(typeof(System.Windows.Markup.IComponentConnector).FullName))); + if (modifier != null) + TypeDefinition.Accessibility = ParseAccessibility(modifier); } } base.VisitDocument(document); diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ClassBrowserSupport.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/ClassBrowserSupport.cs index d4b76afdaf..8bfd17cf10 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/ClassBrowserSupport.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/ClassBrowserSupport.cs @@ -106,7 +106,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads public override object Icon { get { - return IconService.GetImageSource("Icons.16x16.Debug.Start"); + return IconService.GetImageSource("Icons.16x16.Debug.Assembly"); } } } @@ -125,7 +125,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads public override object Icon { get { - return IconService.GetImageSource("PadIcons.LoadedModules"); + return SD.ResourceService.GetImageSource("Icons.16x16.Module"); } } diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs index 52e1a449ae..a79dc21863 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs @@ -24,15 +24,8 @@ using ICSharpCode.SharpDevelop.Workbench; namespace ICSharpCode.AvalonEdit.AddIn { - [ViewContentService] - public interface ICodeEditorProvider : ITextEditorProvider - { - [Obsolete("Use viewContent.GetService() instead.")] - CodeEditor CodeEditor { get; } - } - public class AvalonEditViewContent - : AbstractViewContent, IEditable, IMementoCapable, ICodeEditorProvider, IPositionable, IToolsHost + : AbstractViewContent, IMementoCapable, IToolsHost { readonly CodeEditor codeEditor = new CodeEditor(); IAnalyticsMonitorTrackedFeature trackedFeature; @@ -62,8 +55,6 @@ namespace ICSharpCode.AvalonEdit.AddIn file.IsDirtyChanged += PrimaryFile_IsDirtyChanged; codeEditor.Document.UndoStack.PropertyChanged += codeEditor_Document_UndoStack_PropertyChanged; - codeEditor.CaretPositionChanged += CaretChanged; - codeEditor.TextCopied += codeEditor_TextCopied; } bool IsKnownFileExtension(string filetype) @@ -91,16 +82,7 @@ namespace ICSharpCode.AvalonEdit.AddIn } } } - - void codeEditor_TextCopied(object sender, ICSharpCode.AvalonEdit.Editing.TextEventArgs e) - { - TextEditorSideBar.Instance.PutInClipboardRing(e.Text); - } - - public CodeEditor CodeEditor { - get { return codeEditor; } - } - + public override object Control { get { return codeEditor; } } @@ -194,25 +176,7 @@ namespace ICSharpCode.AvalonEdit.AddIn public override INavigationPoint BuildNavPoint() { - int lineNumber = this.Line; - string txt = codeEditor.Document.GetText(codeEditor.Document.GetLineByNumber(lineNumber)); - return new TextNavigationPoint(this.PrimaryFileName, lineNumber, this.Column, txt); - } - - void CaretChanged(object sender, EventArgs e) - { - NavigationService.Log(this.BuildNavPoint()); - var document = codeEditor.Document; - int lineOffset = document.GetLineByNumber(this.Line).Offset; - int chOffset = this.Column; - int col = 1; - for (int i = 1; i < chOffset; i++) { - if (document.GetCharAt(lineOffset + i - 1) == '\t') - col += CodeEditorOptions.Instance.IndentationSize; - else - col += 1; - } - SD.StatusBar.SetCaretPosition(col, this.Line, chOffset); + return codeEditor.BuildNavPoint(); } public override bool IsReadOnly { @@ -294,22 +258,6 @@ namespace ICSharpCode.AvalonEdit.AddIn return "[" + GetType().Name + " " + this.PrimaryFileName + "]"; } - #region IEditable - public ITextSource CreateSnapshot() - { - return codeEditor.Document.CreateSnapshot(); - } - - /// - /// Gets the document text. - /// - public string Text { - get { - return codeEditor.Document.Text; - } - } - #endregion - #region IMementoCapable public Properties CreateMemento() { @@ -330,35 +278,6 @@ namespace ICSharpCode.AvalonEdit.AddIn } #endregion - #region ITextEditorProvider - public ITextEditor TextEditor { - get { return codeEditor.ActiveTextEditorAdapter; } - } - - public IDocument GetDocumentForFile(OpenedFile file) - { - if (file == this.PrimaryFile) - return codeEditor.Document; - else - return null; - } - #endregion - - #region IPositionable - public int Line { - get { return this.TextEditor.Caret.Line; } - } - - public int Column { - get { return this.TextEditor.Caret.Column; } - } - - public void JumpTo(int line, int column) - { - codeEditor.ActiveTextEditor.JumpTo(line, column); - } - #endregion - object IToolsHost.ToolsContent { get { return TextEditorSideBar.Instance; } } diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs index 2521a09d71..fac26f62c6 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs @@ -38,17 +38,14 @@ namespace ICSharpCode.AvalonEdit.AddIn /// Also provides support for Split-View (showing two AvalonEdit instances using the same TextDocument) /// [TextEditorService, ViewContentService] - public class CodeEditor : Grid, IDisposable + public class CodeEditor + : Grid, IDisposable, ICSharpCode.SharpDevelop.Gui.IEditable, IFileDocumentProvider, ICSharpCode.SharpDevelop.Gui.IPositionable, IServiceProvider { const string contextMenuPath = "/SharpDevelop/ViewContent/AvalonEdit/ContextMenu"; QuickClassBrowser quickClassBrowser; readonly CodeEditorView primaryTextEditor; readonly CodeEditorAdapter primaryTextEditorAdapter; - CodeEditorView secondaryTextEditor; - CodeEditorView activeTextEditor; - CodeEditorAdapter secondaryTextEditorAdapter; - GridSplitter gridSplitter; readonly IconBarManager iconBarManager; readonly TextMarkerService textMarkerService; readonly IChangeWatcher changeWatcher; @@ -58,14 +55,9 @@ namespace ICSharpCode.AvalonEdit.AddIn get { return primaryTextEditor; } } + [Obsolete()] public CodeEditorView ActiveTextEditor { - get { return activeTextEditor; } - private set { - if (activeTextEditor != value) { - activeTextEditor = value; - HandleCaretPositionChange(); - } - } + get { return primaryTextEditor; } } TextDocument document; @@ -114,8 +106,6 @@ namespace ICSharpCode.AvalonEdit.AddIn this.document.FileName = fileName; primaryTextEditorAdapter.FileNameChanged(); - if (secondaryTextEditorAdapter != null) - secondaryTextEditorAdapter.FileNameChanged(); if (this.errorPainter == null) { this.errorPainter = new ErrorPainter(primaryTextEditorAdapter); @@ -143,12 +133,6 @@ namespace ICSharpCode.AvalonEdit.AddIn primaryTextEditor.TextArea.TextView.LineTransformers.Insert(0, new HighlightingColorizer(highlighter)); primaryTextEditor.UpdateCustomizedHighlighting(); - if (secondaryTextEditor != null) { - secondaryTextEditor.SyntaxHighlighting = highlighting; - secondaryTextEditor.TextArea.TextView.LineTransformers.RemoveAll(t => t is HighlightingColorizer); - secondaryTextEditor.TextArea.TextView.LineTransformers.Insert(0, new HighlightingColorizer(highlighter)); - secondaryTextEditor.UpdateCustomizedHighlighting(); - } // Dispose the old highlighter; necessary to avoid memory leaks as // semantic highlighters might attach to global parser events. if (oldHighlighter != null) { @@ -159,9 +143,6 @@ namespace ICSharpCode.AvalonEdit.AddIn public void Redraw(ISegment segment, DispatcherPriority priority) { primaryTextEditor.TextArea.TextView.Redraw(segment, priority); - if (secondaryTextEditor != null) { - secondaryTextEditor.TextArea.TextView.Redraw(segment, priority); - } } const double minRowHeight = 40; @@ -175,7 +156,6 @@ namespace ICSharpCode.AvalonEdit.AddIn this.FlowDirection = FlowDirection.LeftToRight; // code editing is always left-to-right this.document = new TextDocument(); var documentServiceContainer = document.GetRequiredService(); - this.CommandBindings.Add(new CommandBinding(SharpDevelopRoutedCommands.SplitView, OnSplitView)); textMarkerService = new TextMarkerService(document); documentServiceContainer.AddService(typeof(ITextMarkerService), textMarkerService); @@ -189,7 +169,6 @@ namespace ICSharpCode.AvalonEdit.AddIn primaryTextEditor = CreateTextEditor(); primaryTextEditorAdapter = (CodeEditorAdapter)primaryTextEditor.TextArea.GetService(typeof(ITextEditor)); Debug.Assert(primaryTextEditorAdapter != null); - activeTextEditor = primaryTextEditor; this.ColumnDefinitions.Add(new ColumnDefinition()); this.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); @@ -210,8 +189,6 @@ namespace ICSharpCode.AvalonEdit.AddIn // CustomizableHighlightingColorizer loads the new values automatically, we just need // to force a refresh in AvalonEdit. primaryTextEditor.UpdateCustomizedHighlighting(); - if (secondaryTextEditor != null) - secondaryTextEditor.UpdateCustomizedHighlighting(); foreach (var bookmark in SD.BookmarkManager.GetBookmarks(fileName).OfType()) bookmark.SetMarker(); } @@ -228,6 +205,9 @@ namespace ICSharpCode.AvalonEdit.AddIn TextView textView = codeEditorView.TextArea.TextView; textView.Services.AddService(typeof(ITextEditor), adapter); textView.Services.AddService(typeof(CodeEditor), this); + textView.Services.AddService(typeof(ICSharpCode.SharpDevelop.Gui.IEditable), this); + textView.Services.AddService(typeof(ICSharpCode.SharpDevelop.Gui.IPositionable), this); + textView.Services.AddService(typeof(IFileDocumentProvider), this); codeEditorView.TextArea.TextEntering += TextAreaTextEntering; codeEditorView.TextArea.TextEntered += TextAreaTextEntered; @@ -251,17 +231,13 @@ namespace ICSharpCode.AvalonEdit.AddIn codeEditorView.TextArea.MouseRightButtonDown += TextAreaMouseRightButtonDown; codeEditorView.TextArea.ContextMenuOpening += TextAreaContextMenuOpening; codeEditorView.TextArea.TextCopied += textEditor_TextArea_TextCopied; - codeEditorView.GotFocus += textEditor_GotFocus; return codeEditorView; } - public event EventHandler TextCopied; - void textEditor_TextArea_TextCopied(object sender, TextEventArgs e) { - if (TextCopied != null) - TextCopied(this, e); + ICSharpCode.SharpDevelop.Gui.TextEditorSideBar.Instance.PutInClipboardRing(e.Text); } protected virtual void DisposeTextEditor(CodeEditorView textEditor) @@ -275,12 +251,6 @@ namespace ICSharpCode.AvalonEdit.AddIn textEditor.Dispose(); } - void textEditor_GotFocus(object sender, RoutedEventArgs e) - { - Debug.Assert(sender is CodeEditorView); - this.ActiveTextEditor = (CodeEditorView)sender; - } - void TextAreaContextMenuOpening(object sender, ContextMenuEventArgs e) { ITextEditor adapter = GetAdapterFromSender(sender); @@ -376,48 +346,6 @@ namespace ICSharpCode.AvalonEdit.AddIn } } - void OnSplitView(object sender, ExecutedRoutedEventArgs e) - { - if (secondaryTextEditor == null) { - // create secondary editor - this.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star), MinHeight = minRowHeight }); - secondaryTextEditor = CreateTextEditor(); - secondaryTextEditorAdapter = (CodeEditorAdapter)secondaryTextEditor.TextArea.GetService(typeof(ITextEditor)); - Debug.Assert(primaryTextEditorAdapter != null); - - secondaryTextEditor.SetBinding(TextEditor.IsReadOnlyProperty, - new Binding(TextEditor.IsReadOnlyProperty.Name) { Source = primaryTextEditor }); - secondaryTextEditor.SyntaxHighlighting = primaryTextEditor.SyntaxHighlighting; - secondaryTextEditor.UpdateCustomizedHighlighting(); - - gridSplitter = new GridSplitter { - Height = 4, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Top - }; - SetRow(gridSplitter, 2); - this.Children.Add(gridSplitter); - - secondaryTextEditor.Margin = new Thickness(0, 4, 0, 0); - SetRow(secondaryTextEditor, 2); - this.Children.Add(secondaryTextEditor); - - secondaryTextEditorAdapter.FileNameChanged(); - FetchParseInformation(); - } else { - // remove secondary editor - this.Children.Remove(secondaryTextEditor); - this.Children.Remove(gridSplitter); - secondaryTextEditorAdapter.DetachExtensions(); - DisposeTextEditor(secondaryTextEditor); - secondaryTextEditor = null; - secondaryTextEditorAdapter = null; - gridSplitter = null; - this.RowDefinitions.RemoveAt(this.RowDefinitions.Count - 1); - this.ActiveTextEditor = primaryTextEditor; - } - } - public event EventHandler CaretPositionChanged; void TextAreaCaretPositionChanged(object sender, EventArgs e) @@ -433,12 +361,32 @@ namespace ICSharpCode.AvalonEdit.AddIn void HandleCaretPositionChange() { + if (CaretPositionChanged != null) + CaretPositionChanged(this, EventArgs.Empty); + if (quickClassBrowser != null) { quickClassBrowser.SelectItemAtCaretPosition(this.ActiveTextEditor.TextArea.Caret.Location); } - if (CaretPositionChanged != null) - CaretPositionChanged(this, EventArgs.Empty); + NavigationService.Log(this.BuildNavPoint()); + var document = this.Document; + int lineOffset = document.GetLineByNumber(this.Line).Offset; + int chOffset = this.Column; + int col = 1; + for (int i = 1; i < chOffset; i++) { + if (document.GetCharAt(lineOffset + i - 1) == '\t') + col += CodeEditorOptions.Instance.IndentationSize; + else + col += 1; + } + SD.StatusBar.SetCaretPosition(col, this.Line, chOffset); + } + + public INavigationPoint BuildNavPoint() + { + int lineNumber = this.Line; + string txt = this.Document.GetText(this.Document.GetLineByNumber(lineNumber)); + return new TextNavigationPoint(this.FileName, lineNumber, this.Column, txt); } volatile static ReadOnlyCollection codeCompletionBindings; @@ -454,17 +402,63 @@ namespace ICSharpCode.AvalonEdit.AddIn SharpDevelopCompletionWindow CompletionWindow { get { - return primaryTextEditor.ActiveCompletionWindow - ?? (secondaryTextEditor == null ? null : secondaryTextEditor.ActiveCompletionWindow); + return primaryTextEditor.ActiveCompletionWindow; } } SharpDevelopInsightWindow InsightWindow { get { - return primaryTextEditor.ActiveInsightWindow - ?? (secondaryTextEditor == null ? null : secondaryTextEditor.ActiveInsightWindow); + return primaryTextEditor.ActiveInsightWindow; + } + } + + #region IEditable + public ITextSource CreateSnapshot() + { + return this.Document.CreateSnapshot(); + } + + /// + /// Gets the document text. + /// + public string Text { + get { + return this.Document.Text; } } + #endregion + + #region IFileDocumentProvider + public IDocument GetDocumentForFile(ICSharpCode.SharpDevelop.Workbench.OpenedFile file) + { + if (file.FileName == this.FileName) + return this.Document; + else + return null; + } + #endregion + + #region IPositionable + public int Line { + get { return this.PrimaryTextEditor.Adapter.Caret.Line; } + } + + public int Column { + get { return this.PrimaryTextEditor.Adapter.Caret.Column; } + } + + public void JumpTo(int line, int column) + { + this.PrimaryTextEditor.JumpTo(line, column); + } + #endregion + + #region IServiceProvider implementation + public object GetService(Type serviceType) + { + return this.primaryTextEditor.Adapter.GetService(serviceType); + } + #endregion void TextAreaTextEntering(object sender, TextCompositionEventArgs e) { @@ -635,8 +629,6 @@ namespace ICSharpCode.AvalonEdit.AddIn } iconBarManager.UpdateClassMemberBookmarks(parseInfo != null ? parseInfo.UnresolvedFile : null, document); primaryTextEditor.UpdateParseInformationForFolding(parseInfo); - if (secondaryTextEditor != null) - secondaryTextEditor.UpdateParseInformationForFolding(parseInfo); } public void Dispose() @@ -647,8 +639,6 @@ namespace ICSharpCode.AvalonEdit.AddIn if (primaryTextEditorAdapter.Language != null) primaryTextEditorAdapter.DetachExtensions(); - if (secondaryTextEditorAdapter != null && secondaryTextEditorAdapter.Language != null) - secondaryTextEditorAdapter.DetachExtensions(); if (errorPainter != null) errorPainter.Dispose(); @@ -656,8 +646,6 @@ namespace ICSharpCode.AvalonEdit.AddIn changeWatcher.Dispose(); this.Document = null; DisposeTextEditor(primaryTextEditor); - if (secondaryTextEditor != null) - DisposeTextEditor(secondaryTextEditor); } } } diff --git a/src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditContainer.Designer.cs b/src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditContainer.Designer.cs index 01873c638d..9f6d60d5ef 100644 --- a/src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditContainer.Designer.cs +++ b/src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditContainer.Designer.cs @@ -36,7 +36,7 @@ namespace HexEditor.View System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(HexEditContainer)); this.tbSizeToFit = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.tCBViewMode = new System.Windows.Forms.DomainUpDown(); + this.tCBViewMode = new System.Windows.Forms.ToolStripComboBox(); this.toolStrip1 = new System.Windows.Forms.ToolStrip(); this.tSTBCharsPerLine = new System.Windows.Forms.NumericUpDown(); this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar(); @@ -69,7 +69,8 @@ namespace HexEditor.View "Decimal"}); this.tCBViewMode.Name = "tCBViewMode"; this.tCBViewMode.Size = new System.Drawing.Size(121, 25); - this.tCBViewMode.SelectedItemChanged += new System.EventHandler(this.TCBViewModeSelectedIndexChanged); + this.tCBViewMode.SelectedIndexChanged += new System.EventHandler(this.TCBViewModeSelectedIndexChanged); + this.tCBViewMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; // // toolStrip1 // @@ -129,7 +130,7 @@ namespace HexEditor.View } private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1; internal HexEditor.Editor hexEditControl; - private System.Windows.Forms.DomainUpDown tCBViewMode; + private System.Windows.Forms.ToolStripComboBox tCBViewMode; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.ToolStripButton tbSizeToFit; private System.Windows.Forms.ToolStrip toolStrip1; diff --git a/src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditContainer.cs b/src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditContainer.cs index a7ab920c49..146ab87868 100644 --- a/src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditContainer.cs +++ b/src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditContainer.cs @@ -51,8 +51,7 @@ namespace HexEditor.View ToolStripControlHost bytesPerLine = new ToolStripControlHost(tSTBCharsPerLine); this.toolStrip1.Items.Insert(1, bytesPerLine); - ToolStripControlHost viewMode = new ToolStripControlHost(tCBViewMode); - this.toolStrip1.Items.Insert(3, viewMode); + this.toolStrip1.Items.Insert(3, tCBViewMode); hexEditControl.BytesPerLine = Settings.BytesPerLine; tSTBCharsPerLine.Text = hexEditControl.BytesPerLine.ToString(); diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs index 287d0e57e6..21d2f1da9a 100644 --- a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs +++ b/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs @@ -30,7 +30,7 @@ namespace ICSharpCode.ILSpyAddIn /// /// Hosts a decompiled type. /// - class DecompiledViewContent : AbstractViewContentWithoutFile, IPositionable + class DecompiledViewContent : AbstractViewContentWithoutFile { readonly FileName assemblyFile; readonly string fullTypeName; @@ -58,8 +58,7 @@ namespace ICSharpCode.ILSpyAddIn { this.VirtualFileName = FileName.Create("ilspy://" + assemblyFile + "/" + fullTypeName + ".cs"); - this.Services = codeEditor.PrimaryTextEditor.GetRequiredService(); - this.Services.AddService(typeof(IPositionable), this); + this.Services = codeEditor.GetRequiredService(); this.assemblyFile = assemblyFile; this.fullTypeName = fullTypeName; @@ -178,7 +177,12 @@ namespace ICSharpCode.ILSpyAddIn // TODO: show Save As dialog to allow the user to save the decompiled file } #endregion - + + public override INavigationPoint BuildNavPoint() + { + return codeEditor.BuildNavPoint(); + } + #region JumpToEntity public void JumpToEntity(string entityIdString) { @@ -188,7 +192,7 @@ namespace ICSharpCode.ILSpyAddIn } TextLocation location; if (entityIdString != null && memberLocations != null && memberLocations.TryGetValue(entityIdString, out location)) - this.JumpTo(location.Line, location.Column); + codeEditor.JumpTo(location.Line, location.Column); } #endregion @@ -299,21 +303,6 @@ namespace ICSharpCode.ILSpyAddIn } #endregion - #region IPositionable - public int Line { - get { return codeEditor.ActiveTextEditorAdapter.Caret.Line; } - } - - public int Column { - get { return codeEditor.ActiveTextEditorAdapter.Caret.Column; } - } - - public void JumpTo(int line, int column) - { - codeEditor.ActiveTextEditor.JumpTo(line, column); - } - #endregion - #region Events public event EventHandler DecompilationFinished; diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfDisplayBinding.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfDisplayBinding.cs index 93ac02c450..b86bf70870 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfDisplayBinding.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfDisplayBinding.cs @@ -45,7 +45,7 @@ namespace ICSharpCode.WpfDesign.AddIn public bool CanAttachTo(IViewContent content) { if (Path.GetExtension(content.PrimaryFileName).Equals(".xaml", StringComparison.OrdinalIgnoreCase)) { - IEditable editable = content as IEditable; + IEditable editable = content.GetService(); if (editable != null) { try { XmlTextReader r = new XmlTextReader(editable.CreateSnapshot().CreateReader()); diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockTextEditorProviderViewContent.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockTextEditorProviderViewContent.cs index f4a134fdc6..ecb291106f 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockTextEditorProviderViewContent.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockTextEditorProviderViewContent.cs @@ -9,23 +9,14 @@ using ICSharpCode.SharpDevelop.Workbench; namespace XmlEditor.Tests.Utils { - public class MockTextEditorProviderViewContent : MockViewContent, ITextEditorProvider + public class MockTextEditorProviderViewContent : MockViewContent { MockTextEditor textEditor = new MockTextEditor(); - public ITextEditor TextEditor { - get { return textEditor; } - } - public MockTextEditor MockTextEditor { get { return textEditor; } } - public IDocument GetDocumentForFile(OpenedFile file) - { - throw new NotImplementedException(); - } - public override object GetService(Type serviceType) { return textEditor.GetService(serviceType); diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/XPath/RemoveXPathHighlightingCommandTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/XPath/RemoveXPathHighlightingCommandTestFixture.cs index 210f894d70..326a48b80f 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/XPath/RemoveXPathHighlightingCommandTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/XPath/RemoveXPathHighlightingCommandTestFixture.cs @@ -69,11 +69,5 @@ namespace XmlEditor.Tests.XPath { Assert.IsTrue(markerService.TextMarkers.Count() > 0); } - - [Test] - public void MockViewContentDoesNotImplementITextEditorProviderInterface() - { - Assert.IsNull(nonTextEditorProviderView as ITextEditorProvider); - } } } diff --git a/src/AddIns/Misc/AddInManager2/Project/AddInManager2.csproj b/src/AddIns/Misc/AddInManager2/Project/AddInManager2.csproj index 126a60a00e..c9a4c03a72 100644 --- a/src/AddIns/Misc/AddInManager2/Project/AddInManager2.csproj +++ b/src/AddIns/Misc/AddInManager2/Project/AddInManager2.csproj @@ -191,9 +191,7 @@ - - PagedResultsView.xaml - + \ No newline at end of file diff --git a/src/AddIns/Misc/AddinScout/Project/Src/Gui/AddinTreeView.cs b/src/AddIns/Misc/AddinScout/Project/Src/Gui/AddinTreeView.cs index 32ed8003ae..175741f970 100644 --- a/src/AddIns/Misc/AddinScout/Project/Src/Gui/AddinTreeView.cs +++ b/src/AddIns/Misc/AddinScout/Project/Src/Gui/AddinTreeView.cs @@ -26,8 +26,8 @@ namespace AddInScout treeView.ImageList = new ImageList(); treeView.ImageList.ColorDepth = ColorDepth.Depth32Bit; treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.Class")); - treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.Assembly")); - treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.OpenAssembly")); + treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.Collection")); + treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.OpenCollection")); treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.ClosedFolderBitmap")); treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.OpenFolderBitmap")); diff --git a/src/AddIns/Misc/AddinScout/Project/Src/Gui/TreeTreeView.cs b/src/AddIns/Misc/AddinScout/Project/Src/Gui/TreeTreeView.cs index 0434e2de95..f38b842a15 100644 --- a/src/AddIns/Misc/AddinScout/Project/Src/Gui/TreeTreeView.cs +++ b/src/AddIns/Misc/AddinScout/Project/Src/Gui/TreeTreeView.cs @@ -23,8 +23,8 @@ namespace AddInScout treeView.ImageList = new ImageList(); treeView.ImageList.ColorDepth = ColorDepth.Depth32Bit; treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.Class")); - treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.Assembly")); - treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.OpenAssembly")); + treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.Collection")); + treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.OpenCollection")); treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.ClosedFolderBitmap")); treeView.ImageList.Images.Add(IconService.GetBitmap("Icons.16x16.OpenFolderBitmap")); diff --git a/src/AddIns/Misc/SearchAndReplace/Project/Gui/DefaultSearchResult.cs b/src/AddIns/Misc/SearchAndReplace/Project/Gui/DefaultSearchResult.cs index 8e1cdc7838..c03923549a 100644 --- a/src/AddIns/Misc/SearchAndReplace/Project/Gui/DefaultSearchResult.cs +++ b/src/AddIns/Misc/SearchAndReplace/Project/Gui/DefaultSearchResult.cs @@ -87,13 +87,13 @@ namespace SearchAndReplace Button expandAll = new Button(); expandAll.SetValueToExtension(Button.ToolTipProperty, new LocalizeExtension("MainWindow.Windows.SearchResultPanel.ExpandAll.ToolTip")); - expandAll.Content = new Image { Height = 16, Source = PresentationResourceService.GetBitmapSource("Icons.16x16.OpenAssembly") }; + expandAll.Content = new Image { Height = 16, Source = PresentationResourceService.GetBitmapSource("Icons.16x16.OpenCollection") }; expandAll.Click += delegate { ExpandCollapseAll(true); }; toolbarItems.Add(expandAll); Button collapseAll = new Button(); collapseAll.SetValueToExtension(Button.ToolTipProperty, new LocalizeExtension("MainWindow.Windows.SearchResultPanel.CollapseAll.ToolTip")); - collapseAll.Content = new Image { Height = 16, Source = PresentationResourceService.GetBitmapSource("Icons.16x16.Assembly") }; + collapseAll.Content = new Image { Height = 16, Source = PresentationResourceService.GetBitmapSource("Icons.16x16.Collection") }; collapseAll.Click += delegate { ExpandCollapseAll(false); }; toolbarItems.Add(collapseAll); } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Utils/CaretNavigationTests.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Utils/CaretNavigationTests.cs index 8439d5f2ad..366e0671ff 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Utils/CaretNavigationTests.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Utils/CaretNavigationTests.cs @@ -113,5 +113,21 @@ namespace ICSharpCode.AvalonEdit.Utils Assert.AreEqual(5, GetPrevCaretStop(c, 6, CaretPositioningMode.WordBorder)); Assert.AreEqual(1, GetPrevCaretStop(c, 5, CaretPositioningMode.WordBorder)); } + + [Test] + public void CombiningMark() + { + string str = " x͆ "; + Assert.AreEqual(3, GetNextCaretStop(str, 1, CaretPositioningMode.Normal)); + Assert.AreEqual(1, GetPrevCaretStop(str, 3, CaretPositioningMode.Normal)); + } + + [Test] + public void StackedCombiningMark() + { + string str = " x͆͆͆͆ "; + Assert.AreEqual(6, GetNextCaretStop(str, 1, CaretPositioningMode.Normal)); + Assert.AreEqual(1, GetPrevCaretStop(str, 6, CaretPositioningMode.Normal)); + } } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextUtilities.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextUtilities.cs index 9780436238..2da8a9badc 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextUtilities.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextUtilities.cs @@ -14,7 +14,7 @@ namespace ICSharpCode.AvalonEdit.Document public enum CaretPositioningMode { /// - /// Normal positioning (stop at every caret position) + /// Normal positioning (stop after every grapheme) /// Normal, /// @@ -32,7 +32,12 @@ namespace ICSharpCode.AvalonEdit.Document /// /// Stop only on word borders, and anywhere in the middle of symbols. /// - WordBorderOrSymbol + WordBorderOrSymbol, + /// + /// Stop between every Unicode codepoint, even within the same grapheme. + /// This is used to implement deleting the previous grapheme when Backspace is pressed. + /// + EveryCodepoint } /// @@ -199,37 +204,43 @@ namespace ICSharpCode.AvalonEdit.Document { if (c == '\r' || c == '\n') return CharacterClass.LineTerminator; - else if (char.IsWhiteSpace(c)) - return CharacterClass.Whitespace; - else if (char.IsLetterOrDigit(c) || c == '_') + if (c == '_') return CharacterClass.IdentifierPart; - else - return CharacterClass.Other; + return GetCharacterClass(char.GetUnicodeCategory(c)); } static CharacterClass GetCharacterClass(char highSurrogate, char lowSurrogate) { if (char.IsSurrogatePair(highSurrogate, lowSurrogate)) { - switch (char.GetUnicodeCategory(highSurrogate.ToString() + lowSurrogate.ToString(), 0)) { - case UnicodeCategory.SpaceSeparator: - case UnicodeCategory.LineSeparator: - case UnicodeCategory.ParagraphSeparator: - return CharacterClass.Whitespace; - case UnicodeCategory.UppercaseLetter: - case UnicodeCategory.LowercaseLetter: - case UnicodeCategory.TitlecaseLetter: - case UnicodeCategory.ModifierLetter: - case UnicodeCategory.OtherLetter: - case UnicodeCategory.DecimalDigitNumber: - return CharacterClass.IdentifierPart; - default: - return CharacterClass.Other; - } + return GetCharacterClass(char.GetUnicodeCategory(highSurrogate.ToString() + lowSurrogate.ToString(), 0)); } else { // malformed surrogate pair return CharacterClass.Other; } } + + static CharacterClass GetCharacterClass(UnicodeCategory c) + { + switch (c) { + case UnicodeCategory.SpaceSeparator: + case UnicodeCategory.LineSeparator: + case UnicodeCategory.ParagraphSeparator: + return CharacterClass.Whitespace; + case UnicodeCategory.UppercaseLetter: + case UnicodeCategory.LowercaseLetter: + case UnicodeCategory.TitlecaseLetter: + case UnicodeCategory.ModifierLetter: + case UnicodeCategory.OtherLetter: + case UnicodeCategory.DecimalDigitNumber: + return CharacterClass.IdentifierPart; + case UnicodeCategory.NonSpacingMark: + case UnicodeCategory.SpacingCombiningMark: + case UnicodeCategory.EnclosingMark: + return CharacterClass.CombiningMark; + default: + return CharacterClass.Other; + } + } #endregion #region GetNextCaretPosition @@ -251,13 +262,16 @@ namespace ICSharpCode.AvalonEdit.Document { if (textSource == null) throw new ArgumentNullException("textSource"); - if (mode != CaretPositioningMode.Normal - && mode != CaretPositioningMode.WordBorder - && mode != CaretPositioningMode.WordStart - && mode != CaretPositioningMode.WordBorderOrSymbol - && mode != CaretPositioningMode.WordStartOrSymbol) - { - throw new ArgumentException("Unsupported CaretPositioningMode: " + mode, "mode"); + switch (mode) { + case CaretPositioningMode.Normal: + case CaretPositioningMode.EveryCodepoint: + case CaretPositioningMode.WordBorder: + case CaretPositioningMode.WordBorderOrSymbol: + case CaretPositioningMode.WordStart: + case CaretPositioningMode.WordStartOrSymbol: + break; // OK + default: + throw new ArgumentException("Unsupported CaretPositioningMode: " + mode, "mode"); } if (direction != LogicalDirection.Backward && direction != LogicalDirection.Forward) @@ -267,7 +281,7 @@ namespace ICSharpCode.AvalonEdit.Document int textLength = textSource.TextLength; if (textLength <= 0) { // empty document? has a normal caret position at 0, though no word borders - if (mode == CaretPositioningMode.Normal) { + if (IsNormal(mode)) { if (offset > 0 && direction == LogicalDirection.Backward) return 0; if (offset < 0 && direction == LogicalDirection.Forward) return 0; } @@ -286,14 +300,14 @@ namespace ICSharpCode.AvalonEdit.Document if (nextPos == 0) { // at the document start, there's only a word border // if the first character is not whitespace - if (mode == CaretPositioningMode.Normal || !char.IsWhiteSpace(textSource.GetCharAt(0))) + if (IsNormal(mode) || !char.IsWhiteSpace(textSource.GetCharAt(0))) return nextPos; } else if (nextPos == textLength) { // at the document end, there's never a word start if (mode != CaretPositioningMode.WordStart && mode != CaretPositioningMode.WordStartOrSymbol) { // at the document end, there's only a word border // if the last character is not whitespace - if (mode == CaretPositioningMode.Normal || !char.IsWhiteSpace(textSource.GetCharAt(textLength - 1))) + if (IsNormal(mode) || !char.IsWhiteSpace(textSource.GetCharAt(textLength - 1))) return nextPos; } } else { @@ -320,9 +334,19 @@ namespace ICSharpCode.AvalonEdit.Document } } + static bool IsNormal(CaretPositioningMode mode) + { + return mode == CaretPositioningMode.Normal || mode == CaretPositioningMode.EveryCodepoint; + } + static bool StopBetweenCharacters(CaretPositioningMode mode, CharacterClass charBefore, CharacterClass charAfter) { - // Stop after every character in normal mode + if (mode == CaretPositioningMode.EveryCodepoint) + return true; + // Don't stop in the middle of a grapheme + if (charAfter == CharacterClass.CombiningMark) + return false; + // Stop after every grapheme in normal mode if (mode == CaretPositioningMode.Normal) return true; if (charBefore == charAfter) { @@ -370,6 +394,11 @@ namespace ICSharpCode.AvalonEdit.Document /// /// The character is line terminator (\r or \n). /// - LineTerminator + LineTerminator, + /// + /// The character is a unicode combining mark that modifies the previous character. + /// Corresponds to the Unicode designations "Mn", "Mc" and "Me". + /// + CombiningMark } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/CaretNavigationCommandHandler.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/CaretNavigationCommandHandler.cs index 8c0774d60f..03a4598beb 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/CaretNavigationCommandHandler.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/CaretNavigationCommandHandler.cs @@ -15,6 +15,24 @@ using ICSharpCode.AvalonEdit.Utils; namespace ICSharpCode.AvalonEdit.Editing { + enum CaretMovementType + { + None, + CharLeft, + CharRight, + Backspace, + WordLeft, + WordRight, + LineUp, + LineDown, + PageUp, + PageDown, + LineStart, + LineEnd, + DocumentStart, + DocumentEnd + } + static class CaretNavigationCommandHandler { /// @@ -102,22 +120,6 @@ namespace ICSharpCode.AvalonEdit.Editing return target as TextArea; } - enum CaretMovementType - { - CharLeft, - CharRight, - WordLeft, - WordRight, - LineUp, - LineDown, - PageUp, - PageDown, - LineStart, - LineEnd, - DocumentStart, - DocumentEnd - } - static ExecutedRoutedEventHandler OnMoveCaret(CaretMovementType direction) { return (target, args) => { @@ -140,8 +142,7 @@ namespace ICSharpCode.AvalonEdit.Editing TextViewPosition oldPosition = textArea.Caret.Position; MoveCaret(textArea, direction); textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position); - if (!textArea.Document.IsInUpdate) // if we're inside a larger update (e.g. called by EditingCommandHandler.OnDelete()), avoid calculating the caret rectangle now - textArea.Caret.BringCaretToView(); + textArea.Caret.BringCaretToView(); } }; } @@ -172,43 +173,55 @@ namespace ICSharpCode.AvalonEdit.Editing } #region Caret movement - static void MoveCaret(TextArea textArea, CaretMovementType direction) + internal static void MoveCaret(TextArea textArea, CaretMovementType direction) { - DocumentLine caretLine = textArea.Document.GetLineByNumber(textArea.Caret.Line); - VisualLine visualLine = textArea.TextView.GetOrConstructVisualLine(caretLine); - TextViewPosition caretPosition = textArea.Caret.Position; + double desiredXPos = textArea.Caret.DesiredXPos; + textArea.Caret.Position = GetNewCaretPosition(textArea.TextView, textArea.Caret.Position, direction, textArea.Selection.EnableVirtualSpace, ref desiredXPos); + textArea.Caret.DesiredXPos = desiredXPos; + } + + internal static TextViewPosition GetNewCaretPosition(TextView textView, TextViewPosition caretPosition, CaretMovementType direction, bool enableVirtualSpace, ref double desiredXPos) + { + switch (direction) { + case CaretMovementType.None: + return caretPosition; + case CaretMovementType.DocumentStart: + desiredXPos = double.NaN; + return new TextViewPosition(0, 0); + case CaretMovementType.DocumentEnd: + desiredXPos = double.NaN; + return new TextViewPosition(textView.Document.GetLocation(textView.Document.TextLength)); + } + DocumentLine caretLine = textView.Document.GetLineByNumber(caretPosition.Line); + VisualLine visualLine = textView.GetOrConstructVisualLine(caretLine); TextLine textLine = visualLine.GetTextLine(caretPosition.VisualColumn, caretPosition.IsAtEndOfLine); switch (direction) { case CaretMovementType.CharLeft: - MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.Normal); - break; + desiredXPos = double.NaN; + return GetPrevCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.Normal, enableVirtualSpace); + case CaretMovementType.Backspace: + desiredXPos = double.NaN; + return GetPrevCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.EveryCodepoint, enableVirtualSpace); case CaretMovementType.CharRight: - MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.Normal); - break; + desiredXPos = double.NaN; + return GetNextCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.Normal, enableVirtualSpace); case CaretMovementType.WordLeft: - MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart); - break; + desiredXPos = double.NaN; + return GetPrevCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.WordStart, enableVirtualSpace); case CaretMovementType.WordRight: - MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart); - break; + desiredXPos = double.NaN; + return GetNextCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.WordStart, enableVirtualSpace); case CaretMovementType.LineUp: case CaretMovementType.LineDown: case CaretMovementType.PageUp: case CaretMovementType.PageDown: - MoveCaretUpDown(textArea, direction, visualLine, textLine, caretPosition.VisualColumn); - break; - case CaretMovementType.DocumentStart: - SetCaretPosition(textArea, 0, 0); - break; - case CaretMovementType.DocumentEnd: - SetCaretPosition(textArea, -1, textArea.Document.TextLength); - break; + return GetUpDownCaretPosition(textView, caretPosition, direction, visualLine, textLine, enableVirtualSpace, ref desiredXPos); case CaretMovementType.LineStart: - MoveCaretToStartOfLine(textArea, visualLine, textLine); - break; + desiredXPos = double.NaN; + return GetStartOfLineCaretPosition(caretPosition.VisualColumn, visualLine, textLine, enableVirtualSpace); case CaretMovementType.LineEnd: - MoveCaretToEndOfLine(textArea, visualLine, textLine); - break; + desiredXPos = double.NaN; + return GetEndOfLineCaretPosition(visualLine, textLine); default: throw new NotSupportedException(direction.ToString()); } @@ -216,81 +229,80 @@ namespace ICSharpCode.AvalonEdit.Editing #endregion #region Home/End - static void MoveCaretToStartOfLine(TextArea textArea, VisualLine visualLine, TextLine textLine) + static TextViewPosition GetStartOfLineCaretPosition(int oldVC, VisualLine visualLine, TextLine textLine, bool enableVirtualSpace) { int newVC = visualLine.GetTextLineVisualStartColumn(textLine); if (newVC == 0) - newVC = visualLine.GetNextCaretPosition(newVC - 1, LogicalDirection.Forward, CaretPositioningMode.WordStart, textArea.Selection.EnableVirtualSpace); + newVC = visualLine.GetNextCaretPosition(newVC - 1, LogicalDirection.Forward, CaretPositioningMode.WordStart, enableVirtualSpace); if (newVC < 0) throw ThrowUtil.NoValidCaretPosition(); // when the caret is already at the start of the text, jump to start before whitespace - if (newVC == textArea.Caret.VisualColumn) + if (newVC == oldVC) newVC = 0; - int offset = visualLine.FirstDocumentLine.Offset + visualLine.GetRelativeOffset(newVC); - SetCaretPosition(textArea, newVC, offset); + return visualLine.GetTextViewPosition(newVC); } - static void MoveCaretToEndOfLine(TextArea textArea, VisualLine visualLine, TextLine textLine) + static TextViewPosition GetEndOfLineCaretPosition(VisualLine visualLine, TextLine textLine) { int newVC = visualLine.GetTextLineVisualStartColumn(textLine) + textLine.Length - textLine.TrailingWhitespaceLength; - int offset = visualLine.FirstDocumentLine.Offset + visualLine.GetRelativeOffset(newVC); - SetCaretPosition(textArea, newVC, offset, isAtEndOfLine: true); + TextViewPosition pos = visualLine.GetTextViewPosition(newVC); + pos.IsAtEndOfLine = true; + return pos; } #endregion #region By-character / By-word movement - static void MoveCaretRight(TextArea textArea, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode) + static TextViewPosition GetNextCaretPosition(TextView textView, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode, bool enableVirtualSpace) { - int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Forward, mode, textArea.Selection.EnableVirtualSpace); + int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Forward, mode, enableVirtualSpace); if (pos >= 0) { - SetCaretPosition(textArea, pos, visualLine.GetRelativeOffset(pos) + visualLine.FirstDocumentLine.Offset); + return visualLine.GetTextViewPosition(pos); } else { // move to start of next line DocumentLine nextDocumentLine = visualLine.LastDocumentLine.NextLine; if (nextDocumentLine != null) { - VisualLine nextLine = textArea.TextView.GetOrConstructVisualLine(nextDocumentLine); - pos = nextLine.GetNextCaretPosition(-1, LogicalDirection.Forward, mode, textArea.Selection.EnableVirtualSpace); + VisualLine nextLine = textView.GetOrConstructVisualLine(nextDocumentLine); + pos = nextLine.GetNextCaretPosition(-1, LogicalDirection.Forward, mode, enableVirtualSpace); if (pos < 0) throw ThrowUtil.NoValidCaretPosition(); - SetCaretPosition(textArea, pos, nextLine.GetRelativeOffset(pos) + nextLine.FirstDocumentLine.Offset); + return nextLine.GetTextViewPosition(pos); } else { // at end of document - Debug.Assert(visualLine.LastDocumentLine.Offset + visualLine.LastDocumentLine.TotalLength == textArea.Document.TextLength); - SetCaretPosition(textArea, -1, textArea.Document.TextLength); + Debug.Assert(visualLine.LastDocumentLine.Offset + visualLine.LastDocumentLine.TotalLength == textView.Document.TextLength); + return new TextViewPosition(textView.Document.GetLocation(textView.Document.TextLength)); } } } - static void MoveCaretLeft(TextArea textArea, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode) + static TextViewPosition GetPrevCaretPosition(TextView textView, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode, bool enableVirtualSpace) { - int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Backward, mode, textArea.Selection.EnableVirtualSpace); + int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Backward, mode, enableVirtualSpace); if (pos >= 0) { - SetCaretPosition(textArea, pos, visualLine.GetRelativeOffset(pos) + visualLine.FirstDocumentLine.Offset); + return visualLine.GetTextViewPosition(pos); } else { // move to end of previous line DocumentLine previousDocumentLine = visualLine.FirstDocumentLine.PreviousLine; if (previousDocumentLine != null) { - VisualLine previousLine = textArea.TextView.GetOrConstructVisualLine(previousDocumentLine); - pos = previousLine.GetNextCaretPosition(previousLine.VisualLength + 1, LogicalDirection.Backward, mode, textArea.Selection.EnableVirtualSpace); + VisualLine previousLine = textView.GetOrConstructVisualLine(previousDocumentLine); + pos = previousLine.GetNextCaretPosition(previousLine.VisualLength + 1, LogicalDirection.Backward, mode, enableVirtualSpace); if (pos < 0) throw ThrowUtil.NoValidCaretPosition(); - SetCaretPosition(textArea, pos, previousLine.GetRelativeOffset(pos) + previousLine.FirstDocumentLine.Offset); + return previousLine.GetTextViewPosition(pos); } else { // at start of document Debug.Assert(visualLine.FirstDocumentLine.Offset == 0); - SetCaretPosition(textArea, 0, 0); + return new TextViewPosition(0, 0); } } } #endregion #region Line+Page up/down - static void MoveCaretUpDown(TextArea textArea, CaretMovementType direction, VisualLine visualLine, TextLine textLine, int caretVisualColumn) + static TextViewPosition GetUpDownCaretPosition(TextView textView, TextViewPosition caretPosition, CaretMovementType direction, VisualLine visualLine, TextLine textLine, bool enableVirtualSpace, ref double xPos) { // moving up/down happens using the desired visual X position - double xPos = textArea.Caret.DesiredXPos; if (double.IsNaN(xPos)) - xPos = visualLine.GetTextLineVisualXPosition(textLine, caretVisualColumn); + xPos = visualLine.GetTextLineVisualXPosition(textLine, caretPosition.VisualColumn); // now find the TextLine+VisualLine where the caret will end up in VisualLine targetVisualLine = visualLine; TextLine targetLine; @@ -304,8 +316,8 @@ namespace ICSharpCode.AvalonEdit.Editing if (textLineIndex > 0) { targetLine = visualLine.TextLines[textLineIndex - 1]; } else if (prevLineNumber >= 1) { - DocumentLine prevLine = textArea.Document.GetLineByNumber(prevLineNumber); - targetVisualLine = textArea.TextView.GetOrConstructVisualLine(prevLine); + DocumentLine prevLine = textView.Document.GetLineByNumber(prevLineNumber); + targetVisualLine = textView.GetOrConstructVisualLine(prevLine); targetLine = targetVisualLine.TextLines[targetVisualLine.TextLines.Count - 1]; } else { targetLine = null; @@ -319,9 +331,9 @@ namespace ICSharpCode.AvalonEdit.Editing int nextLineNumber = visualLine.LastDocumentLine.LineNumber + 1; if (textLineIndex < visualLine.TextLines.Count - 1) { targetLine = visualLine.TextLines[textLineIndex + 1]; - } else if (nextLineNumber <= textArea.Document.LineCount) { - DocumentLine nextLine = textArea.Document.GetLineByNumber(nextLineNumber); - targetVisualLine = textArea.TextView.GetOrConstructVisualLine(nextLine); + } else if (nextLineNumber <= textView.Document.LineCount) { + DocumentLine nextLine = textView.Document.GetLineByNumber(nextLineNumber); + targetVisualLine = textView.GetOrConstructVisualLine(nextLine); targetLine = targetVisualLine.TextLines[0]; } else { targetLine = null; @@ -334,11 +346,11 @@ namespace ICSharpCode.AvalonEdit.Editing // Page up/down: find the target line using its visual position double yPos = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.LineMiddle); if (direction == CaretMovementType.PageUp) - yPos -= textArea.TextView.RenderSize.Height; + yPos -= textView.RenderSize.Height; else - yPos += textArea.TextView.RenderSize.Height; - DocumentLine newLine = textArea.TextView.GetDocumentLineByVisualTop(yPos); - targetVisualLine = textArea.TextView.GetOrConstructVisualLine(newLine); + yPos += textView.RenderSize.Height; + DocumentLine newLine = textView.GetDocumentLineByVisualTop(yPos); + targetVisualLine = textView.GetOrConstructVisualLine(newLine); targetLine = targetVisualLine.GetTextLineByVisualYPosition(yPos); break; } @@ -347,30 +359,18 @@ namespace ICSharpCode.AvalonEdit.Editing } if (targetLine != null) { double yPos = targetVisualLine.GetTextLineVisualYPosition(targetLine, VisualYPosition.LineMiddle); - int newVisualColumn = targetVisualLine.GetVisualColumn(new Point(xPos, yPos), textArea.Selection.EnableVirtualSpace); - SetCaretPosition(textArea, targetVisualLine, targetLine, newVisualColumn, false); - textArea.Caret.DesiredXPos = xPos; - } - } - #endregion - - #region SetCaretPosition - static void SetCaretPosition(TextArea textArea, VisualLine targetVisualLine, TextLine targetLine, - int newVisualColumn, bool allowWrapToNextLine) - { - int targetLineStartCol = targetVisualLine.GetTextLineVisualStartColumn(targetLine); - if (!allowWrapToNextLine && newVisualColumn >= targetLineStartCol + targetLine.Length) { - if (newVisualColumn <= targetVisualLine.VisualLength) - newVisualColumn = targetLineStartCol + targetLine.Length - 1; + int newVisualColumn = targetVisualLine.GetVisualColumn(new Point(xPos, yPos), enableVirtualSpace); + + // prevent wrapping to the next line; TODO: could 'IsAtEnd' help here? + int targetLineStartCol = targetVisualLine.GetTextLineVisualStartColumn(targetLine); + if (newVisualColumn >= targetLineStartCol + targetLine.Length) { + if (newVisualColumn <= targetVisualLine.VisualLength) + newVisualColumn = targetLineStartCol + targetLine.Length - 1; + } + return targetVisualLine.GetTextViewPosition(newVisualColumn); + } else { + return caretPosition; } - int newOffset = targetVisualLine.GetRelativeOffset(newVisualColumn) + targetVisualLine.FirstDocumentLine.Offset; - SetCaretPosition(textArea, newVisualColumn, newOffset); - } - - static void SetCaretPosition(TextArea textArea, int newVisualColumn, int newOffset, bool isAtEndOfLine = false) - { - textArea.Caret.Position = new TextViewPosition(textArea.Document.GetLocation(newOffset), newVisualColumn) { IsAtEndOfLine = isAtEndOfLine }; - textArea.Caret.DesiredXPos = double.NaN; } #endregion } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs index f7cbb167ff..204489208e 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs @@ -46,12 +46,12 @@ namespace ICSharpCode.AvalonEdit.Editing static EditingCommandHandler() { - CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, OnDelete(ApplicationCommands.NotACommand), CanDelete)); - AddBinding(EditingCommands.Delete, ModifierKeys.None, Key.Delete, OnDelete(EditingCommands.SelectRightByCharacter)); - AddBinding(EditingCommands.DeleteNextWord, ModifierKeys.Control, Key.Delete, OnDelete(EditingCommands.SelectRightByWord)); - AddBinding(EditingCommands.Backspace, ModifierKeys.None, Key.Back, OnDelete(EditingCommands.SelectLeftByCharacter)); + CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, OnDelete(CaretMovementType.None), CanDelete)); + AddBinding(EditingCommands.Delete, ModifierKeys.None, Key.Delete, OnDelete(CaretMovementType.CharRight)); + AddBinding(EditingCommands.DeleteNextWord, ModifierKeys.Control, Key.Delete, OnDelete(CaretMovementType.WordRight)); + AddBinding(EditingCommands.Backspace, ModifierKeys.None, Key.Back, OnDelete(CaretMovementType.Backspace)); InputBindings.Add(TextAreaDefaultInputHandler.CreateFrozenKeyBinding(EditingCommands.Backspace, ModifierKeys.Shift, Key.Back)); // make Shift-Backspace do the same as plain backspace - AddBinding(EditingCommands.DeletePreviousWord, ModifierKeys.Control, Key.Back, OnDelete(EditingCommands.SelectLeftByWord)); + AddBinding(EditingCommands.DeletePreviousWord, ModifierKeys.Control, Key.Back, OnDelete(CaretMovementType.WordLeft)); AddBinding(EditingCommands.EnterParagraphBreak, ModifierKeys.None, Key.Enter, OnEnter); AddBinding(EditingCommands.EnterLineBreak, ModifierKeys.Shift, Key.Enter, OnEnter); AddBinding(EditingCommands.TabForward, ModifierKeys.None, Key.Tab, OnTab); @@ -225,34 +225,24 @@ namespace ICSharpCode.AvalonEdit.Editing #endregion #region Delete - static ExecutedRoutedEventHandler OnDelete(RoutedUICommand selectingCommand) + static ExecutedRoutedEventHandler OnDelete(CaretMovementType caretMovement) { return (target, args) => { TextArea textArea = GetTextArea(target); if (textArea != null && textArea.Document != null) { - // call BeginUpdate before running the 'selectingCommand' - // so that undoing the delete does not select the deleted character - using (textArea.Document.RunUpdate()) { - if (textArea.Selection.IsEmpty) { - TextViewPosition oldCaretPosition = textArea.Caret.Position; - if (textArea.Caret.IsInVirtualSpace && selectingCommand == EditingCommands.SelectRightByCharacter) - EditingCommands.SelectRightByWord.Execute(args.Parameter, textArea); - else - selectingCommand.Execute(args.Parameter, textArea); - bool hasSomethingDeletable = false; - foreach (ISegment s in textArea.Selection.Segments) { - if (textArea.GetDeletableSegments(s).Length > 0) { - hasSomethingDeletable = true; - break; - } - } - if (!hasSomethingDeletable) { - // If nothing in the selection is deletable; then reset caret+selection - // to the previous value. This prevents the caret from moving through read-only sections. - textArea.Caret.Position = oldCaretPosition; - textArea.ClearSelection(); - } - } + if (textArea.Selection.IsEmpty) { + TextViewPosition startPos = textArea.Caret.Position; + bool enableVirtualSpace = textArea.Options.EnableVirtualSpace; + // When pressing delete; don't move the caret further into virtual space - instead delete the newline + if (caretMovement == CaretMovementType.CharRight) + enableVirtualSpace = false; + double desiredXPos = textArea.Caret.DesiredXPos; + TextViewPosition endPos = CaretNavigationCommandHandler.GetNewCaretPosition( + textArea.TextView, startPos, caretMovement, enableVirtualSpace, ref desiredXPos); + // Don't select the text to be deleted; just reuse the ReplaceSelectionWithText logic + var sel = new SimpleSelection(textArea, startPos, endPos); + sel.ReplaceSelectionWithText(string.Empty); + } else { textArea.RemoveSelectedText(); } textArea.Caret.BringCaretToView(); diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs index 5f053b08ac..76e48d2cf6 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs @@ -55,10 +55,16 @@ namespace ICSharpCode.AvalonEdit.Editing if (segmentsToDelete[i].Offset == SurroundingSegment.Offset && segmentsToDelete[i].Length == SurroundingSegment.Length) { newText = AddSpacesIfRequired(newText, start, end); } - int vc = textArea.Caret.VisualColumn; - textArea.Caret.Offset = segmentsToDelete[i].EndOffset; - if (string.IsNullOrEmpty(newText)) - textArea.Caret.VisualColumn = vc; + if (string.IsNullOrEmpty(newText)) { + // place caret at the beginning of the selection + if (start.CompareTo(end) <= 0) + textArea.Caret.Position = start; + else + textArea.Caret.Position = end; + } else { + // place caret so that it ends up behind the new text + textArea.Caret.Offset = segmentsToDelete[i].EndOffset; + } textArea.Document.Replace(segmentsToDelete[i], newText); } else { textArea.Document.Remove(segmentsToDelete[i]); @@ -100,7 +106,7 @@ namespace ICSharpCode.AvalonEdit.Editing /// public override bool IsEmpty { - get { return startOffset == endOffset; } + get { return startOffset == endOffset && start.VisualColumn == end.VisualColumn; } } /// diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs index b1cf4e6b8b..46a600bf69 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs @@ -111,7 +111,7 @@ namespace ICSharpCode.AvalonEdit.Rendering public override int GetNextCaretPosition(int visualColumn, LogicalDirection direction, CaretPositioningMode mode) { - if (mode == CaretPositioningMode.Normal) + if (mode == CaretPositioningMode.Normal || mode == CaretPositioningMode.EveryCodepoint) return base.GetNextCaretPosition(visualColumn, direction, mode); else return -1; @@ -146,7 +146,7 @@ namespace ICSharpCode.AvalonEdit.Rendering public override int GetNextCaretPosition(int visualColumn, LogicalDirection direction, CaretPositioningMode mode) { - if (mode == CaretPositioningMode.Normal) + if (mode == CaretPositioningMode.Normal || mode == CaretPositioningMode.EveryCodepoint) return base.GetNextCaretPosition(visualColumn, direction, mode); else return -1; diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs index 76d6e657c1..f1e437588e 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs @@ -548,6 +548,15 @@ namespace ICSharpCode.AvalonEdit.Rendering return ch.FirstCharacterIndex; } + /// + /// Gets the text view position from the specified visual column. + /// + public TextViewPosition GetTextViewPosition(int visualColumn) + { + int documentOffset = GetRelativeOffset(visualColumn) + this.FirstDocumentLine.Offset; + return new TextViewPosition(this.Document.GetLocation(documentOffset), visualColumn); + } + /// /// Gets the text view position from the specified visual position. /// If the position is within a character, it is rounded to the next character boundary. @@ -690,12 +699,12 @@ namespace ICSharpCode.AvalonEdit.Rendering static bool HasStopsInVirtualSpace(CaretPositioningMode mode) { - return mode == CaretPositioningMode.Normal; + return mode == CaretPositioningMode.Normal || mode == CaretPositioningMode.EveryCodepoint; } static bool HasImplicitStopAtLineStart(CaretPositioningMode mode) { - return mode == CaretPositioningMode.Normal; + return mode == CaretPositioningMode.Normal || mode == CaretPositioningMode.EveryCodepoint; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "mode", diff --git a/src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeView.cs b/src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeView.cs index 9b3f1a76f9..5e1f073eea 100644 --- a/src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeView.cs +++ b/src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeView.cs @@ -239,11 +239,20 @@ namespace ICSharpCode.TreeView } break; case Key.Return: - case Key.Space: if (container != null && Keyboard.Modifiers == ModifierKeys.None && this.SelectedItems.Count == 1 && this.SelectedItem == container.Node) { container.Node.ActivateItem(e); } break; + case Key.Space: + if (container != null && Keyboard.Modifiers == ModifierKeys.None && this.SelectedItems.Count == 1 && this.SelectedItem == container.Node) { + if(container.Node.IsCheckable) { + if(container.Node.IsChecked == null) // If partially selected, we want to select everything + container.Node.IsChecked = true; + else + container.Node.IsChecked = !container.Node.IsChecked; + } + } + break; case Key.Add: if (container != null && ItemsControl.ItemsControlFromItemContainer(container) == this) { container.Node.IsExpanded = true; diff --git a/src/Main/Base/Project/Dom/ClassBrowser/AssemblyTreeNode.cs b/src/Main/Base/Project/Dom/ClassBrowser/AssemblyTreeNode.cs index 28e67cd2db..ff499c969f 100644 --- a/src/Main/Base/Project/Dom/ClassBrowser/AssemblyTreeNode.cs +++ b/src/Main/Base/Project/Dom/ClassBrowser/AssemblyTreeNode.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using ICSharpCode.Core.Presentation; using ICSharpCode.TreeView; namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -43,7 +44,19 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser public override object Icon { get { - return base.Icon; + if (model.Context.IsValid) { + return SD.ResourceService.GetImageSource("Icons.16x16.Assembly"); + } else { + return SD.ResourceService.GetImageSource("Icons.16x16.AssemblyError"); + } + } + } + + public override void ShowContextMenu() + { + var assemblyModel = this.Model as IAssemblyModel; + if (assemblyModel != null) { + var ctx = MenuService.ShowContextMenu(null, assemblyModel, "/SharpDevelop/Pads/ClassBrowser/AssemblyContextMenu"); } } } diff --git a/src/Main/Base/Project/Dom/ClassBrowser/TypeDefinitionTreeNode.cs b/src/Main/Base/Project/Dom/ClassBrowser/TypeDefinitionTreeNode.cs index d1a36f5d9b..7141734783 100644 --- a/src/Main/Base/Project/Dom/ClassBrowser/TypeDefinitionTreeNode.cs +++ b/src/Main/Base/Project/Dom/ClassBrowser/TypeDefinitionTreeNode.cs @@ -5,12 +5,14 @@ using System; using System.Collections.Generic; using ICSharpCode.Core.Presentation; using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.Utils; using ICSharpCode.TreeView; namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser { public class TypeDefinitionTreeNode : ModelCollectionTreeNode { + static readonly IComparer TypeMemberNodeComparer = new TypeDefinitionMemberNodeComparer(); ITypeDefinitionModel definition; public TypeDefinitionTreeNode(ITypeDefinitionModel definition) @@ -40,7 +42,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser protected override IComparer NodeComparer { get { - return NodeTextComparer; + return TypeMemberNodeComparer; } } @@ -64,6 +66,29 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser var ctx = MenuService.ShowContextMenu(null, entityModel, "/SharpDevelop/EntityContextMenu"); } } + + class TypeDefinitionMemberNodeComparer : IComparer + { + public int Compare(SharpTreeNode x, SharpTreeNode y) + { + var a = x.Model as IMemberModel; + var b = y.Model as IMemberModel; + + if (a == null && b == null) + return NodeTextComparer.Compare(x, y); + if (a == null) + return -1; + if (b == null) + return 1; + + if (a.SymbolKind < b.SymbolKind) + return -1; + if (a.SymbolKind > b.SymbolKind) + return 1; + + return NodeTextComparer.Compare(x, y); + } + } } } diff --git a/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs b/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs index 9eb0abb97a..0a7117eb12 100644 --- a/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs +++ b/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using ICSharpCode.NRefactory.Utils; using ICSharpCode.TreeView; namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -13,7 +14,25 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser /// public class WorkspaceTreeNode : ModelCollectionTreeNode { + class WorkspaceChildComparer : IComparer + { + IComparer stringComparer = StringComparer.OrdinalIgnoreCase; + + public int Compare(SharpTreeNode x, SharpTreeNode y) + { + // Solution node has precedence over other nodes + if ((x is SolutionTreeNode) && !(y is SolutionTreeNode)) + return -1; + if (!(x is SolutionTreeNode) && (y is SolutionTreeNode)) + return 1; + + // Both nodes are solutions or not solutions, compare their Text property + return stringComparer.Compare(x.Text.ToString(), y.Text.ToString()); + } + } + WorkspaceModel workspace; + protected static readonly IComparer ChildNodeComparer = new WorkspaceChildComparer(); public IMutableModelCollection SpecialNodes { get { return workspace.SpecialNodes; } @@ -40,7 +59,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser } protected override IComparer NodeComparer { - get { return NodeTextComparer; } + get { return ChildNodeComparer; } } public override object Text { @@ -51,7 +70,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser public override object Icon { get { - return SD.ResourceService.GetImageSource("PadIcons.ClassBrowser"); + return SD.ResourceService.GetImageSource("Icons.16x16.Workspace"); } } @@ -62,7 +81,9 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser protected override void InsertSpecialNodes() { - Children.AddRange(workspace.SpecialNodes); + foreach (var node in workspace.SpecialNodes) { + Children.OrderedInsert(node, ChildNodeComparer); + } } void SpecialNodesModelCollectionChanged(IReadOnlyCollection removedItems, IReadOnlyCollection addedItems) diff --git a/src/Main/Base/Project/Dom/IAssemblyModel.cs b/src/Main/Base/Project/Dom/IAssemblyModel.cs index 11a081dd01..f3df5c2589 100644 --- a/src/Main/Base/Project/Dom/IAssemblyModel.cs +++ b/src/Main/Base/Project/Dom/IAssemblyModel.cs @@ -42,6 +42,11 @@ namespace ICSharpCode.SharpDevelop.Dom /// This always is the namespace without a name - it's unrelated to the 'root namespace' project setting. /// INamespaceModel RootNamespace { get; } + + /// + /// Gets the of this assembly model. + /// + IEntityModelContext Context { get; } } /// @@ -92,6 +97,12 @@ namespace ICSharpCode.SharpDevelop.Dom public INamespaceModel RootNamespace { get { return EmptyNamespaceModel.Instance; } } + + public IEntityModelContext Context { + get { + return null; + } + } } } diff --git a/src/Main/Base/Project/Dom/IEntityModelContext.cs b/src/Main/Base/Project/Dom/IEntityModelContext.cs index 5fe67f32e4..542c87d107 100644 --- a/src/Main/Base/Project/Dom/IEntityModelContext.cs +++ b/src/Main/Base/Project/Dom/IEntityModelContext.cs @@ -34,6 +34,21 @@ namespace ICSharpCode.SharpDevelop.Dom /// Returns true if part1 is considered a better candidate for the primary part than part2. /// bool IsBetterPart(IUnresolvedTypeDefinition part1, IUnresolvedTypeDefinition part2); + + /// + /// Short name of current assembly. + /// + string AssemblyName { get; } + + /// + /// Full path and file name of the assembly. Output assembly for projects. + /// + string Location { get; } + + /// + /// Returns whether this is a valid context (based on a existing and readable definition). + /// + bool IsValid { get; } } public class ProjectEntityModelContext : IEntityModelContext @@ -53,6 +68,10 @@ namespace ICSharpCode.SharpDevelop.Dom get { return project.AssemblyName; } } + public string Location { + get { return project.OutputAssemblyFullPath; } + } + public IProject Project { get { return project; } } @@ -66,6 +85,10 @@ namespace ICSharpCode.SharpDevelop.Dom { return EntityModelContextUtils.IsBetterPart(part1, part2, primaryCodeFileExtension); } + + public bool IsValid { + get { return true; } + } } public class AssemblyEntityModelContext : IEntityModelContext @@ -88,6 +111,10 @@ namespace ICSharpCode.SharpDevelop.Dom get { return mainAssembly.AssemblyName; } } + public string Location { + get { return mainAssembly.Location; } + } + public ICompilation GetCompilation() { return compilation; @@ -101,6 +128,10 @@ namespace ICSharpCode.SharpDevelop.Dom public IProject Project { get { return null; } } + + public bool IsValid { + get { return true; } + } } public static class EntityModelContextUtils diff --git a/src/Main/Base/Project/Editor/Bookmarks/BookmarkPad.cs b/src/Main/Base/Project/Editor/Bookmarks/BookmarkPad.cs index 67995138de..b18fc2fdcb 100644 --- a/src/Main/Base/Project/Editor/Bookmarks/BookmarkPad.cs +++ b/src/Main/Base/Project/Editor/Bookmarks/BookmarkPad.cs @@ -69,6 +69,16 @@ namespace ICSharpCode.SharpDevelop.Editor.Bookmarks if (bm != null) OnItemActivated(bm); }; + + this.control.listView.KeyDown += delegate(object sender, System.Windows.Input.KeyEventArgs e) { + SDBookmark bm = this.control.listView.SelectedItem as SDBookmark; + if (bm == null) return; + switch (e.Key) { + case System.Windows.Input.Key.Delete: + SD.BookmarkManager.RemoveMark(bm); + break; + } + }; } public override void Dispose() diff --git a/src/Main/Base/Project/Editor/CodeCompletion/SnippetCompletionData.cs b/src/Main/Base/Project/Editor/CodeCompletion/SnippetCompletionData.cs new file mode 100644 index 0000000000..97758c305e --- /dev/null +++ b/src/Main/Base/Project/Editor/CodeCompletion/SnippetCompletionData.cs @@ -0,0 +1,110 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.Completion; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; + +namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion +{ + /// + /// Code completion data for snippets. + /// + public class SnippetCompletionData : IFancyCompletionItem, ISnippetCompletionItem, ICompletionData, ICompletionItem + { + #region ICompletionData implementation + + void ICompletionData.AddOverload(ICompletionData data) { } + + CompletionCategory category; + CompletionCategory ICompletionData.CompletionCategory { + get { return category; } + set { category = value; } + } + + string ICompletionData.DisplayText { + get { return snippet.Text; } + set { } + } + + string ICompletionData.Description { + get { return snippet.Description; } + set { } + } + + string ICompletionData.CompletionText { + get { return snippet.Text; } + set { } + } + + DisplayFlags displayFlags; + DisplayFlags ICompletionData.DisplayFlags { + get { return displayFlags; } + set { displayFlags = value; } + } + + bool ICompletionData.HasOverloads { + get { return false; } + } + + System.Collections.Generic.IEnumerable ICompletionData.OverloadedData { + get { return EmptyList.Instance; } + } + + #endregion + + ISnippetCompletionItem snippet; + + public SnippetCompletionData(ISnippetCompletionItem completionItem) + { + snippet = completionItem; + } + + #region ISnippetCompletionItem implementation + + public string Keyword { + get { return snippet.Keyword; } + } + + #endregion + + #region ICompletionItem implementation + + public void Complete(CompletionContext context) + { + snippet.Complete(context); + } + + public string Text { + get { return snippet.Text; } + } + + string ICompletionItem.Description { + get { return snippet.Description; } + } + + public ICSharpCode.SharpDevelop.IImage Image { + get { return snippet.Image; } + } + + public double Priority { + get { return snippet.Priority; } + } + + #endregion + + #region IFancyCompletionItem implementation + + public object Content { + get { return snippet.Text; } + } + + public object Description { + get { return snippet.Description; } + } + + #endregion + + } +} diff --git a/src/Main/Base/Project/Editor/ITextEditor.cs b/src/Main/Base/Project/Editor/ITextEditor.cs index 583a956265..4e696e31ef 100644 --- a/src/Main/Base/Project/Editor/ITextEditor.cs +++ b/src/Main/Base/Project/Editor/ITextEditor.cs @@ -13,15 +13,6 @@ using ICSharpCode.SharpDevelop.Refactoring; namespace ICSharpCode.SharpDevelop.Editor { - [ViewContentService] - public interface ITextEditorProvider : IFileDocumentProvider - { - [Obsolete("Use viewContent.GetService() instead.")] - ITextEditor TextEditor { - get; - } - } - /// /// Interface for text editors. /// diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin index 984f5175ad..ba134100d2 100755 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin @@ -238,7 +238,7 @@ class = "ICSharpCode.SharpDevelop.Project.Commands.RefreshProjectBrowser"/> @@ -908,7 +908,7 @@ - - + --> - + + + + @@ -979,6 +988,13 @@ class = "ICSharpCode.SharpDevelop.Gui.ClassBrowser.ClassBrowserCancelSearch"/> + + + + @@ -1905,10 +1921,6 @@ shortcut = "Shift|Control|Tab" class = "ICSharpCode.SharpDevelop.Commands.SelectPrevWindow" /> - diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index e859ed1fc5..c787f8550f 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -126,6 +126,7 @@ + diff --git a/src/Main/Base/Project/Src/Commands/SharpDevelopRoutedCommands.cs b/src/Main/Base/Project/Src/Commands/SharpDevelopRoutedCommands.cs index e63872269b..d365c4eeb8 100644 --- a/src/Main/Base/Project/Src/Commands/SharpDevelopRoutedCommands.cs +++ b/src/Main/Base/Project/Src/Commands/SharpDevelopRoutedCommands.cs @@ -11,7 +11,5 @@ namespace ICSharpCode.SharpDevelop /// public static class SharpDevelopRoutedCommands { - public static readonly RoutedCommand SplitView = new RoutedCommand( - "SplitView", typeof(SharpDevelopRoutedCommands)); } } diff --git a/src/Main/Base/Project/Src/Editor/Dialogs/RenameSymbolDialog.xaml.cs b/src/Main/Base/Project/Src/Editor/Dialogs/RenameSymbolDialog.xaml.cs index 16a71c429e..580ea9ff5f 100644 --- a/src/Main/Base/Project/Src/Editor/Dialogs/RenameSymbolDialog.xaml.cs +++ b/src/Main/Base/Project/Src/Editor/Dialogs/RenameSymbolDialog.xaml.cs @@ -42,6 +42,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Dialogs // Set focus into TextBox this.symbolNameTextBox.Focus(); + this.IsVisibleChanged += (sender, e) => this.symbolNameTextBox.SelectAll(); } public string OldSymbolName diff --git a/src/Main/Base/Project/Src/Gui/Pads/AbstractConsolePad.cs b/src/Main/Base/Project/Src/Gui/Pads/AbstractConsolePad.cs index 80adaf7a2b..af9b408298 100755 --- a/src/Main/Base/Project/Src/Gui/Pads/AbstractConsolePad.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/AbstractConsolePad.cs @@ -24,7 +24,7 @@ using ICSharpCode.SharpDevelop.Workbench; namespace ICSharpCode.SharpDevelop.Gui { - public abstract class AbstractConsolePad : AbstractPadContent, IEditable, IPositionable, ITextEditorProvider, IToolsHost + public abstract class AbstractConsolePad : AbstractPadContent, IEditable, IPositionable, IToolsHost { const string toolBarTreePath = "/SharpDevelop/Pads/CommonConsole/ToolBar"; diff --git a/src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs b/src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs index dfcdd1b60a..fe5ded64f1 100755 --- a/src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs @@ -6,7 +6,7 @@ using System.IO; using System.Threading.Tasks; using System.Windows; -using ICSharpCode.AvalonEdit; +using System.Windows.Threading; using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.Core; @@ -24,14 +24,13 @@ namespace ICSharpCode.SharpDevelop.Gui public class DefinitionViewPad : AbstractPadContent { AvalonEdit.TextEditor ctl; + DispatcherTimer timer; /// /// The control representing the pad /// public override object Control { - get { - return ctl; - } + get { return ctl; } } /// @@ -42,8 +41,11 @@ namespace ICSharpCode.SharpDevelop.Gui ctl = Editor.AvalonEditTextEditorAdapter.CreateAvalonEditInstance(); ctl.IsReadOnly = true; ctl.MouseDoubleClick += OnDoubleClick; - throw new NotImplementedException(); - //ParserService.ParserUpdateStepFinished += OnParserUpdateStep; + SD.ParserService.ParseInformationUpdated += OnParserUpdateStep; + SD.ParserService.LoadSolutionProjectsThread.Finished += LoadThreadFinished; + timer = new DispatcherTimer(DispatcherPriority.Background) { Interval = TimeSpan.FromSeconds(2) }; + timer.Tick += delegate { UpdateTick(null); }; + timer.IsEnabled = !SD.ParserService.LoadSolutionProjectsThread.IsRunning; ctl.IsVisibleChanged += delegate { UpdateTick(null); }; } @@ -52,47 +54,55 @@ namespace ICSharpCode.SharpDevelop.Gui /// public override void Dispose() { - //ParserService.ParserUpdateStepFinished -= OnParserUpdateStep; + SD.ParserService.ParseInformationUpdated -= OnParserUpdateStep; + SD.ParserService.LoadSolutionProjectsThread.Finished -= LoadThreadFinished; ctl.Document = null; base.Dispose(); } void OnDoubleClick(object sender, EventArgs e) { - string fileName = currentFileName; + FileName fileName = currentFileName; if (fileName != null) { var caret = ctl.TextArea.Caret; - FileService.JumpToFilePosition(fileName, caret.Line, caret.Column); + SD.FileService.JumpToFilePosition(fileName, caret.Line, caret.Column); // refresh DefinitionView to show the definition of the expression that was double-clicked UpdateTick(null); } } - void OnParserUpdateStep(object sender, ParserUpdateStepEventArgs e) + void LoadThreadFinished(object sender, EventArgs e) + { + timer.IsEnabled = true; + UpdateTick(null); + } + + void OnParserUpdateStep(object sender, ParseInformationEventArgs e) { UpdateTick(e); } - async void UpdateTick(ParserUpdateStepEventArgs e) + async void UpdateTick(ParseInformationEventArgs e) { + timer.IsEnabled = ctl.IsVisible; if (!ctl.IsVisible) return; LoggingService.Debug("DefinitionViewPad.Update"); ResolveResult res = await ResolveAtCaretAsync(e); if (res == null) return; var pos = res.GetDefinitionRegion(); - if (pos.IsEmpty) return; + if (pos.IsEmpty) return; // TODO : try to decompile? OpenFile(pos); } - Task ResolveAtCaretAsync(ParserUpdateStepEventArgs e) + Task ResolveAtCaretAsync(ParseInformationEventArgs e) { IWorkbenchWindow window = SD.Workbench.ActiveWorkbenchWindow; - if (window == null) + if (window == null) return Task.FromResult(null); IViewContent viewContent = window.ActiveViewContent; - if (viewContent == null) + if (viewContent == null) return Task.FromResult(null); ITextEditor editor = viewContent.GetService(); if (editor == null) @@ -107,14 +117,14 @@ namespace ICSharpCode.SharpDevelop.Gui } DomRegion oldPosition; - string currentFileName; + FileName currentFileName; void OpenFile(DomRegion pos) { if (pos.Equals(oldPosition)) return; oldPosition = pos; if (pos.FileName != currentFileName) - LoadFile(pos.FileName); + LoadFile(new FileName(pos.FileName)); ctl.TextArea.Caret.Location = pos.Begin; Rect r = ctl.TextArea.Caret.CalculateCaretRectangle(); if (!r.IsEmpty) { @@ -126,7 +136,7 @@ namespace ICSharpCode.SharpDevelop.Gui /// Loads the file from the corresponding text editor window if it is /// open otherwise the file is loaded from the file system. /// - void LoadFile(string fileName) + void LoadFile(FileName fileName) { // Load the text into the definition view's text editor. ctl.Document = new TextDocument(SD.FileService.GetFileContent(fileName)); diff --git a/src/Main/SharpDevelop/Dom/AssemblyModel.cs b/src/Main/SharpDevelop/Dom/AssemblyModel.cs index 1cecb2ee50..b10684186e 100644 --- a/src/Main/SharpDevelop/Dom/AssemblyModel.cs +++ b/src/Main/SharpDevelop/Dom/AssemblyModel.cs @@ -50,6 +50,12 @@ namespace ICSharpCode.SharpDevelop.Dom } } + public IEntityModelContext Context { + get { + return context; + } + } + public void Update(IUnresolvedFile oldFile, IUnresolvedFile newFile) { IList old = EmptyList.Instance; diff --git a/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs b/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs index 871bc7a139..891508f62b 100644 --- a/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs +++ b/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs @@ -2,17 +2,78 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.IO; using System.Linq; using System.Collections.Generic; using System.Diagnostics; using System.Windows.Controls; +using ICSharpCode.Core; using ICSharpCode.Core.Presentation; +using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.TreeView; using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Workbench; namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser { + public class PersistedWorkspace + { + public PersistedWorkspace() + { + AssemblyFiles = new List(); + } + + public string Name { get; set; } + public List AssemblyFiles { get; set; } + public bool IsActive { get; set; } + } + + class UnresolvedAssemblyEntityModelContext : IEntityModelContext + { + string assemblyName; + string location; + + public UnresolvedAssemblyEntityModelContext(string assemblyName, string location) + { + this.assemblyName = assemblyName; + this.location = location; + } + + public ICompilation GetCompilation() + { + return null; + } + + public bool IsBetterPart(IUnresolvedTypeDefinition part1, IUnresolvedTypeDefinition part2) + { + return false; + } + + public IProject Project { + get { + return null; + } + } + + public string AssemblyName { + get { + return assemblyName; + } + } + + public string Location { + get { + return location; + } + } + + public bool IsValid { + get { return false; } + } + } + class ClassBrowserPad : AbstractPadContent, IClassBrowser { #region IClassBrowser implementation @@ -25,13 +86,19 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser get { return treeView.AssemblyList; } set { treeView.AssemblyList = value; } } - + #endregion + + const string PersistedWorkspaceSetting = "ClassBrowser.Workspaces"; + const string DefaultWorkspaceName = ""; IProjectService projectService; ClassBrowserTreeView treeView; DockPanel panel; ToolBar toolBar; + + List persistedWorkspaces; + PersistedWorkspace activeWorkspace; public ClassBrowserPad() : this(SD.GetRequiredService()) @@ -53,6 +120,9 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser //treeView.ContextMenu = CreateContextMenu("/SharpDevelop/Pads/UnitTestsPad/ContextMenu"); projectService.CurrentSolutionChanged += ProjectServiceCurrentSolutionChanged; ProjectServiceCurrentSolutionChanged(null, null); + + // Load workspaces from configuration + LoadWorkspaces(); } public override void Dispose() @@ -77,6 +147,26 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser treeView.SpecialNodes.Add(new SolutionTreeNode(projectService.CurrentSolution)); } + void AssemblyListCollectionChanged(IReadOnlyCollection removedItems, IReadOnlyCollection addedItems) + { + foreach (var assembly in addedItems) { + // Add this assembly to current workspace + if (activeWorkspace != null) { + activeWorkspace.AssemblyFiles.Add(assembly.Context.Location); + } + } + + foreach (var assembly in removedItems) { + // Add this assembly to current workspace + if (activeWorkspace != null) { + activeWorkspace.AssemblyFiles.Remove(assembly.Context.Location); + } + } + + // Update workspace list in configuration + SaveWorkspaces(); + } + /// /// Virtual method so we can override this method and return /// a dummy ToolBar when testing. @@ -96,5 +186,120 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser Debug.Assert(treeView != null); return MenuService.CreateContextMenu(treeView, name); } + + /// + /// Loads persisted workspaces from configuration. + /// + void LoadWorkspaces() + { + persistedWorkspaces = SD.PropertyService.GetList(PersistedWorkspaceSetting).ToList(); + if (!persistedWorkspaces.Any()) + { + // Add at least default workspace + persistedWorkspaces = new List(); + persistedWorkspaces.Add(new PersistedWorkspace() + { + Name = DefaultWorkspaceName + }); + } + + // Load all assemblies (for now always from default workspace) + PersistedWorkspace defaultWorkspace = persistedWorkspaces.FirstOrDefault(w => w.Name == DefaultWorkspaceName); + ActivateWorkspace(defaultWorkspace); + } + + /// + /// Stores currently saved workspaces in configuration. + /// + void SaveWorkspaces() + { + SD.PropertyService.SetList(PersistedWorkspaceSetting, persistedWorkspaces); + } + + public static IAssemblyModel CreateAssemblyModelFromFile(string fileName) + { + try { + var loader = new CecilLoader(); + loader.IncludeInternalMembers = true; + loader.LazyLoad = true; + var assembly = loader.LoadAssemblyFile(fileName); + + IEntityModelContext context = new AssemblyEntityModelContext(assembly); + IAssemblyModel model = SD.GetRequiredService().CreateAssemblyModel(context); + if (model is IUpdateableAssemblyModel) { + ((IUpdateableAssemblyModel)model).Update(EmptyList.Instance, assembly.TopLevelTypeDefinitions.ToList()); + ((IUpdateableAssemblyModel) model).AssemblyName = assembly.AssemblyName; + } + return model; + } catch (BadImageFormatException ex) { + SD.MessageService.ShowWarningFormatted("{0} is not a valid .NET assembly.", Path.GetFileName(fileName)); + } catch (FileNotFoundException ex) { + SD.MessageService.ShowWarningFormatted("{0} is not accessible or doesn't exist anymore.", fileName); + } + + // AssemblyModel for unresolved file references + IEntityModelContext unresolvedContext = new UnresolvedAssemblyEntityModelContext(Path.GetFileName(fileName), fileName); + IAssemblyModel unresolvedModel = SD.GetRequiredService().CreateAssemblyModel(unresolvedContext); + if (unresolvedModel is IUpdateableAssemblyModel) { + ((IUpdateableAssemblyModel) unresolvedModel).AssemblyName = unresolvedContext.AssemblyName; + } + + return unresolvedModel; + } + + void AppendAssemblyFileToList(string assemblyFile) + { + IAssemblyModel assemblyModel = CreateAssemblyModelFromFile(assemblyFile); + if (assemblyModel != null) { + AssemblyList.Assemblies.Add(assemblyModel); + } else { + // TODO Throw exception? + + } + } + + /// + /// Activates the specified workspace. + /// + void ActivateWorkspace(PersistedWorkspace workspace) + { + // Update the activation flags in workspace list + foreach (var workspaceElement in persistedWorkspaces) { + workspaceElement.IsActive = (workspaceElement == workspace); + } + + UpdateActiveWorkspace(); + } + + /// + /// Updates active workspace and AssemblyList according to flags. + /// + void UpdateActiveWorkspace() + { + if ((AssemblyList != null) && (activeWorkspace != null)) { + // Temporarily detach from event handler + AssemblyList.Assemblies.CollectionChanged -= AssemblyListCollectionChanged; + } + + activeWorkspace = persistedWorkspaces.FirstOrDefault(w => w.IsActive); + if (activeWorkspace == null) { + // If no workspace is active, activate default + var defaultWorkspace = persistedWorkspaces.FirstOrDefault(w => w.Name == DefaultWorkspaceName); + activeWorkspace = defaultWorkspace; + defaultWorkspace.IsActive = true; + } + + AssemblyList.Assemblies.Clear(); + if (activeWorkspace != null) { + foreach (string assemblyFile in activeWorkspace.AssemblyFiles) { + AppendAssemblyFileToList(assemblyFile); + } + } + + // Attach to event handler, again. + if (AssemblyList != null) { + AssemblyList.Assemblies.CollectionChanged += AssemblyListCollectionChanged; + } + } } } diff --git a/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserTreeNodesFactory.cs b/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserTreeNodesFactory.cs index c85f22786a..23fe3fcb2f 100644 --- a/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserTreeNodesFactory.cs +++ b/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserTreeNodesFactory.cs @@ -21,6 +21,8 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser return typeof(ITypeDefinitionModel); if (model is IMemberModel) return typeof(IMemberModel); + if (model is IAssemblyModel) + return typeof(IAssemblyModel); return null; } @@ -36,6 +38,8 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser return new TypeDefinitionTreeNode((ITypeDefinitionModel)model); if (model is IMemberModel) return new MemberTreeNode((IMemberModel)model); + if (model is IAssemblyModel) + return new AssemblyTreeNode((IAssemblyModel) model); return null; } } diff --git a/src/Main/SharpDevelop/Dom/ClassBrowser/Commands.cs b/src/Main/SharpDevelop/Dom/ClassBrowser/Commands.cs new file mode 100644 index 0000000000..7496f03f0b --- /dev/null +++ b/src/Main/SharpDevelop/Dom/ClassBrowser/Commands.cs @@ -0,0 +1,85 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.IO; +using System.Linq; +using Microsoft.Win32; + +namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser +{ + /// + /// Description of OpenAssemblyFromFileCommand. + /// + class OpenAssemblyFromFileCommand : SimpleCommand + { + public override void Execute(object parameter) + { + var classBrowser = SD.GetService(); + if (classBrowser != null) { + OpenFileDialog openFileDialog = new OpenFileDialog(); + openFileDialog.Filter = "Assembly files (*.exe, *.dll)|*.exe;*.dll"; + openFileDialog.CheckFileExists = true; + openFileDialog.CheckPathExists = true; + if (openFileDialog.ShowDialog() ?? false) + { + classBrowser.AssemblyList.Assemblies.Add(ClassBrowserPad.CreateAssemblyModelFromFile(openFileDialog.FileName)); + } + } + } + } + + /// + /// Description of OpenAssemblyFromGACCommand. + /// + class OpenAssemblyFromGACCommand : SimpleCommand + { + public override void Execute(object parameter) + { + var classBrowser = SD.GetService(); + if (classBrowser != null) { + OpenFromGacDialog gacDialog = new OpenFromGacDialog(); + if (gacDialog.ShowDialog() ?? false) + { + foreach (string assemblyFile in gacDialog.SelectedFileNames) { + classBrowser.AssemblyList.Assemblies.Add(ClassBrowserPad.CreateAssemblyModelFromFile(assemblyFile)); + } + } + } + } + } + + /// + /// Description of RemoveAssemblyCommand. + /// + class RemoveAssemblyCommand : SimpleCommand + { + public override bool CanExecute(object parameter) + { + return parameter is AssemblyModel; + } + + public override void Execute(object parameter) + { + var classBrowser = SD.GetService(); + if (classBrowser != null) { + IAssemblyModel assemblyModel = (IAssemblyModel) parameter; + classBrowser.AssemblyList.Assemblies.Remove(assemblyModel); + } + } + } + + /// + /// Description of RemoveAssemblyCommand. + /// + class ClassBrowserCollapseAllCommand : SimpleCommand + { + public override void Execute(object parameter) + { +// var classBrowser = SD.GetService() as ClassBrowserPad; +// if (classBrowser != null) { +// classBrowser.TreeView +// } + } + } +} diff --git a/src/Main/SharpDevelop/Dom/ClassBrowser/OpenAssemblyCommand.cs b/src/Main/SharpDevelop/Dom/ClassBrowser/OpenAssemblyCommand.cs deleted file mode 100644 index d76b0dbd8d..0000000000 --- a/src/Main/SharpDevelop/Dom/ClassBrowser/OpenAssemblyCommand.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using Microsoft.Win32; - -namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser -{ - /// - /// Description of OpenAssemblyCommand. - /// - class OpenAssemblyCommand : SimpleCommand - { - public override void Execute(object parameter) - { - } - } -} diff --git a/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml b/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml new file mode 100644 index 0000000000..ae78f0982f --- /dev/null +++ b/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml.cs b/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml.cs new file mode 100644 index 0000000000..a13572bcf2 --- /dev/null +++ b/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml.cs @@ -0,0 +1,188 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// 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; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Threading; +using ICSharpCode.Core.Presentation; +using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.Parser; + +namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser +{ + /// + /// Interaction logic for OpenFromGacDialog.xaml + /// + public partial class OpenFromGacDialog : Window + { + ObservableCollection gacEntries = new ObservableCollection(); + ObservableCollection filteredEntries = new ObservableCollection(); + Predicate filterMethod = _ => true; + volatile bool cancelFetchThread; + + public OpenFromGacDialog() + { + InitializeComponent(); + FormLocationHelper.ApplyWindow(this, "ICSharpCode.SharpDevelop.Dom.OpenFromGacDialog.Bounds", true); + listView.ItemsSource = filteredEntries; + SortableGridViewColumn.SetCurrentSortColumn(listView, nameColumn); + SortableGridViewColumn.SetSortDirection(listView, ColumnSortDirection.Ascending); + + new Thread(new ThreadStart(FetchGacContents)).Start(); + } + + protected override void OnClosing(CancelEventArgs e) + { + base.OnClosing(e); + cancelFetchThread = true; + } + + #region Fetch Gac Contents + sealed class GacEntry + { + readonly DomAssemblyName r; + readonly string fileName; + string formattedVersion; + + public GacEntry(DomAssemblyName r, string fileName) + { + this.r = r; + this.fileName = fileName; + } + + public string FullName { + get { return r.FullName; } + } + + public string ShortName { + get { return r.ShortName; } + } + + public string FileName { + get { return fileName; } + } + + public Version Version { + get { return r.Version; } + } + + public string FormattedVersion { + get { + if (formattedVersion == null) + formattedVersion = Version.ToString(); + return formattedVersion; + } + } + + public string Culture { + get { return r.Culture; } + } + + public string PublicKeyToken { + get { + StringBuilder s = new StringBuilder(); + foreach (byte b in r.PublicKeyToken) + s.Append(b.ToString("x2")); + return s.ToString(); + } + } + + public override string ToString() + { + return r.FullName; + } + } + + void FetchGacContents() + { + IGlobalAssemblyCacheService gacService = SD.GetService(); + HashSet fullNames = new HashSet(); + UpdateProgressBar(pg => { pg.Visibility = System.Windows.Visibility.Visible; pg.IsIndeterminate = true; }); + var list = gacService.Assemblies.TakeWhile(_ => !cancelFetchThread).ToList(); + UpdateProgressBar(pg => { pg.IsIndeterminate = false; pg.Maximum = list.Count; }); + foreach (var r in list) { + if (cancelFetchThread) + break; + if (fullNames.Add(r.FullName)) { // filter duplicates + var file = gacService.FindAssemblyInNetGac(r); + if (file != null) { + var entry = new GacEntry(r, file); + UpdateProgressBar(pg => { pg.Value = pg.Value + 1; AddNewEntry(entry); }); + } + } + } + UpdateProgressBar(pg => { pg.Visibility = System.Windows.Visibility.Hidden; }); + } + + void UpdateProgressBar(Action updateAction) + { + Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => updateAction(gacReadingProgressBar))); + } + + void AddNewEntry(GacEntry entry) + { + gacEntries.Add(entry); + if (filterMethod(entry)) + filteredEntries.Add(entry); + } + #endregion + + void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e) + { + string filterString = filterTextBox.Text.Trim(); + if (filterString.Length == 0) + filterMethod = _ => true; + else { + var elements = filterString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + filterMethod = entry => elements.All(el => Contains(entry.FullName, el) || Contains(entry.FormattedVersion, el)); + } + + filteredEntries.Clear(); + filteredEntries.AddRange(gacEntries.Where(entry => filterMethod(entry))); + } + + static bool Contains(string s, string subString) + { + return s.IndexOf(subString, StringComparison.OrdinalIgnoreCase) >= 0; + } + + void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + okButton.IsEnabled = listView.SelectedItems.Count > 0; + } + + void OKButton_Click(object sender, RoutedEventArgs e) + { + this.DialogResult = true; + Close(); + } + + public string[] SelectedFileNames { + get { + return listView.SelectedItems.OfType().Select(e => e.FileName).ToArray(); + } + } + } +} \ No newline at end of file diff --git a/src/Main/SharpDevelop/Resources/BitmapResources.resources b/src/Main/SharpDevelop/Resources/BitmapResources.resources index 57204edbcc..a449ace4db 100644 Binary files a/src/Main/SharpDevelop/Resources/BitmapResources.resources and b/src/Main/SharpDevelop/Resources/BitmapResources.resources differ diff --git a/src/Main/SharpDevelop/SharpDevelop.csproj b/src/Main/SharpDevelop/SharpDevelop.csproj index d62dcd7030..8eed81e197 100644 --- a/src/Main/SharpDevelop/SharpDevelop.csproj +++ b/src/Main/SharpDevelop/SharpDevelop.csproj @@ -108,7 +108,11 @@ - + + + OpenFromGacDialog.xaml + Code + @@ -331,6 +335,7 @@ + diff --git a/src/Main/SharpDevelop/Workbench/FileService.cs b/src/Main/SharpDevelop/Workbench/FileService.cs index a91e45dfe9..c52a3b65c5 100644 --- a/src/Main/SharpDevelop/Workbench/FileService.cs +++ b/src/Main/SharpDevelop/Workbench/FileService.cs @@ -454,12 +454,12 @@ namespace ICSharpCode.SharpDevelop.Workbench try { IViewContent content = OpenFile(fileName); - if (content is IPositionable) { - // TODO: enable jumping to a particular view + IPositionable positionable = content.GetService(); + if (positionable != null) { content.WorkbenchWindow.ActiveViewContent = content; NavigationService.ResumeLogging(); loggingResumed = true; - ((IPositionable)content).JumpTo(Math.Max(1, line), Math.Max(1, column)); + positionable.JumpTo(Math.Max(1, line), Math.Max(1, column)); } else { NavigationService.ResumeLogging(); loggingResumed = true;