Browse Source

Allow data-binding to the TextEditor.SyntaxHighlighting property.

Make HighlightingManager thread-safe.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4972 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 16 years ago
parent
commit
b4142ddb14
  1. 8
      samples/AvalonEdit.Sample/App.xaml
  2. 19
      samples/AvalonEdit.Sample/App.xaml.cs
  3. 100
      samples/AvalonEdit.Sample/AvalonEdit.Sample.csproj
  4. BIN
      samples/AvalonEdit.Sample/Images/Copy.png
  5. BIN
      samples/AvalonEdit.Sample/Images/Cut.png
  6. BIN
      samples/AvalonEdit.Sample/Images/Delete.png
  7. BIN
      samples/AvalonEdit.Sample/Images/Open.png
  8. BIN
      samples/AvalonEdit.Sample/Images/Paste.png
  9. BIN
      samples/AvalonEdit.Sample/Images/Redo.png
  10. BIN
      samples/AvalonEdit.Sample/Images/Save.png
  11. BIN
      samples/AvalonEdit.Sample/Images/Undo.png
  12. BIN
      samples/AvalonEdit.Sample/Images/WordWrap.png
  13. 31
      samples/AvalonEdit.Sample/Properties/AssemblyInfo.cs
  14. 27
      samples/AvalonEdit.Sample/Properties/WPFAssemblyInfo.cs
  15. 69
      samples/AvalonEdit.Sample/Window1.xaml
  16. 78
      samples/AvalonEdit.Sample/Window1.xaml.cs
  17. 196
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingManager.cs
  18. 5
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Xshd/XmlHighlightingDefinition.cs
  19. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
  20. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Properties/AssemblyInfo.cs
  21. 44
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs
  22. 59
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/BusyManager.cs

8
samples/AvalonEdit.Sample/App.xaml

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
<Application x:Class="AvalonEdit.Sample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
</Application.Resources>
</Application>

19
samples/AvalonEdit.Sample/App.xaml.cs

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
using System;
using System.Windows;
using System.Data;
using System.Xml;
using System.Configuration;
namespace AvalonEdit.Sample
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public App()
{
InitializeComponent();
}
}
}

100
samples/AvalonEdit.Sample/AvalonEdit.Sample.csproj

@ -0,0 +1,100 @@ @@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<ProjectGuid>{13A5B497-BA12-45AE-9033-22620C3153FB}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>WinExe</OutputType>
<RootNamespace>AvalonEdit.Sample</RootNamespace>
<AssemblyName>AvalonEdit.Sample</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<AppDesignerFolder>Properties</AppDesignerFolder>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<PlatformTarget>x86</PlatformTarget>
</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>
</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="PresentationCore">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="PresentationFramework">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsFormsIntegration">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml" />
</ItemGroup>
<ItemGroup>
<Compile Include="App.xaml.cs">
<SubType>Code</SubType>
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\WPFAssemblyInfo.cs" />
<Compile Include="Window1.xaml.cs">
<SubType>Code</SubType>
<DependentUpon>Window1.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="Window1.xaml" />
</ItemGroup>
<ItemGroup>
<Resource Include="Images\Copy.png" />
<Resource Include="Images\Cut.png" />
<Resource Include="Images\Delete.png" />
<Resource Include="Images\Open.png" />
<Resource Include="Images\Paste.png" />
<Resource Include="Images\Redo.png" />
<Resource Include="Images\Save.png" />
<Resource Include="Images\Undo.png" />
<Resource Include="Images\WordWrap.png" />
</ItemGroup>
<ItemGroup>
<Folder Include="Images" />
<Folder Include="Images" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj">
<Project>{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}</Project>
<Name>ICSharpCode.AvalonEdit</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

BIN
samples/AvalonEdit.Sample/Images/Copy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

BIN
samples/AvalonEdit.Sample/Images/Cut.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

BIN
samples/AvalonEdit.Sample/Images/Delete.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

BIN
samples/AvalonEdit.Sample/Images/Open.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
samples/AvalonEdit.Sample/Images/Paste.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

BIN
samples/AvalonEdit.Sample/Images/Redo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

BIN
samples/AvalonEdit.Sample/Images/Save.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

BIN
samples/AvalonEdit.Sample/Images/Undo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 B

BIN
samples/AvalonEdit.Sample/Images/WordWrap.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

31
samples/AvalonEdit.Sample/Properties/AssemblyInfo.cs

@ -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("AvalonEdit.Sample")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AvalonEdit.Sample")]
[assembly: AssemblyCopyright("Copyright 2009")]
[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.*")]

27
samples/AvalonEdit.Sample/Properties/WPFAssemblyInfo.cs

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
#region Using directives
using System.Resources;
using System.Windows;
#endregion
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

69
samples/AvalonEdit.Sample/Window1.xaml

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
<Window x:Class="AvalonEdit.Sample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
xmlns:forms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="AvalonEdit.Sample" Height="500" Width="700"
>
<DockPanel>
<ToolBar DockPanel.Dock="Top">
<ToolBar.Resources>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ButtonBase}, AncestorLevel=1}, Path=IsEnabled}" Value="False">
<Setter Property="Opacity" Value="0.30" />
</DataTrigger>
</Style.Triggers>
</Style>
</ToolBar.Resources>
<Button Click="openFileClick"><Image Source="Images/Open.png" Height="16"/></Button>
<Button Click="saveFileClick"><Image Source="Images/Save.png" Height="16"/></Button>
<Separator/>
<Button Command="Cut"><Image Source="Images/Cut.png" Height="16"/></Button>
<Button Command="Copy"><Image Source="Images/Copy.png" Height="16"/></Button>
<Button Command="Paste"><Image Source="Images/Paste.png" Height="16"/></Button>
<Button Command="Delete"><Image Source="Images/Delete.png" Height="16"/></Button>
<Separator/>
<Button Command="Undo"><Image Source="Images/Undo.png" Height="16"/></Button>
<Button Command="Redo"><Image Source="Images/Redo.png" Height="16"/></Button>
<Separator/>
<CheckBox IsChecked="{Binding ElementName=textEditor,Path=WordWrap}">
<Image Source="Images/WordWrap.png" Height="16"/>
</CheckBox>
<CheckBox IsChecked="{Binding ElementName=textEditor,Path=ShowLineNumbers}">
<TextBlock Width="16" TextAlignment="Center">#</TextBlock>
</CheckBox>
<CheckBox IsChecked="{Binding ElementName=textEditor,Path=Options.ShowEndOfLine}">
<TextBlock Width="16" TextAlignment="Center">¶</TextBlock>
</CheckBox>
<ComboBox Name="highlightingComboBox"
SelectedItem="{Binding SyntaxHighlighting, ElementName=textEditor}"
ItemsSource="{Binding Source={x:Static avalonEdit:HighlightingManager.Instance}, Path=Highlightings}"/>
</ToolBar>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<avalonEdit:TextEditor
Name="textEditor"
FontFamily="Consolas"
FontSize="10pt"
>
Initial Text
</avalonEdit:TextEditor>
<GridSplitter Grid.Column="1" Width="4" HorizontalAlignment="Left"/>
<DockPanel Grid.Column="1" Margin="4 0 0 0">
<ComboBox Name="propertyGridComboBox" DockPanel.Dock="Top"
SelectedIndex="0" SelectionChanged="propertyGridComboBoxSelectionChanged">
<ComboBoxItem>TextEditor</ComboBoxItem>
<ComboBoxItem>Options</ComboBoxItem>
<ComboBoxItem>TextArea</ComboBoxItem>
</ComboBox>
<WindowsFormsHost DockPanel.Dock="Right" Name="propertyGridHost">
<forms:PropertyGrid x:Name="propertyGrid"/>
</WindowsFormsHost>
</DockPanel>
</Grid>
</DockPanel>
</Window>

78
samples/AvalonEdit.Sample/Window1.xaml.cs

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
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.AvalonEdit.Highlighting;
using Microsoft.Win32;
namespace AvalonEdit.Sample
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
string currentFileName;
void openFileClick(object sender, RoutedEventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.CheckFileExists = true;
if (dlg.ShowDialog() ?? false) {
currentFileName = dlg.FileName;
textEditor.Load(currentFileName);
textEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(currentFileName));
}
}
void saveFileClick(object sender, EventArgs e)
{
if (currentFileName == null) {
SaveFileDialog dlg = new SaveFileDialog();
dlg.DefaultExt = ".txt";
if (dlg.ShowDialog() ?? false) {
currentFileName = dlg.FileName;
} else {
return;
}
}
textEditor.Save(currentFileName);
}
void propertyGridComboBoxSelectionChanged(object sender, RoutedEventArgs e)
{
if (propertyGrid == null)
return;
switch (propertyGridComboBox.SelectedIndex) {
case 0:
propertyGrid.SelectedObject = textEditor;
break;
case 1:
propertyGrid.SelectedObject = textEditor.Options;
break;
case 2:
propertyGrid.SelectedObject = textEditor.TextArea;
break;
}
}
}
}

196
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingManager.cs

@ -7,25 +7,105 @@ @@ -7,25 +7,105 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Xml;
using ICSharpCode.AvalonEdit.Utils;
namespace ICSharpCode.AvalonEdit.Highlighting
{
/// <summary>
/// Manages a list of syntax highlighting definitions.
/// </summary>
/// <remarks>
/// All memers on this class (including instance members) are thread-safe.
/// </remarks>
public class HighlightingManager : IHighlightingDefinitionReferenceResolver
{
sealed class RegisteredHighlighting
sealed class DelayLoadedHighlightingDefinition : IHighlightingDefinition
{
public IHighlightingDefinition Definition;
public Func<IHighlightingDefinition> LazyLoadingFunction;
readonly object lockObj = new object();
readonly string name;
Func<IHighlightingDefinition> lazyLoadingFunction;
IHighlightingDefinition definition;
Exception storedException;
public DelayLoadedHighlightingDefinition(string name, Func<IHighlightingDefinition> lazyLoadingFunction)
{
this.name = name;
this.lazyLoadingFunction = lazyLoadingFunction;
}
public string Name {
get {
if (name != null)
return name;
else
return GetDefinition().Name;
}
}
IHighlightingDefinition GetDefinition()
{
Func<IHighlightingDefinition> func;
lock (lockObj) {
if (this.definition != null)
return this.definition;
func = this.lazyLoadingFunction;
}
Exception exception = null;
IHighlightingDefinition def = null;
try {
using (var busyLock = BusyManager.Enter(this)) {
if (!busyLock.Success)
throw new InvalidOperationException("Tried to create delay-loaded highlighting definition recursively. Make sure the are no cyclic references between the highlighting definitions.");
def = func();
}
if (def == null)
throw new InvalidOperationException("Function for delay-loading highlighting definition returned null");
} catch (Exception ex) {
exception = ex;
}
lock (lockObj) {
this.lazyLoadingFunction = null;
if (this.definition == null && this.storedException == null) {
this.definition = def;
this.storedException = exception;
}
if (this.storedException != null)
throw new HighlightingDefinitionInvalidException("Error delay-loading highlighting definition", this.storedException);
return this.definition;
}
}
public HighlightingRuleSet MainRuleSet {
get {
return GetDefinition().MainRuleSet;
}
}
public HighlightingRuleSet GetNamedRuleSet(string name)
{
return GetDefinition().GetNamedRuleSet(name);
}
public HighlightingColor GetNamedColor(string name)
{
return GetDefinition().GetNamedColor(name);
}
public override string ToString()
{
return this.Name;
}
}
Dictionary<string, RegisteredHighlighting> highlightingsByName = new Dictionary<string, RegisteredHighlighting>();
Dictionary<string, RegisteredHighlighting> highlightingsByExtension = new Dictionary<string, RegisteredHighlighting>(StringComparer.OrdinalIgnoreCase);
readonly object lockObj = new object();
Dictionary<string, IHighlightingDefinition> highlightingsByName = new Dictionary<string, IHighlightingDefinition>();
Dictionary<string, IHighlightingDefinition> highlightingsByExtension = new Dictionary<string, IHighlightingDefinition>(StringComparer.OrdinalIgnoreCase);
List<IHighlightingDefinition> allHighlightings = new List<IHighlightingDefinition>();
/// <summary>
/// Gets a highlighting definition by name.
@ -33,18 +113,36 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -33,18 +113,36 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// </summary>
public IHighlightingDefinition GetDefinition(string name)
{
RegisteredHighlighting rh;
if (highlightingsByName.TryGetValue(name, out rh))
return GetDefinition(rh);
else
return null;
lock (lockObj) {
IHighlightingDefinition rh;
if (highlightingsByName.TryGetValue(name, out rh))
return rh;
else
return null;
}
}
/// <summary>
/// Gets a copy of all highlightings.
/// </summary>
public ReadOnlyCollection<IHighlightingDefinition> Highlightings {
get {
lock (lockObj) {
return Array.AsReadOnly(allHighlightings.ToArray());
}
}
}
/// <summary>
/// Gets the names of the registered highlightings.
/// </summary>
[ObsoleteAttribute("Use the Highlightings property instead.")]
public IEnumerable<string> HighlightingNames {
get { return highlightingsByName.Keys; }
get {
lock (lockObj) {
return new List<string>(highlightingsByName.Keys);
}
}
}
/// <summary>
@ -53,25 +151,12 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -53,25 +151,12 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// </summary>
public IHighlightingDefinition GetDefinitionByExtension(string extension)
{
RegisteredHighlighting rh;
if (highlightingsByExtension.TryGetValue(extension, out rh))
return GetDefinition(rh);
else
return null;
}
static IHighlightingDefinition GetDefinition(RegisteredHighlighting rh)
{
if (rh != null) {
var func = rh.LazyLoadingFunction;
if (func != null) {
// prevent endless recursion when there are cyclic references between syntax definitions
rh.LazyLoadingFunction = null;
rh.Definition = func();
}
return rh.Definition;
} else {
return null;
lock (lockObj) {
IHighlightingDefinition rh;
if (highlightingsByExtension.TryGetValue(extension, out rh))
return rh;
else
return null;
}
}
@ -85,7 +170,18 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -85,7 +170,18 @@ namespace ICSharpCode.AvalonEdit.Highlighting
{
if (highlighting == null)
throw new ArgumentNullException("highlighting");
RegisterHighlighting(name, extensions, new RegisteredHighlighting { Definition = highlighting });
lock (lockObj) {
allHighlightings.Add(highlighting);
if (name != null) {
highlightingsByName[name] = highlighting;
}
if (extensions != null) {
foreach (string ext in extensions) {
highlightingsByExtension[ext] = highlighting;
}
}
}
}
/// <summary>
@ -98,19 +194,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -98,19 +194,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
{
if (lazyLoadedHighlighting == null)
throw new ArgumentNullException("lazyLoadedHighlighting");
RegisterHighlighting(name, extensions, new RegisteredHighlighting { LazyLoadingFunction = lazyLoadedHighlighting });
}
void RegisterHighlighting(string name, string[] extensions, RegisteredHighlighting rh)
{
if (name != null) {
highlightingsByName[name] = rh;
}
if (extensions != null) {
foreach (string ext in extensions) {
highlightingsByExtension[ext] = rh;
}
}
RegisterHighlighting(name, extensions, new DelayLoadedHighlightingDefinition(name, lazyLoadedHighlighting));
}
/// <summary>
@ -136,7 +220,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -136,7 +220,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
internal void RegisterHighlighting(string name, string[] extensions, string resourceName)
{
try {
#if DEBUG
#if false //DEBUG
// don't use lazy-loading in debug builds, show errors immediately
Xshd.XshdSyntaxDefinition xshd;
using (Stream s = Resources.OpenStream(resourceName)) {
@ -151,17 +235,17 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -151,17 +235,17 @@ namespace ICSharpCode.AvalonEdit.Highlighting
Debug.Assert(xshd.Extensions.Count == 0);
// round-trip xshd:
string resourceFileName = Path.Combine(Path.GetTempPath(), resourceName);
using (XmlTextWriter writer = new XmlTextWriter(resourceFileName, System.Text.Encoding.UTF8)) {
writer.Formatting = Formatting.Indented;
new Xshd.SaveXshdVisitor(writer).WriteDefinition(xshd);
}
using (FileStream fs = File.Create(resourceFileName + ".bin")) {
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(fs, xshd);
}
using (FileStream fs = File.Create(resourceFileName + ".compiled")) {
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(fs, Xshd.HighlightingLoader.Load(xshd, this));
}
// string resourceFileName = Path.Combine(Path.GetTempPath(), resourceName);
// using (XmlTextWriter writer = new XmlTextWriter(resourceFileName, System.Text.Encoding.UTF8)) {
// writer.Formatting = Formatting.Indented;
// new Xshd.SaveXshdVisitor(writer).WriteDefinition(xshd);
// }
// using (FileStream fs = File.Create(resourceFileName + ".bin")) {
// new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(fs, xshd);
// }
// using (FileStream fs = File.Create(resourceFileName + ".compiled")) {
// new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(fs, Xshd.HighlightingLoader.Load(xshd, this));
// }
RegisterHighlighting(name, extensions, Xshd.HighlightingLoader.Load(xshd, this));
#else

5
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Xshd/XmlHighlightingDefinition.cs

@ -346,5 +346,10 @@ namespace ICSharpCode.AvalonEdit.Highlighting.Xshd @@ -346,5 +346,10 @@ namespace ICSharpCode.AvalonEdit.Highlighting.Xshd
else
return null;
}
public override string ToString()
{
return this.Name;
}
}
}

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj

@ -296,6 +296,7 @@ @@ -296,6 +296,7 @@
</Compile>
<Compile Include="TextViewPosition.cs" />
<Compile Include="Utils\Boxes.cs" />
<Compile Include="Utils\BusyManager.cs" />
<Compile Include="Utils\CharRope.cs" />
<Compile Include="Utils\CompressingTreeList.cs" />
<Compile Include="Utils\Constants.cs" />

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Properties/AssemblyInfo.cs

@ -37,3 +37,4 @@ using System.Windows.Markup; @@ -37,3 +37,4 @@ using System.Windows.Markup;
[assembly: XmlnsDefinition("http://icsharpcode.net/sharpdevelop/avalonedit", "ICSharpCode.AvalonEdit")]
[assembly: XmlnsDefinition("http://icsharpcode.net/sharpdevelop/avalonedit", "ICSharpCode.AvalonEdit.Editing")]
[assembly: XmlnsDefinition("http://icsharpcode.net/sharpdevelop/avalonedit", "ICSharpCode.AvalonEdit.Rendering")]
[assembly: XmlnsDefinition("http://icsharpcode.net/sharpdevelop/avalonedit", "ICSharpCode.AvalonEdit.Highlighting")]

44
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs

@ -291,27 +291,39 @@ namespace ICSharpCode.AvalonEdit @@ -291,27 +291,39 @@ namespace ICSharpCode.AvalonEdit
#endregion
#region Syntax highlighting
IHighlightingDefinition syntaxHighlighting;
HighlightingColorizer colorizer;
/// <summary>
/// The <see cref="SyntaxHighlighting"/> property.
/// </summary>
public static readonly DependencyProperty SyntaxHighlightingProperty =
DependencyProperty.Register("SyntaxHighlighting", typeof(IHighlightingDefinition), typeof(TextEditor),
new FrameworkPropertyMetadata(OnSyntaxHighlightingChanged));
/// <summary>
/// Gets/sets the syntax highlighting definition used to colorize the text.
/// </summary>
public IHighlightingDefinition SyntaxHighlighting {
get { return syntaxHighlighting; }
set {
if (syntaxHighlighting != value) {
if (colorizer != null) {
this.TextArea.TextView.LineTransformers.Remove(colorizer);
colorizer = null;
}
syntaxHighlighting = value;
if (value != null) {
TextView textView = this.TextArea.TextView;
colorizer = new HighlightingColorizer(textView, value.MainRuleSet);
textView.LineTransformers.Insert(0, colorizer);
}
}
get { return (IHighlightingDefinition)GetValue(SyntaxHighlightingProperty); }
set { SetValue(SyntaxHighlightingProperty, value); }
}
HighlightingColorizer colorizer;
static void OnSyntaxHighlightingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((TextEditor)d).OnSyntaxHighlightingChanged(e.NewValue as IHighlightingDefinition);
}
void OnSyntaxHighlightingChanged(IHighlightingDefinition newValue)
{
if (colorizer != null) {
this.TextArea.TextView.LineTransformers.Remove(colorizer);
colorizer = null;
}
if (newValue != null) {
TextView textView = this.TextArea.TextView;
colorizer = new HighlightingColorizer(textView, newValue.MainRuleSet);
textView.LineTransformers.Insert(0, colorizer);
}
}
#endregion

59
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/BusyManager.cs

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
namespace ICSharpCode.AvalonEdit.Utils
{
/// <summary>
/// This class is used to prevent stack overflows by representing a 'busy' flag
/// that prevents reentrance when another call is running.
/// However, using a simple 'bool busy' is not thread-safe, so we use a
/// thread-static BusyManager.
/// </summary>
static class BusyManager
{
public struct BusyLock : IDisposable
{
public static readonly BusyLock Failed = new BusyLock(null);
readonly List<object> objectList;
public BusyLock(List<object> objectList)
{
this.objectList = objectList;
}
public bool Success {
get { return objectList != null; }
}
public void Dispose()
{
if (objectList != null) {
objectList.RemoveAt(objectList.Count - 1);
}
}
}
[ThreadStatic] static List<object> _activeObjects;
public static BusyLock Enter(object obj)
{
List<object> activeObjects = _activeObjects;
if (activeObjects == null)
activeObjects = _activeObjects = new List<object>();
for (int i = 0; i < activeObjects.Count; i++) {
if (activeObjects[i] == obj)
return BusyLock.Failed;
}
activeObjects.Add(obj);
return new BusyLock(activeObjects);
}
}
}
Loading…
Cancel
Save