⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defaulthighlightingstrategy.cs

📁 c#源代码
💻 CS
📖 第 1 页 / 共 2 页
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Mike Kr黦er" email="mike@icsharpcode.net"/>
//     <version value="$version"/>
// </file>

using System;
using System.Drawing;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Collections;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;
using System.Text;

namespace ICSharpCode.TextEditor.Document
{
	public class DefaultHighlightingStrategy : IHighlightingStrategy
	{
		string    name;
		ArrayList rules = new ArrayList();
		
		Hashtable environmentColors = new Hashtable();
		Hashtable properties       = new Hashtable();
		string[]  extensions;
		
		HighlightColor   digitColor;
		HighlightRuleSet defaultRuleSet = null;
		
		public HighlightColor DigitColor {
			get {
				return digitColor;
			}
			set {
				digitColor = value;
			}
		}
		
		
		public DefaultHighlightingStrategy() : this("Default")
		{
		}
		
		public DefaultHighlightingStrategy(string name) 
		{
			this.name = name;
			
			digitColor      = new HighlightBackground("WindowText", "Window", false, false);
			
			// set small 'default color environment'
			environmentColors["DefaultBackground"]= new HighlightBackground("WindowText", "Window", false, false);
			environmentColors["Default"]          = new HighlightColor(System.Drawing.SystemColors.WindowText, false, false);
			environmentColors["Selection"]        = new HighlightColor("HighlightText", "Highlight", false, false);
			environmentColors["VRuler"]           = new HighlightColor("ControlLight", "Window", false, false);
			environmentColors["InvalidLines"]     = new HighlightColor(Color.Red, false, false);
			environmentColors["CaretMarker"]      = new HighlightColor(Color.Yellow, false, false);
			environmentColors["LineNumbers"]      = new HighlightBackground("ControlDark", "Window", false, false);
			
			environmentColors["FoldLine"]         = new HighlightColor(Color.FromArgb(0x80, 0x80, 0x80), Color.Black, false, false);
			environmentColors["FoldMarker"]       = new HighlightColor(Color.FromArgb(0x80, 0x80, 0x80), Color.White, false, false);
			environmentColors["SelectedFoldLine"] = new HighlightColor(Color.Black, false, false);
			environmentColors["EOLMarkers"]       = new HighlightColor("ControlLight", "Window", false, false);
			environmentColors["SpaceMarkers"]     = new HighlightColor("ControlLight", "Window", false, false);
			environmentColors["TabMarkers"]       = new HighlightColor("ControlLight", "Window", false, false);
			
		}
		
		public Hashtable Properties {
			get {
				return properties;
			}
		}
		
		public string Name
		{
			get {
				return name;
			}
		}
		
		public string[] Extensions
		{
			set {
				extensions = value;
			}
			get {
				return extensions;
			}
		}
		
		public ArrayList Rules
		{
			get {
				return rules;
			}
		}
		
		public HighlightRuleSet FindHighlightRuleSet(string name)
		{
			foreach(HighlightRuleSet ruleSet in rules) {
				if (ruleSet.Name == name) {
					return ruleSet;
				}
			}
			return null;
		}
		
		public void AddRuleSet(HighlightRuleSet aRuleSet)
		{
			rules.Add(aRuleSet);
		}
		
		internal void ResolveReferences()
		{
			// Resolve references from Span definitions to RuleSets
			ResolveRuleSetReferences();
			// Resolve references from RuleSet defintitions to Highlighters defined in an external mode file
			ResolveExternalReferences();
		}
		
		void ResolveRuleSetReferences() 
		{
			foreach (HighlightRuleSet ruleSet in Rules) {
				if (ruleSet.Name == null) {
					defaultRuleSet = ruleSet;
				}
				
				foreach (Span aSpan in ruleSet.Spans) {
					if (aSpan.Rule != null) {
						bool found = false;
						foreach (HighlightRuleSet refSet in Rules) {
							if (refSet.Name == aSpan.Rule) {
								found = true;
								aSpan.RuleSet = refSet;
								break;
							}
						}
						if (!found) {
							MessageBox.Show("The RuleSet " + aSpan.Rule + " could not be found in mode definition " + this.Name, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
							aSpan.RuleSet = null;
						}
					} else {
						aSpan.RuleSet = null;
					}
				}
			}
			
			if (defaultRuleSet == null) {
				MessageBox.Show("No default RuleSet is defined for mode definition " + this.Name, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
			}
		}
		
		void ResolveExternalReferences() 
		{
			foreach (HighlightRuleSet ruleSet in Rules) {
				if (ruleSet.Reference != null) {
					IHighlightingStrategy highlighter = HighlightingManager.Manager.FindHighlighter (ruleSet.Reference);
					
					if (highlighter != null) {
						ruleSet.Highlighter = highlighter;
					} else {
						MessageBox.Show("The mode defintion " + ruleSet.Reference + " which is refered from the " + this.Name + " mode definition could not be found", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
						ruleSet.Highlighter = this;
					}
				} else {
					ruleSet.Highlighter = this;
				}
			}
		}
		
//		internal void SetDefaultColor(HighlightBackground color)
//		{
//			return (HighlightColor)environmentColors[name];
//			defaultColor = color;
//		}		
		
		internal void SetColorFor(string name, HighlightColor color)
		{
			environmentColors[name] = color;
		}

		public HighlightColor GetColorFor(string name)
		{
			if (environmentColors[name] == null) {
				throw new Exception("Color : " + name + " not found!");
			}
			return (HighlightColor)environmentColors[name];
		}
		
		public HighlightColor GetColor(IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
		{
			return GetColor(defaultRuleSet, document, currentSegment, currentOffset, currentLength);
		}

		HighlightColor GetColor(HighlightRuleSet ruleSet, IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
		{
			if (ruleSet != null) {
				if (ruleSet.Reference != null) {
					return ruleSet.Highlighter.GetColor(document, currentSegment, currentOffset, currentLength);
				} else {
					return (HighlightColor)ruleSet.KeyWords[document,  currentSegment, currentOffset, currentLength];
				}				
			}
			return null;
		}
		
		public HighlightRuleSet GetRuleSet(Span aSpan)
		{
			if (aSpan == null) {
				return this.defaultRuleSet;
			} else {
				if (aSpan.RuleSet != null)
				{
					if (aSpan.RuleSet.Reference != null) {
						return aSpan.RuleSet.Highlighter.GetRuleSet(null);
					} else {
						return aSpan.RuleSet;
					}
				} else {
					return null;
				}
			}
		}

		// Line state variable
		LineSegment currentLine;
		
		// Span stack state variable
		Stack currentSpanStack;

		public void MarkTokens(IDocument document)
		{
			try
			{
				if (Rules.Count == 0) {
					return;
				}
				
				int lineNumber = 0;
				
				while (lineNumber < document.TotalNumberOfLines) {
					LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);
					if (lineNumber >= document.LineSegmentCollection.Count) { // may be, if the last line ends with a delimiter
						break;                                                // then the last line is not in the collection :)
					}
					
					currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? ((Stack)(previousLine.HighlightSpanStack.Clone())) : null);
					
					if (currentSpanStack != null) {
						while (currentSpanStack.Count > 0 && ((Span)currentSpanStack.Peek()).StopEOL)
						{
							currentSpanStack.Pop();
						}
						if (currentSpanStack.Count == 0) currentSpanStack = null;
					}
					
					currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];
					
					if (currentLine.Length == -1) { // happens when buffer is empty !
						return;
					}
					
					ArrayList words = ParseLine(document);
	//// Alex: clear old words
					if (currentLine.Words!=null) currentLine.Words.Clear();
					currentLine.Words = words;
					currentLine.HighlightSpanStack = (currentSpanStack==null || currentSpanStack.Count==0) ? null : currentSpanStack;
					
					++lineNumber;
				}
				document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
				document.CommitUpdate();
			}
			finally
			{
				currentLine = null;
			}
		}
		
		bool MarkTokensInLine(IDocument document, int lineNumber, ref bool spanChanged)
		{
			bool processNextLine = false;
			LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);
			
			currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? ((Stack)(previousLine.HighlightSpanStack.Clone())) : null);
			if (currentSpanStack != null) {
				while (currentSpanStack.Count > 0 && ((Span)currentSpanStack.Peek()).StopEOL) {
					currentSpanStack.Pop();
				}
				if (currentSpanStack.Count == 0) {
					currentSpanStack = null;
				}
			}
			
			currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];
			
			if (currentLine.Length == -1) { // happens when buffer is empty !
				return false;
			}
			
			ArrayList words = ParseLine(document);
			
			if (currentSpanStack != null && currentSpanStack.Count == 0) {
				currentSpanStack = null;
			}
			
			// Check if the span state has changed, if so we must re-render the next line
			// This check may seem utterly complicated but I didn't want to introduce any function calls
			// or alllocations here for perf reasons.
			if(currentLine.HighlightSpanStack != currentSpanStack) {
				if (currentLine.HighlightSpanStack == null) {
					processNextLine = false;
					foreach (Span sp in currentSpanStack) {
						if (!sp.StopEOL) {
							spanChanged = true;
							processNextLine = true;
							break;
						}
					}
				} else if (currentSpanStack == null) {
					processNextLine = false;
					foreach (Span sp in currentLine.HighlightSpanStack) {
						if (!sp.StopEOL) {
							spanChanged = true;
							processNextLine = true;
							break;
						}
					}
				} else {
					IEnumerator e1 = currentSpanStack.GetEnumerator();
					IEnumerator e2 = currentLine.HighlightSpanStack.GetEnumerator();
					bool done = false;
					while (!done) {
						bool blockSpanIn1 = false;
						while (e1.MoveNext()) {
							if (!((Span)e1.Current).StopEOL) {
								blockSpanIn1 = true;
								break;
							}
						}
						bool blockSpanIn2 = false;
						while (e2.MoveNext()) {
							if (!((Span)e2.Current).StopEOL) {
								blockSpanIn2 = true;
								break;
							}
						}
						if (blockSpanIn1 || blockSpanIn2) {
							if (blockSpanIn1 && blockSpanIn2) {
								if (e1.Current != e2.Current) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -