csharpdesignerdisplaybindingwrapper.cs

来自「全功能c#编译器」· CS 代码 · 共 614 行 · 第 1/2 页

CS
614
字号
// <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.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Design;
using System.Reflection;
using System.Windows.Forms;
using System.Drawing.Printing;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Xml;

using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Internal.Project;
using ICSharpCode.SharpDevelop.Internal.Undo;
using ICSharpCode.SharpDevelop.Gui.Components;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;

using ICSharpCode.Core.Properties;
using ICSharpCode.Core.AddIns;
using ICSharpCode.Core.Services;
using ICSharpCode.SharpDevelop.Services;
using SharpDevelop.Internal.Parser;
using ICSharpCode.SharpDevelop.FormDesigner.Services;
using ICSharpCode.SharpDevelop.FormDesigner.Hosts;
using ICSharpCode.SharpDevelop.FormDesigner.Util;
using ICSharpCode.Core.AddIns.Codons;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;

using ICSharpCode.SharpRefactory.Parser;
using ICSharpCode.SharpRefactory.Parser.AST;
using ICSharpCode.SharpRefactory.PrettyPrinter;

using System.CodeDom;
using System.CodeDom.Compiler;

using Microsoft.CSharp;
using Microsoft.VisualBasic;


namespace ICSharpCode.SharpDevelop.FormDesigner
{
	public class CSharpDesignerDisplayBindingWrapper : FormDesignerDisplayBindingBase, ISecondaryViewContent
	{
		protected bool failedDesignerInitialize;
		
		protected IClass                   c;
		protected IMethod                  initializeComponents;
		protected IViewContent             viewContent;
		
		protected                          ITextEditorControlProvider textAreaControlProvider;
		
		protected string                   compilationErrors;

		public override string FileName {
			get {
				string fileName = textAreaControlProvider.TextEditorControl.FileName;
				return fileName == null ? viewContent.UntitledName : fileName;
			}
		}
		
		public override IClipboardHandler ClipboardHandler {
			get {
				return this;
			}
		}
		
		public override Control Control {
			get {
				return base.designPanel;
			}
		}
		
		public override bool IsDirty {
			get {
				if (viewContent == null) {
					return false;
				}
				return viewContent.IsDirty;
			}
			set {
				if (viewContent != null) {
					viewContent.IsDirty = value;
				}
			}
		}
		
		IDocument Document {
			get {
				return textAreaControlProvider.TextEditorControl.Document;
			}
		}
		
		public CSharpDesignerDisplayBindingWrapper(IViewContent viewContent)
			: this(viewContent, true)
		{
		}

		public CSharpDesignerDisplayBindingWrapper(IViewContent viewContent, bool secondary)
		{
			this.viewContent             = viewContent;
			this.textAreaControlProvider = viewContent as ITextEditorControlProvider;
			InitializeComponents(secondary);
		}
		
		void InitializeComponents(bool secondary)
		{
			failedDesignerInitialize = false;
			undoHandler.Reset();
			Reload();
			UpdateSelectableObjects();
			if (designPanel != null && secondary == true) {
				base.designPanel.Disable();
			}
		}
		
		protected override void CreateDesignerHost()	
		{
			base.CreateDesignerHost();
			host.AddService(typeof(CodeDomProvider), new CSharpCodeProvider());
		}
		
		public override void Reload()
		{
			try {
				Initialize();
			} catch (Exception ex) {
				Console.WriteLine("Initialization exception : " + ex);
			}
			
			bool dirty = viewContent.IsDirty;
			if (host != null && c != null) {
				base.host.SetRootFullName(c.FullyQualifiedName);
			}
			try {
				CodeDOMVisitor visitor = new CodeDOMVisitor();
				
				// parse the source file first to find errors ...
				Parser p = new Parser();
				p.Parse(new Lexer(new ICSharpCode.SharpRefactory.Parser.StringReader(Document.TextContent)));
				
				failedDesignerInitialize = p.Errors.count != 0;
				if (failedDesignerInitialize) {
					compilationErrors    = p.Errors.ErrorOutput;
					return;
				}
				
				// now parse the generated file ...
				p = new Parser();
				p.Parse(new Lexer(new ICSharpCode.SharpRefactory.Parser.StringReader(GenerateClassString(Document))));
	
				if (host != null && c != null) {
					base.host.SetRootFullName(c.FullyQualifiedName);
				}
			
//				new DebugASTVisitor().Visit(Parser.compilationUnit, null);
//				host.DesignerLoader.BeginLoad(host);
				CodeDomDesignerSerializetionManager serializationManager = (CodeDomDesignerSerializetionManager)host.GetService(typeof(IDesignerSerializationManager));
				serializationManager.Initialize();
				
				visitor.Visit(p.compilationUnit, null);
				
				Type baseType = typeof(System.Windows.Forms.Form);
				foreach (CodeNamespace codeNamespace in visitor.codeCompileUnit.Namespaces) {
					if (codeNamespace.Types.Count > 0)  {
						baseType = host.GetType(visitor.codeCompileUnit.Namespaces[0].Types[0].BaseTypes[0].BaseType);
						break;
					}  
				}

				CodeDomSerializer rootSerializer = serializationManager.GetRootSerializer(baseType);
				if (rootSerializer == null) {
					throw new Exception("No root serializer found");
				}
				
				/*
				// output generated CodeDOM to the console : 
				Microsoft.CSharp.CSharpCodeProvider provider = new CSharpCodeProvider();
				System.CodeDom.Compiler.ICodeGenerator generator = provider.CreateGenerator();
				generator.GenerateCodeFromCompileUnit(visitor.codeCompileUnit, Console.Out, null);
				*/
				foreach (CodeNamespace codeNamespace in visitor.codeCompileUnit.Namespaces) {
					if (codeNamespace.Types.Count > 0) {
						//Console.WriteLine("Try to deserialize type : " + codeNamespace.Types[0].Name);
						DesignerResourceService designerResourceService = (DesignerResourceService)host.GetService(typeof(System.ComponentModel.Design.IResourceService));
						if (designerResourceService != null) {
							designerResourceService.SerializationStarted(false);
						}

//						designerResourceService.NameSpace = codeNamespace.Name;
//						designerResourceService.RootType  = codeNamespace.Types[0].Name;
//						designerResourceService.LoadResources();
						try {
							rootSerializer.Deserialize(serializationManager, codeNamespace.Types[0]);
						} catch (Exception e) {
							Console.WriteLine(e);
							StringParserService stringParserService = (StringParserService)ServiceManager.Services.GetService(typeof(StringParserService));
							compilationErrors        = stringParserService.Parse("${res:ICSharpCode.SharpDevelop.FormDesigner.CantDeserializeFormError}");
							failedDesignerInitialize = true;
							return;
						}
						serializationManager.OnSerializationComplete();
						if (designerResourceService != null) {
							designerResourceService.SerializationEnded(false);
						}
 						designPanel.SetRootDesigner();
						designPanel.Enable();
						break;
					}
				}
				failedDesignerInitialize = false;
				undoHandler.Reset();
				
			} catch (Exception ex) {
				Console.WriteLine("Got exception : " + ex);
				compilationErrors = ex.ToString();
				failedDesignerInitialize = true;
			} finally {
//				host.DesignerLoader.EndLoad();
			}
			viewContent.IsDirty = dirty;
		}
		
		protected virtual void AppendUsings(StringBuilder builder, IUsingCollection usings)
		{
			foreach (IUsing u in c.CompilationUnit.Usings)  {
				foreach (string usingString in u.Usings)  {
					if (usingString.StartsWith("System"))  {
						builder.Append("using " + usingString + ";\n");
					}
				}
			}
		}
		
		string GenerateClassString(IDocument document)
		{
			Reparse(document.TextContent);
			
			StringBuilder builder = new StringBuilder();
			// generate usings
			AppendUsings(builder, c.CompilationUnit.Usings);
			string className = c.Name;
			builder.Append("class ");
			builder.Append(className);
			builder.Append(" : ");
			builder.Append(ExtractBaseClass(c));
			builder.Append(" {\n");
			ArrayList fields = GetUsedFields(document, c, initializeComponents);
			foreach (IField field in fields) {
				LineSegment fieldLine = document.GetLineSegment(field.Region.BeginLine - 1);
				builder.Append(document.GetText(fieldLine.Offset, fieldLine.Length));
				builder.Append("\n");
			}
			
			builder.Append("\tpublic ");
			builder.Append(className);
			builder.Append("() {\n\t\t");
			builder.Append(initializeComponents.Name);
			builder.Append("();\n");
			builder.Append("\t}\n");
			string initializeComponentsString = GetInitializeComponentsString(document, initializeComponents);
			builder.Append(initializeComponentsString);
			
			builder.Append("}");
			return builder.ToString();
		}
		
		string GetInitializeComponentsString(IDocument doc, IMethod initializeComponents)
		{
			LineSegment beginLine = doc.GetLineSegment(initializeComponents.Region.BeginLine - 1);
			LineSegment endLine   = doc.GetLineSegment(initializeComponents.BodyRegion.EndLine - 1);
			
			int startOffset = beginLine.Offset + initializeComponents.Region.BeginColumn - 1;
			int endOffset   = endLine.Offset   + initializeComponents.BodyRegion.EndColumn - 1;
			
			string initializeComponentsString = doc.GetText(startOffset, endOffset - startOffset);
			int idx = initializeComponentsString.LastIndexOf('}');
			if (idx > 0) {
				initializeComponentsString = initializeComponentsString.Substring(0, idx + 1);
			}
			return initializeComponentsString;
		}
		
		
		ArrayList GetUsedFields(IDocument doc, IClass c, IMethod initializeComponents)
		{
			string InitializeComponentsString = GetInitializeComponentsString(doc, initializeComponents);
			ArrayList fields = new ArrayList();
			foreach (IField field in c.Fields) {
//				if (field.IsPrivate) {
					if (InitializeComponentsString.IndexOf("this." + field.Name + " ") >= 0) {
						fields.Add(field);
					}
//				}
			}

⌨️ 快捷键说明

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