#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

604 lines
19 KiB

// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Design;
using System.Reflection;
using System.Windows.Forms;
using System.Windows.Forms.Design;
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.Project;
using ICSharpCode.SharpDevelop.Internal.Undo;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.Core;
using ICSharpCode.FormsDesigner.Services;
using ICSharpCode.FormsDesigner.UndoRedo;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.AST;
using ICSharpCode.NRefactory.PrettyPrinter;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using Microsoft.VisualBasic;
namespace ICSharpCode.FormsDesigner
{
public class FormsDesignerViewContent : AbstractSecondaryViewContent, IClipboardHandler, IUndoHandler, IHasPropertyContainer, IContextHelpProvider
{
protected bool failedDesignerInitialize;
protected IViewContent viewContent;
protected Dictionary<string, DesignerResourceService.ResourceStorage> resources = new Dictionary<string, DesignerResourceService.ResourceStorage>();
protected ITextEditorControlProvider textAreaControlProvider;
Panel p = new Panel();
DesignSurface designSurface;
bool disposing;
string activeTabName = String.Empty;
IDesignerLoaderProvider loaderProvider;
IDesignerGenerator generator;
DesignerResourceService designerResourceService;
FormsDesignerUndoEngine undoEngine;
public override Control Control {
get {
return p;
}
}
public override string TabPageText {
get {
return "${res:FormsDesigner.DesignTabPages.DesignTabPage}";
}
}
public DesignSurface DesignSurface {
get {
return designSurface;
}
}
public TextEditorControl TextEditorControl {
get {
return textAreaControlProvider.TextEditorControl;
}
}
public IDocument Document {
get {
return TextEditorControl.Document;
}
}
public IDesignerHost Host {
get {
if (designSurface == null)
return null;
return (IDesignerHost)designSurface.GetService(typeof(IDesignerHost));
}
}
public FormsDesignerViewContent(IViewContent viewContent, IDesignerLoaderProvider loaderProvider, IDesignerGenerator generator)
{
if (!FormKeyHandler.inserted) {
FormKeyHandler.Insert();
}
this.loaderProvider = loaderProvider;
this.generator = generator;
p.BackColor = Color.White;
p.RightToLeft = RightToLeft.No;
this.viewContent = viewContent;
this.textAreaControlProvider = viewContent as ITextEditorControlProvider;
}
public override void SwitchedTo()
{
if (IsFormsDesignerVisible) {
AddSideBars();
}
}
void LoadDesigner()
{
LoggingService.Info("Form Designer: BEGIN INITIALIZE");
DefaultServiceContainer serviceContainer = new DefaultServiceContainer();
serviceContainer.AddService(typeof(System.Windows.Forms.Design.IUIService), new UIService());
serviceContainer.AddService(typeof(System.Drawing.Design.IToolboxService), ToolboxProvider.ToolboxService);
serviceContainer.AddService(typeof(IHelpService), new HelpService());
serviceContainer.AddService(typeof(System.Drawing.Design.IPropertyValueUIService), new PropertyValueUIService());
designerResourceService = new DesignerResourceService(viewContent.FileName, this.resources);
serviceContainer.AddService(typeof(System.ComponentModel.Design.IResourceService), designerResourceService);
AmbientProperties ambientProperties = new AmbientProperties();
serviceContainer.AddService(typeof(AmbientProperties), ambientProperties);
serviceContainer.AddService(typeof(ITypeResolutionService), new TypeResolutionService(viewContent.FileName));
serviceContainer.AddService(typeof(System.ComponentModel.Design.IDesignerEventService), new DesignerEventService());
serviceContainer.AddService(typeof(DesignerOptionService), new SharpDevelopDesignerOptionService());
serviceContainer.AddService(typeof(ITypeDiscoveryService), new TypeDiscoveryService());
serviceContainer.AddService(typeof(MemberRelationshipService), new DefaultMemberRelationshipService());
designSurface = new DesignSurface(serviceContainer);
serviceContainer.AddService(typeof(System.ComponentModel.Design.IMenuCommandService), new ICSharpCode.FormsDesigner.Services.MenuCommandService(p, designSurface));
ICSharpCode.FormsDesigner.Services.EventBindingService eventBindingService = new ICSharpCode.FormsDesigner.Services.EventBindingService(designSurface);
serviceContainer.AddService(typeof(System.ComponentModel.Design.IEventBindingService), eventBindingService);
designerResourceService.Host = Host;
DesignerLoader designerLoader = loaderProvider.CreateLoader(generator);
TypeResolutionService.AddAssemblyResolver();
designSurface.BeginLoad(designerLoader);
TypeResolutionService.RemoveAssemblyResolver();
generator.Attach(this);
undoEngine = new FormsDesignerUndoEngine(Host);
IComponentChangeService componentChangeService = (IComponentChangeService)designSurface.GetService(typeof(IComponentChangeService));
componentChangeService.ComponentChanged += delegate { viewContent.IsDirty = true; };
componentChangeService.ComponentAdded += ComponentListChanged;
componentChangeService.ComponentRemoved += ComponentListChanged;
componentChangeService.ComponentRename += ComponentListChanged;
this.Host.TransactionClosed += TransactionClose;
ISelectionService selectionService = (ISelectionService)designSurface.GetService(typeof(ISelectionService));
selectionService.SelectionChanged += SelectionChangedHandler;
LoggingService.Info("Form Designer: END INITIALIZE");
}
bool shouldUpdateSelectableObjects = false;
void TransactionClose(object sender, DesignerTransactionCloseEventArgs e)
{
if (shouldUpdateSelectableObjects) {
// update the property pad after the transaction is *really* finished
// (including updating the selection)
p.BeginInvoke(new MethodInvoker(UpdatePropertyPad));
shouldUpdateSelectableObjects = false;
}
}
void ComponentListChanged(object sender, EventArgs e)
{
shouldUpdateSelectableObjects = true;
}
void UnloadDesigner()
{
generator.Detach();
bool savedIsDirty = viewContent.IsDirty;
p.Controls.Clear();
viewContent.IsDirty = savedIsDirty;
// We cannot dispose the design surface now because of SD2-451:
// When the switch to the source view was triggered by a double-click on an event
// in the PropertyPad, "InvalidOperationException: The container cannot be disposed
// at design time" is thrown.
// This is solved by calling dispose after the double-click event has been processed.
if (disposing) {
designSurface.Dispose();
} else {
p.BeginInvoke(new MethodInvoker(designSurface.Dispose));
}
designSurface = null;
}
PropertyContainer propertyContainer = new PropertyContainer();
public PropertyContainer PropertyContainer {
get {
return propertyContainer;
}
}
public void ShowHelp()
{
ISelectionService selectionService = (ISelectionService)Host.GetService(typeof(ISelectionService));
if (selectionService != null) {
Control ctl = selectionService.PrimarySelection as Control;
if (ctl != null) {
ICSharpCode.SharpDevelop.Dom.HelpProvider.ShowHelp(ctl.GetType().FullName);
}
}
}
public void Reload()
{
try {
failedDesignerInitialize = false;
LoadDesigner();
bool savedIsDirty = viewContent.IsDirty;
if (designSurface != null && p.Controls.Count == 0) {
Control designer = designSurface.View as Control;
designer.Dock = DockStyle.Fill;
p.Controls.Add(designer);
}
viewContent.IsDirty = savedIsDirty;
} catch (Exception e) {
failedDesignerInitialize = true;
TextBox errorText = new TextBox();
errorText.Multiline = true;
if (e.InnerException is FormsDesignerLoadException) {
errorText.Text = e.InnerException.Message;
} else if (e is FormsDesignerLoadException) {
errorText.Text = e.Message;
} else if (!designSurface.IsLoaded && designSurface.LoadErrors != null) {
errorText.Text = "Error loading designer:\r\n\r\n";
foreach(Exception le in designSurface.LoadErrors) {
errorText.Text += le.ToString();
errorText.Text += "\r\n";
}
} else {
errorText.Text = e.ToString();
}
errorText.Dock = DockStyle.Fill;
p.Controls.Add(errorText);
Control title = new Label();
title.Text = "Failed to load designer. Check the source code for syntax errors and check if all references are available.";
title.Dock = DockStyle.Top;
p.Controls.Add(title);
}
}
public virtual void MergeFormChanges()
{
if (this.failedDesignerInitialize) {
return;
}
bool isDirty = viewContent.IsDirty;
LoggingService.Info("Merging form changes...");
designSurface.Flush();
LoggingService.Info("Finished merging form changes");
viewContent.IsDirty = isDirty;
}
public void ShowSourceCode()
{
WorkbenchWindow.SwitchView(0);
}
public void ShowSourceCode(int lineNumber)
{
ShowSourceCode();
textAreaControlProvider.TextEditorControl.ActiveTextAreaControl.JumpTo(lineNumber - 1);
}
public void ShowSourceCode(IComponent component, EventDescriptor edesc, string eventMethodName)
{
int position;
string file;
generator.InsertComponentEvent(component, edesc, eventMethodName, "", out file, out position);
if (FileUtility.IsEqualFileName(file, this.TextEditorControl.FileName)) {
ShowSourceCode(position);
} else {
FileService.JumpToFilePosition(file, position - 1, 0);
}
}
public ICollection GetCompatibleMethods(EventDescriptor edesc)
{
return generator.GetCompatibleMethods(edesc);
}
public ICollection GetCompatibleMethods(EventInfo edesc)
{
return generator.GetCompatibleMethods(edesc);
}
public override void Selected()
{
PropertyPad.PropertyValueChanged += PropertyValueChanged;
Reload();
IsFormsDesignerVisible = true;
AddSideBars();
SetActiveSideTab();
UpdatePropertyPad();
}
public override void Dispose()
{
disposing = true;
if (IsFormsDesignerVisible) {
Deselecting();
}
base.Dispose();
}
public override void Deselecting()
{
// can happen if form designer is disposed and then deselected
if (!IsFormsDesignerVisible)
return;
LoggingService.Info("Deselecting form designer, unloading..." + viewContent.TitleName);
PropertyPad.PropertyValueChanged -= PropertyValueChanged;
propertyContainer.Clear();
IsFormsDesignerVisible = false;
activeTabName = String.Empty;
if (SharpDevelopSideBar.SideBar.ActiveTab != null && ToolboxProvider.SideTabs.Contains(SharpDevelopSideBar.SideBar.ActiveTab)) {
activeTabName = SharpDevelopSideBar.SideBar.ActiveTab.Name;
}
foreach(AxSideTab tab in ToolboxProvider.SideTabs) {
if (!SharpDevelopSideBar.SideBar.Tabs.Contains(tab)) {
return;
}
SharpDevelopSideBar.SideBar.Tabs.Remove(tab);
}
SharpDevelopSideBar.SideBar.Refresh();
if (!failedDesignerInitialize) {
MergeFormChanges();
textAreaControlProvider.TextEditorControl.Refresh();
}
UnloadDesigner();
LoggingService.Info("Unloading form designer finished");
}
public override void NotifyBeforeSave()
{
base.NotifyBeforeSave();
if (IsFormsDesignerVisible)
MergeFormChanges();
}
public override void NotifyAfterSave(bool successful)
{
if (successful) {
if (designerResourceService != null) {
designerResourceService.Save();
}
}
}
void SelectionChangedHandler(object sender, EventArgs args)
{
UpdatePropertyPadSelection((ISelectionService)sender);
}
void UpdatePropertyPadSelection(ISelectionService selectionService)
{
ICollection selection = selectionService.GetSelectedComponents();
object[] selArray = new object[selection.Count];
selection.CopyTo(selArray, 0);
propertyContainer.SelectedObjects = selArray;
}
protected void UpdatePropertyPad()
{
if (IsFormsDesignerVisible) {
propertyContainer.Host = Host;
propertyContainer.SelectableObjects = Host.Container.Components;
ISelectionService selectionService = (ISelectionService)Host.GetService(typeof(ISelectionService));
if (selectionService != null) {
UpdatePropertyPadSelection(selectionService);
}
}
}
public bool IsFormsDesignerVisible = false;
#region IUndoHandler implementation
public bool EnableUndo {
get {
if (undoEngine != null) {
return undoEngine.EnableUndo;
}
return false;
}
}
public bool EnableRedo {
get {
if (undoEngine != null) {
return undoEngine.EnableRedo;
}
return false;
}
}
public virtual void Undo()
{
if (undoEngine != null) {
undoEngine.Undo();
}
}
public virtual void Redo()
{
if (undoEngine != null) {
undoEngine.Redo();
}
}
#endregion
#region IClipboardHandler implementation
public bool EnableCut {
get {
//ISelectionService selectionService = (ISelectionService)designSurface.GetService(typeof(ISelectionService));
//return selectionService.SelectionCount >= 0 && selectionService.PrimarySelection != host.RootComponent;
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
System.ComponentModel.Design.MenuCommand menuCommand = menuCommandService.FindCommand(StandardCommands.Cut);
if (menuCommand == null) {
return false;
}
int status = menuCommand.OleStatus;
return menuCommand.Enabled;
}
}
public bool EnableCopy {
get {
//ISelectionService selectionService = (ISelectionService)designSurface.GetService(typeof(ISelectionService));
//return selectionService.SelectionCount >= 0 && selectionService.PrimarySelection != host.RootComponent;
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
System.ComponentModel.Design.MenuCommand menuCommand = menuCommandService.FindCommand(StandardCommands.Copy);
if (menuCommand == null) {
return false;
}
int status = menuCommand.OleStatus;
return menuCommand.Enabled;
}
}
const string ComponentClipboardFormat = "CF_DESIGNERCOMPONENTS";
public bool EnablePaste {
get {
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
System.ComponentModel.Design.MenuCommand menuCommand = menuCommandService.FindCommand(StandardCommands.Paste);
if (menuCommand == null) {
return false;
}
int status = menuCommand.OleStatus;
return menuCommand.Enabled;
}
}
public bool EnableDelete {
get {
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
System.ComponentModel.Design.MenuCommand menuCommand = menuCommandService.FindCommand(StandardCommands.Delete);
if (menuCommand == null) {
return false;
}
int status = menuCommand.OleStatus;
return menuCommand.Enabled;
}
}
public bool EnableSelectAll {
get {
return true;
}
}
public void Cut()
{
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
menuCommandService.GlobalInvoke(StandardCommands.Cut);
}
public void Copy()
{
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
menuCommandService.GlobalInvoke(StandardCommands.Copy);
}
public void Paste()
{
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
menuCommandService.GlobalInvoke(StandardCommands.Paste);
}
public void Delete()
{
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
menuCommandService.GlobalInvoke(StandardCommands.Delete);
}
public void SelectAll()
{
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
menuCommandService.GlobalInvoke(StandardCommands.SelectAll);
}
#endregion
#region Tab Order Handling
bool tabOrderMode = false;
public virtual bool IsTabOrderMode {
get {
return tabOrderMode;
}
}
public virtual void ShowTabOrder()
{
if (!IsTabOrderMode) {
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
menuCommandService.GlobalInvoke(StandardCommands.TabOrder);
tabOrderMode = true;
}
}
public virtual void HideTabOrder()
{
if (IsTabOrderMode) {
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
menuCommandService.GlobalInvoke(StandardCommands.TabOrder);
tabOrderMode = false;
}
}
#endregion
/// <summary>
/// Reloads the form designer if the language property has changed.
/// </summary>
void PropertyValueChanged(object source, PropertyValueChangedEventArgs e)
{
if (e.ChangedItem == null || e.OldValue == null)
return;
if (e.ChangedItem.GridItemType == GridItemType.Property) {
if (e.ChangedItem.PropertyDescriptor.Name == "Language") {
if (!e.OldValue.Equals(e.ChangedItem.Value)) {
LoggingService.Debug("Reloading designer due to language change.");
propertyContainer.Clear();
if (!failedDesignerInitialize) {
MergeFormChanges();
}
UnloadDesigner();
Reload();
UpdatePropertyPad();
}
}
}
}
void AddSideBars()
{
foreach(AxSideTab tab in ToolboxProvider.SideTabs) {
if (!SharpDevelopSideBar.SideBar.Tabs.Contains(tab)) {
SharpDevelopSideBar.SideBar.Tabs.Add(tab);
}
}
SharpDevelopSideBar.SideBar.Refresh();
}
void SetActiveSideTab()
{
if (activeTabName.Length == 0) {
return;
}
foreach(AxSideTab tab in ToolboxProvider.SideTabs) {
if (activeTabName == tab.Name) {
SharpDevelopSideBar.SideBar.ActiveTab = tab;
return;
}
}
}
}
}