mirror of https://github.com/icsharpcode/ILSpy.git
270 changed files with 18922 additions and 9211 deletions
@ -0,0 +1,109 @@
@@ -0,0 +1,109 @@
|
||||
// Copyright (c) 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; |
||||
|
||||
public class TypeAnalysisTests |
||||
{ |
||||
public byte SubtractFrom256(byte b) |
||||
{ |
||||
return (byte)(256 - (int)b); |
||||
} |
||||
|
||||
#region Shift
|
||||
public int LShiftInteger(int num1, int num2) |
||||
{ |
||||
return num1 << num2; |
||||
} |
||||
|
||||
public uint LShiftUnsignedInteger(uint num1, uint num2) |
||||
{ |
||||
return num1 << (int)num2; |
||||
} |
||||
|
||||
public long LShiftLong(long num1, long num2) |
||||
{ |
||||
return num1 << (int)num2; |
||||
} |
||||
|
||||
public ulong LShiftUnsignedLong(ulong num1, ulong num2) |
||||
{ |
||||
return num1 << (int)num2; |
||||
} |
||||
|
||||
public int RShiftInteger(int num1, int num2) |
||||
{ |
||||
return num1 >> num2; |
||||
} |
||||
|
||||
public uint RShiftUnsignedInteger(uint num1, int num2) |
||||
{ |
||||
return num1 >> num2; |
||||
} |
||||
|
||||
public long RShiftLong(long num1, long num2) |
||||
{ |
||||
return num1 >> (int)num2; |
||||
} |
||||
|
||||
public ulong RShiftUnsignedLong(ulong num1, ulong num2) |
||||
{ |
||||
return num1 >> (int)num2; |
||||
} |
||||
|
||||
public int ShiftByte(byte num) |
||||
{ |
||||
return (int)num << 8; |
||||
} |
||||
|
||||
public int RShiftByte(byte num) |
||||
{ |
||||
return num >> 8; |
||||
} |
||||
|
||||
public uint RShiftByteWithZeroExtension(byte num) |
||||
{ |
||||
return (uint)num >> 8; |
||||
} |
||||
|
||||
public int RShiftByteAsSByte(byte num) |
||||
{ |
||||
return (sbyte)num >> 8; |
||||
} |
||||
|
||||
public int RShiftSByte(sbyte num) |
||||
{ |
||||
return num >> 8; |
||||
} |
||||
|
||||
public uint RShiftSByteWithZeroExtension(sbyte num) |
||||
{ |
||||
return (uint)num >> 8; |
||||
} |
||||
|
||||
public int RShiftSByteAsByte(sbyte num) |
||||
{ |
||||
return (byte)num >> 8; |
||||
} |
||||
#endregion
|
||||
|
||||
public int GetHashCode(long num) |
||||
{ |
||||
return (int)num ^ (int)(num >> 32); |
||||
} |
||||
} |
||||
@ -1,183 +0,0 @@
@@ -1,183 +0,0 @@
|
||||
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
|
||||
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel; |
||||
using System.Reflection; |
||||
using System.Text; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using Microsoft.Win32; |
||||
using System.Threading; |
||||
using System.Security.Permissions; |
||||
using System.Security; |
||||
|
||||
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||
{ |
||||
public delegate void AssemblyResolveEventHandler(object s, AssemblyResolveEventArgs e); |
||||
|
||||
public class AppDomainTypeResolver : MarshalByRefObject, ITypeResolver |
||||
{ |
||||
private readonly AppDomain _domain; |
||||
private string baseDir; |
||||
|
||||
public event AssemblyResolveEventHandler AssemblyResolve; |
||||
|
||||
public static AppDomainTypeResolver GetIntoNewAppDomain(string baseDir) |
||||
{ |
||||
AppDomainSetup info = new AppDomainSetup(); |
||||
info.ApplicationBase = Environment.CurrentDirectory; |
||||
AppDomain domain = AppDomain.CreateDomain("AppDomainTypeResolver", null, info, new PermissionSet(PermissionState.Unrestricted)); |
||||
AppDomainTypeResolver resolver = (AppDomainTypeResolver)domain.CreateInstanceAndUnwrap(typeof(AppDomainTypeResolver).Assembly.FullName, |
||||
typeof(AppDomainTypeResolver).FullName, false, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, new object[] { domain, baseDir }, null, null, null); |
||||
|
||||
return resolver; |
||||
} |
||||
|
||||
Assembly domain_AssemblyResolve(object sender, ResolveEventArgs args) |
||||
{ |
||||
// Cerco di risolvere automaticamente
|
||||
AssemblyName name = new AssemblyName(args.Name); |
||||
string fileName = Path.Combine(this.baseDir, name.Name + ".exe"); |
||||
if (!File.Exists(fileName)) |
||||
fileName = Path.Combine(this.baseDir, name.Name + ".dll"); |
||||
|
||||
// Carico il percorso autocalcolato
|
||||
if (File.Exists(fileName)) |
||||
return Assembly.LoadFile(fileName); |
||||
|
||||
if (AssemblyResolve != null) |
||||
{ |
||||
AssemblyResolveEventArgs e = new AssemblyResolveEventArgs(args.Name, this.baseDir); |
||||
AssemblyResolve(this, e); |
||||
if (!String.IsNullOrEmpty(e.Location) && File.Exists(e.Location)) |
||||
return Assembly.LoadFile(e.Location); |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public static void DestroyResolver(AppDomainTypeResolver resolver) |
||||
{ |
||||
if (resolver == null) throw new ArgumentNullException("resolver"); |
||||
|
||||
ThreadPool.QueueUserWorkItem(delegate |
||||
{ |
||||
AppDomain.Unload(resolver.Domain); |
||||
}); |
||||
} |
||||
|
||||
protected AppDomainTypeResolver(AppDomain domain, string baseDir) |
||||
{ |
||||
_domain = domain; |
||||
this.baseDir = baseDir; |
||||
|
||||
domain.AssemblyResolve += new ResolveEventHandler(domain_AssemblyResolve); |
||||
} |
||||
|
||||
public BamlAssembly LoadAssembly(AssemblyName asm) |
||||
{ |
||||
//return new BamlAssembly(Assembly.Load(asm));
|
||||
return new BamlAssembly(_domain.Load(asm)); |
||||
} |
||||
|
||||
public BamlAssembly LoadAssembly(string location) |
||||
{ |
||||
Assembly asm = Assembly.LoadFile(location); |
||||
return new BamlAssembly(asm); |
||||
//return _domain.Load(System.IO.File.ReadAllBytes(location));
|
||||
//return Assembly.LoadFrom(location);
|
||||
} |
||||
|
||||
public BamlAssembly[] GetReferencedAssemblies(BamlAssembly asm) |
||||
{ |
||||
AssemblyName[] list = asm.Assembly.GetReferencedAssemblies(); |
||||
|
||||
return (from an in list |
||||
select this.LoadAssembly(an)).ToArray(); |
||||
} |
||||
|
||||
public AppDomain Domain |
||||
{ |
||||
get { return _domain; } |
||||
} |
||||
|
||||
#region ITypeResolver Members
|
||||
|
||||
public IType GetTypeByAssemblyQualifiedName(string name) |
||||
{ |
||||
return new DotNetType(name); |
||||
} |
||||
|
||||
public IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType) |
||||
{ |
||||
if (name == null) throw new ArgumentNullException("name"); |
||||
if (ownerType == null) throw new ArgumentNullException("ownerType"); |
||||
if (targetType == null) throw new ArgumentNullException("targetType"); |
||||
|
||||
Type dOwnerType = ((DotNetType)ownerType).Type; |
||||
Type dTargetType = ((DotNetType)targetType).Type; |
||||
|
||||
try |
||||
{ |
||||
DependencyPropertyDescriptor propertyDescriptor = DependencyPropertyDescriptor.FromName(name, dOwnerType, dTargetType); |
||||
if (propertyDescriptor != null) |
||||
return new WpfDependencyPropertyDescriptor(propertyDescriptor); |
||||
return null; |
||||
} |
||||
catch (Exception) |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public bool IsLocalAssembly(string name) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
public string RuntimeVersion { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
public override object InitializeLifetimeService() |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public class AssemblyResolveEventArgs : MarshalByRefObject |
||||
{ |
||||
|
||||
private string _location; |
||||
private string _name; |
||||
private string _baseDir; |
||||
|
||||
public AssemblyResolveEventArgs(string name, string baseDir) |
||||
{ |
||||
_name = name; |
||||
_baseDir = baseDir; |
||||
} |
||||
|
||||
public string Location |
||||
{ |
||||
get { return _location; } |
||||
set { _location = value; } |
||||
} |
||||
|
||||
public string Name |
||||
{ |
||||
get { return _name; } |
||||
} |
||||
|
||||
public string BaseDir |
||||
{ |
||||
get { return _baseDir; } |
||||
} |
||||
} |
||||
} |
||||
@ -1,112 +0,0 @@
@@ -1,112 +0,0 @@
|
||||
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
|
||||
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
using System.IO; |
||||
using System.Reflection; |
||||
using System.Resources; |
||||
using System.Text; |
||||
|
||||
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||
{ |
||||
public class BamlAssembly : MarshalByRefObject |
||||
{ |
||||
private readonly string _filePath; |
||||
private Assembly _assembly; |
||||
private BamlFileList _bamlFile; |
||||
|
||||
public BamlAssembly(Assembly assembly) |
||||
{ |
||||
_assembly = assembly; |
||||
_filePath = assembly.CodeBase; |
||||
|
||||
ReadBaml(); |
||||
} |
||||
|
||||
public BamlAssembly(string filePath) |
||||
{ |
||||
this._filePath = Path.GetFullPath(filePath); |
||||
this._assembly = Assembly.LoadFile(this.FilePath); |
||||
if (String.Compare(this.Assembly.CodeBase, this.FilePath, true) != 0) |
||||
throw new ArgumentException("Cannot load filePath because Assembly is already loaded", "filePath"); |
||||
|
||||
ReadBaml(); |
||||
} |
||||
|
||||
private void ReadBaml() |
||||
{ |
||||
// Get available names
|
||||
string[] resources = this.Assembly.GetManifestResourceNames(); |
||||
foreach (string res in resources) |
||||
{ |
||||
// Solo le risorse
|
||||
if (String.Compare(Path.GetExtension(res), ".resources", true) != 0) continue; |
||||
|
||||
// Get stream
|
||||
using (Stream stream = this.Assembly.GetManifestResourceStream(res)) |
||||
{ |
||||
try |
||||
{ |
||||
ResourceReader reader = new ResourceReader(stream); |
||||
foreach (DictionaryEntry entry in reader) |
||||
{ |
||||
if (String.Compare(Path.GetExtension(entry.Key.ToString()), ".baml", true) == 0 && entry.Value is Stream) |
||||
{ |
||||
BamlFile bm = new BamlFile(GetAssemblyResourceUri(entry.Key.ToString()), (Stream)entry.Value); |
||||
this.BamlFiles.Add(bm); |
||||
} |
||||
} |
||||
} |
||||
catch (ArgumentException) |
||||
{} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private Uri GetAssemblyResourceUri(string resourceName) |
||||
{ |
||||
AssemblyName asm = this.Assembly.GetName(); |
||||
byte[] data = asm.GetPublicKeyToken(); |
||||
StringBuilder token = new StringBuilder(data.Length * 2); |
||||
for (int x = 0; x < data.Length; x++) |
||||
{ |
||||
token.Append(data[x].ToString("x", System.Globalization.CultureInfo.InvariantCulture)); |
||||
} |
||||
|
||||
return new Uri(String.Format(@"{0};V{1};{2};component\{3}", asm.Name, asm.Version, token, Path.ChangeExtension(resourceName, ".xaml")), UriKind.RelativeOrAbsolute); |
||||
} |
||||
|
||||
public string FilePath |
||||
{ |
||||
get { return _filePath; } |
||||
} |
||||
|
||||
public Assembly Assembly |
||||
{ |
||||
get { return _assembly; } |
||||
} |
||||
|
||||
public BamlFileList BamlFiles |
||||
{ |
||||
get |
||||
{ |
||||
if (_bamlFile == null) |
||||
_bamlFile = new BamlFileList(); |
||||
return _bamlFile; |
||||
} |
||||
} |
||||
|
||||
public override object InitializeLifetimeService() |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
[Serializable()] |
||||
public class BamlFileList : Collection<BamlFile> |
||||
{} |
||||
|
||||
} |
||||
@ -1,80 +0,0 @@
@@ -1,80 +0,0 @@
|
||||
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
|
||||
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel; |
||||
using System.IO; |
||||
using System.Resources; |
||||
using System.Text; |
||||
using System.Windows; |
||||
|
||||
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||
{ |
||||
/// <summary>
|
||||
/// Rappresenta un singole file Baml all'interno di un assembly
|
||||
/// </summary>
|
||||
public class BamlFile : Component |
||||
{ |
||||
private Uri _uri; |
||||
private readonly Stream _stream; |
||||
|
||||
public BamlFile(Uri uri, Stream stream) |
||||
{ |
||||
if (uri == null) |
||||
new ArgumentNullException("uri"); |
||||
if (stream == null) |
||||
throw new ArgumentNullException("stream"); |
||||
|
||||
_uri = uri; |
||||
_stream = stream; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Carica il Baml attraverso il motore di WPF con Application.LoadComponent
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public object LoadContent() |
||||
{ |
||||
try |
||||
{ |
||||
return Application.LoadComponent(this.Uri); |
||||
} |
||||
catch (Exception e) |
||||
{ |
||||
throw new InvalidOperationException("Invalid baml file.", e); |
||||
} |
||||
} |
||||
|
||||
protected override void Dispose(bool disposing) |
||||
{ |
||||
base.Dispose(disposing); |
||||
|
||||
if (disposing) |
||||
this.Stream.Dispose(); |
||||
} |
||||
|
||||
public override object InitializeLifetimeService() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Restituisce lo stream originale contenente il Baml
|
||||
/// </summary>
|
||||
public Stream Stream |
||||
{ |
||||
get { return _stream; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Restituisce l'indirizzo secondo lo schema pack://
|
||||
/// </summary>
|
||||
public Uri Uri |
||||
{ |
||||
get { return _uri; } |
||||
} |
||||
|
||||
} |
||||
} |
||||
@ -1,64 +0,0 @@
@@ -1,64 +0,0 @@
|
||||
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
|
||||
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
|
||||
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||
{ |
||||
public class DotNetType : MarshalByRefObject, IType |
||||
{ |
||||
private readonly string _assemblyQualifiedName; |
||||
private Type _type; |
||||
|
||||
public DotNetType(string assemblyQualifiedName) |
||||
{ |
||||
if (assemblyQualifiedName == null) throw new ArgumentNullException("assemblyQualifiedName"); |
||||
|
||||
_assemblyQualifiedName = assemblyQualifiedName; |
||||
_type = Type.GetType(assemblyQualifiedName, false, true); |
||||
} |
||||
|
||||
#region IType Members
|
||||
|
||||
public string AssemblyQualifiedName |
||||
{ |
||||
get { return _assemblyQualifiedName; } |
||||
} |
||||
|
||||
public bool IsSubclassOf(IType type) |
||||
{ |
||||
if (type == null) throw new ArgumentNullException("type"); |
||||
if (!(type is DotNetType)) throw new ArgumentException("type"); |
||||
if (_type == null) return false; |
||||
return this._type.IsSubclassOf(((DotNetType)type).Type); |
||||
} |
||||
|
||||
public bool Equals(IType type) |
||||
{ |
||||
if (type == null) throw new ArgumentNullException("type"); |
||||
if (!(type is DotNetType)) throw new ArgumentException("type"); |
||||
if (_type == null) return false; |
||||
return this._type.Equals(((DotNetType)type).Type); |
||||
} |
||||
|
||||
public IType BaseType { |
||||
get { |
||||
return new DotNetType(this._type.BaseType.AssemblyQualifiedName); |
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
public Type Type |
||||
{ |
||||
get { return _type; } |
||||
} |
||||
|
||||
public override object InitializeLifetimeService() |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
|
||||
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel; |
||||
using System.Diagnostics; |
||||
using System.Globalization; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using System.Text; |
||||
using System.Xml; |
||||
using System.Windows.Media; |
||||
|
||||
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||
{ |
||||
class NodesCollection : List<XmlBamlNode> |
||||
{ |
||||
public XmlBamlNode Last |
||||
{ |
||||
get |
||||
{ |
||||
if (this.Count > 0) |
||||
{ |
||||
int i = this.Count - 1; |
||||
return this[i]; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public void RemoveLast() |
||||
{ |
||||
if (this.Count > 0) |
||||
this.Remove(this.Last); |
||||
} |
||||
|
||||
public XmlBamlNode Dequeue() |
||||
{ |
||||
return DequeueInternal(true); |
||||
} |
||||
|
||||
public XmlBamlNode Peek() |
||||
{ |
||||
return DequeueInternal(false); |
||||
} |
||||
|
||||
XmlBamlNode DequeueInternal(bool remove) |
||||
{ |
||||
if (this.Count > 0) |
||||
{ |
||||
XmlBamlNode node = this[0]; |
||||
if (remove) |
||||
this.RemoveAt(0); |
||||
return node; |
||||
} |
||||
else |
||||
return null; |
||||
} |
||||
|
||||
public void Enqueue(XmlBamlNode node) |
||||
{ |
||||
this.Add(node); |
||||
} |
||||
} |
||||
} |
||||
@ -1,35 +0,0 @@
@@ -1,35 +0,0 @@
|
||||
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
|
||||
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel; |
||||
using System.Text; |
||||
|
||||
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||
{ |
||||
public class WpfDependencyPropertyDescriptor : MarshalByRefObject, IDependencyPropertyDescriptor |
||||
{ |
||||
private readonly DependencyPropertyDescriptor _propertyDescriptor; |
||||
|
||||
public WpfDependencyPropertyDescriptor(DependencyPropertyDescriptor propertyDescriptor) |
||||
{ |
||||
if (propertyDescriptor == null) throw new ArgumentNullException("propertyDescriptor"); |
||||
_propertyDescriptor = propertyDescriptor; |
||||
} |
||||
|
||||
#region IDependencyPropertyDescriptor Members
|
||||
|
||||
public bool IsAttached |
||||
{ |
||||
get { return _propertyDescriptor.IsAttached; } |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
public override object InitializeLifetimeService() |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||
<Color x:Key="VeryDark" A="255" R="70" G="70" B="70" /> |
||||
<Color x:Key="Dark" A="255" R="102" G="102" B="102" /> |
||||
<Color x:Key="Medium" A="255" R="140" G="140" B="140" /> |
||||
<Color x:Key="Light" A="255" R="204" G="204" B="204" /> |
||||
<Color x:Key="VeryLight" A="255" R="241" G="241" B="241" /> |
||||
<Color x:Key="OffWhite" A="255" R="255" G="255" B="255" /> |
||||
<Color x:Key="Highlight" A="255" R="220" G="107" B="47" /> |
||||
<SolidColorBrush x:Key="VeryDarkBrush" Color="{StaticResource VeryDark}" /> |
||||
<SolidColorBrush x:Key="DarkBrush" Color="{StaticResource Dark}" /> |
||||
<SolidColorBrush x:Key="MediumBrush" Color="{StaticResource Medium}" /> |
||||
<SolidColorBrush x:Key="LightBrush" Color="{StaticResource Light}" /> |
||||
<SolidColorBrush x:Key="VeryLightBrush" Color="{StaticResource VeryLight}" /> |
||||
<SolidColorBrush x:Key="OffWhiteBrush" Color="{StaticResource OffWhite}" /> |
||||
<SolidColorBrush x:Key="HighlightBrush" Color="{StaticResource Highlight}" /> |
||||
<LinearGradientBrush x:Key="EdgeBorder" StartPoint="0,0" EndPoint="0,1"> |
||||
<GradientStop Color="#0000" Offset="0" /> |
||||
<GradientStop Color="#1000" Offset="0.65" /> |
||||
<GradientStop Color="#3000" Offset="1" /> |
||||
</LinearGradientBrush> |
||||
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#6FFF" /> |
||||
<SolidColorBrush x:Key="SelectedBackgroundBrush" Color="{StaticResource Light}" /> |
||||
</ResourceDictionary> |
||||
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<UserControl |
||||
x:Class="ICSharpCode.ILSpy.Controls.ResourceStringTable" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||
<UserControl.CommandBindings> |
||||
<CommandBinding Command="ApplicationCommands.Copy" |
||||
Executed="ExecuteCopy" |
||||
CanExecute="CanExecuteCopy"/> |
||||
</UserControl.CommandBindings> |
||||
<ListView |
||||
Name="resourceListView" |
||||
SelectionMode="Extended"> |
||||
<ListView.View> |
||||
<GridView |
||||
AllowsColumnReorder="False"> |
||||
<GridView.Columns> |
||||
<GridViewColumn |
||||
Header="Resource id" |
||||
DisplayMemberBinding="{Binding Key}" /> |
||||
<GridViewColumn |
||||
Header="Resource value" |
||||
DisplayMemberBinding="{Binding Value}" /> |
||||
</GridView.Columns> |
||||
</GridView> |
||||
</ListView.View> |
||||
</ListView> |
||||
</UserControl> |
||||
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
/* |
||||
* Created by SharpDevelop. |
||||
* User: Ronny Klier |
||||
* Date: 31.05.2011 |
||||
* Time: 00:13 |
||||
* |
||||
* To change this template use Tools | Options | Coding | Edit Standard Headers. |
||||
*/ |
||||
using System; |
||||
using System.Collections; |
||||
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; |
||||
|
||||
namespace ICSharpCode.ILSpy.Controls |
||||
{ |
||||
/// <summary>
|
||||
/// Interaction logic for ResourceStringTable.xaml
|
||||
/// </summary>
|
||||
public partial class ResourceStringTable : UserControl |
||||
{ |
||||
public ResourceStringTable(IEnumerable strings) |
||||
{ |
||||
InitializeComponent(); |
||||
// set size to fit decompiler window
|
||||
// TODO: there should be a more transparent way to do this
|
||||
MaxWidth = MainWindow.Instance.mainPane.ActualWidth-20; |
||||
MaxHeight = MainWindow.Instance.mainPane.ActualHeight-100; |
||||
resourceListView.ItemsSource = strings; |
||||
} |
||||
|
||||
void ExecuteCopy(object sender, ExecutedRoutedEventArgs args) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(); |
||||
foreach (var item in resourceListView.SelectedItems) |
||||
{ |
||||
sb.AppendLine(item.ToString()); |
||||
} |
||||
Clipboard.SetText(sb.ToString()); |
||||
} |
||||
|
||||
void CanExecuteCopy(object sender, CanExecuteRoutedEventArgs args) |
||||
{ |
||||
args.CanExecute = true; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build"> |
||||
<PropertyGroup> |
||||
<ProjectGuid>{F054A788-B591-4561-A8BA-AE745BBEB817}</ProjectGuid> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>ICSharpCode.Editor</RootNamespace> |
||||
<AssemblyName>ICSharpCode.Editor</AssemblyName> |
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> |
||||
<TargetFrameworkProfile>Client</TargetFrameworkProfile> |
||||
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||
<SignAssembly>False</SignAssembly> |
||||
<DelaySign>False</DelaySign> |
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent> |
||||
<DocumentationFile>bin\Debug\ICSharpCode.Editor.xml</DocumentationFile> |
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||
<NoStdLib>False</NoStdLib> |
||||
<WarningLevel>4</WarningLevel> |
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
||||
<RunCodeAnalysis>False</RunCodeAnalysis> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Platform)' == 'x86' "> |
||||
<PlatformTarget>x86</PlatformTarget> |
||||
<RegisterForComInterop>False</RegisterForComInterop> |
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
||||
<BaseAddress>4194304</BaseAddress> |
||||
<FileAlignment>4096</FileAlignment> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
||||
<OutputPath>bin\Debug\</OutputPath> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>Full</DebugType> |
||||
<Optimize>False</Optimize> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
<StartAction>Project</StartAction> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||
<OutputPath>bin\Release\</OutputPath> |
||||
<DebugSymbols>False</DebugSymbols> |
||||
<DebugType>None</DebugType> |
||||
<Optimize>True</Optimize> |
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Core"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System.Xml" /> |
||||
<Reference Include="System.Xml.Linq"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="IDocument.cs" /> |
||||
<Compile Include="IDocumentLine.cs" /> |
||||
<Compile Include="ISegment.cs" /> |
||||
<Compile Include="ITextEditor.cs" /> |
||||
<Compile Include="ITextSource.cs" /> |
||||
<Compile Include="LinkedElement.cs" /> |
||||
<Compile Include="ReadOnlyDocument.cs" /> |
||||
<Compile Include="StringTextSource.cs" /> |
||||
<Compile Include="TextLocation.cs" /> |
||||
<Compile Include="ITextAnchor.cs" /> |
||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||
<Compile Include="TextChangeEventArgs.cs" /> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
</Project> |
||||
@ -0,0 +1,141 @@
@@ -0,0 +1,141 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.Editor |
||||
{ |
||||
/// <summary>
|
||||
/// A document representing a source code file for refactoring.
|
||||
/// Line and column counting starts at 1.
|
||||
/// Offset counting starts at 0.
|
||||
/// </summary>
|
||||
public interface IDocument : ITextSource, IServiceProvider |
||||
{ |
||||
/// <summary>
|
||||
/// Gets/Sets the text of the whole document..
|
||||
/// </summary>
|
||||
new string Text { get; set; } // hides TextBuffer.Text to add the setter
|
||||
|
||||
/// <summary>
|
||||
/// Is raised when the Text property changes.
|
||||
/// </summary>
|
||||
event EventHandler TextChanged; |
||||
|
||||
/// <summary>
|
||||
/// Gets the total number of lines in the document.
|
||||
/// </summary>
|
||||
int TotalNumberOfLines { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the document line with the specified number.
|
||||
/// </summary>
|
||||
/// <param name="lineNumber">The number of the line to retrieve. The first line has number 1.</param>
|
||||
IDocumentLine GetLine(int lineNumber); |
||||
|
||||
/// <summary>
|
||||
/// Gets the document line that contains the specified offset.
|
||||
/// </summary>
|
||||
IDocumentLine GetLineByOffset(int offset); |
||||
|
||||
/// <summary>
|
||||
/// Gets the offset from a text location.
|
||||
/// </summary>
|
||||
/// <seealso cref="GetLocation"/>
|
||||
int GetOffset(int line, int column); |
||||
|
||||
/// <summary>
|
||||
/// Gets the offset from a text location.
|
||||
/// </summary>
|
||||
/// <seealso cref="GetLocation"/>
|
||||
int GetOffset(TextLocation location); |
||||
|
||||
/// <summary>
|
||||
/// Gets the location from an offset.
|
||||
/// </summary>
|
||||
/// <seealso cref="GetOffset(TextLocation)"/>
|
||||
TextLocation GetLocation(int offset); |
||||
|
||||
/// <summary>
|
||||
/// Inserts text.
|
||||
/// </summary>
|
||||
/// <param name="offset">The offset at which the text is inserted.</param>
|
||||
/// <param name="text">The new text.</param>
|
||||
/// <remarks>
|
||||
/// Anchors positioned exactly at the insertion offset will move according to their movement type.
|
||||
/// For AnchorMovementType.Default, they will move behind the inserted text.
|
||||
/// The caret will also move behind the inserted text.
|
||||
/// </remarks>
|
||||
void Insert(int offset, string text); |
||||
|
||||
/// <summary>
|
||||
/// Inserts text.
|
||||
/// </summary>
|
||||
/// <param name="offset">The offset at which the text is inserted.</param>
|
||||
/// <param name="text">The new text.</param>
|
||||
/// <param name="defaultAnchorMovementType">
|
||||
/// Anchors positioned exactly at the insertion offset will move according to the anchor's movement type.
|
||||
/// For AnchorMovementType.Default, they will move according to the movement type specified by this parameter.
|
||||
/// The caret will also move according to the <paramref name="defaultAnchorMovementType"/> parameter.
|
||||
/// </param>
|
||||
void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType); |
||||
|
||||
/// <summary>
|
||||
/// Removes text.
|
||||
/// </summary>
|
||||
/// <param name="offset">Starting offset of the text to be removed.</param>
|
||||
/// <param name="length">Length of the text to be removed.</param>
|
||||
void Remove(int offset, int length); |
||||
|
||||
/// <summary>
|
||||
/// Replaces text.
|
||||
/// </summary>
|
||||
/// <param name="offset">The starting offset of the text to be replaced.</param>
|
||||
/// <param name="length">The length of the text to be replaced.</param>
|
||||
/// <param name="newText">The new text.</param>
|
||||
void Replace(int offset, int length, string newText); |
||||
|
||||
/// <summary>
|
||||
/// Make the document combine the following actions into a single
|
||||
/// action for undo purposes.
|
||||
/// </summary>
|
||||
void StartUndoableAction(); |
||||
|
||||
/// <summary>
|
||||
/// Ends the undoable action started with <see cref="StartUndoableAction"/>.
|
||||
/// </summary>
|
||||
void EndUndoableAction(); |
||||
|
||||
/// <summary>
|
||||
/// Creates an undo group. Dispose the returned value to close the undo group.
|
||||
/// </summary>
|
||||
/// <returns>An object that closes the undo group when Dispose() is called.</returns>
|
||||
IDisposable OpenUndoGroup(); |
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ITextAnchor"/> at the specified offset.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="ITextAnchor" select="remarks|example"/>
|
||||
ITextAnchor CreateAnchor(int offset); |
||||
|
||||
/// <summary>
|
||||
/// This event is called directly before a change is applied to the document.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is invalid to modify the document within this event handler.
|
||||
/// Aborting the change (by throwing an exception) is likely to cause corruption of data structures
|
||||
/// that listen to the Changing and Changed events.
|
||||
/// </remarks>
|
||||
event EventHandler<TextChangeEventArgs> Changing; |
||||
|
||||
/// <summary>
|
||||
/// This event is called directly after a change is applied to the document.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is invalid to modify the document within this event handler.
|
||||
/// Aborting the event handler (by throwing an exception) is likely to cause corruption of data structures
|
||||
/// that listen to the Changing and Changed events.
|
||||
/// </remarks>
|
||||
event EventHandler<TextChangeEventArgs> Changed; |
||||
} |
||||
} |
||||
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.Editor |
||||
{ |
||||
/// <summary>
|
||||
/// A line inside a <see cref="IDocument"/>.
|
||||
/// </summary>
|
||||
public interface IDocumentLine : ISegment |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the length of this line, including the line delimiter.
|
||||
/// </summary>
|
||||
int TotalLength { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the line terminator.
|
||||
/// Returns 1 or 2; or 0 at the end of the document.
|
||||
/// </summary>
|
||||
int DelimiterLength { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the number of this line.
|
||||
/// The first line has the number 1.
|
||||
/// </summary>
|
||||
int LineNumber { get; } |
||||
} |
||||
} |
||||
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.Editor |
||||
{ |
||||
/// <summary>
|
||||
/// An (Offset,Length)-pair.
|
||||
/// </summary>
|
||||
public interface ISegment |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the start offset of the segment.
|
||||
/// </summary>
|
||||
int Offset { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the segment.
|
||||
/// </summary>
|
||||
/// <remarks>Must not be negative.</remarks>
|
||||
int Length { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the end offset of the segment.
|
||||
/// </summary>
|
||||
/// <remarks>EndOffset = Offset + Length;</remarks>
|
||||
int EndOffset { get; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="ISegment"/>.
|
||||
/// </summary>
|
||||
public static class ISegmentExtensions |
||||
{ |
||||
/// <summary>
|
||||
/// Gets whether the segment contains the offset.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// True, if offset is between segment.Start and segment.End (inclusive); otherwise, false.
|
||||
/// </returns>
|
||||
public static bool Contains (this ISegment segment, int offset) |
||||
{ |
||||
return segment.Offset <= offset && offset <= segment.EndOffset; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// True, if the segment contains the specified segment, false otherwise.
|
||||
/// </summary>
|
||||
public static bool Contains (this ISegment thisSegment, ISegment segment) |
||||
{ |
||||
return segment != null && thisSegment.Offset <= segment.Offset && segment.EndOffset <= thisSegment.EndOffset; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.Editor |
||||
{ |
||||
/// <summary>
|
||||
/// The TextAnchor class references an offset (a position between two characters).
|
||||
/// It automatically updates the offset when text is inserted/removed in front of the anchor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Use the <see cref="ITextAnchor.Offset"/> property to get the offset from a text anchor.
|
||||
/// Use the <see cref="IDocument.CreateAnchor"/> method to create an anchor from an offset.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The document will automatically update all text anchors; and because it uses weak references to do so,
|
||||
/// the garbage collector can simply collect the anchor object when you don't need it anymore.
|
||||
/// </para>
|
||||
/// <para>Moreover, the document is able to efficiently update a large number of anchors without having to look
|
||||
/// at each anchor object individually. Updating the offsets of all anchors usually only takes time logarithmic
|
||||
/// to the number of anchors. Retrieving the <see cref="ITextAnchor.Offset"/> property also runs in O(lg N).</para>
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// Usage:
|
||||
/// <code>TextAnchor anchor = document.CreateAnchor(offset);
|
||||
/// ChangeMyDocument();
|
||||
/// int newOffset = anchor.Offset;
|
||||
/// </code>
|
||||
/// </example>
|
||||
public interface ITextAnchor |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the text location of this anchor.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">Thrown when trying to get the Offset from a deleted anchor.</exception>
|
||||
TextLocation Location { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the offset of the text anchor.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">Thrown when trying to get the Offset from a deleted anchor.</exception>
|
||||
int Offset { get; } |
||||
|
||||
/// <summary>
|
||||
/// Controls how the anchor moves.
|
||||
/// </summary>
|
||||
AnchorMovementType MovementType { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// Specifies whether the anchor survives deletion of the text containing it.
|
||||
/// <c>false</c>: The anchor is deleted when the a selection that includes the anchor is deleted.
|
||||
/// <c>true</c>: The anchor is not deleted.
|
||||
/// </summary>
|
||||
bool SurviveDeletion { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// Gets whether the anchor was deleted.
|
||||
/// </summary>
|
||||
bool IsDeleted { get; } |
||||
|
||||
/// <summary>
|
||||
/// Occurs after the anchor was deleted.
|
||||
/// </summary>
|
||||
event EventHandler Deleted; |
||||
|
||||
/// <summary>
|
||||
/// Gets the line number of the anchor.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">Thrown when trying to get the Offset from a deleted anchor.</exception>
|
||||
int Line { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the column number of this anchor.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">Thrown when trying to get the Offset from a deleted anchor.</exception>
|
||||
int Column { get; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Defines how a text anchor moves.
|
||||
/// </summary>
|
||||
public enum AnchorMovementType |
||||
{ |
||||
/// <summary>
|
||||
/// When text is inserted at the anchor position, the type of the insertion
|
||||
/// determines where the caret moves to. For normal insertions, the anchor will stay
|
||||
/// behind the inserted text.
|
||||
/// </summary>
|
||||
Default, |
||||
/// <summary>
|
||||
/// Behaves like a start marker - when text is inserted at the anchor position, the anchor will stay
|
||||
/// before the inserted text.
|
||||
/// </summary>
|
||||
BeforeInsertion, |
||||
/// <summary>
|
||||
/// Behave like an end marker - when text is insered at the anchor position, the anchor will move
|
||||
/// after the inserted text.
|
||||
/// </summary>
|
||||
AfterInsertion |
||||
} |
||||
} |
||||
@ -0,0 +1,100 @@
@@ -0,0 +1,100 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace ICSharpCode.Editor |
||||
{ |
||||
/// <summary>
|
||||
/// Interface for text editors.
|
||||
/// </summary>
|
||||
public interface ITextEditor : IServiceProvider |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the document that is being edited.
|
||||
/// </summary>
|
||||
IDocument Document { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets an object that represents the caret inside this text editor.
|
||||
/// </summary>
|
||||
ITextEditorCaret Caret { get; } |
||||
|
||||
/// <summary>
|
||||
/// Sets the caret to the specified line/column and brings the caret into view.
|
||||
/// </summary>
|
||||
void JumpTo(int line, int column); |
||||
|
||||
/// <summary>
|
||||
/// Gets the start offset of the selection.
|
||||
/// </summary>
|
||||
int SelectionStart { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the selection.
|
||||
/// </summary>
|
||||
int SelectionLength { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the selected text.
|
||||
/// </summary>
|
||||
string SelectedText { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// Sets the selection.
|
||||
/// </summary>
|
||||
/// <param name="selectionStart">Start offset of the selection</param>
|
||||
/// <param name="selectionLength">Length of the selection</param>
|
||||
void Select(int selectionStart, int selectionLength); |
||||
|
||||
/// <summary>
|
||||
/// Shows the specified linked elements, and allows the user to edit them.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Returns true when the user has finished editing the elements and pressed Return;
|
||||
/// or false when editing is aborted for any reason.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// The user can also edit other parts of the document (or other documents) while in link mode.
|
||||
/// In case of success (true return value), this method will update the offsets of the linked elements
|
||||
/// to reflect the changes done by the user.
|
||||
/// If the text editor does not support link mode, it will immediately return false.
|
||||
/// </remarks>
|
||||
// Task<bool> ShowLinkedElements(IEnumerable<LinkedElement> linkedElements);
|
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Represents the caret in a text editor.
|
||||
/// </summary>
|
||||
public interface ITextEditorCaret |
||||
{ |
||||
/// <summary>
|
||||
/// Gets/Sets the caret offset;
|
||||
/// </summary>
|
||||
int Offset { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the caret line number.
|
||||
/// Line numbers are counted starting from 1.
|
||||
/// </summary>
|
||||
int Line { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the caret column number.
|
||||
/// Column numbers are counted starting from 1.
|
||||
/// </summary>
|
||||
int Column { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the caret location.
|
||||
/// </summary>
|
||||
TextLocation Location { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// Is raised whenever the location of the caret has changed.
|
||||
/// </summary>
|
||||
event EventHandler LocationChanged; |
||||
} |
||||
} |
||||
@ -0,0 +1,147 @@
@@ -0,0 +1,147 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
|
||||
namespace ICSharpCode.Editor |
||||
{ |
||||
/// <summary>
|
||||
/// A read-only view on a (potentially mutable) text source.
|
||||
/// The IDocument interfaces derives from this interface.
|
||||
/// </summary>
|
||||
public interface ITextSource |
||||
{ |
||||
/// <summary>
|
||||
/// Gets a version identifier for this text source.
|
||||
/// Returns null for unversioned text sources.
|
||||
/// </summary>
|
||||
ITextSourceVersion Version { get; } |
||||
|
||||
/// <summary>
|
||||
/// Creates an immutable snapshot of this text source.
|
||||
/// Unlike all other methods in this interface, this method is thread-safe.
|
||||
/// </summary>
|
||||
ITextSource CreateSnapshot(); |
||||
|
||||
/// <summary>
|
||||
/// Creates an immutable snapshot of a part of this text source.
|
||||
/// Unlike all other methods in this interface, this method is thread-safe.
|
||||
/// </summary>
|
||||
ITextSource CreateSnapshot(int offset, int length); |
||||
|
||||
/// <summary>
|
||||
/// Creates a new TextReader to read from this text source.
|
||||
/// </summary>
|
||||
TextReader CreateReader(); |
||||
|
||||
/// <summary>
|
||||
/// Creates a new TextReader to read from this text source.
|
||||
/// </summary>
|
||||
TextReader CreateReader(int offset, int length); |
||||
|
||||
/// <summary>
|
||||
/// Gets the total text length.
|
||||
/// </summary>
|
||||
/// <returns>The length of the text, in characters.</returns>
|
||||
/// <remarks>This is the same as Text.Length, but is more efficient because
|
||||
/// it doesn't require creating a String object.</remarks>
|
||||
int TextLength { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the whole text as string.
|
||||
/// </summary>
|
||||
string Text { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets a character at the specified position in the document.
|
||||
/// </summary>
|
||||
/// <paramref name="offset">The index of the character to get.</paramref>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Offset is outside the valid range (0 to TextLength-1).</exception>
|
||||
/// <returns>The character at the specified position.</returns>
|
||||
/// <remarks>This is the same as Text[offset], but is more efficient because
|
||||
/// it doesn't require creating a String object.</remarks>
|
||||
char GetCharAt(int offset); |
||||
|
||||
/// <summary>
|
||||
/// Retrieves the text for a portion of the document.
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentOutOfRangeException">offset or length is outside the valid range.</exception>
|
||||
/// <remarks>This is the same as Text.Substring, but is more efficient because
|
||||
/// it doesn't require creating a String object for the whole document.</remarks>
|
||||
string GetText(int offset, int length); |
||||
|
||||
/// <summary>
|
||||
/// Retrieves the text for a portion of the document.
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentOutOfRangeException">offset or length is outside the valid range.</exception>
|
||||
string GetText(ISegment segment); |
||||
|
||||
/// <summary>
|
||||
/// Gets the index of the first occurrence of any character in the specified array.
|
||||
/// </summary>
|
||||
/// <param name="anyOf">Characters to search for</param>
|
||||
/// <param name="startIndex">Start index of the search.</param>
|
||||
/// <param name="count">Length of the area to search.</param>
|
||||
/// <returns>The first index where any character was found; or -1 if no occurrence was found.</returns>
|
||||
int IndexOfAny(char[] anyOf, int startIndex, int count); |
||||
|
||||
/* What about: |
||||
void Insert (int offset, string value); |
||||
void Remove (int offset, int count); |
||||
void Remove (ISegment segment); |
||||
|
||||
void Replace (int offset, int count, string value); |
||||
|
||||
Or more search operations: |
||||
|
||||
IEnumerable<int> SearchForward (string pattern, int startIndex); |
||||
IEnumerable<int> SearchForwardIgnoreCase (string pattern, int startIndex); |
||||
|
||||
IEnumerable<int> SearchBackward (string pattern, int startIndex); |
||||
IEnumerable<int> SearchBackwardIgnoreCase (string pattern, int startIndex); |
||||
*/ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Represents a version identifier for a text source.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Verions can be used to efficiently detect whether a document has changed and needs reparsing;
|
||||
/// or even to implement incremental parsers.
|
||||
/// It is a separate class from ITextBuffer to allow the GC to collect the text buffer while
|
||||
/// the version checkpoint is still in use.
|
||||
/// </remarks>
|
||||
public interface ITextSourceVersion |
||||
{ |
||||
/// <summary>
|
||||
/// Gets whether this checkpoint belongs to the same document as the other checkpoint.
|
||||
/// </summary>
|
||||
bool BelongsToSameDocumentAs(ITextSourceVersion other); |
||||
|
||||
/// <summary>
|
||||
/// Compares the age of this checkpoint to the other checkpoint.
|
||||
/// </summary>
|
||||
/// <remarks>This method is thread-safe.</remarks>
|
||||
/// <exception cref="ArgumentException">Raised if 'other' belongs to a different document than this version.</exception>
|
||||
/// <returns>-1 if this version is older than <paramref name="other"/>.
|
||||
/// 0 if <c>this</c> version instance represents the same version as <paramref name="other"/>.
|
||||
/// 1 if this version is newer than <paramref name="other"/>.</returns>
|
||||
int CompareAge(ITextSourceVersion other); |
||||
|
||||
/// <summary>
|
||||
/// Gets the changes from this checkpoint to the other checkpoint.
|
||||
/// If 'other' is older than this checkpoint, reverse changes are calculated.
|
||||
/// </summary>
|
||||
/// <remarks>This method is thread-safe.</remarks>
|
||||
/// <exception cref="ArgumentException">Raised if 'other' belongs to a different document than this checkpoint.</exception>
|
||||
IEnumerable<TextChangeEventArgs> GetChangesTo(ITextSourceVersion other); |
||||
|
||||
/// <summary>
|
||||
/// Calculates where the offset has moved in the other buffer version.
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentException">Raised if 'other' belongs to a different document than this checkpoint.</exception>
|
||||
int MoveOffsetTo(ITextSourceVersion other, int oldOffset, AnchorMovementType movement); |
||||
} |
||||
} |
||||
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.Editor |
||||
{ |
||||
// I'm not sure if we need this.
|
||||
// How about a method in the context - this method could wrap the internal representation.
|
||||
// public void StartTextLinkMode (int linkLength, IEnumerable<int> offsets)
|
||||
// and maybe then variations taking more than one link element ?
|
||||
|
||||
// /// <summary>
|
||||
// /// Represents an element in the text editor that is either editable, or bound to another editable element.
|
||||
// /// Used with <see cref="ITextEditor.ShowLinkedElements"/>
|
||||
// /// </summary>
|
||||
// public class LinkedElement
|
||||
// {
|
||||
// LinkedElement boundTo;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Gets/Sets the start offset of this linked element.
|
||||
// /// </summary>
|
||||
// public int StartOffset { get; set; }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Gets/Sets the end offset of this linked element.
|
||||
// /// </summary>
|
||||
// public int EndOffset { get; set; }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Gets the linked element to which this element is bound.
|
||||
// /// </summary>
|
||||
// public LinkedElement BoundTo {
|
||||
// get { return boundTo; }
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Gets whether this element is editable. Returns true if this element is not bound.
|
||||
// /// </summary>
|
||||
// public bool IsEditable {
|
||||
// get { return boundTo == null; }
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Creates a new editable element.
|
||||
// /// </summary>
|
||||
// public LinkedElement(int startOffset, int endOffset)
|
||||
// {
|
||||
// this.StartOffset = startOffset;
|
||||
// this.EndOffset = endOffset;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Creates a new element that is bound to <paramref name="boundTo"/>.
|
||||
// /// </summary>
|
||||
// public LinkedElement(int startOffset, int endOffset, LinkedElement boundTo)
|
||||
// {
|
||||
// if (boundTo == null)
|
||||
// throw new ArgumentNullException("boundTo");
|
||||
// this.StartOffset = startOffset;
|
||||
// this.EndOffset = endOffset;
|
||||
// while (boundTo.boundTo != null)
|
||||
// boundTo = boundTo.boundTo;
|
||||
// this.boundTo = boundTo;
|
||||
// }
|
||||
// }
|
||||
} |
||||
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
#region Using directives
|
||||
|
||||
using System; |
||||
using System.Reflection; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
#endregion
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ICSharpCode.Editor")] |
||||
[assembly: AssemblyDescription("")] |
||||
[assembly: AssemblyConfiguration("")] |
||||
[assembly: AssemblyCompany("")] |
||||
[assembly: AssemblyProduct("ICSharpCode.Editor")] |
||||
[assembly: AssemblyCopyright("Copyright 2011")] |
||||
[assembly: AssemblyTrademark("")] |
||||
[assembly: AssemblyCulture("")] |
||||
|
||||
// This sets the default COM visibility of types in the assembly to invisible.
|
||||
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
||||
[assembly: ComVisible(false)] |
||||
|
||||
// The assembly version has following format :
|
||||
//
|
||||
// Major.Minor.Build.Revision
|
||||
//
|
||||
// You can specify all the values or you can use the default the Revision and
|
||||
// Build Numbers by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.0.*")] |
||||
@ -0,0 +1,321 @@
@@ -0,0 +1,321 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.Editor |
||||
{ |
||||
/// <summary>
|
||||
/// Read-only implementation of <see cref="IDocument"/>.
|
||||
/// </summary>
|
||||
public sealed class ReadOnlyDocument : IDocument |
||||
{ |
||||
readonly ITextSource textSource; |
||||
int[] lines; |
||||
|
||||
static readonly char[] newline = { '\r', '\n' }; |
||||
|
||||
/// <summary>
|
||||
/// Creates a new ReadOnlyDocument from the given text source.
|
||||
/// </summary>
|
||||
public ReadOnlyDocument(ITextSource textSource) |
||||
{ |
||||
if (textSource == null) |
||||
throw new ArgumentNullException("textSource"); |
||||
// ensure that underlying buffer is immutable
|
||||
this.textSource = textSource.CreateSnapshot(); |
||||
List<int> lines = new List<int>(); |
||||
lines.Add(0); |
||||
int offset = 0; |
||||
int textLength = textSource.TextLength; |
||||
while ((offset = textSource.IndexOfAny(newline, offset, textLength - offset)) >= 0) { |
||||
offset++; |
||||
if (textSource.GetCharAt(offset - 1) == '\r' && offset < textLength && textSource.GetCharAt(offset) == '\n') { |
||||
offset++; |
||||
} |
||||
lines.Add(offset); |
||||
} |
||||
this.lines = lines.ToArray(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a new ReadOnlyDocument from the given string.
|
||||
/// </summary>
|
||||
public ReadOnlyDocument(string text) |
||||
: this(new StringTextSource(text)) |
||||
{ |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public IDocumentLine GetLine(int lineNumber) |
||||
{ |
||||
if (lineNumber < 1 || lineNumber > lines.Length) |
||||
throw new ArgumentOutOfRangeException("lineNumber", lineNumber, "Value must be between 1 and " + lines.Length); |
||||
return new ReadOnlyDocumentLine(this, lineNumber); |
||||
} |
||||
|
||||
sealed class ReadOnlyDocumentLine : IDocumentLine |
||||
{ |
||||
readonly ReadOnlyDocument doc; |
||||
readonly int lineNumber; |
||||
readonly int offset, endOffset; |
||||
|
||||
public ReadOnlyDocumentLine(ReadOnlyDocument doc, int lineNumber) |
||||
{ |
||||
this.doc = doc; |
||||
this.lineNumber = lineNumber; |
||||
this.offset = doc.GetStartOffset(lineNumber); |
||||
this.endOffset = doc.GetEndOffset(lineNumber); |
||||
} |
||||
|
||||
public int Offset { |
||||
get { return offset; } |
||||
} |
||||
|
||||
public int Length { |
||||
get { return endOffset - offset; } |
||||
} |
||||
|
||||
public int EndOffset { |
||||
get { return endOffset; } |
||||
} |
||||
|
||||
public int TotalLength { |
||||
get { |
||||
return doc.GetTotalEndOffset(lineNumber) - offset; |
||||
} |
||||
} |
||||
|
||||
public int DelimiterLength { |
||||
get { |
||||
return doc.GetTotalEndOffset(lineNumber) - endOffset; |
||||
} |
||||
} |
||||
|
||||
public int LineNumber { |
||||
get { return lineNumber; } |
||||
} |
||||
} |
||||
|
||||
int GetStartOffset(int lineNumber) |
||||
{ |
||||
return lines[lineNumber-1]; |
||||
} |
||||
|
||||
int GetTotalEndOffset(int lineNumber) |
||||
{ |
||||
return lineNumber < lines.Length ? lines[lineNumber] : textSource.TextLength; |
||||
} |
||||
|
||||
int GetEndOffset(int lineNumber) |
||||
{ |
||||
if (lineNumber == lines.Length) |
||||
return textSource.TextLength; |
||||
int off = lines[lineNumber] - 1; |
||||
if (off > 0 && textSource.GetCharAt(off - 1) == '\r' && textSource.GetCharAt(off) == '\n') |
||||
off--; |
||||
return off; |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public IDocumentLine GetLineByOffset(int offset) |
||||
{ |
||||
return GetLine(GetLineNumberForOffset(offset)); |
||||
} |
||||
|
||||
int GetLineNumberForOffset(int offset) |
||||
{ |
||||
int r = Array.BinarySearch(lines, offset); |
||||
return r < 0 ? ~r : r + 1; |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public int GetOffset(int line, int column) |
||||
{ |
||||
if (line < 1 || line > lines.Length) |
||||
throw new ArgumentOutOfRangeException("line", line, "Value must be between 1 and " + lines.Length); |
||||
int lineStart = GetStartOffset(line); |
||||
if (column <= 0) |
||||
return lineStart; |
||||
int lineEnd = GetEndOffset(line); |
||||
if (column >= lineEnd - lineStart) |
||||
return lineEnd; |
||||
return lineStart + column - 1; |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public int GetOffset(TextLocation location) |
||||
{ |
||||
return GetOffset(location.Line, location.Column); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public TextLocation GetLocation(int offset) |
||||
{ |
||||
if (offset < 0 || offset > textSource.TextLength) |
||||
throw new ArgumentOutOfRangeException("offset", offset, "Value must be between 0 and " + textSource.TextLength); |
||||
int line = GetLineNumberForOffset(offset); |
||||
return new TextLocation(offset-GetStartOffset(line)+1, line); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public string Text { |
||||
get { return textSource.Text; } |
||||
set { |
||||
throw new NotSupportedException(); |
||||
} |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public int TotalNumberOfLines { |
||||
get { return lines.Length; } |
||||
} |
||||
|
||||
ITextSourceVersion ITextSource.Version { |
||||
get { return null; } |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public int TextLength { |
||||
get { return textSource.TextLength; } |
||||
} |
||||
|
||||
event EventHandler<TextChangeEventArgs> IDocument.Changing { add {} remove {} } |
||||
|
||||
event EventHandler<TextChangeEventArgs> IDocument.Changed { add {} remove {} } |
||||
|
||||
event EventHandler IDocument.TextChanged { add {} remove {} } |
||||
|
||||
void IDocument.Insert(int offset, string text) |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
void IDocument.Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType) |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
void IDocument.Remove(int offset, int length) |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
void IDocument.Replace(int offset, int length, string newText) |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
void IDocument.StartUndoableAction() |
||||
{ |
||||
} |
||||
|
||||
void IDocument.EndUndoableAction() |
||||
{ |
||||
} |
||||
|
||||
IDisposable IDocument.OpenUndoGroup() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public ITextAnchor CreateAnchor(int offset) |
||||
{ |
||||
return new ReadOnlyDocumentTextAnchor(GetLocation(offset), offset); |
||||
} |
||||
|
||||
sealed class ReadOnlyDocumentTextAnchor : ITextAnchor |
||||
{ |
||||
readonly TextLocation location; |
||||
readonly int offset; |
||||
|
||||
public ReadOnlyDocumentTextAnchor(TextLocation location, int offset) |
||||
{ |
||||
this.location = location; |
||||
this.offset = offset; |
||||
} |
||||
|
||||
public event EventHandler Deleted { add {} remove {} } |
||||
|
||||
public TextLocation Location { |
||||
get { return location; } |
||||
} |
||||
|
||||
public int Offset { |
||||
get { return offset; } |
||||
} |
||||
|
||||
public AnchorMovementType MovementType { get; set; } |
||||
|
||||
public bool SurviveDeletion { get; set; } |
||||
|
||||
public bool IsDeleted { |
||||
get { return false; } |
||||
} |
||||
|
||||
public int Line { |
||||
get { return location.Line; } |
||||
} |
||||
|
||||
public int Column { |
||||
get { return location.Column; } |
||||
} |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public ITextSource CreateSnapshot() |
||||
{ |
||||
return textSource; // textBuffer is immutable
|
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public ITextSource CreateSnapshot(int offset, int length) |
||||
{ |
||||
return textSource.CreateSnapshot(offset, length); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public System.IO.TextReader CreateReader() |
||||
{ |
||||
return textSource.CreateReader(); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public System.IO.TextReader CreateReader(int offset, int length) |
||||
{ |
||||
return textSource.CreateReader(offset, length); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public char GetCharAt(int offset) |
||||
{ |
||||
return textSource.GetCharAt(offset); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public string GetText(int offset, int length) |
||||
{ |
||||
return textSource.GetText(offset, length); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public string GetText(ISegment segment) |
||||
{ |
||||
return textSource.GetText(segment); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public int IndexOfAny(char[] anyOf, int startIndex, int count) |
||||
{ |
||||
return textSource.IndexOfAny(anyOf, startIndex, count); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public object GetService(Type serviceType) |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,91 @@
@@ -0,0 +1,91 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.IO; |
||||
|
||||
namespace ICSharpCode.Editor |
||||
{ |
||||
/// <summary>
|
||||
/// Implements the ITextSource interface using a string.
|
||||
/// </summary>
|
||||
[Serializable] |
||||
public class StringTextSource : ITextSource |
||||
{ |
||||
readonly string text; |
||||
|
||||
/// <summary>
|
||||
/// Creates a new StringTextSource with the given text.
|
||||
/// </summary>
|
||||
public StringTextSource(string text) |
||||
{ |
||||
if (text == null) |
||||
throw new ArgumentNullException("text"); |
||||
this.text = text; |
||||
} |
||||
|
||||
ITextSourceVersion ITextSource.Version { |
||||
get { return null; } |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public int TextLength { |
||||
get { return text.Length; } |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public string Text { |
||||
get { return text; } |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public ITextSource CreateSnapshot() |
||||
{ |
||||
return this; // StringTextBuffer is immutable
|
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public ITextSource CreateSnapshot(int offset, int length) |
||||
{ |
||||
return new StringTextSource(text.Substring(offset, length)); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public TextReader CreateReader() |
||||
{ |
||||
return new StringReader(text); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public TextReader CreateReader(int offset, int length) |
||||
{ |
||||
return new StringReader(text.Substring(offset, length)); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public char GetCharAt(int offset) |
||||
{ |
||||
return text[offset]; |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public string GetText(int offset, int length) |
||||
{ |
||||
return text.Substring(offset, length); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public string GetText(ISegment segment) |
||||
{ |
||||
if (segment == null) |
||||
throw new ArgumentNullException("segment"); |
||||
return text.Substring(segment.Offset, segment.Length); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public int IndexOfAny(char[] anyOf, int startIndex, int count) |
||||
{ |
||||
return text.IndexOfAny(anyOf, startIndex, count); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.Editor |
||||
{ |
||||
/// <summary>
|
||||
/// Describes a change of the document text.
|
||||
/// This class is thread-safe.
|
||||
/// </summary>
|
||||
[Serializable] |
||||
public class TextChangeEventArgs : EventArgs |
||||
{ |
||||
readonly int offset; |
||||
readonly string removedText; |
||||
readonly string insertedText; |
||||
|
||||
/// <summary>
|
||||
/// The offset at which the change occurs.
|
||||
/// </summary>
|
||||
public int Offset { |
||||
get { return offset; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The text that was inserted.
|
||||
/// </summary>
|
||||
public string RemovedText { |
||||
get { return removedText; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The number of characters removed.
|
||||
/// </summary>
|
||||
public int RemovalLength { |
||||
get { return removedText.Length; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The text that was inserted.
|
||||
/// </summary>
|
||||
public string InsertedText { |
||||
get { return insertedText; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The number of characters inserted.
|
||||
/// </summary>
|
||||
public int InsertionLength { |
||||
get { return insertedText.Length; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a new TextChangeEventArgs object.
|
||||
/// </summary>
|
||||
public TextChangeEventArgs(int offset, string removedText, string insertedText) |
||||
{ |
||||
this.offset = offset; |
||||
this.removedText = removedText ?? string.Empty; |
||||
this.insertedText = insertedText ?? string.Empty; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,173 @@
@@ -0,0 +1,173 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Globalization; |
||||
|
||||
namespace ICSharpCode.Editor |
||||
{ |
||||
/// <summary>
|
||||
/// A line/column position.
|
||||
/// Text editor lines/columns are counted started from one.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The document provides the methods <see cref="IDocument.GetLocation"/> and
|
||||
/// <see cref="IDocument.GetOffset(TextLocation)"/> to convert between offsets and TextLocations.
|
||||
/// </remarks>
|
||||
[Serializable] |
||||
public struct TextLocation : IComparable<TextLocation>, IEquatable<TextLocation> |
||||
{ |
||||
/// <summary>
|
||||
/// Represents no text location (0, 0).
|
||||
/// </summary>
|
||||
public static readonly TextLocation Empty = new TextLocation(0, 0); |
||||
|
||||
/// <summary>
|
||||
/// Constant of the minimum line.
|
||||
/// </summary>
|
||||
public const int MinLine = 1; |
||||
|
||||
/// <summary>
|
||||
/// Constant of the minimum column.
|
||||
/// </summary>
|
||||
public const int MinColumn = 1; |
||||
|
||||
/// <summary>
|
||||
/// Creates a TextLocation instance.
|
||||
/// </summary>
|
||||
public TextLocation(int line, int column) |
||||
{ |
||||
this.line = line; |
||||
this.column = column; |
||||
} |
||||
|
||||
int column, line; |
||||
|
||||
/// <summary>
|
||||
/// Gets the line number.
|
||||
/// </summary>
|
||||
public int Line { |
||||
get { return line; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the column number.
|
||||
/// </summary>
|
||||
public int Column { |
||||
get { return column; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets whether the TextLocation instance is empty.
|
||||
/// </summary>
|
||||
public bool IsEmpty { |
||||
get { |
||||
return column < MinLine && line < MinColumn; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets a string representation for debugging purposes.
|
||||
/// </summary>
|
||||
public override string ToString() |
||||
{ |
||||
return string.Format(CultureInfo.InvariantCulture, "(Line {1}, Col {0})", this.column, this.line); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets a hash code.
|
||||
/// </summary>
|
||||
public override int GetHashCode() |
||||
{ |
||||
return unchecked (191 * column.GetHashCode() ^ line.GetHashCode()); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Equality test.
|
||||
/// </summary>
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
if (!(obj is TextLocation)) return false; |
||||
return (TextLocation)obj == this; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Equality test.
|
||||
/// </summary>
|
||||
public bool Equals(TextLocation other) |
||||
{ |
||||
return this == other; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Equality test.
|
||||
/// </summary>
|
||||
public static bool operator ==(TextLocation left, TextLocation right) |
||||
{ |
||||
return left.column == right.column && left.line == right.line; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Inequality test.
|
||||
/// </summary>
|
||||
public static bool operator !=(TextLocation left, TextLocation right) |
||||
{ |
||||
return left.column != right.column || left.line != right.line; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Compares two text locations.
|
||||
/// </summary>
|
||||
public static bool operator <(TextLocation left, TextLocation right) |
||||
{ |
||||
if (left.line < right.line) |
||||
return true; |
||||
else if (left.line == right.line) |
||||
return left.column < right.column; |
||||
else |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Compares two text locations.
|
||||
/// </summary>
|
||||
public static bool operator >(TextLocation left, TextLocation right) |
||||
{ |
||||
if (left.line > right.line) |
||||
return true; |
||||
else if (left.line == right.line) |
||||
return left.column > right.column; |
||||
else |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Compares two text locations.
|
||||
/// </summary>
|
||||
public static bool operator <=(TextLocation left, TextLocation right) |
||||
{ |
||||
return !(left > right); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Compares two text locations.
|
||||
/// </summary>
|
||||
public static bool operator >=(TextLocation left, TextLocation right) |
||||
{ |
||||
return !(left < right); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Compares two text locations.
|
||||
/// </summary>
|
||||
public int CompareTo(TextLocation other) |
||||
{ |
||||
if (this == other) |
||||
return 0; |
||||
if (this < other) |
||||
return -1; |
||||
else |
||||
return 1; |
||||
} |
||||
} |
||||
} |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue