diff options
author | Ivan Zlatev <ivan@ivanz.com> | 2007-08-29 23:19:04 +0400 |
---|---|---|
committer | Ivan Zlatev <ivan@ivanz.com> | 2007-08-29 23:19:04 +0400 |
commit | 03db1d8407d939f55dd11118e0f53fda5730cb60 (patch) | |
tree | 7eb808dabf1a56964fbef280fd17f5d5a97fe280 | |
parent | 3eca38f019b1f6324a98b0dbd996c2de32380ea8 (diff) |
2007-08-29 Ivan N. Zlatev <contact@i-nz.net>
* ParentControlDesigner.cs: implemented.
* IUISelectionService.cs: implemented.
* WndProcRouter.cs: implemented.
* SelectionFrame.cs: implemented.
* ControlDesigner.cs: implemented.
* ControlDataObject.cs: implemented.
* ComponentTray.cs: implemented.
* ScrollableControlDesigner.cs: implemented.
* UISelectionService.cs: implemented.
* SplitContainerDesigner.cs: implemented.
* IMessageReceiver.cs: implemented.
* Native.cs: implemented.
* DocumentDesigner.cs: implemented.
* DefaultSerializationProviderAttribute.cs: implemented.
* ComponentSerializationService.cs: implemented.
* MemberRelationship.cs: implemented.
* SerializationStore.cs: implemented.
* DesignSurfaceManager.cs: implemented.
* DesignerEventService.cs: implemented.
* ComponentDesigner.cs: implemented.
* ActiveDesignSurfaceChangedEventHandler.cs: implemented.
* LoadedEventHandler.cs: implemented.
* DesignSurfaceCollection.cs: implemented.
* DesignerHost.cs: implemented.
* ExtenderService.cs: implemented.
* DesignModeSite.cs: implemented.
* SelectionService.cs: implemented.
* DesignSurfaceServiceContainer.cs: implemented.
* DesignerActionListCollection.cs: implemented.
* ActiveDesignSurfaceChangedEventArgs.cs: implemented.
* LoadedEventArgs.cs: implemented.
* TypeDescriptorFilterService.cs: implemented.
* ReferenceService.cs: implemented.
* DesignSurface.cs: implemented.
* DesignSurfaceEventHandler.cs: implemented.
* DesignModeNestedContainer.cs: implemented.
* EventBindingService.cs: implemented.
* DesignSurfaceEventArgs.cs: implemented.
* DesignerOptionService.cs: implemented.
* ITreeDesigner.cs: implemented.
* CodeDomComponentSerializationService.cs: implemented.
* CollectionCodeDomSerializer.cs: implemented.
* CodeDomDesignerLoader.cs: implemented.
* CodeDomSerializationProvider.cs: implemented.
* ComponentCodeDomSerializer.cs: implemented.
* RootContext.cs: implemented.
* BasicDesignerLoader.cs: implemented.
* DesignerSerializationManager.cs: implemented.
* EnumCodeDomSerializer.cs: implemented.
* SerializeAbsoluteContext.cs: implemented.
* MemberCodeDomSerializer.cs: implemented.
* PrimitiveCodeDomSerializer.cs: implemented.
* CodeDomSerializerBase.cs: implemented.
* CodeDomSerializer.cs: implemented.
* ExpressionContext.cs: implemented.
* EventCodeDomSerializer.cs: implemented.
* TypeCodeDomSerializer.cs: implemented.
* ObjectStatementCollection.cs: implemented.
* RootCodeDomSerializer.cs: implemented.
* PropertyCodeDomSerializer.cs: implemented.
* StatementContext.cs: implemented.
svn path=/trunk/mcs/; revision=85023
70 files changed, 11712 insertions, 1211 deletions
diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/BasicDesignerLoader.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/BasicDesignerLoader.cs new file mode 100644 index 00000000000..fee3980cdd3 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/BasicDesignerLoader.cs @@ -0,0 +1,409 @@ +// +// System.ComponentModel.Design.Serialization.BasicDesignerLoader +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Windows.Forms; + +namespace System.ComponentModel.Design.Serialization +{ + public abstract class BasicDesignerLoader : DesignerLoader, IDesignerLoaderService + { + + [Flags] + protected enum ReloadOptions + { + Default, + Force, + ModifyOnError, + NoFlush + } + + private bool _loaded; + private bool _loading; + private IDesignerLoaderHost _host; + private int _dependenciesCount; + private bool _notificationsEnabled; + private bool _modified; + private string _baseComponentClassName; + private DesignerSerializationManager _serializationMananger; + private bool _flushing; + private bool _reloadScheduled; + private ReloadOptions _reloadOptions; + + protected BasicDesignerLoader () + { + _loading = _loaded = _flushing = _reloadScheduled = false; + _host = null; + _notificationsEnabled = false; + _modified = false; + _dependenciesCount = 0; + } + + protected virtual void Initialize () + { + _serializationMananger = new DesignerSerializationManager (_host); + + DesignSurfaceServiceContainer serviceContainer = _host.GetService (typeof (IServiceContainer)) as DesignSurfaceServiceContainer; + if (serviceContainer != null) { + serviceContainer.AddService (typeof (IDesignerLoaderService), (IDesignerLoaderService) this); + serviceContainer.AddNonReplaceableService (typeof (IDesignerSerializationManager), _serializationMananger); + } + } + + // TODO: toggle comments of exception handlers + // + public override void BeginLoad (IDesignerLoaderHost host) + { + if (host == null) + throw new ArgumentNullException ("host"); + if (_loaded) + throw new InvalidOperationException ("Already loaded."); + if (_host != null && _host != host) + throw new InvalidOperationException ("Trying to load with a different host"); + + if (_host == null) { // beingload is called on reload - no need to initialize twice. + _host = host; + Initialize (); + } + IDisposable session = _serializationMananger.CreateSession (); + + IDesignerLoaderService loader = _host.GetService (typeof (IDesignerLoaderService)) as IDesignerLoaderService; + + if (loader != null) { + _dependenciesCount = -1; + loader.AddLoadDependency (); + } else { + OnBeginLoad (); + } + + bool successful = true; + +// try { + PerformLoad (_serializationMananger); +// } catch (Exception e) { +// successful = false; +// _serializationMananger.Errors.Add (e); +// while (e.InnerException != null) { +// _serializationMananger.Errors.Add (e); +// Console.WriteLine (e.InnerException); +// e = e.InnerException; +// } +// } + + if (loader != null) + loader.DependentLoadComplete (successful, _serializationMananger.Errors); + else + OnEndLoad (successful, _serializationMananger.Errors); + + session.Dispose (); + } + + protected abstract void PerformLoad (IDesignerSerializationManager serializationManager); + + protected virtual void OnBeginLoad () + { + _loading = true; + } + + protected virtual void OnEndLoad (bool successful, ICollection errors) + { + _host.EndLoad (_baseComponentClassName, successful, errors); + + if (successful) { + _loaded = true; + EnableComponentNotification (true); + } else { + if (_reloadScheduled) { // we are reloading + bool modify = ((_reloadOptions & ReloadOptions.ModifyOnError) == ReloadOptions.ModifyOnError); + if (modify) { + OnModifying (); + this.Modified = true; + } + } + } + _loading = false; + } + + public override bool Loading { + get { return _loading; } + } + + protected IDesignerLoaderHost LoaderHost { + get { return _host; } + } + + protected virtual bool Modified { + get { return _modified; } + set { _modified = value; } + } + + protected object PropertyProvider { + get { + if (!_loaded) + throw new InvalidOperationException ("host not initialized"); + return _serializationMananger.PropertyProvider; + } + set { + if (!_loaded) + throw new InvalidOperationException ("host not initialized"); + _serializationMananger.PropertyProvider = value; + } + } + + protected bool ReloadPending { + get { return _reloadScheduled; } + } + + protected virtual bool EnableComponentNotification (bool enable) + { + if (!_loaded) + throw new InvalidOperationException ("host not initialized"); + + IComponentChangeService service = _host.GetService (typeof (IComponentChangeService)) as IComponentChangeService; + if (service != null && _notificationsEnabled != enable) { + if (enable) { + service.ComponentAdding += new ComponentEventHandler (OnComponentAdding); + service.ComponentAdded += new ComponentEventHandler (OnComponentAdded); + service.ComponentRemoving += new ComponentEventHandler (OnComponentRemoving); + service.ComponentRemoved += new ComponentEventHandler (OnComponentRemoved); + service.ComponentChanging += new ComponentChangingEventHandler (OnComponentChanging); + service.ComponentChanged += new ComponentChangedEventHandler (OnComponentChanged); + service.ComponentRename += new ComponentRenameEventHandler (OnComponentRename); + } else { + service.ComponentAdding -= new ComponentEventHandler (OnComponentAdding); + service.ComponentAdded -= new ComponentEventHandler (OnComponentAdded); + service.ComponentRemoving -= new ComponentEventHandler (OnComponentRemoving); + service.ComponentRemoved -= new ComponentEventHandler (OnComponentRemoved); + service.ComponentChanging -= new ComponentChangingEventHandler (OnComponentChanging); + service.ComponentChanged -= new ComponentChangedEventHandler (OnComponentChanged); + service.ComponentRename -= new ComponentRenameEventHandler (OnComponentRename); + } + } + return _notificationsEnabled == true ? true : false; + } + + private void OnComponentAdded (object sender, ComponentEventArgs args) + { + if (!_loading && _loaded) + this.Modified = true; + } + + private void OnComponentRemoved (object sender, ComponentEventArgs args) + { + if (!_loading && _loaded) + this.Modified = true; + } + + private void OnComponentAdding (object sender, ComponentEventArgs args) + { + if (!_loading && _loaded) + OnModifying (); + } + + private void OnComponentRemoving (object sender, ComponentEventArgs args) + { + if (!_loading && _loaded) + OnModifying (); + } + + private void OnComponentChanged (object sender, ComponentChangedEventArgs args) + { + if (!_loading && _loaded) + this.Modified = true; + } + + private void OnComponentChanging (object sender, ComponentChangingEventArgs args) + { + if (!_loading && _loaded) + OnModifying (); + } + + private void OnComponentRename (object sender, ComponentRenameEventArgs args) + { + if (!_loading && _loaded) { + OnModifying (); + this.Modified = true; + } + } + + // TODO: Toggle comments of exception handlers + public override void Flush () + { + if (!_loaded) + throw new InvalidOperationException ("host not initialized"); + + if (!_flushing && this.Modified) { + _flushing = true; + using ((IDisposable)_serializationMananger.CreateSession ()) { +// try { + PerformFlush (_serializationMananger); +// } +// catch (Exception e) { +// _serializationMananger.Errors.Add (e); +// while (e.InnerException != null) { +// _serializationMananger.Errors.Add (e); +// Console.WriteLine (e.InnerException); +// e = e.InnerException; +// } +// ReportFlushErrors (_serializationMananger.Errors); +// } + } + _flushing = false; + } + } + + protected abstract void PerformFlush (IDesignerSerializationManager serializationManager); + + // MSDN: The default implementation always returns true. + protected virtual bool IsReloadNeeded () + { + return true; + } + + + protected virtual void OnBeginUnload () + { + } + + protected virtual void OnModifying () + { + } + + // MSDN: reloads are performed at idle time + protected void Reload (ReloadOptions flags) + { + if (!_reloadScheduled) { + _reloadScheduled = true; + _reloadOptions = flags; + bool force = ((flags & ReloadOptions.Force) == ReloadOptions.Force); + if (force) + ReloadCore (); + else + Application.Idle += new EventHandler (OnIdle); + } + } + + private void OnIdle (object sender, EventArgs args) + { + Application.Idle -= new EventHandler (OnIdle); + ReloadCore (); + } + + private void ReloadCore () + { + bool flush = !((_reloadOptions & ReloadOptions.NoFlush) == ReloadOptions.NoFlush); + + if (flush) + Flush (); + Unload (); + _host.Reload (); + BeginLoad (_host); // calls EndLoad, which will check for ReloadOptions.ModifyOnError + _reloadScheduled = false; + } + + private void Unload () + { + OnBeginUnload (); + EnableComponentNotification (false); + _loaded = false; + _baseComponentClassName = null; + } + + + // The default implementation of ReportFlushErrors raises the last exception in the collection. + // + protected virtual void ReportFlushErrors (ICollection errors) + { + object last = null; + foreach (object o in errors) + last = o; + throw (Exception)last; + } + + // Must be called during PerformLoad by subclasses. + protected void SetBaseComponentClassName (string name) + { + if (name == null) + throw new ArgumentNullException ("name"); + _baseComponentClassName = name; + } + +#region IDesignerLoaderService implementation + + void IDesignerLoaderService.AddLoadDependency () + { + _dependenciesCount++; + if (_dependenciesCount == 0) { + _dependenciesCount = 1; + OnBeginLoad (); + } + } + + void IDesignerLoaderService.DependentLoadComplete (bool successful, ICollection errorCollection) + { + if (_dependenciesCount == 0) + throw new InvalidOperationException ("dependencies == 0"); + + _dependenciesCount--; + if (_dependenciesCount == 0) { + OnEndLoad (successful, errorCollection); + } + } + + bool IDesignerLoaderService.Reload () + { + if (_dependenciesCount == 0) { + this.Reload (ReloadOptions.Force); + return true; + } + return false; + } +#endregion + + protected object GetService (Type serviceType) + { + if (_host != null) + return _host.GetService (serviceType); + return null; + } + + public override void Dispose () + { + this.LoaderHost.RemoveService (typeof (IDesignerLoaderService)); + Unload (); + } + } +} + +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/Changelog b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/Changelog index b1326cddd7d..b767c2f69dc 100644 --- a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/Changelog +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/Changelog @@ -1,3 +1,19 @@ +2007-08-29 Ivan N. Zlatev <contact@i-nz.net> + + * ParentControlDesigner.cs: implemented. + * IUISelectionService.cs: implemented. + * WndProcRouter.cs: implemented. + * SelectionFrame.cs: implemented. + * ControlDesigner.cs: implemented. + * ControlDataObject.cs: implemented. + * ComponentTray.cs: implemented. + * ScrollableControlDesigner.cs: implemented. + * UISelectionService.cs: implemented. + * SplitContainerDesigner.cs: implemented. + * IMessageReceiver.cs: implemented. + * Native.cs: implemented. + * DocumentDesigner.cs: implemented. + 2004-05-16 Gert Driesen (drieseng@users.sourceforge.net) * CodeDomSerializerException.cs: removed default public diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomComponentSerializationService.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomComponentSerializationService.cs new file mode 100644 index 00000000000..3ffea8d6de4 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomComponentSerializationService.cs @@ -0,0 +1,98 @@ +// +// System.ComponentModel.Design.Serialization.CodeDomComponentSerializationService +// +// Authors: +// Ivan N. Zlatev (contact@i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +// STUBS ONLY + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.Collections; +using System.IO; + +namespace System.ComponentModel.Design.Serialization +{ + public sealed class CodeDomComponentSerializationService : ComponentSerializationService + { + + public CodeDomComponentSerializationService () : this (null) + { + } + + public CodeDomComponentSerializationService (IServiceProvider provider) + { + } + + public override SerializationStore CreateStore () + { + throw new NotImplementedException (); + } + + public override ICollection Deserialize (SerializationStore store) + { + throw new NotImplementedException (); + } + + public override ICollection Deserialize (SerializationStore store, IContainer container) + { + throw new NotImplementedException (); + } + + public override SerializationStore LoadStore (Stream stream) + { + throw new NotImplementedException (); + } + + public override void Serialize (SerializationStore store, object value) + { + throw new NotImplementedException (); + } + + public override void SerializeAbsolute (SerializationStore store, object value) + { + throw new NotImplementedException (); + } + + public override void SerializeMember (SerializationStore store, object owningObject, MemberDescriptor member) + { + throw new NotImplementedException (); + } + + public override void SerializeMemberAbsolute (SerializationStore store, object owningObject, MemberDescriptor member) + { + throw new NotImplementedException (); + } + + public override void DeserializeTo (SerializationStore store, IContainer container, bool validateRecycledTypes, bool applyDefaults) + { + throw new NotImplementedException (); + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomDesignerLoader.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomDesignerLoader.cs new file mode 100644 index 00000000000..aafc18afeda --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomDesignerLoader.cs @@ -0,0 +1,271 @@ +// +// System.ComponentModel.Design.Serialization.CodeDomDesignerLoader +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; +using System.CodeDom.Compiler; + +namespace System.ComponentModel.Design.Serialization +{ + public abstract class CodeDomDesignerLoader : BasicDesignerLoader, INameCreationService, IDesignerSerializationService + { + private CodeDomSerializer _rootSerializer; + + protected CodeDomDesignerLoader () + { + } + + protected override void Initialize () + { + base.Initialize (); + base.LoaderHost.AddService (typeof (IDesignerSerializationService), this); + base.LoaderHost.AddService (typeof (INameCreationService), this); + base.LoaderHost.AddService (typeof (ComponentSerializationService), new + CodeDomComponentSerializationService (base.LoaderHost)); + IDesignerSerializationManager manager = base.LoaderHost.GetService (typeof (IDesignerSerializationManager)) as IDesignerSerializationManager; + if (manager != null) + manager.AddSerializationProvider (new CodeDomSerializationProvider ()); + } + + protected override bool IsReloadNeeded () + { + if (this.CodeDomProvider is ICodeDomDesignerReload) + return ((ICodeDomDesignerReload) CodeDomProvider).ShouldReloadDesigner (Parse ()); + return base.IsReloadNeeded (); + } + + protected override void PerformLoad (IDesignerSerializationManager manager) + { + if (manager == null) + throw new ArgumentNullException ("manager"); + + CodeCompileUnit document = this.Parse (); + if (document == null) + throw new NotSupportedException ("The language did not provide a code parser for this file"); + + string namespaceName = null; + CodeTypeDeclaration rootDocument = GetFirstCodeTypeDecl (document, out namespaceName); + if (rootDocument == null) + throw new InvalidOperationException ("Cannot find a declaration in a namespace to load."); + + _rootSerializer = manager.GetSerializer (manager.GetType (rootDocument.BaseTypes[0].BaseType), + typeof (RootCodeDomSerializer)) as CodeDomSerializer; + if (_rootSerializer == null) + throw new InvalidOperationException ("Serialization not supported for this class"); + + _rootSerializer.Deserialize (manager, rootDocument); + + base.SetBaseComponentClassName (namespaceName + "." + rootDocument.Name); + } + + private CodeTypeDeclaration GetFirstCodeTypeDecl (CodeCompileUnit document, out string namespaceName) + { + namespaceName = null; + + foreach (CodeNamespace namesp in document.Namespaces) { + foreach (CodeTypeDeclaration declaration in namesp.Types) { + if (declaration.IsClass) { + namespaceName = namesp.Name; + return declaration; + } + } + } + return null; + } + + protected override void PerformFlush (IDesignerSerializationManager manager) + { + if (_rootSerializer != null) { + CodeTypeDeclaration typeDecl = (CodeTypeDeclaration) _rootSerializer.Serialize (manager, + base.LoaderHost.RootComponent); + this.Write (MergeTypeDeclWithCompileUnit (typeDecl, this.Parse ())); + } + } + + // Will either add the class or replace an existing class + // with the one from GenerateClass () + // + private CodeCompileUnit MergeTypeDeclWithCompileUnit (CodeTypeDeclaration typeDecl, CodeCompileUnit unit) + { + CodeNamespace namespac = null; + int typeIndex = -1; + + foreach (CodeNamespace namesp in unit.Namespaces) { + for (int i=0; i< namesp.Types.Count; i++) { + if (namesp.Types[i].Name == typeDecl.Name) { + typeIndex = i; + namespac = namesp; + } + } + } + + if (typeIndex != -1) + namespac.Types.RemoveAt (typeIndex); + + namespac.Types.Add (typeDecl); + return unit; + } + + protected override void OnBeginLoad () + { + base.OnBeginLoad (); + + IComponentChangeService service = base.GetService (typeof (IComponentChangeService)) as IComponentChangeService; + if (service != null) + service.ComponentRename += this.OnComponentRename_EventHandler; + } + + protected override void OnBeginUnload () + { + base.OnBeginUnload (); + + IComponentChangeService service = base.GetService (typeof (IComponentChangeService)) as IComponentChangeService; + if (service != null) + service.ComponentRename -= this.OnComponentRename_EventHandler; + } + + protected override void OnEndLoad (bool successful, ICollection errors) + { + base.OnEndLoad (successful, errors); + // XXX: msdn says overriden + } + + private void OnComponentRename_EventHandler (object sender, ComponentRenameEventArgs args) + { + this.OnComponentRename (args.Component, args.OldName, args.NewName); + } + + // MSDN says that here one should raise ComponentRename event and that's nonsense. + // + protected virtual void OnComponentRename (object component, string oldName, string newName) + { + // What shall we do with the drunken sailor, + // what shall we do with the drunken sailor early in the morning? + } + + protected abstract CodeDomProvider CodeDomProvider { get; } + protected abstract ITypeResolutionService TypeResolutionService { get; } + protected abstract CodeCompileUnit Parse (); + protected abstract void Write (CodeCompileUnit unit); + + public override void Dispose () + { + base.Dispose (); + } + +#region INameCreationService implementation + + // very simplistic implementation to generate names like "button1", "someControl2", etc + // + string INameCreationService.CreateName (IContainer container, Type dataType) + { + if (dataType == null) + throw new ArgumentNullException ("dataType"); + + string name = dataType.Name; + char lower = Char.ToLower (name[0]); + name = name.Remove (0, 1); + name = name.Insert (0, Char.ToString (lower)); + + int uniqueId = 1; + bool unique = false; + + while (!unique) { + if (container != null && container.Components[name + uniqueId] != null) { + uniqueId++; + } else { + unique = true; + name = name + uniqueId; + } + } + + if (this.CodeDomProvider != null) + name = CodeDomProvider.CreateValidIdentifier (name); + + return name; + } + + bool INameCreationService.IsValidName (string name) + { + if (name == null) + throw new ArgumentNullException ("name"); + + bool valid = true; + if (this.CodeDomProvider != null) { + valid = CodeDomProvider.IsValidIdentifier (name); + } else { + if (name.Trim().Length == 0) + valid = false; + foreach (char c in name) { + if (!Char.IsLetterOrDigit (c)) { + valid = false; + break; + } + } + } + + return valid; + } + + void INameCreationService.ValidateName (string name) + { + if (!((INameCreationService) this).IsValidName (name)) + throw new ArgumentException ("Only digits and numbers allows in the name"); + } +#endregion + + +#region IDesignerSerializationService implementation + + ICollection IDesignerSerializationService.Deserialize (object serializationData) + { + IDesignerSerializationService service = LoaderHost.GetService (typeof (IDesignerSerializationService)) as IDesignerSerializationService; + if (service != null) + return service.Deserialize (serializationData); + return new object[0]; + } + + object IDesignerSerializationService.Serialize (ICollection objects) + { + IDesignerSerializationService service = LoaderHost.GetService (typeof (IDesignerSerializationService)) as IDesignerSerializationService; + if (service != null) + return service.Serialize (objects); + return null; + } +#endregion + } +} + +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomSerializationProvider.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomSerializationProvider.cs new file mode 100644 index 00000000000..8bbd54835e9 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomSerializationProvider.cs @@ -0,0 +1,97 @@ +// +// System.ComponentModel.Design.Serialization.CodeDomSerializationProvider +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + // Added as a provider by the RootCodeDomSerializationProvider + // + internal class CodeDomSerializationProvider : IDesignerSerializationProvider + { + public CodeDomSerializationProvider () + { + _componentSerializer = new ComponentCodeDomSerializer (); + _propertySerializer = new PropertyCodeDomSerializer (); + _eventSerializer = new EventCodeDomSerializer (); + _collectionSerializer = new CollectionCodeDomSerializer (); + _primitiveSerializer = new PrimitiveCodeDomSerializer (); + _rootSerializer = new RootCodeDomSerializer (); + _enumSerializer = new EnumCodeDomSerializer (); + _othersSerializer = new CodeDomSerializer (); + } + + private CodeDomSerializerBase _componentSerializer; + private CodeDomSerializerBase _propertySerializer; + private CodeDomSerializerBase _eventSerializer; + private CodeDomSerializerBase _primitiveSerializer; + private CodeDomSerializerBase _collectionSerializer; + private CodeDomSerializerBase _rootSerializer; + private CodeDomSerializerBase _enumSerializer; + private CodeDomSerializerBase _othersSerializer; + + public object GetSerializer (IDesignerSerializationManager manager, object currentSerializer, + Type objectType, Type serializerType) + { + CodeDomSerializerBase serializer = null; + + if (serializerType == typeof(CodeDomSerializer)) { // CodeDomSerializer + if (objectType == null) // means that value to serialize is null CodePrimitiveExpression (null) + serializer = _primitiveSerializer; + else if (typeof(IComponent).IsAssignableFrom (objectType)) + serializer = _componentSerializer; + else if (objectType.IsEnum || typeof (Enum).IsAssignableFrom (objectType)) + serializer = _enumSerializer; + else if (objectType.IsPrimitive || objectType == typeof (String)) + serializer = _primitiveSerializer; + else if (typeof(ICollection).IsAssignableFrom (objectType)) + serializer = _collectionSerializer; + else + serializer = _othersSerializer; + } else if (serializerType == typeof(MemberCodeDomSerializer)) { // MemberCodeDomSerializer + if (typeof (PropertyDescriptor).IsAssignableFrom (objectType)) + serializer = _propertySerializer; + else if (typeof (EventDescriptor).IsAssignableFrom (objectType)) + serializer = _eventSerializer; + } else if (serializerType == typeof (RootCodeDomSerializer)) { + serializer = _rootSerializer; + } + + return serializer; + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomSerializer.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomSerializer.cs index e30163272fb..cb4b704f5ab 100644 --- a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomSerializer.cs +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomSerializer.cs @@ -1,10 +1,10 @@ -// System.ComponentModel.Design.Serialization.CodeDomSerializer.cs // -// Author: -// Alejandro Sánchez Acosta <raciel@gnome.org> +// System.ComponentModel.Design.Serialization.CodeDomSerializer // -// (C) Alejandro Sánchez Acosta +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) // +// (C) 2007 Ivan N. Zlatev // // Permission is hereby granted, free of charge, to any person obtaining @@ -14,10 +14,10 @@ // 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 @@ -27,81 +27,181 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; + using System.CodeDom; -using System.Web.UI.Design; namespace System.ComponentModel.Design.Serialization { - public abstract class CodeDomSerializer + public class CodeDomSerializer : CodeDomSerializerBase { - [MonoTODO] - protected CodeDomSerializer() { - throw new NotImplementedException (); - } - - public abstract object Deserialize (IDesignerSerializationManager manager, object codeObject); - [MonoTODO] - protected void DeserializePropertiesFromResources (IDesignerSerializationManager manager, object value, Attribute[] filter) + public CodeDomSerializer () { - throw new NotImplementedException (); } - [MonoTODO] - protected object DeserializeExpression (IDesignerSerializationManager manager, string name, CodeExpression expression) + + public object SerializeAbsolute (IDesignerSerializationManager manager, object value) { - throw new NotImplementedException (); - } + if (value == null) + throw new ArgumentNullException ("value"); + if (manager == null) + throw new ArgumentNullException ("manager"); - [MonoTODO] - protected void DeserializeStatement (IDesignerSerializationManager manager, CodeStatement statement) - { - throw new NotImplementedException (); + SerializeAbsoluteContext context = new SerializeAbsoluteContext (); + manager.Context.Push (context); + object result = this.Serialize (manager, value); + manager.Context.Pop (); + return result; } - public abstract object Serialize (IDesignerSerializationManager manager, object value); - - [MonoTODO] - protected void SerializeEvents (IDesignerSerializationManager manager, CodeStatementCollection statements, object value, Attribute[] filter) + public virtual object Serialize (IDesignerSerializationManager manager, object value) { - throw new NotImplementedException (); + if (value == null) + throw new ArgumentNullException ("value"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + object serialized = null; + bool isComplete = false; + CodeExpression createExpr = base.SerializeCreationExpression (manager, value, out isComplete); + if (isComplete) { + serialized = createExpr; + base.SetExpression (manager, value, createExpr); + } else { + ExpressionContext context = manager.Context[typeof (ExpressionContext)] as ExpressionContext; + if (context != null && context.PresetValue == value) { + CodeStatementCollection statements = new CodeStatementCollection (); + statements.Add (new CodeAssignStatement (context.Expression, createExpr)); + base.SerializeProperties (manager, statements, value, new Attribute[0]); + base.SerializeEvents (manager, statements, value, new Attribute[0]); + } else { + CodeExpression expression = base.GetExpression (manager, value); + if (expression == null) { + serialized = expression = createExpr; + base.SetExpression (manager, value, expression); + } + } + } + return serialized; } - [MonoTODO] - protected void SerializeProperties (IDesignerSerializationManager manager, CodeStatementCollection statements, object value, Attribute[] filter) + [Obsolete ("This method has been deprecated. Use SerializeToExpression or GetExpression instead.")] + protected CodeExpression SerializeToReferenceExpression (IDesignerSerializationManager manager, object value) { - throw new NotImplementedException (); + return base.SerializeToExpression (manager, value); } - [MonoTODO] - protected void SerializePropertiesToResources (IDesignerSerializationManager manager, CodeStatementCollection statements, object value, Attribute[] filter) + // I am not sure what this does, but the only name I can think of this can get is a variable name from + // the expression + public virtual string GetTargetComponentName (CodeStatement statement, CodeExpression expression, Type targetType) { - throw new NotImplementedException (); + if (expression is CodeFieldReferenceExpression) + return ((CodeFieldReferenceExpression) expression).FieldName; + else if (expression is CodeVariableReferenceExpression) + return ((CodeVariableReferenceExpression) expression).VariableName; + return null; } - - [MonoTODO] - protected void SerializeResource (IDesignerSerializationManager manager, string resourceName, object value) + public virtual CodeStatementCollection SerializeMember (IDesignerSerializationManager manager, + object owningobject, MemberDescriptor member) { - throw new NotImplementedException (); + if (member == null) + throw new ArgumentNullException ("member"); + if (owningobject == null) + throw new ArgumentNullException ("owningobject"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + CodeStatementCollection statements = new CodeStatementCollection (); + + CodeExpression expression = base.GetExpression (manager, owningobject); + if (expression == null) { + string name = manager.GetName (owningobject); + if (name == null) + name = base.GetUniqueName (manager, owningobject); + expression = new CodeVariableReferenceExpression (name); + base.SetExpression (manager, owningobject, expression); + } + + manager.Context.Push (new ExpressionContext (expression, expression.GetType (), null, owningobject)); + + if (member is PropertyDescriptor) + base.SerializeProperty (manager, statements, owningobject, (PropertyDescriptor) member); + if (member is EventDescriptor) + base.SerializeEvent (manager, statements, owningobject, (EventDescriptor) member); + + manager.Context.Pop (); + + return statements; } - [MonoTODO] - protected void SerializeResourceInvariant (IDesignerSerializationManager manager, string resourceName, object value) + public virtual CodeStatementCollection SerializeMemberAbsolute (IDesignerSerializationManager manager, + object owningobject, MemberDescriptor member) { - throw new NotImplementedException (); + if (member == null) + throw new ArgumentNullException ("member"); + if (owningobject == null) + throw new ArgumentNullException ("owningobject"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + SerializeAbsoluteContext context = new SerializeAbsoluteContext (member); + manager.Context.Push (context); + CodeStatementCollection result = this.SerializeMember (manager, owningobject, member); + manager.Context.Pop (); + return result; } - - [MonoTODO] - protected CodeExpression SerializeToExpression (IDesignerSerializationManager manager, object value) + + + public virtual object Deserialize (IDesignerSerializationManager manager, object codeObject) { - throw new NotImplementedException (); + object deserialized = null; + + CodeExpression expression = codeObject as CodeExpression; + if (expression != null) + deserialized = base.DeserializeExpression (manager, null, expression); + + CodeStatement statement = codeObject as CodeStatement; + if (statement != null) + deserialized = DeserializeStatementToInstance (manager, statement); + + CodeStatementCollection statements = codeObject as CodeStatementCollection; + if (statements != null) { + foreach (CodeStatement s in statements) { + if (deserialized == null) + deserialized = DeserializeStatementToInstance (manager, s); + else + break; + } + } + + return deserialized; } - [MonoTODO] - protected CodeExpression SerializeToReferenceExpression (IDesignerSerializationManager manager, object value) + protected object DeserializeStatementToInstance (IDesignerSerializationManager manager, CodeStatement statement) { - throw new NotImplementedException (); + object deserialized = null; + + CodeAssignStatement assignment = statement as CodeAssignStatement; + if (assignment == null) + return null; + + // CodeFieldReferenceExpression + // + CodeFieldReferenceExpression fieldRef = assignment.Left as CodeFieldReferenceExpression; + if (fieldRef != null) + deserialized = base.DeserializeExpression (manager, fieldRef.FieldName, assignment.Right); + + base.DeserializeStatement (manager, statement); + + return deserialized; } } } +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomSerializerBase.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomSerializerBase.cs new file mode 100644 index 00000000000..2926e9cf9e9 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CodeDomSerializerBase.cs @@ -0,0 +1,706 @@ +// +// System.ComponentModel.Design.Serialization.CodeDomSerializerBase +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.Reflection; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + public abstract class CodeDomSerializerBase + { + + private class ExpressionTable : Hashtable // just so that we have a specific type to append to the context stack + { + } + + protected CodeExpression SerializeToExpression (IDesignerSerializationManager manager, object instance) + { + if (manager == null) + throw new ArgumentNullException ("manager"); + + CodeExpression expression = null; + if (instance != null) + expression = this.GetExpression (manager, instance); // 1 - IDesignerSerializationManager.GetExpression + if (expression == null) { + CodeDomSerializer serializer = this.GetSerializer (manager, instance); // 2 - manager.GetSerializer().Serialize() + if (serializer != null) { + object serialized = serializer.Serialize (manager, instance); + expression = serialized as CodeExpression; // 3 - CodeStatement or CodeStatementCollection + if (expression == null) { + CodeStatement statement = serialized as CodeStatement; + CodeStatementCollection statements = serialized as CodeStatementCollection; + + if (statement != null || statements != null) { + CodeStatementCollection contextStatements = null; + + StatementContext context = manager.Context[typeof (StatementContext)] as StatementContext; + if (context != null && instance != null) + contextStatements = context.StatementCollection[instance]; + + if (contextStatements == null) + contextStatements = manager.Context[typeof (CodeStatementCollection)] as CodeStatementCollection; + + if (contextStatements != null) { + if (statements != null) + contextStatements.AddRange (statements); + else + contextStatements.Add (statement); + } + } + } + if (expression == null && instance != null) + expression = this.GetExpression (manager, instance); // 4 + + if (expression == null) + Console.WriteLine ("SerializeToExpression: " + instance + " failed."); + } + } + return expression; + } + + protected CodeDomSerializer GetSerializer (IDesignerSerializationManager manager, object instance) + { + DesignerSerializerAttribute attrInstance, attrType; + attrType = attrInstance = null; + + CodeDomSerializer serializer = null; + if (instance == null) + serializer = this.GetSerializer (manager, null); + else { + AttributeCollection attributes = TypeDescriptor.GetAttributes (instance); + foreach (Attribute a in attributes) { + DesignerSerializerAttribute designerAttr = a as DesignerSerializerAttribute; + if (designerAttr != null && manager.GetType (designerAttr.SerializerBaseTypeName) == typeof (CodeDomSerializer)) { + attrInstance = designerAttr; + break; + } + } + + attributes = TypeDescriptor.GetAttributes (instance.GetType ()); + foreach (Attribute a in attributes) { + DesignerSerializerAttribute designerAttr = a as DesignerSerializerAttribute; + if (designerAttr != null && manager.GetType (designerAttr.SerializerBaseTypeName) == typeof (CodeDomSerializer)) { + attrType = designerAttr; + break; + } + } + + // if there is metadata modification in the instance then create the specified serializer instead of the one + // in the Type. + if (attrType != null && attrInstance != null && attrType.SerializerTypeName != attrInstance.SerializerTypeName) + serializer = Activator.CreateInstance (manager.GetType (attrInstance.SerializerTypeName)) as CodeDomSerializer; + else + serializer = this.GetSerializer (manager, instance.GetType ()); + } + + return serializer; + } + + protected CodeDomSerializer GetSerializer (IDesignerSerializationManager manager, Type instanceType) + { + return manager.GetSerializer (instanceType, typeof (CodeDomSerializer)) as CodeDomSerializer; + } + + protected CodeExpression GetExpression (IDesignerSerializationManager manager, object instance) + { + if (manager == null) + throw new ArgumentNullException ("manager"); + if (instance == null) + throw new ArgumentNullException ("instance"); + + CodeExpression expression = null; + + ExpressionTable expressions = manager.Context[typeof (ExpressionTable)] as ExpressionTable; + if (expressions != null) // 1st try: ExpressionTable + expression = expressions [instance] as CodeExpression; + + if (expression == null) { // 2nd try: RootContext + RootContext context = manager.Context[typeof (RootContext)] as RootContext; + if (context != null && context.Value == instance) + expression = context.Expression; + } + + if (expression == null) { // 3rd try: IReferenceService (instnace.property.property.property + string name = manager.GetName (instance); + if (name == null || name.IndexOf (".") == -1) { + IReferenceService service = manager.GetService (typeof (IReferenceService)) as IReferenceService; + if (service != null) { + name = service.GetName (instance); + if (name != null && name.IndexOf (".") != -1) { + string[] parts = name.Split (new char[] { ',' }); + instance = manager.GetInstance (parts[0]); + if (instance != null) { + expression = SerializeToExpression (manager, instance); + if (expression != null) { + for (int i=1; i < parts.Length; i++) + expression = new CodePropertyReferenceExpression (expression, parts[i]); + } + } + } + } + } + } + return expression; + } + + protected void SetExpression (IDesignerSerializationManager manager, object instance, CodeExpression expression) + { + SetExpression (manager, instance, expression, false); + } + + // XXX: isPreset - what does this do when set? + // + protected void SetExpression (IDesignerSerializationManager manager, object instance, CodeExpression expression, bool isPreset) + { + if (manager == null) + throw new ArgumentNullException ("manager"); + if (instance == null) + throw new ArgumentNullException ("instance"); + if (expression == null) + throw new ArgumentNullException ("expression"); + + ExpressionTable expressions = manager.Context[typeof (ExpressionTable)] as ExpressionTable; + if (expressions == null) { + expressions = new ExpressionTable (); + manager.Context.Append (expressions); + } + + expressions[instance] = expression; + } + + protected bool IsSerialized (IDesignerSerializationManager manager, object value) + { + return this.IsSerialized (manager, value, false); + } + + // XXX: What should honorPreset do? + protected bool IsSerialized (IDesignerSerializationManager manager, object instance, bool honorPreset) + { + if (instance == null) + throw new ArgumentNullException ("instance"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + if (this.GetExpression (manager, instance) != null) + return true; + else + return false; + } + + protected CodeExpression SerializeCreationExpression (IDesignerSerializationManager manager, object value, out bool isComplete) + { + if (value == null) + throw new ArgumentNullException ("value"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + CodeExpression expression = null; + + TypeConverter converter = TypeDescriptor.GetConverter (value); + if (converter != null && converter.CanConvertTo (typeof (InstanceDescriptor))) { + InstanceDescriptor descriptor = converter.ConvertTo (value, typeof (InstanceDescriptor)) as InstanceDescriptor; + isComplete = descriptor.IsComplete; + expression = this.SerializeInstanceDescriptor (manager, descriptor); + } else { + expression = new CodeObjectCreateExpression (value.GetType ().FullName, new CodeExpression[0]); + isComplete = false; + } + if (value.GetType ().Name.EndsWith ("Color")) + Console.WriteLine ("SerializeCreationExpression: " + expression); + return expression; + } + + private CodeExpression SerializeInstanceDescriptor (IDesignerSerializationManager manager, InstanceDescriptor descriptor) + { + CodeExpression expression = null; + MemberInfo member = descriptor.MemberInfo; + CodeExpression target = new CodeTypeReferenceExpression (member.DeclaringType); + + if (member is PropertyInfo) { + expression = new CodePropertyReferenceExpression (target, member.Name); + } else if (member is FieldInfo) { + expression = new CodeFieldReferenceExpression (target, member.Name); + } else if (member is MethodInfo) { + CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression (target, member.Name); + manager.Context.Push (new ExpressionContext (methodInvoke, methodInvoke.GetType (), null, null)); + if (descriptor.Arguments != null && descriptor.Arguments.Count > 0) + methodInvoke.Parameters.AddRange (SerializeParameters (manager, descriptor.Arguments)); + manager.Context.Pop (); + expression = methodInvoke; + } else if (member is ConstructorInfo) { + CodeObjectCreateExpression createExpr = new CodeObjectCreateExpression (member.DeclaringType); + manager.Context.Push (new ExpressionContext (createExpr, createExpr.GetType (), null, null)); + if (descriptor.Arguments != null && descriptor.Arguments.Count > 0) + createExpr.Parameters.AddRange (SerializeParameters (manager, descriptor.Arguments)); + manager.Context.Pop (); + expression = createExpr; + } + + return expression; + } + + private CodeExpression[] SerializeParameters (IDesignerSerializationManager manager, ICollection parameters) + { + CodeExpression[] expressions = null; + + if (parameters != null && parameters.Count > 0) { + expressions = new CodeExpression[parameters.Count]; + int i = 0; + foreach (object parameter in parameters) { + expressions[i] = this.SerializeToExpression (manager, parameter); + i++; + } + } + + return expressions; + } + + protected void SerializeEvent (IDesignerSerializationManager manager, CodeStatementCollection statements, + object value, EventDescriptor descriptor) + { + if (descriptor == null) + throw new ArgumentNullException ("descriptor"); + if (value == null) + throw new ArgumentNullException ("value"); + if (statements == null) + throw new ArgumentNullException ("statements"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + MemberCodeDomSerializer serializer = manager.GetSerializer (descriptor.GetType (), typeof (MemberCodeDomSerializer)) as MemberCodeDomSerializer; + if (serializer != null && serializer.ShouldSerialize (manager, value, descriptor)) + serializer.Serialize (manager, value, descriptor, statements); + } + + protected void SerializeEvents (IDesignerSerializationManager manager, CodeStatementCollection statements, + object value, params Attribute[] filter) + { + if (filter == null) + throw new ArgumentNullException ("filter"); + if (value == null) + throw new ArgumentNullException ("value"); + if (statements == null) + throw new ArgumentNullException ("statements"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + EventDescriptorCollection events = TypeDescriptor.GetEvents (value, filter); + foreach (EventDescriptor e in events) + this.SerializeEvent (manager, statements, value, e); + } + + protected void SerializeProperty (IDesignerSerializationManager manager, CodeStatementCollection statements, object value, PropertyDescriptor propertyToSerialize) + { + if (propertyToSerialize == null) + throw new ArgumentNullException ("propertyToSerialize"); + if (value == null) + throw new ArgumentNullException ("value"); + if (statements == null) + throw new ArgumentNullException ("statements"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + MemberCodeDomSerializer serializer = manager.GetSerializer (propertyToSerialize.GetType (), typeof (MemberCodeDomSerializer)) as MemberCodeDomSerializer; + if (serializer != null && serializer.ShouldSerialize (manager, value, propertyToSerialize)) + serializer.Serialize (manager, value, propertyToSerialize, statements); + } + + protected void SerializeProperties (IDesignerSerializationManager manager, CodeStatementCollection statements, + object value, Attribute[] filter) + { + if (filter == null) + throw new ArgumentNullException ("filter"); + if (value == null) + throw new ArgumentNullException ("value"); + if (statements == null) + throw new ArgumentNullException ("statements"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + PropertyDescriptorCollection properties = TypeDescriptor.GetProperties (value, filter); + foreach (PropertyDescriptor property in properties) + this.SerializeProperty (manager, statements, value, property); + } + + protected virtual object DeserializeInstance (IDesignerSerializationManager manager, Type type, + object[] parameters, string name, bool addToContainer) + { + if (type == null) + throw new ArgumentNullException ("type"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + return manager.CreateInstance (type, parameters, name, addToContainer); + } + + protected string GetUniqueName (IDesignerSerializationManager manager, object instance) + { + if (instance == null) + throw new ArgumentNullException ("instance"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + string name = manager.GetName (instance); + if (name == null) { + INameCreationService service = manager.GetService (typeof (INameCreationService)) as INameCreationService; + name = service.CreateName (null, instance.GetType ()); + if (name == null) + name = instance.GetType ().Name.ToLower (); + manager.SetName (instance, name); + } + return name; + } + + protected object DeserializeExpression (IDesignerSerializationManager manager, string name, CodeExpression expression) + { + if (expression == null) + throw new ArgumentNullException ("expression"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + object deserialized = null; + + // CodeThisReferenceExpression + // + CodeThisReferenceExpression thisExpr = expression as CodeThisReferenceExpression; + if (thisExpr != null) { + RootContext context = manager.Context[typeof (RootContext)] as RootContext; + if (context != null) { + deserialized = context.Value; + } else { + IDesignerHost host = manager.GetService (typeof (IDesignerHost)) as IDesignerHost; + if (host != null) + deserialized = host.RootComponent; + } + } + + // CodeVariableReferenceExpression + // + + CodeVariableReferenceExpression varRef = expression as CodeVariableReferenceExpression; + if (deserialized == null && varRef != null) + deserialized = manager.GetInstance (varRef.VariableName); + + // CodeFieldReferenceExpression + // + CodeFieldReferenceExpression fieldRef = expression as CodeFieldReferenceExpression; + if (deserialized == null && fieldRef != null) + deserialized = manager.GetInstance (fieldRef.FieldName); + + + // CodePrimitiveExpression + // + CodePrimitiveExpression primitiveExp = expression as CodePrimitiveExpression; + if (deserialized == null && primitiveExp != null) + deserialized = primitiveExp.Value; + + // CodePropertyReferenceExpression + // + // Enum references are represented by a PropertyReferenceExpression, where + // PropertyName is the enum field name and the target object is a TypeReference + // to the enum's type + // + CodePropertyReferenceExpression propRef = expression as CodePropertyReferenceExpression; + if (deserialized == null && propRef != null) { + object target = DeserializeExpression (manager, null, propRef.TargetObject); + if (target != null) { + if (target is Type) { // Enum reference + FieldInfo field = ((Type)target).GetField (propRef.PropertyName, + BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static); + if (field != null) + deserialized = field.GetValue (null); + } else { + PropertyDescriptor property = TypeDescriptor.GetProperties (target)[propRef.PropertyName]; + if (property != null) + deserialized = property.GetValue (target); + } + } + } + + // CodeObjectCreateExpression + // + CodeObjectCreateExpression createExpr = expression as CodeObjectCreateExpression; + if (deserialized == null && createExpr != null) { + Type type = manager.GetType (createExpr.CreateType.BaseType); + object[] arguments = new object[createExpr.Parameters.Count]; + for (int i=0; i < createExpr.Parameters.Count; i++) + arguments[i] = this.DeserializeExpression (manager, null, createExpr.Parameters[i]); + bool addToContainer = false; + if (typeof(IComponent).IsAssignableFrom (type)) + addToContainer = true; + deserialized = this.DeserializeInstance (manager, type, arguments, name, addToContainer); + } + + // CodeArrayCreateExpression + // + CodeArrayCreateExpression arrayCreateExpr = expression as CodeArrayCreateExpression; + if (deserialized == null && arrayCreateExpr != null) { + Type arrayType = manager.GetType (arrayCreateExpr.CreateType.BaseType); + if (arrayType != null) { + ArrayList initializers = new ArrayList (); + foreach (CodeExpression initExpression in arrayCreateExpr.Initializers) { + initializers.Add (this.DeserializeExpression (manager, null, initExpression)); + } + deserialized = Array.CreateInstance (arrayType, initializers.Count); + initializers.CopyTo ((Array)deserialized, 0); + } + } + + // CodeMethodInvokeExpression + // + CodeMethodInvokeExpression methodExpr = expression as CodeMethodInvokeExpression; + if (deserialized == null && methodExpr != null) { + object target = this.DeserializeExpression (manager, null, methodExpr.Method.TargetObject); + object[] parameters = new object[methodExpr.Parameters.Count]; + for (int i=0; i < methodExpr.Parameters.Count; i++) + parameters[i] = this.DeserializeExpression (manager, null, methodExpr.Parameters[i]); + + MethodInfo method = null; + if (target is Type) { + method = GetExactMethod ((Type)target, methodExpr.Method.MethodName, + BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, + parameters); + } else { + method = GetExactMethod (target.GetType(), methodExpr.Method.MethodName, + BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, + parameters); + } + + if (method == null) + Console.WriteLine ("DeserializeExpression: Unable to find method: " + methodExpr.Method.MethodName); + else + deserialized = method.Invoke (target, parameters); + } + + // CodeTypeReferenceExpression + // + CodeTypeReferenceExpression typeRef = expression as CodeTypeReferenceExpression; + if (deserialized == null && typeRef != null) + deserialized = manager.GetType (typeRef.Type.BaseType); + + // CodeBinaryOperatorExpression + // + CodeBinaryOperatorExpression binOperator = expression as CodeBinaryOperatorExpression; + if (deserialized == null && binOperator != null) { + switch (binOperator.Operator) { + case CodeBinaryOperatorType.BitwiseOr: + IConvertible left = DeserializeExpression (manager, null, binOperator.Left) as IConvertible; + IConvertible right = DeserializeExpression (manager, null, binOperator.Right) as IConvertible; + if (left is Enum) + deserialized = Enum.ToObject (left.GetType (), Convert.ToInt64 (left) | Convert.ToInt64 (right)); + break; + } + } + + if (deserialized == null && methodExpr == null && primitiveExp == null) + Console.WriteLine ("DeserializeExpression not supported for: " + expression); + + return deserialized; + } + + // Searches for a method on type that matches argument types + // + private MethodInfo GetExactMethod (Type type, string methodName, BindingFlags flags, ICollection argsCollection) + { + object[] arguments = null; + Type[] types = new Type[0]; + + if (argsCollection != null) { + arguments = new object[argsCollection.Count]; + types = new Type[argsCollection.Count]; + argsCollection.CopyTo (arguments, 0); + + for (int i=0; i < arguments.Length; i++) { + if (arguments[i] == null) + types[i] = null; + else + types[i] = arguments[i].GetType (); + } + } + + return type.GetMethod (methodName, flags, null, types, null); + } + + protected void DeserializeStatement (IDesignerSerializationManager manager, CodeStatement statement) + { + if (statement == null) + throw new ArgumentNullException ("statement"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + bool deserialized = false; + + // CodeAssignStatement + // + CodeAssignStatement assignment = statement as CodeAssignStatement; + if (assignment != null) { + DeserializeAssignmentStatement (manager, assignment); + deserialized = true; + } + + // CodeExpressionStatement + // + CodeExpressionStatement expression = statement as CodeExpressionStatement; + if (expression != null) { + this.DeserializeExpression (manager, null, expression.Expression); + deserialized = true; + } + + + // CodeAttachEventStatement + // + CodeAttachEventStatement attachStatement = statement as CodeAttachEventStatement; + if (attachStatement != null) { + string methodName = null; + + CodeObjectCreateExpression createExpr = attachStatement.Listener as CodeObjectCreateExpression; + if (createExpr != null && createExpr.Parameters.Count == 1 ) { // += new EventType (method) + CodeMethodReferenceExpression handlerRef = createExpr.Parameters[0] as CodeMethodReferenceExpression; + if (handlerRef != null) + methodName = handlerRef.MethodName; + } + + CodeDelegateCreateExpression delegateCreateExpr = attachStatement.Listener as CodeDelegateCreateExpression; + if (delegateCreateExpr != null)// += new EventType (method) + methodName = delegateCreateExpr.MethodName; + + CodeMethodReferenceExpression methodRef = attachStatement.Listener as CodeMethodReferenceExpression; + if (methodRef != null) // += method + methodName = methodRef.MethodName; + + object component = DeserializeExpression (manager, null, attachStatement.Event.TargetObject); + if (component != null) { + EventDescriptor eventDescriptor = TypeDescriptor.GetEvents (component)[attachStatement.Event.EventName]; + if (eventDescriptor != null) { + IEventBindingService service = manager.GetService (typeof (IEventBindingService)) as IEventBindingService; + if (service != null) { + service.GetEventProperty (eventDescriptor).SetValue (component, methodName); + deserialized = true; + } + } + } + } + + if (!deserialized) + Console.WriteLine ("DeserializeStatement not supported for: " + statement); + } + + private void DeserializeAssignmentStatement (IDesignerSerializationManager manager, CodeAssignStatement statement) + { + bool deserialized = false; + CodeExpression leftExpr = statement.Left; + + // Assign to a Property + // + CodePropertyReferenceExpression propRef = leftExpr as CodePropertyReferenceExpression; + if (propRef != null) { + object target = DeserializeExpression (manager, null, propRef.TargetObject); + object value = DeserializeExpression (manager, null, statement.Right); + if (target != null) { + PropertyDescriptor property = TypeDescriptor.GetProperties (target)[propRef.PropertyName]; + if (property != null) { + try { + property.SetValue (target, value); + } catch (Exception e) { + // FIXME: This is just for testing on MSNET + } + deserialized = true; + } + } + } + + // Assign to a Field + // + // This will fail for fields defined during the serialization process. + // + CodeFieldReferenceExpression fieldRef = leftExpr as CodeFieldReferenceExpression; + if (fieldRef != null) { + object value = DeserializeExpression (manager, fieldRef.FieldName, statement.Right); + object fieldHolder = DeserializeExpression (manager, null, fieldRef.TargetObject); + if (fieldHolder != null) { + FieldInfo field = null; + if (fieldHolder is Type) // static field + field = ((Type)fieldHolder).GetField (fieldRef.FieldName, + BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static); + else // instance field + field = fieldHolder.GetType().GetField (fieldRef.FieldName, + BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance); + if (field != null) { + field.SetValue (fieldHolder, value); + deserialized = true; + } + } + } + + if (!deserialized) + Console.WriteLine ("DeserializeAssignmentStatement error: " + statement); + } + +#region Resource Serialization - TODO + protected CodeExpression SerializeToResourceExpression (IDesignerSerializationManager manager, object value) + { + throw new NotImplementedException (); + } + + protected CodeExpression SerializeToResourceExpression (IDesignerSerializationManager manager, object value, bool ensureInvariant) + { + throw new NotImplementedException (); + } + + protected void SerializePropertiesToResources (IDesignerSerializationManager manager, CodeStatementCollection statements, + object value, Attribute[] filter) + { + throw new NotImplementedException (); + } + + protected void SerializeResource (IDesignerSerializationManager manager, string resourceName, object value) + { + throw new NotImplementedException (); + } + + protected void SerializeResourceInvariant (IDesignerSerializationManager manager, string resourceName, object value) + { + throw new NotImplementedException (); + } + + protected void DeserializePropertiesFromResources (IDesignerSerializationManager manager, object value, Attribute[] filter) + { + throw new NotImplementedException (); + } +#endregion + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CollectionCodeDomSerializer.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CollectionCodeDomSerializer.cs new file mode 100644 index 00000000000..c5067f523f9 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/CollectionCodeDomSerializer.cs @@ -0,0 +1,161 @@ +// +// System.ComponentModel.Design.Serialization.CollectionCodeDomSerializer +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.Reflection; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + public class CollectionCodeDomSerializer : CodeDomSerializer + { + + public CollectionCodeDomSerializer () + { + } + + // FIXME: What is this supposed to do? + protected bool MethodSupportsSerialization (MethodInfo method) + { + return true; + } + + public override object Serialize (IDesignerSerializationManager manager, object value) + { + if (value == null) + throw new ArgumentNullException ("value"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + ICollection originalCollection = value as ICollection; + if (originalCollection == null) + throw new ArgumentException ("originalCollection is not an ICollection"); + + CodeExpression targetExpression = null; + + ExpressionContext exprContext = manager.Context[typeof (ExpressionContext)] as ExpressionContext; + RootContext root = manager.Context[typeof (RootContext)] as RootContext; + + if (exprContext != null && exprContext.PresetValue == value) + targetExpression = exprContext.Expression; + else if (root != null) + targetExpression = root.Expression; + + ArrayList valuesToSerialize = new ArrayList (); + foreach (object o in originalCollection) + valuesToSerialize.Add (o); + + return this.SerializeCollection (manager, targetExpression, value.GetType (), originalCollection, valuesToSerialize); + } + + protected virtual object SerializeCollection (IDesignerSerializationManager manager, CodeExpression targetExpression, + Type targetType, ICollection originalCollection, ICollection valuesToSerialize) + { + if (valuesToSerialize == null) + throw new ArgumentNullException ("valuesToSerialize"); + if (originalCollection == null) + throw new ArgumentNullException ("originalCollection"); + if (targetType == null) + throw new ArgumentNullException ("targetType"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + if (valuesToSerialize.Count == 0) + return null; + + MethodInfo method = null; + try { + object sampleParam = null; + IEnumerator e = valuesToSerialize.GetEnumerator (); + e.MoveNext (); + sampleParam = e.Current; + // try to find a method matching the type of the sample parameter. + // Assuming objects in the collection are from the same base type + method = GetExactMethod (targetType, "Add", new object [] { sampleParam }); + } catch { + Console.WriteLine ("SerializeCollection: No compatible Add method found in " + targetType); + } + + if (method == null) + return null; + + CodeStatementCollection statements = new CodeStatementCollection (); + + foreach (object value in valuesToSerialize) { + CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression (); + methodInvoke.Method = new CodeMethodReferenceExpression (targetExpression, "Add"); + + manager.Context.Push (new ExpressionContext (methodInvoke, methodInvoke.GetType (), null, originalCollection)); + CodeExpression expression = base.SerializeToExpression (manager, value); + if (expression == null) { + Console.WriteLine ("SerializeCollection: Unable to serialize " + value); + methodInvoke = null; + } else { + methodInvoke.Parameters.AddRange (new CodeExpression[] { expression }); + } + manager.Context.Pop (); + + if (methodInvoke != null) + statements.Add (methodInvoke); + } + + return statements; + } + + // Searches for a method on type that matches argument types + // + private MethodInfo GetExactMethod (Type type, string methodName, ICollection argsCollection) + { + object[] arguments = null; + Type[] types = new Type[0]; + + if (argsCollection != null) { + arguments = new object[argsCollection.Count]; + types = new Type[argsCollection.Count]; + argsCollection.CopyTo (arguments, 0); + + for (int i=0; i < arguments.Length; i++) { + if (arguments[i] == null) + types[i] = null; + else + types[i] = arguments[i].GetType (); + } + } + + return type.GetMethod (methodName, types); + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/ComponentCodeDomSerializer.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/ComponentCodeDomSerializer.cs new file mode 100644 index 00000000000..7d4b4e29a4e --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/ComponentCodeDomSerializer.cs @@ -0,0 +1,114 @@ +// +// System.ComponentModel.Design.Serialization.ComponentCodeDomSerializer +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + // A serializer for the IComponent Type, supplied by the CodeDomSerializationProvider, + // added as a provider by the RootComponentCodeDomSerializer + // + internal class ComponentCodeDomSerializer : CodeDomSerializer + { + + public ComponentCodeDomSerializer () + { + } + + public override object Serialize (IDesignerSerializationManager manager, object value) + { + if (value == null) + throw new ArgumentNullException ("value"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + // Check if we are serializing the root component. Happens, because GetSerializer does not + // check for a RootCodeDomSerializer so reference-to type of an expression is delivered + // by the CodeDomSerializer + RootContext rootContext = manager.Context[typeof (RootContext)] as RootContext; + if (rootContext != null && rootContext.Value == value) + return rootContext.Expression; + + if (((IComponent)value).Site == null) { + Console.WriteLine ("ComponentCodeDomSerializer: Not sited : " + value); + return null; + } + + object serialized = null; + // the trick with the nested components is that GetName will return the full name + // e.g splitter1.Panel1 and thus the code below will create a reference to that. + // + string name = manager.GetName (value); + + CodeExpression componentRef = null; + if (rootContext != null) + componentRef = new CodeFieldReferenceExpression (rootContext.Expression , name); + else + componentRef = new CodeFieldReferenceExpression (new CodeThisReferenceExpression () , name); + + ExpressionContext exprContext = manager.Context[typeof (ExpressionContext)] as ExpressionContext; + if (exprContext != null && exprContext.PresetValue == value) { + bool isComplete = true; + CodeStatementCollection statements = new CodeStatementCollection (); + statements.Add (new CodeCommentStatement (String.Empty)); + statements.Add (new CodeCommentStatement (name)); + statements.Add (new CodeCommentStatement (String.Empty)); + + // Do not serialize a creation expression for Nested components + // + if (! (((IComponent)value).Site is INestedSite)) + statements.Add (new CodeAssignStatement (componentRef, + base.SerializeCreationExpression (manager, value, out isComplete))); + + manager.Context.Push (new ExpressionContext (componentRef, componentRef.GetType (), null, value)); + base.SerializeProperties (manager, statements, value, new Attribute[0]); + base.SerializeEvents (manager, statements, value); + manager.Context.Pop (); + + serialized = statements; + } else { + serialized = base.GetExpression (manager, value); + if (serialized == null) { + base.SetExpression (manager, value, componentRef); + serialized = componentRef; + } + } + + return serialized; + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/DesignerSerializationManager.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/DesignerSerializationManager.cs new file mode 100644 index 00000000000..72d0756fe32 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/DesignerSerializationManager.cs @@ -0,0 +1,517 @@ +// +// System.ComponentModel.Design.Serialization.DesignerSerializationManager +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.ComponentModel; +using System.ComponentModel.Design; + + + +namespace System.ComponentModel.Design.Serialization +{ + + public class DesignerSerializationManager : IDesignerSerializationManager, IServiceProvider + { + + private class Session : IDisposable + { + + private DesignerSerializationManager _manager; + + public Session (DesignerSerializationManager manager) + { + _manager = manager; + } + + public void Dispose () + { + _manager.OnSessionDisposed (EventArgs.Empty); + } + } + + + + public DesignerSerializationManager () : this (null) + { + } + + // This constructor sets the PreserveNames and ValidateRecycledTypes properties to true. + // + public DesignerSerializationManager (IServiceProvider provider) + { + _serviceProvider = provider; + _preserveNames = true; + _validateRecycledTypes = true; + } + + private IServiceProvider _serviceProvider; + private bool _preserveNames = false; + private bool _validateRecycledTypes = false; + private bool _recycleInstances = false; + private IContainer _designerContainer = null; + private object _propertyProvider = null; + private Session _session = null; + private ArrayList _errors = null; + private List <IDesignerSerializationProvider> _serializationProviders; + private Dictionary <Type, object> _serializersCache = null; // componentType - serializer instance + private Dictionary <string, object> _instancesByNameCache = null; // name - instance + private Dictionary <object, string> _instancesByValueCache = null; // instance - name + private ContextStack _contextStack = null; + + + public bool RecycleInstances { + get { return _recycleInstances; } + set { + VerifyNotInSession (); + _recycleInstances = value; + } + } + + public bool PreserveNames { + get { return _preserveNames; } + set { + VerifyNotInSession (); + _preserveNames = value; + } + } + + public bool ValidateRecycledTypes { + get { return _validateRecycledTypes; } + set { + VerifyNotInSession (); + _validateRecycledTypes = value; + } + } + + public IContainer Container { + get { + if (_designerContainer == null) { + _designerContainer = (this.GetService (typeof (IDesignerHost)) as IDesignerHost).Container; + } + return _designerContainer; + } + set{ + VerifyNotInSession (); + _designerContainer = value; + } + } + + public object PropertyProvider { + get { return _propertyProvider; } + set { _propertyProvider = value; } + } + + public IList Errors { + get { return _errors; } + } + + public event EventHandler SessionDisposed; + public event EventHandler SessionCreated; + + protected virtual void OnSessionCreated (EventArgs e) + { + if (SessionCreated != null) { + SessionCreated (this, e); + } + } + + // For behaviour description: + // + // http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.designerserializationmanager.validaterecycledtypes.aspx + // http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.designerserializationmanager.preservenames.aspx + // + protected virtual object CreateInstance (Type type, ICollection arguments, string name, bool addToContainer) + { + VerifyInSession (); + + object instance = null; + + if (name != null && _recycleInstances) { + _instancesByNameCache.TryGetValue (name, out instance); + if (instance != null && _validateRecycledTypes) { + if (instance.GetType () != type) + instance = null; + } + } + + if (instance == null || !_recycleInstances) { + instance = this.CreateInstance (type, arguments); + } + + if (addToContainer && instance != null && this.Container != null && typeof (IComponent).IsAssignableFrom (type)) { + if (_preserveNames) { + this.Container.Add ((IComponent) instance, name); + } + else { + if (name != null && this.Container.Components[name] != null) { + this.Container.Add ((IComponent) instance); + } + else { + this.Container.Add ((IComponent) instance, name); + } + } + ISite site = ((IComponent)instance).Site; // get the name from the site in case a name has been generated. + if (site != null) + name = site.Name; + } + + if (instance != null && name != null) { + _instancesByNameCache[name] = instance; + _instancesByValueCache[instance] = name; + } + + return instance; + } + + // Invokes the constructor that matches the arguments + // + private object CreateInstance (Type type, ICollection argsCollection) + { + object instance = null; + object[] arguments = null; + Type[] types = new Type[0]; + + if (argsCollection != null) { + arguments = new object[argsCollection.Count]; + types = new Type[argsCollection.Count]; + argsCollection.CopyTo (arguments, 0); + + for (int i=0; i < arguments.Length; i++) { + if (arguments[i] == null) + types[i] = null; + else + types[i] = arguments[i].GetType (); + } + } + + ConstructorInfo ctor = type.GetConstructor (types); + if (ctor != null) { + instance = ctor.Invoke (arguments); + } + + return instance; + } + + public object GetSerializer (Type componentType, Type serializerType) + { + VerifyInSession (); + + if (serializerType == null) + throw new ArgumentNullException ("serializerType"); + + object serializer = null; + + if (componentType != null) { + // try 1: from cache + // + _serializersCache.TryGetValue (componentType, out serializer); + + // check for provider attribute and add it to the list of providers + // + if (serializer != null && !serializerType.IsAssignableFrom (serializer.GetType ())) + serializer = null; + + AttributeCollection attributes = TypeDescriptor.GetAttributes (componentType); + DefaultSerializationProviderAttribute providerAttribute = attributes[typeof (DefaultSerializationProviderAttribute)] + as DefaultSerializationProviderAttribute; + if (providerAttribute != null && this.GetType (providerAttribute.ProviderTypeName) == serializerType) { + + object provider = Activator.CreateInstance (this.GetType (providerAttribute.ProviderTypeName), + BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.NonPublic, + null, null, null); + + ((IDesignerSerializationManager)this).AddSerializationProvider ((IDesignerSerializationProvider) provider); + } + } + + // try 2: from provider + // + if (serializer == null) { + foreach (IDesignerSerializationProvider provider in _serializationProviders) { + serializer = provider.GetSerializer (this, null, componentType, serializerType); + if (serializer != null) + break; + } + } + + if (componentType != null) { + // try 3: Activator + // + if (serializer == null) { + AttributeCollection attributes = TypeDescriptor.GetAttributes (componentType); + DesignerSerializerAttribute serializerAttribute = attributes[typeof (DesignerSerializerAttribute)] as DesignerSerializerAttribute; + if (serializerAttribute != null && this.GetType (serializerAttribute.SerializerTypeName) == serializerType) { + serializer = Activator.CreateInstance (this.GetType (serializerAttribute.SerializerTypeName), + BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.NonPublic, + null, null, null); + } + } + + if (serializer != null) + _serializersCache[componentType] = serializer; + } + + return serializer; + } + + private void VerifyInSession () + { + if (_session == null) + throw new InvalidOperationException ("Not in session."); + } + + private void VerifyNotInSession () + { + if (_session != null) + throw new InvalidOperationException ("In session."); + } + + public IDisposable CreateSession () + { + _errors = new ArrayList (); + _session = new Session (this); + _serializersCache = new Dictionary<System.Type,object> (); + _instancesByNameCache = new Dictionary<string,object> (); + _instancesByValueCache = new Dictionary<object, string> (); + _contextStack = new ContextStack (); + + this.OnSessionCreated (EventArgs.Empty); + if (_serializationCompleteHandler != null) + _serializationCompleteHandler (this, EventArgs.Empty); + + return _session; + } + + protected virtual void OnSessionDisposed (EventArgs e) + { + _errors.Clear (); + _errors = null; + _serializersCache.Clear (); + _serializersCache = null; + _instancesByNameCache.Clear (); + _instancesByNameCache = null; + _instancesByValueCache.Clear (); + _instancesByValueCache = null; + _session = null; + _contextStack = null; + _resolveNameHandler = null; + _serializationCompleteHandler = null; + + if (SessionDisposed != null) { + SessionDisposed (this, e); + } + } + + protected virtual Type GetType (string name) + { + if (name == null) + throw new ArgumentNullException ("name"); + + this.VerifyInSession (); + + Type result = null; + ITypeResolutionService typeResSvc = this.GetService (typeof (ITypeResolutionService)) as ITypeResolutionService; + if (typeResSvc != null) + result = typeResSvc.GetType (name); + if (result == null) + result = Type.GetType (name); + + return result; + } + +#region IDesignerSerializationManager implementation + + protected virtual void OnResolveName (ResolveNameEventArgs e) + { + if (_resolveNameHandler != null) { + _resolveNameHandler (this, e); + } + } + + void IDesignerSerializationManager.AddSerializationProvider (IDesignerSerializationProvider provider) + { + if (_serializationProviders == null) + _serializationProviders = new List <IDesignerSerializationProvider> (); + + if (!_serializationProviders.Contains (provider)) + _serializationProviders.Add (provider); + } + + void IDesignerSerializationManager.RemoveSerializationProvider (IDesignerSerializationProvider provider) + { + if (_serializationProviders != null) + _serializationProviders.Remove (provider); + } + + object IDesignerSerializationManager.CreateInstance (Type type, ICollection arguments, string name, bool addToContainer) + { + return this.CreateInstance (type, arguments, name, addToContainer); + } + + //Retrieves an instance of a created object of the specified name. + // + object IDesignerSerializationManager.GetInstance (string name) + { + if (name == null) + throw new ArgumentNullException ("name"); + this.VerifyInSession (); + + object instance = null; + _instancesByNameCache.TryGetValue (name, out instance); + + if (instance == null && _preserveNames && this.Container != null) + instance = this.Container.Components[name]; + + if (instance == null) + instance = this.RequestInstance (name); + + return instance; + } + + private object RequestInstance (string name) + { + ResolveNameEventArgs args = new ResolveNameEventArgs (name); + this.OnResolveName (args); + return args.Value; + } + + Type IDesignerSerializationManager.GetType (string name) + { + return this.GetType (name); + } + + object IDesignerSerializationManager.GetSerializer (Type type, Type serializerType) + { + return this.GetSerializer (type, serializerType); + } + + string IDesignerSerializationManager.GetName (object instance) + { + if (instance == null) + throw new ArgumentNullException ("instance"); + this.VerifyInSession (); + + string name = null; + if (instance is IComponent) { + ISite site = ((IComponent)instance).Site; + if (site != null && site is INestedSite) + name = ((INestedSite)site).FullName; + else if (site != null) + name = site.Name; + } + if (name == null) + _instancesByValueCache.TryGetValue (instance, out name); + return name; + } + + // Used to set the name for objects not created via CreateInstance + // == it's not named, nor cached. + // + // XXX: "Used by another object" ? + // + void IDesignerSerializationManager.SetName (object instance, string name) + { + if (instance == null) + throw new ArgumentNullException ("instance"); + if (name == null) + throw new ArgumentNullException ("name"); + + if (_instancesByNameCache.ContainsKey (name)) + throw new ArgumentException ("The object specified by instance already has a name, or name is already used by another named object."); + + _instancesByNameCache.Add (name, instance); + _instancesByValueCache.Add (instance, name); + } + + void IDesignerSerializationManager.ReportError (object error) + { + this.VerifyInSession (); + _errors.Add (error); + } + + ContextStack IDesignerSerializationManager.Context { + get { return _contextStack; } + } + + PropertyDescriptorCollection IDesignerSerializationManager.Properties { + get { + PropertyDescriptorCollection properties = new PropertyDescriptorCollection (new PropertyDescriptor[0]); + object component = this.PropertyProvider; + if (component != null) + properties = TypeDescriptor.GetProperties (component); + + return properties; + } + } + + private EventHandler _serializationCompleteHandler; + private ResolveNameEventHandler _resolveNameHandler; + + event EventHandler IDesignerSerializationManager.SerializationComplete { + add { + this.VerifyInSession (); + _serializationCompleteHandler = (EventHandler) Delegate.Combine (_serializationCompleteHandler, value); + } + remove { + _serializationCompleteHandler = (EventHandler) Delegate.Remove (_serializationCompleteHandler, value); + } + } + + event ResolveNameEventHandler IDesignerSerializationManager.ResolveName { + add { + this.VerifyInSession (); + _resolveNameHandler = (ResolveNameEventHandler) Delegate.Combine (_resolveNameHandler, value); + } + remove { + _resolveNameHandler = (ResolveNameEventHandler) Delegate.Remove (_resolveNameHandler, value); + } + } +#endregion + + object IServiceProvider.GetService (Type service) + { + return this.GetService (service); + } + + protected virtual object GetService (Type service) + { + object result = null; + if (_serviceProvider != null) + result = _serviceProvider.GetService (service); + + return result; + } + } +} +#endif
\ No newline at end of file diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/EnumCodeDomSerializer.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/EnumCodeDomSerializer.cs new file mode 100644 index 00000000000..5d26def4351 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/EnumCodeDomSerializer.cs @@ -0,0 +1,84 @@ +// +// System.ComponentModel.Design.Serialization.EnumCodeDomSerializer +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + internal class EnumCodeDomSerializer : CodeDomSerializer + { + + public EnumCodeDomSerializer () + { + } + + public override object Serialize (IDesignerSerializationManager manager, object value) + { + if (manager == null) + throw new ArgumentNullException ("manager"); + if (value == null) + throw new ArgumentNullException ("value"); + + Enum[] enums = null; + TypeConverter converter = TypeDescriptor.GetConverter (value); + if (converter.CanConvertTo (typeof (Enum[]))) + enums = (Enum[]) converter.ConvertTo (value, typeof (Enum[])); + else + enums = new Enum[] { (Enum) value }; + CodeExpression left = null; + CodeExpression right = null; + foreach (Enum e in enums) { + right = GetEnumExpression (e); + if (left == null) // just the first time + left = right; + else + left = new CodeBinaryOperatorExpression (left, CodeBinaryOperatorType.BitwiseOr, right); + } + + return left; + } + + private CodeExpression GetEnumExpression (Enum e) + { + TypeConverter converter = TypeDescriptor.GetConverter (e); + if (converter != null && converter.CanConvertTo (typeof (string))) + return new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (e.GetType().FullName), + (string) converter.ConvertTo (e, typeof (string))); + else + return null; + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/EventCodeDomSerializer.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/EventCodeDomSerializer.cs new file mode 100644 index 00000000000..609241401d0 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/EventCodeDomSerializer.cs @@ -0,0 +1,90 @@ +// +// System.ComponentModel.Design.Serialization.EventCodeDomSerializer +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + internal class EventCodeDomSerializer : MemberCodeDomSerializer + { + + private CodeThisReferenceExpression _thisReference; + + public EventCodeDomSerializer () + { + // don't waste memory on something that is constant when generating the + // event codedom code - keep it as a field. + _thisReference = new CodeThisReferenceExpression (); + } + + + public override void Serialize (IDesignerSerializationManager manager, object value, MemberDescriptor descriptor, CodeStatementCollection statements) + { + if (statements == null) + throw new ArgumentNullException ("statements"); + if (manager == null) + throw new ArgumentNullException ("manager"); + if (value == null) + throw new ArgumentNullException ("value"); + if (descriptor == null) + throw new ArgumentNullException ("descriptor"); + + IEventBindingService service = manager.GetService (typeof (IEventBindingService)) as IEventBindingService; + if (service != null) { + EventDescriptor eventDescriptor = (EventDescriptor) descriptor; + string methodName = (string) service.GetEventProperty (eventDescriptor).GetValue (value); + + if (methodName != null) { + CodeDelegateCreateExpression listener = new CodeDelegateCreateExpression (new CodeTypeReference (eventDescriptor.EventType), + _thisReference, methodName); + manager.Context.Push (new ExpressionContext (listener, listener.GetType (), null, eventDescriptor)); + CodeExpression targetObject = base.SerializeToExpression (manager, value); + manager.Context.Pop (); + CodeEventReferenceExpression eventRef = new CodeEventReferenceExpression (targetObject, eventDescriptor.Name); + statements.Add (new CodeAttachEventStatement (eventRef, listener)); + } + } + } + + public override bool ShouldSerialize (IDesignerSerializationManager manager, object value, MemberDescriptor descriptor) + { + IEventBindingService service = manager.GetService (typeof (IEventBindingService)) as IEventBindingService; + if (service != null) // serialize only if there is an event to serialize + return service.GetEventProperty ((EventDescriptor)descriptor).GetValue (value) != null; + return false; + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/ExpressionContext.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/ExpressionContext.cs new file mode 100644 index 00000000000..39aee1cc03b --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/ExpressionContext.cs @@ -0,0 +1,78 @@ +// +// System.ComponentModel.Design.Serialization.ExpressionContext +// +// Authors: +// Ivan N. Zlatev (contact@i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + public sealed class ExpressionContext + { + + private object _owner; + private Type _expressionType; + private CodeExpression _expression; + private object _presetValue; + + public ExpressionContext (CodeExpression expression, Type expressionType, object owner) + { + _expression = expression; + _expressionType = expressionType; + _owner = owner; + _presetValue = null; + } + + public ExpressionContext (CodeExpression expression, Type expressionType, object owner, object presetValue) + { + _expression = expression; + _expressionType = expressionType; + _owner = owner; + _presetValue = presetValue; + } + + public object PresetValue { + get { return _presetValue; } + } + + public CodeExpression Expression { + get { return _expression; } + } + + public Type ExpressionType { + get { return _expressionType; } + } + + public object Owner { + get { return _owner; } + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/MemberCodeDomSerializer.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/MemberCodeDomSerializer.cs new file mode 100644 index 00000000000..dc8c9e46bbf --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/MemberCodeDomSerializer.cs @@ -0,0 +1,51 @@ +// +// System.ComponentModel.Design.Serialization.MemberCodeDomSerializer +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + public abstract class MemberCodeDomSerializer : CodeDomSerializerBase + { + + protected MemberCodeDomSerializer () + { + } + + public abstract void Serialize (IDesignerSerializationManager manager, object value, MemberDescriptor descriptor, CodeStatementCollection statements); + public abstract bool ShouldSerialize (IDesignerSerializationManager manager, object value, MemberDescriptor descriptor); + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/ObjectStatementCollection.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/ObjectStatementCollection.cs new file mode 100644 index 00000000000..2b76c56c736 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/ObjectStatementCollection.cs @@ -0,0 +1,81 @@ +// +// System.ComponentModel.Design.Serialization.ObjectStatementCollection +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + public sealed class ObjectStatementCollection : IEnumerable + { + + private Hashtable _statements; + + internal ObjectStatementCollection () + { + _statements = new Hashtable (); + } + + public bool ContainsKey (object statementOwner) + { + return _statements.ContainsKey (statementOwner); + } + + public IDictionaryEnumerator GetEnumerator() + { + return _statements.GetEnumerator (); + } + + public CodeStatementCollection this[object owner] + { + get { return _statements[owner] as CodeStatementCollection; } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return this.GetEnumerator (); + } + + public void Populate (object owner) + { + if (_statements[owner] == null) + _statements[owner] = null; + } + + public void Populate (ICollection statementOwners) + { + foreach (object o in statementOwners) + this.Populate (o); + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/PrimitiveCodeDomSerializer.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/PrimitiveCodeDomSerializer.cs new file mode 100644 index 00000000000..892969797c0 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/PrimitiveCodeDomSerializer.cs @@ -0,0 +1,49 @@ +// +// System.ComponentModel.Design.Serialization.PrimitiveCodeDomSerializer +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + internal class PrimitiveCodeDomSerializer : CodeDomSerializer + { + + public override object Serialize (IDesignerSerializationManager manager, object value) + { + return new CodePrimitiveExpression (value); + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/PropertyCodeDomSerializer.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/PropertyCodeDomSerializer.cs new file mode 100644 index 00000000000..bd105ef5d4c --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/PropertyCodeDomSerializer.cs @@ -0,0 +1,223 @@ +// +// System.ComponentModel.Design.Serialization.PropertyCodeDomSerializer +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + internal class PropertyCodeDomSerializer : MemberCodeDomSerializer + { + + public PropertyCodeDomSerializer () + { + } + + public override void Serialize (IDesignerSerializationManager manager, object value, MemberDescriptor descriptor, CodeStatementCollection statements) + { + if (manager == null) + throw new ArgumentNullException ("manager"); + if (value == null) + throw new ArgumentNullException ("value"); + if (descriptor == null) + throw new ArgumentNullException ("descriptor"); + if (statements == null) + throw new ArgumentNullException ("statements"); + + PropertyDescriptor property = (PropertyDescriptor) descriptor; + + if (property.Attributes.Contains (DesignerSerializationVisibilityAttribute.Content)) + SerializeContentProperty (manager, value, property, statements); + else if (!property.Attributes.Contains (DesignerSerializationVisibilityAttribute.Hidden)) + SerializeNormalProperty (manager, value, property, statements); + } + + + private void SerializeNormalProperty (IDesignerSerializationManager manager, + object component, PropertyDescriptor descriptor, CodeStatementCollection statements) + { + CodeAssignStatement assignment = new CodeAssignStatement (); + + CodeExpression leftSide = null; + CodePropertyReferenceExpression propRef = null; + ExpressionContext expression = manager.Context[typeof (ExpressionContext)] as ExpressionContext; + RootContext root = manager.Context[typeof (RootContext)] as RootContext; + + if (expression != null && expression.PresetValue == component && expression.Expression != null) { + leftSide = new CodePropertyReferenceExpression (expression.Expression, descriptor.Name); + } else if (root != null && root.Value == component) { + leftSide = new CodePropertyReferenceExpression (root.Expression, descriptor.Name); + } else { + propRef = new CodePropertyReferenceExpression (); + propRef.PropertyName = descriptor.Name; + propRef.TargetObject = TryGetCachedExpression (manager, component, propRef); + leftSide = propRef; + } + + CodeExpression rightSide = null; + + MemberRelationship relationship = GetRelationship (manager, component, descriptor); + if (!relationship.IsEmpty) { + propRef = new CodePropertyReferenceExpression (); + propRef.PropertyName = relationship.Member.Name; + propRef.TargetObject = TryGetCachedExpression (manager, relationship.Owner, propRef); + rightSide = propRef; + } else { + object rightSideValue = descriptor.GetValue (component); + rightSide = TryGetCachedExpression (manager, rightSideValue, null, component); + } + + if (rightSide == null) { + Console.WriteLine ("SerializeNormalProperty: <" + component.GetType().Name + "." + + descriptor.Name + "> - unable to serialize the right side of the assignment to expression"); + } else if (leftSide == null) { + Console.WriteLine ("SerializeNormalProperty: <" + component.GetType().Name + "." + + descriptor.Name + "> - unable to serialize the left side of the assignment to expression"); + } else { + assignment.Left = leftSide; + assignment.Right = rightSide; + statements.Add (assignment); + } + } + + private CodeExpression TryGetCachedExpression (IDesignerSerializationManager manager, object value) + { + return TryGetCachedExpression (manager, value, null); + } + + private CodeExpression TryGetCachedExpression (IDesignerSerializationManager manager, object value, + CodeExpression parentExpression) + { + return TryGetCachedExpression (manager, value, parentExpression, null); + } + + private CodeExpression TryGetCachedExpression (IDesignerSerializationManager manager, object value, + CodeExpression parentExpression, object presetValue) + { + CodeExpression expression = null; + if (value != null) // in order to support null value serialization + expression = base.GetExpression (manager, value); + if (expression == null) { + if (parentExpression == null) + manager.Context.Push (new ExpressionContext (null, null, value, presetValue)); + else + manager.Context.Push (new ExpressionContext (parentExpression, parentExpression.GetType (), value, presetValue)); + expression = base.SerializeToExpression (manager, value); + manager.Context.Pop (); + } + return expression; + } + + private void SerializeContentProperty (IDesignerSerializationManager manager, object component, + PropertyDescriptor descriptor, CodeStatementCollection statements) + { + CodePropertyReferenceExpression propRef = new CodePropertyReferenceExpression (); + propRef.PropertyName = descriptor.Name; + object value = descriptor.GetValue (component); + + ExpressionContext expressionCtx = manager.Context[typeof (ExpressionContext)] as ExpressionContext; + if (expressionCtx != null && expressionCtx.PresetValue == component) { + propRef.TargetObject = expressionCtx.Expression; + } else { + manager.Context.Push (new CodeStatementCollection ()); + propRef.TargetObject = TryGetCachedExpression (manager, component, propRef, value); + manager.Context.Pop (); + } + + CodeDomSerializer serializer = manager.GetSerializer (value.GetType (), typeof (CodeDomSerializer)) as CodeDomSerializer; + + if (propRef.TargetObject != null && serializer != null) { + // request full serialization (presetvalue == instance) + // + manager.Context.Push (new ExpressionContext (propRef, propRef.GetType (), component, value)); + object serialized = serializer.Serialize (manager, value); + manager.Context.Pop (); + + CodeStatementCollection serializedStatements = serialized as CodeStatementCollection; + if (serializedStatements != null) + statements.AddRange (serializedStatements); + + CodeStatement serializedStatement = serialized as CodeStatement; + if (serializedStatement != null) + statements.Add (serializedStatement); + + CodeExpression serializedExpr = serialized as CodeExpression; + if (serializedExpr != null) + statements.Add (new CodeAssignStatement (propRef, serializedExpr)); + } + } + + public override bool ShouldSerialize (IDesignerSerializationManager manager, object value, MemberDescriptor descriptor) + { + if (manager == null) + throw new ArgumentNullException ("manager"); + if (value == null) + throw new ArgumentNullException ("value"); + if (descriptor == null) + throw new ArgumentNullException ("descriptor"); + + PropertyDescriptor property = (PropertyDescriptor) descriptor; + + if (property.Attributes.Contains (DesignerSerializationVisibilityAttribute.Hidden)) + return false; + else if (property.Attributes.Contains (DesignOnlyAttribute.Yes)) + return false; + + bool result = property.ShouldSerializeValue (value); + + if (!result) { + if (!GetRelationship (manager, value, descriptor).IsEmpty) + result = true; + } + + if (!result) { + SerializeAbsoluteContext absolute = manager.Context[typeof (SerializeAbsoluteContext)] as SerializeAbsoluteContext; + if (absolute != null && absolute.ShouldSerialize (descriptor)) + result = true; + } + + return result; + } + + private MemberRelationship GetRelationship (IDesignerSerializationManager manager, object value, MemberDescriptor descriptor) + { + MemberRelationshipService service = manager.GetService (typeof (MemberRelationshipService)) as MemberRelationshipService; + if (service != null) + return service[value, descriptor]; + else + return MemberRelationship.Empty; + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/RootCodeDomSerializer.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/RootCodeDomSerializer.cs new file mode 100644 index 00000000000..078330be924 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/RootCodeDomSerializer.cs @@ -0,0 +1,275 @@ +// +// System.ComponentModel.Design.Serialization.RootCodeDomSerializer +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + internal class RootCodeDomSerializer : CodeDomSerializer + { + + internal class CodeMap + { + + private string _className; + private Type _classType; + private List<CodeMemberField> _fields; + private CodeStatementCollection _preInit; + private CodeStatementCollection _init; + private CodeStatementCollection _postInit; + + public CodeMap (Type classType, string className) + { + if (classType == null) + throw new ArgumentNullException ("classType"); + if (className == null) + throw new ArgumentNullException ("className"); + + _classType = classType; + _className = className; + _fields = new List<CodeMemberField> (); + _preInit = new CodeStatementCollection (); + _init = new CodeStatementCollection (); + _init = new CodeStatementCollection (); + _postInit = new CodeStatementCollection (); + } + + public void AddField (CodeMemberField field) + { + _fields.Add (field); + } + + public void AddPreInitStatement (CodeStatement statement) + { + _preInit.Add (statement); + } + + public void AddInitStatement (CodeStatement statement) + { + _init.Add (statement); + } + + public void AddInitStatements (CodeStatementCollection statements) + { + _init.AddRange (statements); + } + + public void AddPostInitStatement (CodeStatement statement) + { + _postInit.Add (statement); + } + + /* + class Type : BaseType + { + #region Windows Form Designer generated code + + private void InitializeComponent () + { + preInit; + init; + postInit; + } + + private field1; + private field2; + + #endregion + } + */ + + public CodeTypeDeclaration GenerateClass () + { + CodeTypeDeclaration clas = new CodeTypeDeclaration (_className); + clas.BaseTypes.Add (_classType); + + clas.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Windows Form Designer generated code")); + + CodeMemberMethod initialize = new CodeMemberMethod (); + initialize.Name = "InitializeComponent"; + initialize.ReturnType = new CodeTypeReference (typeof (void)); + initialize.Attributes = MemberAttributes.Private; + + initialize.Statements.AddRange (_preInit); + initialize.Statements.AddRange (_init); + initialize.Statements.AddRange (_postInit); + + clas.Members.Add (initialize); + + foreach (CodeMemberField field in _fields) + clas.Members.Add (field); + + clas.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, null)); + + return clas; + } + + public void Clear () + { + _preInit.Clear (); + _init.Clear (); + _postInit.Clear (); + _fields.Clear (); + } + } + + + private CodeMap _codeMap; + + public RootCodeDomSerializer () + { + } + + public override object Serialize (IDesignerSerializationManager manager, object value) + { + if (manager == null) + throw new ArgumentNullException ("manager"); + if (value == null) + throw new ArgumentNullException ("value"); + + if (_codeMap == null) + _codeMap = new CodeMap (value.GetType (), manager.GetName (value)); + _codeMap.Clear (); + + RootContext rootContext = new RootContext (new CodeThisReferenceExpression (), value); + manager.Context.Push (rootContext); + + this.SerializeComponents (manager, ((IComponent) value).Site.Container.Components, (IComponent) value); + + // Serialize root component + // + CodeStatementCollection statements = new CodeStatementCollection (); + statements.Add (new CodeCommentStatement (String.Empty)); + statements.Add (new CodeCommentStatement (manager.GetName (value))); + statements.Add (new CodeCommentStatement (String.Empty)); + // Note that during the serialization process below ComponentCodeDomSerializer + // will be invoked to serialize the rootcomponent during expression serialization. + // It will check for RootContext and return that. + base.SerializeProperties (manager, statements, value, new Attribute[0]); + base.SerializeEvents (manager, statements, value, new Attribute[0]); + _codeMap.AddInitStatements (statements); + + manager.Context.Pop (); + return _codeMap.GenerateClass (); + } + + private void SerializeComponents (IDesignerSerializationManager manager, ICollection components, IComponent rootComponent) + { + foreach (IComponent component in components) { + if (!Object.ReferenceEquals (component, rootComponent)) { + manager.Context.Push (new ExpressionContext (null, null, rootComponent, component)); + SerializeComponent (manager, component); + manager.Context.Pop (); + } + } + } + + private void SerializeComponent (IDesignerSerializationManager manager, IComponent component) + { + CodeDomSerializer serializer = base.GetSerializer (manager, component) as CodeDomSerializer; // ComponentCodeDomSerializer + if (serializer != null) { + this.Code.AddField (new CodeMemberField (component.GetType (), manager.GetName (component))); + + CodeStatementCollection statements = (CodeStatementCollection) serializer.Serialize (manager, component); + + CodeStatement ctorStatement = ExtractCtorStatement (manager, statements, component); + if (ctorStatement != null) + Code.AddPreInitStatement (ctorStatement); + Code.AddInitStatements (statements); + } + } + + internal CodeMap Code { + get { return _codeMap; } + } + + // Used to remove the ctor from the statement colletion in order for the ctor statement to be moved. + // + private CodeStatement ExtractCtorStatement (IDesignerSerializationManager manager, CodeStatementCollection statements, + object component) + { + CodeStatement result = null; + CodeAssignStatement assignment = null; + CodeObjectCreateExpression ctor = null; + int toRemove = -1; + + for (int i=0; i < statements.Count; i++) { + assignment = statements[i] as CodeAssignStatement; + if (assignment != null) { + ctor = assignment.Right as CodeObjectCreateExpression; + if (ctor != null && manager.GetType (ctor.CreateType.BaseType) == component.GetType ()) { + result = assignment; + toRemove = i; + } + } + } + + if (toRemove != -1) + statements.RemoveAt (toRemove); + + return result; + } + + public override object Deserialize (IDesignerSerializationManager manager, object codeObject) + { + CodeTypeDeclaration declaration = (CodeTypeDeclaration) codeObject; + Type rootType = manager.GetType (declaration.BaseTypes[0].BaseType); + object root = manager.CreateInstance (rootType, null, declaration.Name, true); + + CodeMemberMethod initComponentMethod = GetInitializeMethod (declaration); + if (initComponentMethod == null) + throw new InvalidOperationException ("InitializeComponent method is missing in: " + declaration.Name); + + foreach (CodeStatement statement in initComponentMethod.Statements) + base.DeserializeStatement (manager, statement); + + return root; + } + + private CodeMemberMethod GetInitializeMethod (CodeTypeDeclaration declaration) + { + CodeMemberMethod method = null; + foreach (CodeTypeMember member in declaration.Members) { + method = member as CodeMemberMethod; + if (method != null && method.Name == "InitializeComponent") + break; + } + return method; + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/RootContext.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/RootContext.cs new file mode 100644 index 00000000000..ba3248a7b4b --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/RootContext.cs @@ -0,0 +1,64 @@ +// +// System.ComponentModel.Design.Serialization.RootContext +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + + public sealed class RootContext + { + + CodeExpression _expression; + object _value; + + public RootContext (CodeExpression expresion, object value) + { + if (expresion == null) + throw new ArgumentNullException ("expression"); + if (value == null) + throw new ArgumentNullException ("value"); + _expression = expresion; + _value = value; + } + + public CodeExpression Expression { + get { return _expression; } + } + + public object Value { + get { return _value; } + } + + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/SerializeAbsoluteContext.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/SerializeAbsoluteContext.cs new file mode 100644 index 00000000000..7f509dfea27 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/SerializeAbsoluteContext.cs @@ -0,0 +1,65 @@ +// +// System.ComponentModel.Design.Serialization.SerializeAbsoluteContext +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; + + +namespace System.ComponentModel.Design.Serialization +{ + public sealed class SerializeAbsoluteContext + { + + private MemberDescriptor _member; + + public SerializeAbsoluteContext () + { + } + + public SerializeAbsoluteContext (MemberDescriptor member) + { + _member = member; + } + + // null indicates that the context will be used for all members + // + public MemberDescriptor Member { + get { return _member; } + } + + public bool ShouldSerialize (MemberDescriptor member) + { + return !(member == _member); + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/StatementContext.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/StatementContext.cs new file mode 100644 index 00000000000..eb0d31deb9a --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/StatementContext.cs @@ -0,0 +1,55 @@ +// +// System.ComponentModel.Design.Serialization.StatementContext +// +// Authors: +// Ivan N. Zlatev (contact@i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + public sealed class StatementContext + { + + ObjectStatementCollection _statements; + + public StatementContext () + { + } + + public ObjectStatementCollection StatementCollection { + get { + if (_statements == null) + _statements = new ObjectStatementCollection (); + return _statements; + } + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design.Serialization/TypeCodeDomSerializer.cs b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/TypeCodeDomSerializer.cs new file mode 100644 index 00000000000..745ee824031 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design.Serialization/TypeCodeDomSerializer.cs @@ -0,0 +1,109 @@ +// +// System.ComponentModel.Design.Serialization.TypeCodeDomSerializer +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; + +using System.CodeDom; + +namespace System.ComponentModel.Design.Serialization +{ + public class TypeCodeDomSerializer : CodeDomSerializer + { + + public TypeCodeDomSerializer () + { + } + + public virtual CodeTypeDeclaration Serialize (IDesignerSerializationManager manager, object root, ICollection members) + { + if (root == null) + throw new ArgumentNullException ("root"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + RootContext rootContext = new RootContext (new CodeThisReferenceExpression (), root); + StatementContext statementContext = new StatementContext (); + if (members != null) + statementContext.StatementCollection.Populate (members); + statementContext.StatementCollection.Populate (root); + CodeTypeDeclaration declaration = new CodeTypeDeclaration (manager.GetName (root)); + + manager.Context.Push (rootContext); + manager.Context.Push (statementContext); + manager.Context.Push (declaration); + + if (members != null) { + foreach (object member in members) + base.SerializeToExpression (manager, member); + } + base.SerializeToExpression (manager, root); + + manager.Context.Pop (); + manager.Context.Pop (); + manager.Context.Pop (); + + return declaration; + } + + // TODO - http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.typecodedomserializer.deserialize.aspx + // + public virtual object Deserialize (IDesignerSerializationManager manager, CodeTypeDeclaration declaration) + { + throw new NotImplementedException (); + } + + protected virtual CodeMemberMethod GetInitializeMethod (IDesignerSerializationManager manager, CodeTypeDeclaration declaration, object value) + { + if (value == null) + throw new ArgumentNullException ("value"); + if (declaration == null) + throw new ArgumentNullException ("declaration"); + if (manager == null) + throw new ArgumentNullException ("manager"); + + return new CodeConstructor (); + } + + protected virtual CodeMemberMethod[] GetInitializeMethods (IDesignerSerializationManager manager, CodeTypeDeclaration declaration) + { + if (manager == null) + throw new ArgumentNullException ("manager"); + if (declaration == null) + throw new ArgumentNullException ("declaration"); + + return (new CodeMemberMethod[] { new CodeConstructor () }); + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/ActiveDesignSurfaceChangedEventArgs.cs b/mcs/class/System.Design/System.ComponentModel.Design/ActiveDesignSurfaceChangedEventArgs.cs new file mode 100644 index 00000000000..111d20d2398 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/ActiveDesignSurfaceChangedEventArgs.cs @@ -0,0 +1,58 @@ +// +// System.ComponentModel.Design.ActiveDesignSurfaceChangedEventArgs +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; + +namespace System.ComponentModel.Design +{ + + public class ActiveDesignSurfaceChangedEventArgs : EventArgs + { + + private DesignSurface _oldSurface; + private DesignSurface _newSurface; + + public ActiveDesignSurfaceChangedEventArgs (DesignSurface oldSurface, DesignSurface newSurface) + { + _newSurface = newSurface; + _oldSurface = oldSurface; + } + + public DesignSurface OldSurface { + get { return _oldSurface; } + } + + public DesignSurface NewSurface { + get { return _newSurface; } + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/ActiveDesignSurfaceChangedEventHandler.cs b/mcs/class/System.Design/System.ComponentModel.Design/ActiveDesignSurfaceChangedEventHandler.cs new file mode 100644 index 00000000000..3de074a55e5 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/ActiveDesignSurfaceChangedEventHandler.cs @@ -0,0 +1,40 @@ +// +// System.ComponentModel.Design.ActiveDesignSurfaceChangedEventHandler +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; + +namespace System.ComponentModel.Design +{ + + public delegate void ActiveDesignSurfaceChangedEventHandler (object sender, ActiveDesignSurfaceChangedEventArgs e); +} + +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/ChangeLog b/mcs/class/System.Design/System.ComponentModel.Design/ChangeLog index 59e9caaf7a3..7761feff16f 100644 --- a/mcs/class/System.Design/System.ComponentModel.Design/ChangeLog +++ b/mcs/class/System.Design/System.ComponentModel.Design/ChangeLog @@ -1,3 +1,27 @@ +2007-08-29 Ivan N. Zlatev <contact@i-nz.net> + + * DesignSurfaceManager.cs: implemented. + * DesignerEventService.cs: implemented. + * ComponentDesigner.cs: implemented. + * ActiveDesignSurfaceChangedEventHandler.cs: implemented. + * LoadedEventHandler.cs: implemented. + * DesignSurfaceCollection.cs: implemented. + * DesignerHost.cs: implemented. + * ExtenderService.cs: implemented. + * DesignModeSite.cs: implemented. + * SelectionService.cs: implemented. + * DesignSurfaceServiceContainer.cs: implemented. + * DesignerActionListCollection.cs: implemented. + * ActiveDesignSurfaceChangedEventArgs.cs: implemented. + * LoadedEventArgs.cs: implemented. + * TypeDescriptorFilterService.cs: implemented. + * ReferenceService.cs: implemented. + * DesignSurface.cs: implemented. + * DesignSurfaceEventHandler.cs: implemented. + * DesignModeNestedContainer.cs: implemented. + * EventBindingService.cs: implemented. + * DesignSurfaceEventArgs.cs: implemented. + 2007-08-27 Ivan N. Zlatev <contact@i-nz.net> * CollectionEditor.cs: - Fix CreateCollectionItemType to deal with "Item" overloads. diff --git a/mcs/class/System.Design/System.ComponentModel.Design/ComponentDesigner.cs b/mcs/class/System.Design/System.ComponentModel.Design/ComponentDesigner.cs index 2f87cbd9290..aaac3109c59 100644 --- a/mcs/class/System.Design/System.ComponentModel.Design/ComponentDesigner.cs +++ b/mcs/class/System.Design/System.ComponentModel.Design/ComponentDesigner.cs @@ -2,16 +2,9 @@ // System.ComponentModel.Design.ComponentDesigner // // Authors: -// Martin Willemoes Hansen (mwh@sysrq.dk) -// -// (C) 2003 Martin Willemoes Hansen -// -// An implementation should be derived from the description here: -// "Writing Custom Designers for .NET Components" -// -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/custdsgnrdotnet.asp -// +// Ivan N. Zlatev (contact i-nZ.net) // +// (C) 2006-2007 Ivan N. Zlatev // // Permission is hereby granted, free of charge, to any person obtaining @@ -21,10 +14,10 @@ // 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 @@ -34,225 +27,425 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // + +using System; using System.Collections; +using System.ComponentModel; namespace System.ComponentModel.Design { + +#if NET_2_0 + public class ComponentDesigner : ITreeDesigner, IDesigner, IDisposable, IDesignerFilter, IComponentInitializer +#else public class ComponentDesigner : IDesigner, IDisposable, IDesignerFilter +#endif { + +#region ShadowPropertyCollection + protected sealed class ShadowPropertyCollection { - Hashtable collection; - - public object this[string propertyName] { + + private Hashtable _properties = null; + private IComponent _component; + + internal ShadowPropertyCollection (IComponent component) + { + _component = component; + } + + // Returns Control's property value (if available) if there is no shadowed one. + // + public object this[string propertyName] + { get { - if (collection == null) - return null; - - return collection [propertyName]; - } + if (propertyName == null) + throw new System.ArgumentNullException("propertyName"); + if (_properties != null && _properties.ContainsKey (propertyName)) + return _properties[propertyName]; + + PropertyDescriptor property = TypeDescriptor.GetProperties (_component.GetType ())[propertyName]; + if (property != null) + return property.GetValue (_component); + else + throw new System.Exception ("Propery not found!"); + } set { - if (collection == null) - collection = new Hashtable (); - - collection [propertyName] = value; + if (_properties == null) + _properties = new Hashtable (); + _properties[propertyName] = value; } } public bool Contains (string propertyName) { - if (collection == null) + if (_properties != null) + return _properties.ContainsKey (propertyName); + else return false; - - return collection.Contains (propertyName); } - } - IComponent component; - ShadowPropertyCollection shadow_property_collection; - DesignerVerbCollection verbs; - + } // ShadowPropertyCollection +#endregion + public ComponentDesigner () { } - #region Implementation of IDesignerFilter - void IDesignerFilter.PostFilterAttributes (IDictionary attributes) - { - PostFilterAttributes (attributes); + private IComponent _component; + private DesignerVerbCollection _verbs; + private ShadowPropertyCollection _shadowPropertyCollection; +#if NET_2_0 + private DesignerActionListCollection _designerActionList; +#endif + + // This property indicates any components to copy or move along with the component managed + // by the designer during a copy, drag, or move operation. + // If this collection contains references to other components in the current design mode document, + // those components will be copied along with the component managed by the designer during a copy operation. + // When the component managed by the designer is selected, this collection is filled with any nested controls. + // This collection can also include other components, such as the buttons of a toolbar. + // + // supposedly contains all the children of the component, thus used for ITreeDesigner.Children + // + public virtual ICollection AssociatedComponents { + get { return new IComponent[0]; } } - void IDesignerFilter.PostFilterEvents (IDictionary events) - { - PostFilterEvents (events); + public IComponent Component { + get { return _component; } } - void IDesignerFilter.PostFilterProperties (IDictionary properties) - { - PostFilterProperties (properties); + public virtual DesignerVerbCollection Verbs { + get { + if (_verbs == null) + _verbs = new DesignerVerbCollection (); + + return _verbs; + } } - void IDesignerFilter.PreFilterAttributes (IDictionary attributes) - { - PreFilterAttributes (attributes); + protected InheritanceAttribute InheritanceAttribute { + get { + IInheritanceService service = (IInheritanceService) this.GetService (typeof (IInheritanceService)); + if (service != null) + return service.GetInheritanceAttribute (_component); + else + return InheritanceAttribute.Default; + } } - void IDesignerFilter.PreFilterEvents (IDictionary events) + protected bool Inherited { + get { return !this.InheritanceAttribute.Equals (InheritanceAttribute.NotInherited); } + } + + //Gets a collection of property values that override user settings. + // + protected ShadowPropertyCollection ShadowProperties { + get { + if (_shadowPropertyCollection == null) { + _shadowPropertyCollection = new ShadowPropertyCollection(_component); + } + return _shadowPropertyCollection; + } + } + +#if NET_2_0 + public virtual DesignerActionListCollection ActionLists { + get { + if (_designerActionList == null) + _designerActionList = new DesignerActionListCollection (); + + return _designerActionList; + } + } + + protected virtual IComponent ParentComponent { + get { + IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost; + if (host != null) { + IComponent rootComponent = host.RootComponent; + if (rootComponent != _component) + return rootComponent; + } + return null; + } + } + + public virtual void InitializeNewComponent (IDictionary defaultValues) { - PreFilterEvents (events); + // Reset + // + OnSetComponentDefaults (); } - void IDesignerFilter.PreFilterProperties (IDictionary properties) + // MSDN: The default implementation of this method does nothing. + // + public virtual void InitializeExistingComponent (IDictionary defaultValues) { - PreFilterProperties (properties); + InitializeNonDefault (); } +#endif - #endregion Implementation of IDesignerFilter - public virtual ICollection AssociatedComponents + public virtual void Initialize (IComponent component) { - [MonoTODO] - get { throw new NotImplementedException (); } + if (component == null) + throw new ArgumentNullException ("component"); + + _component = component; } - public IComponent Component +#if NET_2_0 + [Obsolete ("This method has been deprecated. Use InitializeExistingComponent instead.")] +#endif + public virtual void InitializeNonDefault () { - get { - return component; - } } - public virtual DesignerVerbCollection Verbs + + // This method is called when a user double-clicks (the representation of) a component. + // Tries to bind the default event to a method or creates a new one. + // + public virtual void DoDefaultAction() { - [MonoTODO] - get { - if (verbs == null) - verbs = new DesignerVerbCollection(); + IDesignerHost host = (IDesignerHost) this.GetService(typeof(IDesignerHost)); + DesignerTransaction transaction = null; + if (host != null) + transaction = host.CreateTransaction ("ComponentDesigner_AddEvent"); + + IEventBindingService eventBindingService = GetService (typeof(IEventBindingService)) as IEventBindingService; + EventDescriptor defaultEventDescriptor = null; + + if (eventBindingService != null) { + ISelectionService selectionService = this.GetService (typeof (ISelectionService)) as ISelectionService; + try { + if (selectionService != null) { + ICollection selectedComponents = selectionService.GetSelectedComponents (); + + foreach (IComponent component in selectedComponents) { + EventDescriptor eventDescriptor = TypeDescriptor.GetDefaultEvent (component); + if (eventDescriptor != null) { + PropertyDescriptor eventProperty = eventBindingService.GetEventProperty (eventDescriptor); + if (eventProperty != null && !eventProperty.IsReadOnly) { + string methodName = eventProperty.GetValue (component) as string; + bool newMethod = true; + + if (methodName != null || methodName != String.Empty) { + ICollection compatibleMethods = eventBindingService.GetCompatibleMethods (eventDescriptor); + foreach (string signature in compatibleMethods) { + if (signature == methodName) { + newMethod = false; + break; + } + } + } + if (newMethod) { + if (methodName == null) + methodName = eventBindingService.CreateUniqueMethodName (component, eventDescriptor); + + eventProperty.SetValue (component, methodName); + } + + if (component == _component) + defaultEventDescriptor = eventDescriptor; + } + } + } + + } + } + catch { + if (transaction != null) { + transaction.Cancel (); + transaction = null; + } + } + finally { + if (transaction != null) + transaction.Commit (); + } - return verbs; + if (defaultEventDescriptor != null) + eventBindingService.ShowCode (_component, defaultEventDescriptor); } } - public void Dispose () + + +#if NET_2_0 + [Obsolete ("This method has been deprecated. Use InitializeNewComponent instead.")] +#endif + // The default implementation of this method sets the default property of the component to + // the name of the component if the default property is a string and the property is not already set. + // This method can be implemented in a derived class to customize the initialization of the component + // that this designer is designing. + // + public virtual void OnSetComponentDefaults () { - Dispose (true); - GC.SuppressFinalize (this); + if (_component != null && _component.Site != null) { + PropertyDescriptor property = TypeDescriptor.GetDefaultProperty (_component); + if (property != null && property.PropertyType.Equals (typeof (string))) { + string propertyValue = (string)property.GetValue (_component); + if (propertyValue != null && propertyValue.Length != 0) + property.SetValue (_component, _component.Site.Name); + } + } } - protected virtual void Dispose (bool disposing) + + + + protected InheritanceAttribute InvokeGetInheritanceAttribute (ComponentDesigner toInvoke) { + return toInvoke.InheritanceAttribute; } - [MonoTODO("Not implemented, currently does nothing")] - public virtual void DoDefaultAction () +#region IDesignerFilter + + // TypeDescriptor queries the component's site for ITypeDescriptorFilterService + // then invokes ITypeDescriptorFilterService.XXXX before retrieveing props/event/attributes, + // which then invokes the IDesignerFilter implementation of the component + // + protected virtual void PostFilterAttributes (IDictionary attributes) { - } - public virtual void Initialize (IComponent component) + protected virtual void PostFilterEvents (IDictionary events) { - this.component = component; } - [MonoTODO] - public virtual void InitializeNonDefault () + protected virtual void PostFilterProperties (IDictionary properties) { - throw new NotImplementedException (); } - [MonoTODO] - public virtual void OnSetComponentDefaults () + protected virtual void PreFilterAttributes (IDictionary attributes) { - throw new NotImplementedException (); } - - protected InheritanceAttribute InheritanceAttribute + protected virtual void PreFilterEvents (IDictionary events) { - [MonoTODO] - get { throw new NotImplementedException (); } } - protected bool Inherited + protected virtual void PreFilterProperties (IDictionary properties) { - [MonoTODO] - get { throw new NotImplementedException (); } } +#endregion - protected ShadowPropertyCollection ShadowProperties + protected void RaiseComponentChanged (MemberDescriptor member, object oldValue, object newValue) { - get { - if (shadow_property_collection == null) - shadow_property_collection = new ShadowPropertyCollection (); - return shadow_property_collection; - } + IComponentChangeService service = GetService (typeof (IComponentChangeService)) as IComponentChangeService; + if (service != null) + service.OnComponentChanged (_component, member, oldValue, newValue); } - [MonoTODO("No designers services are provided in Mono")] - protected virtual object GetService (Type serviceType) + protected void RaiseComponentChanging (MemberDescriptor member) { - return null; + IComponentChangeService service = GetService (typeof (IComponentChangeService)) as IComponentChangeService; + if (service != null) + service.OnComponentChanging (_component, member); } - [MonoTODO] - protected InheritanceAttribute InvokeGetInheritanceAttribute (ComponentDesigner toInvoke) +#region Implementation of IDesignerFilter + + void IDesignerFilter.PostFilterAttributes (IDictionary attributes) { - throw new NotImplementedException (); + PostFilterAttributes (attributes); } - [MonoTODO] - protected virtual void PostFilterAttributes (IDictionary attributes) + void IDesignerFilter.PostFilterEvents (IDictionary events) { - throw new NotImplementedException (); + PostFilterEvents (events); } - [MonoTODO] - protected virtual void PostFilterEvents (IDictionary events) + void IDesignerFilter.PostFilterProperties (IDictionary properties) { - throw new NotImplementedException (); + PostFilterProperties (properties); } - [MonoTODO] - protected virtual void PostFilterProperties (IDictionary properties) + void IDesignerFilter.PreFilterAttributes (IDictionary attributes) { - throw new NotImplementedException (); + PreFilterAttributes (attributes); } - [MonoTODO] - protected virtual void PreFilterAttributes (IDictionary attributes) + void IDesignerFilter.PreFilterEvents (IDictionary events) { - throw new NotImplementedException (); + PreFilterEvents (events); } - [MonoTODO] - protected virtual void PreFilterEvents (IDictionary events) + void IDesignerFilter.PreFilterProperties (IDictionary properties) { - throw new NotImplementedException (); + PreFilterProperties (properties); } - [MonoTODO] - protected virtual void PreFilterProperties (IDictionary properties) +#endregion + +#if NET_2_0 + +#region ITreeDesigner + // Returns a collection of the designers of the associated components + // + ICollection ITreeDesigner.Children { + get { + ICollection components = this.AssociatedComponents; + IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost; + + if (host != null) { + ArrayList designers = new ArrayList (); + foreach (IComponent component in components) { + IDesigner designer = host.GetDesigner (component); + if (designer != null) + designers.Add (designer); + } + IDesigner[] result = new IDesigner[designers.Count]; + designers.CopyTo (result); + return result; + } + return new IDesigner[0]; + } + } + + IDesigner ITreeDesigner.Parent { + get { + IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost; + if (host != null && this.ParentComponent != null) + return host.GetDesigner (this.ParentComponent); + + return null; + } + } +#endregion + +#endif + // Helper method - not an ISerivceProvider + // + protected virtual object GetService (Type service) { - throw new NotImplementedException (); + if (_component != null && _component.Site != null) + return _component.Site.GetService (service); + + return null; } - [MonoTODO("Currently no event is raised")] - protected void RaiseComponentChanged (MemberDescriptor member, object oldValue, object newValue) + public void Dispose () { - // FIXME: Should notify the IComponentChangeService - // that this component has changed + this.Dispose (true); + GC.SuppressFinalize (this); } - [MonoTODO("Currently no event is raised")] - protected void RaiseComponentChanging (MemberDescriptor member) + + protected virtual void Dispose (bool disposing) { - + if (disposing) + _component = null; } ~ComponentDesigner () { + this.Dispose (false); } } } diff --git a/mcs/class/System.Design/System.ComponentModel.Design/DesignModeNestedContainer.cs b/mcs/class/System.Design/System.ComponentModel.Design/DesignModeNestedContainer.cs new file mode 100644 index 00000000000..3d00713fcba --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/DesignModeNestedContainer.cs @@ -0,0 +1,141 @@ +// +// System.ComponentModel.Design.DesignModeSite +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; + +namespace System.ComponentModel.Design +{ + + internal class DesignModeNestedContainer : NestedContainer + { + + // DesignModeNestedContainer is a NestedContainer where: + // * Site's Name property is a qualified name that includes the owning component's name + // followed by a period (.) and the child component's name. + // * GetService is routed through the owner + + private class Site : DesignModeSite, INestedSite + { + + public Site (IComponent component, string name, IContainer container, IServiceProvider serviceProvider) : + base (component, name, container, serviceProvider) + { + } + + // [owner].[container].[site] + // + public string FullName { + get { + if (this.Name == null) + return null; + + string ownerName = ((DesignModeNestedContainer)this.Container).OwnerName; + if (ownerName == null) + return this.Name; + + return ownerName + "." + this.Name; + } + } + } + + private string _containerName; + + public DesignModeNestedContainer (IComponent owner, string containerName) : base (owner) + { + _containerName = containerName; + } + + public override void Add (IComponent component, string name) + { + if (this.Owner.Site != null) { + DesignerHost host = this.Owner.Site.GetService (typeof (IDesignerHost)) as DesignerHost; + if (host != null) { + host.AddPreProcess (component, name); + base.Add (component, name); + host.AddPostProcess (component, name); + } + } + } + + public override void Remove (IComponent component) + { + if (this.Owner.Site != null) { + DesignerHost host = this.Owner.Site.GetService (typeof (IDesignerHost)) as DesignerHost; + if (host != null) { + host.RemovePreProcess (component); + base.Remove (component); + host.RemovePostProcess (component); + } + } + } + + // [owner].[container] + // + protected override string OwnerName { + get { + if (_containerName != null) + return base.OwnerName + "." + _containerName; + else + return base.OwnerName; + } + } + + protected override ISite CreateSite (IComponent component, string name) + { + if (component == null) + throw new ArgumentNullException("component"); + + if (Owner.Site == null) + throw new InvalidOperationException ("Owner not sited."); + + return new DesignModeNestedContainer.Site (component, name, this, (IServiceProvider)Owner.Site); + } + + protected override object GetService (Type service) + { + if (service == typeof (INestedContainer)) + return this; + + object serviceInstance = null; + + if (this.Owner.Site != null) + serviceInstance = this.Owner.Site.GetService (service); + + if (serviceInstance == null) + return base.GetService (service); + + return null; + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/DesignModeSite.cs b/mcs/class/System.Design/System.ComponentModel.Design/DesignModeSite.cs new file mode 100644 index 00000000000..909cabe00f4 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/DesignModeSite.cs @@ -0,0 +1,227 @@ +// +// System.ComponentModel.Design.DesignModeSite +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; + +namespace System.ComponentModel.Design +{ + + internal class DesignModeSite : ISite, IDictionaryService, IServiceProvider, IServiceContainer + { + + // The DesignModeSite: + // * offers the IDictionaryService and INestedContaineroffers site-specific services + // * implements the IServiceContainer interface, but according to the tests it: + // - does *NOT* offer IServiceContainer as a site-specific service + // - offers the added site-specific services via IServiceProvider + + private IServiceProvider _serviceProvider; + private IComponent _component; + private IContainer _container; + private string _componentName; + private NestedContainer _nestedContainer; + + + public DesignModeSite (IComponent component, string name, IContainer container, IServiceProvider serviceProvider) + { + _component = component; + _container = container; + _componentName = name; + _serviceProvider = serviceProvider; + } + + public IComponent Component { + get { return _component; } + } + + public IContainer Container { + get { return _container; } + } + + // Yay yay yay, guess who's in design mode ??? + // + public bool DesignMode { + get { return true; } + } + + // The place where renaming of a component takes place. + // We should validate the new name here, if INameCreation service is present + // + public string Name { + get { + return _componentName; + } + set { + if (value != null && value.Trim().Length > 0) { + + INameCreationService nameService = this.GetService (typeof (INameCreationService)) as INameCreationService; + + // Get the component with that name, if any + // + IComponent component = _container.Components[value]; + + // check for duplicated name + // + if (component != null && _component != component) { // duplicate name + if (nameService != null) + value = nameService.CreateName (_container, _component.GetType ()); + else + value = _componentName; + } + else { // if not a duplicate -> check the validity of the name + if (nameService != null && !nameService.IsValidName (value)) + value = _componentName; + } + + string oldName = _componentName; + _componentName = value; + + ((DesignerHost)this.GetService (typeof (IDesignerHost))).OnComponentRename (_component, oldName, _componentName); + } + } + } + +#region IServiceContainer + + private ServiceContainer _siteSpecificServices; + + private ServiceContainer SiteSpecificServices { + get { + if (_siteSpecificServices == null) + _siteSpecificServices = new ServiceContainer (null); + + return _siteSpecificServices; + } + } + + void IServiceContainer.AddService (Type serviceType, object serviceInstance) + { + SiteSpecificServices.AddService (serviceType, serviceInstance); + } + + void IServiceContainer.AddService (Type serviceType, object serviceInstance, bool promote) + { + SiteSpecificServices.AddService (serviceType, serviceInstance, promote); + } + void IServiceContainer.AddService (Type serviceType, ServiceCreatorCallback callback) + { + SiteSpecificServices.AddService (serviceType, callback); + } + + void IServiceContainer.AddService (Type serviceType, ServiceCreatorCallback callback, bool promote) + { + SiteSpecificServices.AddService (serviceType, callback, promote); + } + + void IServiceContainer.RemoveService (Type serviceType) + { + SiteSpecificServices.RemoveService (serviceType); + } + + void IServiceContainer.RemoveService (Type serviceType, bool promote) + { + SiteSpecificServices.RemoveService (serviceType, promote); + } + +#endregion + + +#region IDictionaryService + + private Hashtable _dictionary; + + object IDictionaryService.GetKey (object value) + { + if (_dictionary != null) { + foreach (DictionaryEntry entry in _dictionary) { + if (value != null && value.Equals (entry.Value)) + return entry.Key; + } + } + return null; + } + + object IDictionaryService.GetValue (object key) + { + if (_dictionary != null) + return _dictionary[key]; + + return null; + } + + // No Remove method: seting the value to null + // will remove the pair. + // + void IDictionaryService.SetValue (object key, object value) + { + if (_dictionary == null) + _dictionary = new Hashtable (); + + if (value == null) + _dictionary.Remove (key); + + _dictionary[key] = value; + } + +#endregion + + +#region IServiceProvider + + public virtual object GetService (Type service) + { + object serviceInstance = null; + + if (typeof (IDictionaryService) == service) + serviceInstance = (IDictionaryService) this; + + if (typeof (INestedContainer) == service) { + if (_nestedContainer == null) + _nestedContainer = new DesignModeNestedContainer (_component, null); + serviceInstance = _nestedContainer; + } + + if (serviceInstance == null && _siteSpecificServices != null) + serviceInstance = _siteSpecificServices.GetService (service); + + if (serviceInstance == null) + serviceInstance = _serviceProvider.GetService (service); + + return serviceInstance; + } +#endregion + + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/DesignSurface.cs b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurface.cs new file mode 100644 index 00000000000..57baba5240d --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurface.cs @@ -0,0 +1,402 @@ +// +// System.ComponentModel.Design.DesignSurface +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; +using System.Reflection; + +namespace System.ComponentModel.Design +{ + + public class DesignSurface : IServiceProvider, IDisposable + { + +#region DefaultDesignerLoader : DesignerLoader + + internal class DefaultDesignerLoader : DesignerLoader + { + // When DesignSurface.BeginLoad is invoked, the designer loader loads the design document, displays the designer + // surface using the IDesignerHost interface, and calls IDesignerLoaderHost.EndLoad + // when done. The IDesignerLoaderHost implementation is usually the same class that implements IDesignerHost. + + // The designer loader informs the designer host that it needs to invoke a load or reload so that the designer + // host can perform additional tasks at these times. + + private Type _componentType; + private bool _loading; + + + public override bool Loading + { + get { return _loading; } + } + + public DefaultDesignerLoader (Type componentType) + { + if (componentType == null) + throw new ArgumentNullException ("componentType"); + + _componentType = componentType; + } + + // Note that IDesignerLoader : IDesignerHost + // + public override void BeginLoad (IDesignerLoaderHost loaderHost) + { + _loading = true; + // initializa root component and designer + // + loaderHost.CreateComponent (_componentType); + // finish off loading - no error collection here. + // + loaderHost.EndLoad (_componentType.FullName, true, null); + _loading = false; + } + + public override void Dispose () + { + _componentType = null; + } + } // DesignerLoader + +#endregion + + + + + private DesignerHost _designerHost; + private DesignSurfaceServiceContainer _serviceContainer; + private ICollection _loadErrors; + private bool _isLoaded; + private DesignerLoader _designerLoader; + + + public DesignSurface () : this ((IServiceProvider) null) + { + } + + public DesignSurface (Type rootComponentType) : this (null, rootComponentType) + { + } + + + public DesignSurface (IServiceProvider parentProvider, Type rootComponentType) : this (parentProvider) + { + if (rootComponentType == null) + throw new System.ArgumentNullException ("rootComponentType"); + + BeginLoad (rootComponentType); + } + + // this ctor doesn't load the surface + // + public DesignSurface (IServiceProvider parentProvider) + { + + _serviceContainer = new DesignSurfaceServiceContainer (parentProvider); + _serviceContainer.AddNonReplaceableService (typeof (IServiceContainer), _serviceContainer); + + _designerHost = new DesignerHost ((IServiceProvider) _serviceContainer); + _designerHost.DesignerLoaderHostLoaded += new LoadedEventHandler (OnDesignerHost_Loaded); + _designerHost.DesignerLoaderHostLoading += new EventHandler (OnDesignerHost_Loading); + _designerHost.DesignerLoaderHostUnloading += new EventHandler (OnDesignerHost_Unloading); + _designerHost.DesignerLoaderHostUnloaded += new EventHandler (OnDesignerHost_Unloaded); + + _designerHost.Activated += new EventHandler (OnDesignerHost_Activated); + + _serviceContainer.AddNonReplaceableService (typeof (IComponentChangeService), _designerHost); + _serviceContainer.AddNonReplaceableService (typeof (IDesignerHost), _designerHost); + _serviceContainer.AddNonReplaceableService (typeof (IContainer), _designerHost); + _serviceContainer.AddService (typeof (ITypeDescriptorFilterService), + (ITypeDescriptorFilterService) new TypeDescriptorFilterService (_serviceContainer)); + + ExtenderService extenderService = new ExtenderService (); + _serviceContainer.AddService (typeof (IExtenderProviderService), (IExtenderProviderService) extenderService); + _serviceContainer.AddService (typeof (IExtenderListService), (IExtenderListService) extenderService); + _serviceContainer.AddService (typeof (DesignSurface), this); + } + + protected ServiceContainer ServiceContainer { + get { + if (_designerHost == null) + throw new ObjectDisposedException ("DesignSurface"); + + return _serviceContainer; + } + } + + public IContainer ComponentContainer { + get { + if (_designerHost == null) + throw new ObjectDisposedException ("DesignSurface"); + + return _designerHost.Container; + } + } + + public bool IsLoaded { + get { return _isLoaded; } + } + + // Returns a collection of loading errors or a void collection. + // + public ICollection LoadErrors { + get { + if (_loadErrors == null) + _loadErrors = new object[0]; + + return _loadErrors; + } + } + + public object View { + get { + if (_designerHost == null) + throw new ObjectDisposedException ("DesignSurface"); + if (this.LoadErrors.Count > 0 || !_isLoaded) + throw new InvalidOperationException ("DesignSurface isn't loaded."); + + + IRootDesigner designer = _designerHost.GetDesigner (_designerHost.RootComponent) as IRootDesigner; + ViewTechnology[] viewTech = designer.SupportedTechnologies; + + for (int i = 0; i < viewTech.Length; i++) { + try { + return designer.GetView (viewTech[i]); + } catch {} + } + // if this code is reached - there is no supported view technology + // + throw new NotSupportedException (); + } + } + + public event EventHandler Disposed; + public event EventHandler Flushed; + public event LoadedEventHandler Loaded; + public event EventHandler Loading; + public event EventHandler Unloaded; + public event EventHandler Unloading; + public event EventHandler ViewActivated; + + public void BeginLoad (Type rootComponentType) + { + if (rootComponentType == null) + throw new System.ArgumentNullException ("rootComponentType"); + if (_designerHost == null) + throw new ObjectDisposedException ("DesignSurface"); + + this.BeginLoad (new DefaultDesignerLoader (rootComponentType)); + } + + public void BeginLoad (DesignerLoader loader) + { + if (loader == null) + throw new System.ArgumentNullException ("loader"); + if (_designerHost == null) + throw new ObjectDisposedException ("DesignSurface"); + + if (!_isLoaded) { + _loadErrors = null; + _designerLoader = loader; + this.OnLoading (EventArgs.Empty); + _designerLoader.BeginLoad (_designerHost); + } + } + + +#region IDisposable + + public void Dispose () + { + this.Dispose (true); + } + + + protected void Dispose (bool disposing) + { + if (_designerHost != null) { + _designerHost.Dispose (); + _designerHost.DesignerLoaderHostLoaded -= new LoadedEventHandler (OnDesignerHost_Loaded); + _designerHost.DesignerLoaderHostLoading -= new EventHandler (OnDesignerHost_Loading); + _designerHost.DesignerLoaderHostUnloading -= new EventHandler (OnDesignerHost_Unloading); + _designerHost.DesignerLoaderHostUnloaded -= new EventHandler (OnDesignerHost_Unloaded); + _designerHost.Activated -= new EventHandler (OnDesignerHost_Activated); + _designerHost = null; + } + if (_serviceContainer != null) { + _serviceContainer.Dispose (); + _serviceContainer = null; + } + + if (Disposed != null) + Disposed (this, EventArgs.Empty); + } + +#endregion + + + public void Flush () + { + _designerLoader.Flush (); + + if (Flushed != null) + Flushed (this, EventArgs.Empty); + } + + private void OnDesignerHost_Loaded (object sender, LoadedEventArgs e) + { + if (_loadErrors == null) + _loadErrors = new object[0]; + + this.OnLoaded (new LoadedEventArgs (e.HasSucceeded, _loadErrors)); + } + + private void OnDesignerHost_Loading (object sender, EventArgs e) + { + this.OnLoading (EventArgs.Empty); + } + + + private void OnDesignerHost_Unloading (object sender, EventArgs e) + { + this.OnUnloading (EventArgs.Empty); + } + + + private void OnDesignerHost_Unloaded (object sender, EventArgs e) + { + this.OnUnloaded (EventArgs.Empty); + } + + protected virtual void OnLoaded (LoadedEventArgs e) + { + _loadErrors = e.Errors; + _isLoaded = e.HasSucceeded; + + if (Loaded != null) + Loaded (this, e); + } + + protected virtual void OnLoading (EventArgs e) + { + if (Loading != null) + Loading (this, e); + } + + + protected virtual void OnUnloaded (EventArgs e) + { + if (Unloaded != null) + Unloaded (this, e); + } + + + protected virtual void OnUnloading (EventArgs e) + { + if (Unloading != null) + Unloading (this, e); + } + + internal void OnDesignerHost_Activated (object sender, EventArgs args) + { + this.OnViewActivated (EventArgs.Empty); + } + + protected virtual void OnViewActivated (EventArgs e) + { + if (ViewActivated != null) + ViewActivated (this, e); + } + + + [ObsoleteAttribute("CreateComponent has been replaced by CreateInstance")] + protected internal virtual IComponent CreateComponent (Type componentType) + { + return (this.CreateInstance (componentType)) as IComponent; + } + + + // XXX: I am not quite sure if this should add the created instance of the component + // to the surface, but it does. (If one finds out that this is wrong just use + // _designerHost.CreateInstance (..) + // + protected internal virtual object CreateInstance (Type type) + { + if (type == null) + throw new System.ArgumentNullException ("type"); + + return _designerHost.CreateComponent (type); + } + + + protected internal virtual IDesigner CreateDesigner (IComponent component, bool rootDesigner) + { + if (component == null) + throw new System.ArgumentNullException ("component"); + if (_designerHost == null) + throw new System.ObjectDisposedException ("DesignerSurface"); + + return _designerHost.CreateDesigner (component, rootDesigner); + } + + public INestedContainer CreateNestedContainer (IComponent owningComponent) + { + return this.CreateNestedContainer (owningComponent, null); + } + + public INestedContainer CreateNestedContainer (IComponent owningComponent, string containerName) + { + if (_designerHost == null) + throw new ObjectDisposedException ("DesignSurface"); + + return new DesignModeNestedContainer (owningComponent, containerName); + } + + +#region IServiceProvider + + public object GetService (Type serviceType) + { + if (typeof (IServiceContainer) == serviceType) + return _serviceContainer; + + return _serviceContainer.GetService (serviceType); + } + +#endregion + + } + +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceCollection.cs b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceCollection.cs new file mode 100644 index 00000000000..69447e440f8 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceCollection.cs @@ -0,0 +1,141 @@ +// +// System.ComponentModel.Design.DesignSurfaceCollection +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.Collections; + +namespace System.ComponentModel.Design +{ + // A read-only collection of design surfaces. + // A wrapper around a DesignerCollection, which get's the DesignSurface for the IDesignerHost + // on the fly. + // + public sealed class DesignSurfaceCollection : ICollection, IEnumerable + { + + private class DesignSurfaceEnumerator : IEnumerator + { + IEnumerator _designerCollectionEnumerator; + + public DesignSurfaceEnumerator (IEnumerator designerCollectionEnumerator) + { + _designerCollectionEnumerator = designerCollectionEnumerator; + } + + public bool MoveNext () + { + return _designerCollectionEnumerator.MoveNext (); + } + + public void Reset () + { + _designerCollectionEnumerator.Reset (); + } + + public object Current { + get { + IDesignerHost designer = (IDesignerHost) _designerCollectionEnumerator.Current; + DesignSurface surface = designer.GetService (typeof (DesignSurface)) as DesignSurface; + if (surface == null) + throw new NotSupportedException (); + + return surface; + } + } + + } // DesignSurfaceEnumerator + + + private DesignerCollection _designers; + + internal DesignSurfaceCollection (DesignerCollection designers) + { + if (designers == null) + designers = new DesignerCollection (null); + + _designers = designers; + } + + public int Count { + get { return _designers.Count; } + } + + public object this[int index] { + get { + IDesignerHost designer = _designers[index]; + DesignSurface surface = designer.GetService (typeof (DesignSurface)) as DesignSurface; + if (surface == null) + throw new NotSupportedException (); + + return surface; + } + } + + public void CopyTo (DesignSurface[] array, int index) + { + ((ICollection) this).CopyTo (array, index); + } + + void ICollection.CopyTo (Array array, int index) + { + foreach (DesignSurface surface in this) { + array.SetValue (surface, index); + index++; + } + } + + public IEnumerator GetEnumerator () + { + return new DesignSurfaceEnumerator (_designers.GetEnumerator ()); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return GetEnumerator (); + } + + int ICollection.Count { + get { return this.Count; } + } + + bool ICollection.IsSynchronized { + get { return false; } + } + + object ICollection.SyncRoot { + get { return null; } + } + + } + +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceEventArgs.cs b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceEventArgs.cs new file mode 100644 index 00000000000..a0bb7bc29c1 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceEventArgs.cs @@ -0,0 +1,56 @@ +// +// System.ComponentModel.Design.DesignSurfaceEventArgs +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + + public class DesignSurfaceEventArgs : EventArgs + { + + private DesignSurface _surface; + + public DesignSurface Surface { + get { return _surface; } + } + + public DesignSurfaceEventArgs (DesignSurface surface) + { + _surface = surface; + } + + } + +} + +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceEventHandler.cs b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceEventHandler.cs new file mode 100644 index 00000000000..62f36ae4572 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceEventHandler.cs @@ -0,0 +1,41 @@ +// +// System.ComponentModel.Design.DesignSurfaceEventHandler +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + + public delegate void DesignSurfaceEventHandler (Object sender, DesignSurfaceEventArgs e); +} + +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceManager.cs b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceManager.cs new file mode 100644 index 00000000000..84b3f7f1919 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceManager.cs @@ -0,0 +1,249 @@ +// +// System.ComponentModel.Design.DesignSurfaceManager +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.Collections; + +namespace System.ComponentModel.Design +{ + + public class DesignSurfaceManager : IServiceProvider, IDisposable + { + + private class MergedServiceProvider : IServiceProvider + { + private IServiceProvider _primaryProvider; + private IServiceProvider _secondaryProvider; + + public MergedServiceProvider (IServiceProvider primary, IServiceProvider secondary) + { + if (primary == null) + throw new ArgumentNullException ("primary"); + if (secondary == null) + throw new ArgumentNullException ("secondary"); + + _primaryProvider = primary; + _secondaryProvider = secondary; + } + + public object GetService (Type service) + { + object result = _primaryProvider.GetService (service); + if (result == null) + result = _secondaryProvider.GetService (service); + + return result; + } + + } // MergedServiceProvider + + + private IServiceProvider _parentProvider; + private ServiceContainer _serviceContainer; + + public DesignSurfaceManager () : this (null) + { + } + + public DesignSurfaceManager (IServiceProvider serviceProvider) + { + _parentProvider = serviceProvider; + this.ServiceContainer.AddService (typeof (IDesignerEventService), new DesignerEventService ()); + } + + // The CreateDesignSurfaceCore method is called by both CreateDesignSurface methods. + // It is the implementation that actually creates the design surface. The default + // implementation just returns a new DesignSurface. You may override this method to provide + // a custom object that derives from the DesignSurface class. + // + protected virtual DesignSurface CreateDesignSurfaceCore (IServiceProvider parentProvider) + { + DesignSurface surface = new DesignSurface (parentProvider); + OnDesignSurfaceCreated (surface); + return surface; + } + + public DesignSurface CreateDesignSurface () + { + return CreateDesignSurfaceCore (this); + } + + // MSDN: parentProvider - A parent service provider. A new merged service provider will be created that + // will first ask this provider for a service, and then delegate any failures to the design surface + // manager object. This merged provider will be passed into the CreateDesignSurfaceCore method. + // + public DesignSurface CreateDesignSurface (IServiceProvider parentProvider) + { + if (parentProvider == null) + throw new ArgumentNullException ("parentProvider"); + + return CreateDesignSurfaceCore (new MergedServiceProvider (parentProvider, this)); + } + + public virtual DesignSurface ActiveDesignSurface { + get { + DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService; + if (eventService != null) { + IDesignerHost designer = eventService.ActiveDesigner; + if (designer != null) + return designer.GetService (typeof (DesignSurface)) as DesignSurface; + } + return null; + } + set { + if (value != null) { + DesignSurface oldSurface = null; + + // get current surface + DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService; + if (eventService != null) { + IDesignerHost designer = eventService.ActiveDesigner; + if (designer != null) + oldSurface = designer.GetService (typeof (DesignSurface)) as DesignSurface; + } + + ISelectionService selectionService = null; + + // unsubscribe from current's selectionchanged + if (oldSurface != null) { + selectionService = oldSurface.GetService (typeof (ISelectionService)) as ISelectionService; + if (selectionService != null) + selectionService.SelectionChanged -= new EventHandler (OnSelectionChanged); + } + // subscribe to new's selectionchanged + selectionService = value.GetService (typeof (ISelectionService)) as ISelectionService; + if (selectionService != null) + selectionService.SelectionChanged += new EventHandler (OnSelectionChanged); + + // set it + eventService.ActiveDesigner = value.GetService (typeof (IDesignerHost)) as IDesignerHost; + + // fire event + if (this.ActiveDesignSurfaceChanged != null) + this.ActiveDesignSurfaceChanged (this, new ActiveDesignSurfaceChangedEventArgs (oldSurface, value)); + } + } + } + + public DesignSurfaceCollection DesignSurfaces { + get { + DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService; + if (eventService != null) + return new DesignSurfaceCollection (eventService.Designers); + + return new DesignSurfaceCollection (null); + } + } + + protected ServiceContainer ServiceContainer { + get { + if (_serviceContainer == null) + _serviceContainer = new ServiceContainer (_parentProvider); + + return _serviceContainer; + } + } + + // MSDN2 says those events are mapped through the IDesignerEventService, + // but I preferd not to do that. Should not cause compitability issues. + // + // + // The SelectionChanged is fired only for a changed component selection on the + // active designersurface. + // + public event EventHandler SelectionChanged; + public event DesignSurfaceEventHandler DesignSurfaceDisposed; + public event DesignSurfaceEventHandler DesignSurfaceCreated; + public event ActiveDesignSurfaceChangedEventHandler ActiveDesignSurfaceChanged; + + private void OnSelectionChanged (object sender, EventArgs args) + { + if (SelectionChanged != null) + SelectionChanged (this, EventArgs.Empty); + + DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService; + if (eventService != null) + eventService.RaiseSelectionChanged (); + } + + private void OnDesignSurfaceCreated (DesignSurface surface) + { + if (DesignSurfaceCreated != null) + DesignSurfaceCreated (this, new DesignSurfaceEventArgs (surface)); + + // monitor disposing + surface.Disposed += new EventHandler (OnDesignSurfaceDisposed); + + DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService; + if (eventService != null) + eventService.RaiseDesignerCreated (surface.GetService (typeof (IDesignerHost)) as IDesignerHost); + } + + private void OnDesignSurfaceDisposed (object sender, EventArgs args) + { + DesignSurface surface = (DesignSurface) sender; + + surface.Disposed -= new EventHandler (OnDesignSurfaceDisposed); + + if (DesignSurfaceDisposed != null) + DesignSurfaceDisposed (this, new DesignSurfaceEventArgs (surface)); + + DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService; + if (eventService != null) + eventService.RaiseDesignerDisposed (surface.GetService (typeof (IDesignerHost)) as IDesignerHost); + + } + + public object GetService (Type service) + { + if (_serviceContainer != null) + return _serviceContainer.GetService (service); + + return null; + } + + public void Dispose () + { + Dispose (true); + } + + protected virtual void Dispose (bool disposing) + { + if (disposing && _serviceContainer != null) { + _serviceContainer.Dispose (); + _serviceContainer = null; + } + } + } + +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceServiceContainer.cs b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceServiceContainer.cs new file mode 100644 index 00000000000..e8d081159c3 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/DesignSurfaceServiceContainer.cs @@ -0,0 +1,81 @@ +// +// System.ComponentModel.Design.DesignSurfaceServiceContainer +// +// Authors: +// Ivan N. Zlatev (contact i-nz.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + + // Implements a ServiceContainer, which allows specific sets of services + // to be non-replacable for users of the IServiceContainer . + // + internal sealed class DesignSurfaceServiceContainer : ServiceContainer + { + + private Hashtable _nonRemoveableServices; + + public DesignSurfaceServiceContainer () : this (null) + { + } + + public DesignSurfaceServiceContainer (IServiceProvider parentProvider) : base (parentProvider) + { + } + + internal void AddNonReplaceableService (Type serviceType, object instance) + { + if (_nonRemoveableServices == null) + _nonRemoveableServices = new Hashtable (); + + _nonRemoveableServices[serviceType] = serviceType; + base.AddService (serviceType, instance); + } + + + internal void RemoveNonReplaceableService (Type serviceType, object instance) + { + if (_nonRemoveableServices != null) + _nonRemoveableServices.Remove (serviceType); + base.RemoveService (serviceType); + } + + public override void RemoveService (Type serviceType, bool promote) + { + if (serviceType != null && _nonRemoveableServices != null && _nonRemoveableServices.ContainsKey (serviceType)) + throw new InvalidOperationException ("Cannot remove non-replaceable service: " + serviceType.AssemblyQualifiedName); + + base.RemoveService (serviceType, promote); + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/DesignerActionListCollection.cs b/mcs/class/System.Design/System.ComponentModel.Design/DesignerActionListCollection.cs new file mode 100644 index 00000000000..19d7ef17b71 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/DesignerActionListCollection.cs @@ -0,0 +1,126 @@ +// +// System.ComponentModel.Design.DesignerActionListCollection +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + + public class DesignerActionListCollection : CollectionBase + { + + public DesignerActionListCollection () + { + } + + public DesignerActionListCollection (DesignerActionList[] value) + { + AddRange (value); + } + + public DesignerActionList this[int index] { + get { return (DesignerActionList) base.List[index]; } + set { base.List[index] = value; } + } + + public int Add (DesignerActionList value) + { + return base.List.Add (value); + } + + public void AddRange (DesignerActionList[] value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + foreach (DesignerActionList actionList in value) + Add (actionList); + } + + public void AddRange (DesignerActionListCollection value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + foreach (DesignerActionList actionList in value) + Add (actionList); + } + + public bool Contains (DesignerActionList value) + { + return base.List.Contains (value); + } + + public void CopyTo (DesignerActionList[] array, int index) + { + base.List.CopyTo (array, index); + } + + public int IndexOf (DesignerActionList value) + { + return base.List.IndexOf (value); + } + + public void Insert (int index, DesignerActionList value) + { + base.List.Insert (index, value); + } + + public void Remove (DesignerActionList value) + { + base.List.Remove (value); + } + + protected override void OnClear () + { + } + + protected override void OnInsert (int index, object value) + { + } + + protected override void OnRemove (int index, object value) + { + } + + protected override void OnSet (int index, object oldValue, object newValue) + { + } + + protected override void OnValidate (object value) + { + } + + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/DesignerEventService.cs b/mcs/class/System.Design/System.ComponentModel.Design/DesignerEventService.cs new file mode 100644 index 00000000000..6243454daa1 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/DesignerEventService.cs @@ -0,0 +1,98 @@ +// +// System.ComponentModel.Design.DesignerEventService +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.Collections; + +namespace System.ComponentModel.Design +{ + // IDesignerEventService provides a global eventing mechanism for designer events. With this mechanism, + // an application is informed when a designer becomes active. The service provides a collection of + // designers and a single place where global objects, such as the Properties window, can monitor selection + // change events. + // + // IDesignerEventService is practicly replaced by the DesignSurfaceManager and also the + // meaning of Designer in IDesignerEventService is actually DesignerHost. + // + internal sealed class DesignerEventService : IDesignerEventService + { + + public DesignerEventService () + { + _designerList = new ArrayList (); + } + + private ArrayList _designerList; + private IDesignerHost _activeDesigner; + + public IDesignerHost ActiveDesigner { + get { + return _activeDesigner; + } + internal set { + IDesignerHost old = _activeDesigner; + _activeDesigner = value; + if (ActiveDesignerChanged != null) + ActiveDesignerChanged (this, new ActiveDesignerEventArgs (old, value)); + } + } + + public DesignerCollection Designers { + get { return new DesignerCollection (_designerList); } + } + + public event ActiveDesignerEventHandler ActiveDesignerChanged; + public event DesignerEventHandler DesignerCreated; + public event DesignerEventHandler DesignerDisposed; + public event EventHandler SelectionChanged; + + public void RaiseDesignerCreated (IDesignerHost host) + { + if (DesignerCreated != null) + DesignerCreated (this, new DesignerEventArgs (host)); + } + + public void RaiseDesignerDisposed (IDesignerHost host) + { + if (DesignerDisposed != null) + DesignerDisposed (this, new DesignerEventArgs (host)); + } + + public void RaiseSelectionChanged () + { + if (SelectionChanged != null) + SelectionChanged (this, EventArgs.Empty); + } + + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/DesignerHost.cs b/mcs/class/System.Design/System.ComponentModel.Design/DesignerHost.cs new file mode 100644 index 00000000000..7ff7206cc75 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/DesignerHost.cs @@ -0,0 +1,570 @@ +// +// System.ComponentModel.Design.DesignerHost +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; +using System.Reflection; + +namespace System.ComponentModel.Design +{ + + // A container for components and their designers + // + internal sealed class DesignerHost : Container, IDesignerLoaderHost, IDesignerHost, IServiceProvider, IComponentChangeService + { + + +#region DesignerHostTransaction : DesignerTransaction + + private sealed class DesignerHostTransaction : DesignerTransaction + { + + DesignerHost _designerHost; + + public DesignerHostTransaction (DesignerHost host, string description) : base (description) + { + _designerHost = host; + } + + protected override void OnCancel () + { + _designerHost.OnTransactionClosing (this, false); + _designerHost.OnTransactionClosed (this, false); + } + + protected override void OnCommit () + { + _designerHost.OnTransactionClosing (this, true); + _designerHost.OnTransactionClosed (this, true); + } + + } // DesignerHostTransaction + +#endregion + + + private IServiceProvider _serviceProvider; + private Hashtable _designers; + private Stack _transactions; + private IServiceContainer _serviceContainer; + private bool _loading; + + public DesignerHost (IServiceProvider serviceProvider) + { + if (serviceProvider == null) + throw new ArgumentNullException ("serviceProvider"); + + _serviceProvider = serviceProvider; + _serviceContainer = serviceProvider.GetService (typeof (IServiceContainer)) as IServiceContainer; + _designers = new Hashtable (); + _transactions = new Stack (); + _loading = true; + } + + +#region IContainer + + // XXX: More validation here? + // (e.g: Make use of a potentially existing INameCreationService) + // + public override void Add (IComponent component, string name) + { + AddPreProcess (component, name); + base.Add (component, name); + AddPostProcess (component, name); + } + + internal void AddPreProcess (IComponent component, string name) + { + if (ComponentAdding != null) + ComponentAdding (this, new ComponentEventArgs (component)); + } + + internal void AddPostProcess (IComponent component, string name) + { + IDesigner designer; + + if (_rootComponent == null) { + _rootComponent = component; + designer = this.CreateDesigner (component, true); + } + else { + designer = this.CreateDesigner (component, false); + } + + if (designer != null) { + _designers[component] = designer; + designer.Initialize (component); + } else { + Console.WriteLine ("Unable to load a designer for " + component.GetType ().FullName); + } + + // Activate the host and design surface once the root component is added to + // the container and its designer is loaded and added to the designers collection + if (component == _rootComponent) + this.Activate (); + + if (component is IExtenderProvider) { + IExtenderProviderService service = this.GetService (typeof (IExtenderProviderService)) as IExtenderProviderService; + if (service != null) + service.AddExtenderProvider ((IExtenderProvider) component); + } + + if (ComponentAdded != null) + ComponentAdded (this, new ComponentEventArgs (component)); + } + + public override void Remove (IComponent component) + { + RemovePreProcess (component); + base.Remove (component); + RemovePostProcess (component); + } + + internal void RemovePreProcess (IComponent component) + { + if (ComponentRemoving != null) + ComponentRemoving (this, new ComponentEventArgs (component)); + + IDesigner designer = _designers[component] as IDesigner; + if (designer != null) + designer.Dispose (); + + _designers.Remove (component); + + if (component == _rootComponent) + _rootComponent = null; + + if (component is IExtenderProvider) { + IExtenderProviderService service = GetService (typeof (IExtenderProviderService)) as IExtenderProviderService; + if (service != null) + service.RemoveExtenderProvider ((IExtenderProvider) component); + } + } + + internal void RemovePostProcess (IComponent component) + { + if (ComponentRemoved != null) + ComponentRemoved (this, new ComponentEventArgs (component)); + } + + protected override ISite CreateSite (IComponent component, string name) + { + if (name == null) { + INameCreationService nameService = this.GetService (typeof (INameCreationService)) as INameCreationService; + if (nameService != null) + name = nameService.CreateName (this, component.GetType ()); + } + return new DesignModeSite (component, name, this, this); + } + +#endregion + + +#region IDesignerHost + + private IComponent _rootComponent; + + public IContainer Container { + get { return this; } + } + + public bool InTransaction { + get { + if (_transactions != null && _transactions.Count > 0) + return true; + + return false; + } + } + + public bool Loading { + get { return _loading; } + } + + public IComponent RootComponent { + get { return _rootComponent; } + } + + public string RootComponentClassName { + get { + if (_rootComponent != null) + return ((object)_rootComponent).GetType ().AssemblyQualifiedName; + + return null; + } + } + + public string TransactionDescription { + get { + if (_transactions != null && _transactions.Count > 0) + return ((DesignerHostTransaction) _transactions.Peek()).Description; + + return null; + } + } + + + // GUI loading in the designer should be done after the Activated event is raised. + // + public void Activate () + { + ISelectionService selectionService = GetService (typeof (ISelectionService)) as ISelectionService; + + // Set the Primary Selection to be the root component + // + if (selectionService != null) + selectionService.SetSelectedComponents (new IComponent[] { _rootComponent }); + + if (Activated != null) + Activated (this, EventArgs.Empty); + } + + public IComponent CreateComponent (Type componentClass) + { + return CreateComponent (componentClass, null); + } + + public IComponent CreateComponent (Type componentClass, string name) + { + if (componentClass == null) + throw new ArgumentNullException ("componentClass"); + + else if (!typeof(IComponent).IsAssignableFrom(componentClass)) + throw new ArgumentException ("componentClass"); + + IComponent component = this.CreateInstance (componentClass) as IComponent; + this.Add (component, name); + + return component; + } + + internal object CreateInstance (Type type) + { + if (type == null) + throw new System.ArgumentNullException ("type"); + + // FIXME: Should I use TypeDescriptor.CreateInstance() for 2.0 ? + // + return Activator.CreateInstance (type, BindingFlags.CreateInstance | BindingFlags.Public + | BindingFlags.Instance, null, null, null); + } + + internal IDesigner CreateDesigner (IComponent component, bool rootDesigner) + { + if (component == null) + throw new System.ArgumentNullException ("component"); + + if (rootDesigner) { + //return TypeDescriptor.CreateDesigner (component, typeof (IRootDesigner)); + return this.CreateDesigner (component, typeof (IRootDesigner)); + } + else { + //return TypeDescriptor.CreateDesigner (component, typeof (IDesigner)); + return this.CreateDesigner (component, typeof (IDesigner)); + } + } + + // Since most of the specific designers are missing this temporary method + // will fallback to the first available designer type in the type's base types + // + private IDesigner CreateDesigner (IComponent component, Type designerBaseType) + { + IDesigner instance = null; + AttributeCollection attributes = TypeDescriptor.GetAttributes (component); + + foreach (Attribute attribute in attributes) { + DesignerAttribute designerAttr = attribute as DesignerAttribute; + if (designerAttr != null && + (designerBaseType.FullName == designerAttr.DesignerBaseTypeName || + designerBaseType.AssemblyQualifiedName == designerAttr.DesignerBaseTypeName)) { + Type type = Type.GetType (designerAttr.DesignerTypeName); + if (type == null && designerBaseType == typeof (IRootDesigner)) + type = typeof (System.Windows.Forms.Design.DocumentDesigner); + if (type != null) + instance = (IDesigner) Activator.CreateInstance (type); + break; + } + } + + if (instance == null) { + Type baseType = component.GetType ().BaseType; + do { + attributes = TypeDescriptor.GetAttributes (baseType); + foreach (Attribute attribute in attributes) { + DesignerAttribute designerAttr = attribute as DesignerAttribute; + if (designerAttr != null && + (designerBaseType.FullName == designerAttr.DesignerBaseTypeName || + designerBaseType.AssemblyQualifiedName == designerAttr.DesignerBaseTypeName)) { + Type type = Type.GetType (designerAttr.DesignerTypeName); + if (type != null) + instance = (IDesigner) Activator.CreateInstance (type); + break; + } + } + baseType = baseType.BaseType; + } while (instance == null && baseType != null); + } + + return instance; + } + + public void DestroyComponent (IComponent component) + { + if (component.Site != null && component.Site.Container == this) { + OnComponentChanging (component, null); + + this.Remove (component); // takes care for the designer as well + component.Dispose (); + + OnComponentChanged (component, null, null, null); + } + } + + public IDesigner GetDesigner (IComponent component) + { + if (component == null) + throw new ArgumentNullException ("component"); + + return _designers[component] as IDesigner; + } + + public DesignerTransaction CreateTransaction () + { + return CreateTransaction (null); + } + + public DesignerTransaction CreateTransaction (string description) + { + if (TransactionOpening != null) + TransactionOpening (this, EventArgs.Empty); + + DesignerHostTransaction transaction = new DesignerHostTransaction (this, description); + _transactions.Push (transaction); + + if (TransactionOpened != null) + TransactionOpened (this, EventArgs.Empty); + + return transaction; + } + + + public Type GetType (string typeName) + { + Type result; + ITypeResolutionService s = GetService (typeof (ITypeResolutionService)) as ITypeResolutionService; + + if (s != null) + result = s.GetType (typeName); + else + result = Type.GetType (typeName); + + return result; + } + + // Take care of disposing the designer the base.Dispose will cleanup + // the components. + // + protected override void Dispose (bool disposing) + { + Unload (); + base.Dispose (disposing); + } + + + public event EventHandler Activated; + public event EventHandler Deactivated; + public event EventHandler LoadComplete; + public event DesignerTransactionCloseEventHandler TransactionClosed; + public event DesignerTransactionCloseEventHandler TransactionClosing; + public event EventHandler TransactionOpened; + public event EventHandler TransactionOpening; + + + private void OnTransactionClosing (DesignerHostTransaction raiser, bool commit) + { + bool lastTransaction = false; + if (_transactions.Count > 0 && _transactions.Peek() == raiser) + lastTransaction = true; + + if (TransactionClosing != null) + TransactionClosing (this, new DesignerTransactionCloseEventArgs (commit, lastTransaction)); + } + + private void OnTransactionClosed (DesignerHostTransaction raiser, bool commit) + { + bool lastTransaction = false; + if (_transactions.Count > 0 && _transactions.Peek() == raiser) { + lastTransaction = true; + _transactions.Pop (); + } + + if (TransactionClosed != null) + TransactionClosed (this, new DesignerTransactionCloseEventArgs (commit, lastTransaction)); + } + +#endregion + + +#region IDesignerLoaderHost + + internal event LoadedEventHandler DesignerLoaderHostLoaded; + internal event EventHandler DesignerLoaderHostLoading; + internal event EventHandler DesignerLoaderHostUnloading; + internal event EventHandler DesignerLoaderHostUnloaded; + + public void EndLoad (string rootClassName, bool successful, ICollection errorCollection) + { + if (DesignerLoaderHostLoaded != null) + DesignerLoaderHostLoaded (this, new LoadedEventArgs (successful, errorCollection)); + + if (LoadComplete != null) + LoadComplete (this, EventArgs.Empty); + + _loading = false; // _loading = true is set by the ctor + } + + // BasicDesignerLoader invokes this.Reload, then invokes BeginLoad on itself, + // then when loading it the loader is done it ends up in this.EndLoad. + // At the end of the day Reload is more like Unload. + // + public void Reload () + { + _loading = true; + Unload (); + if (DesignerLoaderHostLoading != null) + DesignerLoaderHostLoading (this, EventArgs.Empty); + } + + private void Unload () + { + if (DesignerLoaderHostUnloading != null) + DesignerLoaderHostUnloading (this, EventArgs.Empty); + + IComponent[] components = new IComponent[this.Components.Count]; + this.Components.CopyTo (components, 0); + + foreach (IComponent component in components) + this.Remove (component); + + _transactions.Clear (); + + if (DesignerLoaderHostUnloaded != null) + DesignerLoaderHostUnloaded (this, EventArgs.Empty); + } + +#endregion + + +#region IComponentChangeService + + public event ComponentEventHandler ComponentAdded; + public event ComponentEventHandler ComponentAdding; + public event ComponentChangedEventHandler ComponentChanged; + public event ComponentChangingEventHandler ComponentChanging; + public event ComponentEventHandler ComponentRemoved; + public event ComponentEventHandler ComponentRemoving; + public event ComponentRenameEventHandler ComponentRename; + + + public void OnComponentChanged (object component, MemberDescriptor member, object oldValue, object newValue) + { + if (ComponentChanged != null) + ComponentChanged (this, new ComponentChangedEventArgs (component, member, oldValue, newValue)); + } + + public void OnComponentChanging (object component, MemberDescriptor member) + { + if (ComponentChanging != null) + ComponentChanging (this, new ComponentChangingEventArgs (component, member)); + } + + internal void OnComponentRename (object component, string oldName, string newName) + { + if (ComponentRename != null) + ComponentRename (this, new ComponentRenameEventArgs (component, oldName, newName)); + } + +#endregion + + +#region IServiceContainer + // Wrapper around the DesignSurface service container + // + + public void AddService (Type serviceType, object serviceInstance) + { + _serviceContainer.AddService (serviceType, serviceInstance); + } + + public void AddService (Type serviceType, object serviceInstance, bool promote) + { + _serviceContainer.AddService (serviceType, serviceInstance, promote); + } + + public void AddService (Type serviceType, ServiceCreatorCallback callback) + { + _serviceContainer.AddService (serviceType, callback); + } + + public void AddService (Type serviceType, ServiceCreatorCallback callback, bool promote) + { + _serviceContainer.AddService (serviceType, callback, promote); + } + + public void RemoveService (Type serviceType) + { + _serviceContainer.RemoveService (serviceType); + } + + public void RemoveService (Type serviceType, bool promote) + { + _serviceContainer.RemoveService (serviceType, promote); + } + +#endregion + + +#region IServiceProvider + + public new object GetService (Type serviceType) + { + return _serviceProvider.GetService (serviceType); + } + +#endregion + + } + + } +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/EventBindingService.cs b/mcs/class/System.Design/System.ComponentModel.Design/EventBindingService.cs new file mode 100644 index 00000000000..0dd0b667f68 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/EventBindingService.cs @@ -0,0 +1,222 @@ +// +// System.ComponentModel.Design.EventBindingService +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections.Generic; +using System.Collections; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + public abstract class EventBindingService : IEventBindingService + { + + private IServiceProvider _provider; + + public EventBindingService (IServiceProvider provider) + { + if (provider == null) + throw new ArgumentNullException ("provider"); + _provider = provider; + } + + protected abstract bool ShowCode (IComponent component, EventDescriptor e, string methodName); + protected abstract bool ShowCode (int lineNumber); + protected abstract bool ShowCode (); + protected abstract string CreateUniqueMethodName (IComponent component, EventDescriptor eventDescriptor); + protected abstract ICollection GetCompatibleMethods (EventDescriptor eventDescriptor); + + protected virtual void FreeMethod (IComponent component, EventDescriptor e, string methodName) + { + } + + protected virtual void UseMethod (IComponent component, EventDescriptor e, string methodName) + { + } + + + protected virtual void ValidateMethodName (string methodName) + { + } + + + protected object GetService (Type service) + { + if (_provider != null) + return _provider.GetService (service); + return null; + } + +#region IEventBindingService implementation + + string IEventBindingService.CreateUniqueMethodName (IComponent component, EventDescriptor eventDescriptor) + { + if (eventDescriptor == null) + throw new ArgumentNullException ("eventDescriptor"); + if (component == null) + throw new ArgumentNullException ("component"); + + return this.CreateUniqueMethodName (component, eventDescriptor); + } + + ICollection IEventBindingService.GetCompatibleMethods (EventDescriptor eventDescriptor) + { + if (eventDescriptor == null) + throw new ArgumentNullException ("eventDescriptor"); + + return this.GetCompatibleMethods (eventDescriptor); + } + + EventDescriptor IEventBindingService.GetEvent (PropertyDescriptor property) + { + if (property == null) + throw new ArgumentNullException ("property"); + + EventPropertyDescriptor eventPropDescriptor = property as EventPropertyDescriptor; + if (eventPropDescriptor == null) + return null; + + return eventPropDescriptor.InternalEventDescriptor; + } + + PropertyDescriptorCollection IEventBindingService.GetEventProperties (EventDescriptorCollection events) + { + if (events == null) + throw new ArgumentNullException ("events"); + + List<PropertyDescriptor> properties = new List <PropertyDescriptor>(); + foreach (EventDescriptor eventDescriptor in events) + properties.Add (((IEventBindingService)this).GetEventProperty (eventDescriptor)); + + return new PropertyDescriptorCollection (properties.ToArray ()); + } + + PropertyDescriptor IEventBindingService.GetEventProperty (EventDescriptor eventDescriptor) + { + if (eventDescriptor == null) + throw new ArgumentNullException ("eventDescriptor"); + + return new EventPropertyDescriptor (eventDescriptor); + } + + bool IEventBindingService.ShowCode (IComponent component, EventDescriptor eventDescriptor) + { + if (component == null) + throw new ArgumentNullException ("component"); + if (eventDescriptor == null) + throw new ArgumentNullException ("eventDescriptor"); + + return this.ShowCode (component, eventDescriptor, (string) ((IEventBindingService)this).GetEventProperty (eventDescriptor).GetValue (component)); + } + + bool IEventBindingService.ShowCode (int lineNumber) + { + return this.ShowCode (lineNumber); + } + + bool IEventBindingService.ShowCode () + { + return this.ShowCode (); + } +#endregion + + } + + internal class EventPropertyDescriptor : PropertyDescriptor + { + private EventDescriptor _eventDescriptor; + + public EventPropertyDescriptor (EventDescriptor eventDescriptor) + : base (eventDescriptor) + { + if (eventDescriptor == null) + throw new ArgumentNullException ("eventDescriptor"); + _eventDescriptor = eventDescriptor; + } + + public override bool CanResetValue (object component) + { + return true; + } + + public override Type ComponentType { + get { return _eventDescriptor.ComponentType; } + } + + public override bool IsReadOnly { + get { return false; } + } + + public override Type PropertyType { + get { return _eventDescriptor.EventType; } + } + + public override void ResetValue (object component) + { + this.SetValue (component, null); + } + + public override object GetValue (object component) + { + if (component is IComponent && ((IComponent)component).Site != null) { + IDictionaryService dictionary = ((IComponent)component).Site.GetService (typeof (IDictionaryService)) as IDictionaryService; + if (dictionary != null) + return dictionary.GetValue (base.Name); + } + return null; + } + + public override void SetValue (object component, object value) + { + if (component is IComponent && ((IComponent)component).Site != null) { + IDictionaryService dictionary = ((IComponent)component).Site.GetService (typeof (IDictionaryService)) as IDictionaryService; + if (dictionary != null) + dictionary.SetValue (base.Name, value); + } + } + + public override bool ShouldSerializeValue (object component) + { + if (this.GetValue (component) != null) + return true; + return false; + } + + public override TypeConverter Converter { + get { return TypeDescriptor.GetConverter (String.Empty); } + } + + internal EventDescriptor InternalEventDescriptor { + get { return _eventDescriptor; } + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/ExtenderService.cs b/mcs/class/System.Design/System.ComponentModel.Design/ExtenderService.cs new file mode 100644 index 00000000000..038627b41d2 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/ExtenderService.cs @@ -0,0 +1,83 @@ +// +// System.ComponentModel.Design.ExtenderService +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 +using System; +using System.Collections; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + + internal sealed class ExtenderService : IExtenderProviderService, IExtenderListService, IDisposable + { + + private ArrayList _extenderProviders; + + public ExtenderService () + { + _extenderProviders = new ArrayList (); + } + + public void AddExtenderProvider (IExtenderProvider provider) + { + if (_extenderProviders != null) { + if (!_extenderProviders.Contains (provider)) + _extenderProviders.Add (provider); + } + } + + public void RemoveExtenderProvider (IExtenderProvider provider) + { + if (_extenderProviders != null) { + if (_extenderProviders.Contains (provider)) + _extenderProviders.Remove (provider); + } + } + + public IExtenderProvider[] GetExtenderProviders() + { + if (_extenderProviders != null) { + IExtenderProvider[] result = new IExtenderProvider[_extenderProviders.Count]; + _extenderProviders.CopyTo (result, 0); + + return result; + } + return null; + } + + public void Dispose () + { + _extenderProviders.Clear (); + _extenderProviders = null; + } + } +} + +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/LoadedEventArgs.cs b/mcs/class/System.Design/System.ComponentModel.Design/LoadedEventArgs.cs new file mode 100644 index 00000000000..87b0c291c03 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/LoadedEventArgs.cs @@ -0,0 +1,66 @@ +// +// System.ComponentModel.Design.LoadedEventArgs +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + + public sealed class LoadedEventArgs : EventArgs + { + + public LoadedEventArgs (bool succeeded, ICollection errors) + { + _succeeded = succeeded; + _errors = errors; + } + + private ICollection _errors; + private bool _succeeded; + + public ICollection Errors { + get { return _errors; } + } + + public bool HasSucceeded { + get { return _succeeded;} + } + + + + + } + +} + +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/LoadedEventHandler.cs b/mcs/class/System.Design/System.ComponentModel.Design/LoadedEventHandler.cs new file mode 100644 index 00000000000..a4b71998cf6 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/LoadedEventHandler.cs @@ -0,0 +1,40 @@ +// +// System.ComponentModel.Design.LoadedEventHandler +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + + public delegate void LoadedEventHandler (Object sender, LoadedEventArgs e); +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/ReferenceService.cs b/mcs/class/System.Design/System.ComponentModel.Design/ReferenceService.cs new file mode 100644 index 00000000000..210cee7bbde --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/ReferenceService.cs @@ -0,0 +1,115 @@ +// +// System.ComponentModel.Design.ReferenceService +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + + internal class ReferenceService : IReferenceService, IDisposable + { + + private List<IComponent> _references; + + internal ReferenceService (IServiceProvider provider) + { + if (provider == null) + throw new ArgumentNullException ("provider"); + + _references = new List<IComponent>(); + IComponentChangeService serv = provider.GetService (typeof (IComponentChangeService)) as IComponentChangeService; + if (serv != null) { + serv.ComponentAdded += OnComponentAdded; + serv.ComponentRemoved += OnComponentRemoved; + } + } + + private void OnComponentAdded (object sender, ComponentEventArgs args) + { + _references.Add (args.Component); + } + + private void OnComponentRemoved (object sender, ComponentEventArgs args) + { + _references.Remove (args.Component); + } + + public IComponent GetComponent (object reference) + { + return reference as IComponent; + } + + public string GetName (object reference) + { + IComponent comp = reference as IComponent; + if (comp != null && comp.Site != null) + return comp.Site.Name; + return null; + } + + public object GetReference (string name) + { + foreach (IComponent component in _references) + if (component.Site != null && component.Site.Name == name) + return component; + return null; + } + + public object[] GetReferences () + { + IComponent[] references = new IComponent[_references.Count]; + _references.CopyTo (references); + return references; + } + + public object[] GetReferences (Type baseType) + { + List<IComponent> references = new List<IComponent>(); + + foreach (IComponent component in _references) + if (baseType.IsAssignableFrom ((component.GetType ()))) + references.Add (component); + + IComponent[] refArray = new IComponent[references.Count]; + references.CopyTo (refArray); + return refArray; + } + + public void Dispose () + { + _references.Clear (); + } + } +} +#endif diff --git a/mcs/class/System.Design/System.ComponentModel.Design/SelectionService.cs b/mcs/class/System.Design/System.ComponentModel.Design/SelectionService.cs new file mode 100644 index 00000000000..035bd684f2c --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/SelectionService.cs @@ -0,0 +1,250 @@ +// +// System.ComponentModel.Design.SelectionService +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev + +// +// 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; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Windows.Forms; + +namespace System.ComponentModel.Design +{ + + internal class SelectionService : ISelectionService + { + + private IServiceProvider _serviceProvider; + + public SelectionService (IServiceProvider provider) + { + _serviceProvider = provider; + _selection = new ArrayList(); + } + + private ArrayList _selection; + private IComponent _primarySelection; + + public event EventHandler SelectionChanging; + public event EventHandler SelectionChanged; + + + + public ICollection GetSelectedComponents() + { + if (_selection != null) + return _selection.ToArray (); + + return new object[0]; + } + + protected virtual void OnSelectionChanging () + { + if (SelectionChanging != null) + SelectionChanging (this, EventArgs.Empty); + } + + protected virtual void OnSelectionChanged () + { + if (SelectionChanged != null) + SelectionChanged (this, EventArgs.Empty); + } + + public object PrimarySelection { + get { return _primarySelection; } + } + + public int SelectionCount { + get { + if (_selection != null) + return _selection.Count; + + return 0; + } + } + + + private IComponent RootComponent { + get { + if (_serviceProvider != null) { + IDesignerHost designerHost = _serviceProvider.GetService (typeof (IDesignerHost)) as IDesignerHost; + if (designerHost != null) + return designerHost.RootComponent; + + } + return null; + } + } + + public bool GetComponentSelected (object component) + { + if (_selection != null) + return _selection.Contains (component); + + return false; + } + + public void SetSelectedComponents (ICollection components) + { +#if NET_2_0 + SetSelectedComponents (components, SelectionTypes.Auto); +#else + SetSelectedComponents (components, SelectionTypes.Normal); +#endif + } + + // If the array is a null reference or does not contain any components, + // SetSelectedComponents selects the top-level component in the designer. + // + public void SetSelectedComponents (ICollection components, SelectionTypes selectionType) + { + bool primary, add, remove, replace, toggle, auto; + primary = add = remove = replace = toggle = auto = false; + + OnSelectionChanging (); + + if (_selection == null) + throw new InvalidOperationException("_selection == null"); + + if (components == null || components.Count == 0) { + components = new ArrayList (); + ((ArrayList) components).Add (this.RootComponent); + selectionType = SelectionTypes.Replace; + } + + if (!Enum.IsDefined (typeof (SelectionTypes), selectionType)) { +#if NET_2_0 + selectionType = SelectionTypes.Auto; +#else + selectionType = SelectionTypes.Normal; +#endif + } + +#if NET_2_0 + auto = ((selectionType & SelectionTypes.Auto) == SelectionTypes.Auto); +#else + if ((selectionType & SelectionTypes.Normal) == SelectionTypes.Normal || + (selectionType & SelectionTypes.MouseDown) == SelectionTypes.MouseDown || + (selectionType & SelectionTypes.MouseUp) == SelectionTypes.MouseUp) { + + auto = true; + } +#endif + + + if (auto) { + if ((((Control.ModifierKeys & Keys.Control) == Keys.Control) || ((Control.ModifierKeys & Keys.Shift) == Keys.Shift))) { + toggle = true; + } + else if (components.Count == 1) { + object component = null; + foreach (object c in components) { + component = c; + break; + } + + if (this.GetComponentSelected (component)) + primary = true; + else + replace = true; + } + else { + replace = true; + } + } + else { +#if NET_2_0 + primary = ((selectionType & SelectionTypes.Primary) == SelectionTypes.Primary); + add = ((selectionType & SelectionTypes.Add) == SelectionTypes.Add); + remove = ((selectionType & SelectionTypes.Remove) == SelectionTypes.Remove); + toggle = ((selectionType & SelectionTypes.Toggle) == SelectionTypes.Toggle); +#else + primary = ((selectionType & SelectionTypes.Click) == SelectionTypes.Click); +#endif + replace = ((selectionType & SelectionTypes.Replace) == SelectionTypes.Replace); + + } + + + if (replace) { + _selection.Clear (); + add = true; + } + + if (add) { + foreach (object component in components) { + if (component is IComponent && !_selection.Contains (component)) { + _selection.Add (component); + _primarySelection = (IComponent) component; + } + } + } + + if (remove) { + foreach (object component in components) { + if (component is IComponent && _selection.Contains (component)) { + _selection.Remove (component); + if (component == _primarySelection) + _primarySelection = this.RootComponent; + } + } + } + + if (toggle) { + foreach (object component in components) { + if (component is IComponent) { + if (_selection.Contains (component)) { + _selection.Remove (component); + if (component == _primarySelection) + _primarySelection = this.RootComponent; + } + else { + _selection.Add (component); + _primarySelection = (IComponent) component; + } + } + } + } + + if (primary) { + object primarySelection = null; + + foreach (object component in components) { + primarySelection = component; + break; + } + + if (!this.GetComponentSelected (primarySelection)) + _selection.Add (_primarySelection); + + _primarySelection = (IComponent) primarySelection; + } + + OnSelectionChanged (); + } + } +} diff --git a/mcs/class/System.Design/System.ComponentModel.Design/TypeDescriptorFilterService.cs b/mcs/class/System.Design/System.ComponentModel.Design/TypeDescriptorFilterService.cs new file mode 100644 index 00000000000..ed677912168 --- /dev/null +++ b/mcs/class/System.Design/System.ComponentModel.Design/TypeDescriptorFilterService.cs @@ -0,0 +1,120 @@ +// +// System.ComponentModel.Design.TypeDescriptorFilterService +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + + internal sealed class TypeDescriptorFilterService : ITypeDescriptorFilterService, IDisposable + { + + IServiceProvider _serviceProvider; + + public TypeDescriptorFilterService (IServiceProvider serviceProvider) + { + if (serviceProvider == null) + throw new ArgumentNullException ("serviceProvider"); + + _serviceProvider = serviceProvider; + } + + // Return values are: + // true if the set of filtered attributes is to be cached; false if the filter service must query again. + // + public bool FilterAttributes (IComponent component, IDictionary attributes) + { + if (_serviceProvider == null) + throw new ObjectDisposedException ("TypeDescriptorFilterService"); + if (component == null) + throw new ArgumentNullException ("component"); + + IDesignerHost designerHost = _serviceProvider.GetService (typeof (IDesignerHost)) as IDesignerHost; + if (designerHost != null) { + IDesigner designer = designerHost.GetDesigner (component); + if (designer is IDesignerFilter) { + ((IDesignerFilter) designer).PreFilterAttributes (attributes); + ((IDesignerFilter) designer).PostFilterAttributes (attributes); + } + } + + return true; + } + + public bool FilterEvents (IComponent component, IDictionary events) + { + if (_serviceProvider == null) + throw new ObjectDisposedException ("TypeDescriptorFilterService"); + if (component == null) + throw new ArgumentNullException ("component"); + + IDesignerHost designerHost = _serviceProvider.GetService (typeof (IDesignerHost)) as IDesignerHost; + if (designerHost != null) { + IDesigner designer = designerHost.GetDesigner (component); + if (designer is IDesignerFilter) { + ((IDesignerFilter) designer).PreFilterEvents (events); + ((IDesignerFilter) designer).PostFilterEvents (events); + } + } + + return true; + } + + public bool FilterProperties (IComponent component, IDictionary properties) + { + if (_serviceProvider == null) + throw new ObjectDisposedException ("TypeDescriptorFilterService"); + if (component == null) + throw new ArgumentNullException ("component"); + + IDesignerHost designerHost = _serviceProvider.GetService (typeof (IDesignerHost)) as IDesignerHost; + if (designerHost != null) { + IDesigner designer = designerHost.GetDesigner (component); + if (designer is IDesignerFilter) { + ((IDesignerFilter) designer).PreFilterProperties (properties); + ((IDesignerFilter) designer).PostFilterProperties (properties); + } + } + + return true; + } + + public void Dispose () + { + _serviceProvider = null; + } + + } +} + +#endif diff --git a/mcs/class/System.Design/System.Design.dll.sources b/mcs/class/System.Design/System.Design.dll.sources index d27b4be81bb..24948d6bea2 100755 --- a/mcs/class/System.Design/System.Design.dll.sources +++ b/mcs/class/System.Design/System.Design.dll.sources @@ -2,27 +2,67 @@ Assembly/AssemblyInfo.cs ../../build/common/Consts.cs ../../build/common/Locale.cs ../../build/common/MonoTODOAttribute.cs +System.ComponentModel.Design/ActiveDesignSurfaceChangedEventArgs.cs +System.ComponentModel.Design/ActiveDesignSurfaceChangedEventHandler.cs System.ComponentModel.Design/ArrayEditor.cs System.ComponentModel.Design/BinaryEditor.cs +System.ComponentModel.Design/ByteViewer.cs System.ComponentModel.Design/CollectionEditor.cs +System.ComponentModel.Design/ComponentDesigner.cs +System.ComponentModel.Design/DateTimeEditor.cs System.ComponentModel.Design/DesignerActionHeaderItem.cs System.ComponentModel.Design/DesignerActionItem.cs System.ComponentModel.Design/DesignerActionItemCollection.cs System.ComponentModel.Design/DesignerActionList.cs +System.ComponentModel.Design/DesignerActionListCollection.cs System.ComponentModel.Design/DesignerActionMethodItem.cs System.ComponentModel.Design/DesignerActionPropertyItem.cs System.ComponentModel.Design/DesignerActionTextItem.cs +System.ComponentModel.Design/DesignerEventService.cs +System.ComponentModel.Design/DesignerHost.cs +System.ComponentModel.Design/DesignModeNestedContainer.cs +System.ComponentModel.Design/DesignModeSite.cs +System.ComponentModel.Design/DesignSurface.cs +System.ComponentModel.Design/DesignSurfaceCollection.cs +System.ComponentModel.Design/DesignSurfaceEventArgs.cs +System.ComponentModel.Design/DesignSurfaceEventHandler.cs +System.ComponentModel.Design/DesignSurfaceManager.cs +System.ComponentModel.Design/DesignSurfaceServiceContainer.cs System.ComponentModel.Design/DisplayMode.cs -System.ComponentModel.Design/ByteViewer.cs -System.ComponentModel.Design/ComponentDesigner.cs -System.ComponentModel.Design/DateTimeEditor.cs +System.ComponentModel.Design/EventBindingService.cs +System.ComponentModel.Design/ExtenderService.cs System.ComponentModel.Design/InheritanceService.cs +System.ComponentModel.Design/LoadedEventArgs.cs +System.ComponentModel.Design/LoadedEventHandler.cs System.ComponentModel.Design/LocalizationExtenderProvider.cs System.ComponentModel.Design/MultilineStringEditor.cs System.ComponentModel.Design/ObjectSelectorEditor.cs +System.ComponentModel.Design/ReferenceService.cs +System.ComponentModel.Design/SelectionService.cs +System.ComponentModel.Design/TypeDescriptorFilterService.cs +System.ComponentModel.Design.Serialization/BasicDesignerLoader.cs +System.ComponentModel.Design.Serialization/CodeDomComponentSerializationService.cs +System.ComponentModel.Design.Serialization/CodeDomDesignerLoader.cs +System.ComponentModel.Design.Serialization/CodeDomSerializationProvider.cs System.ComponentModel.Design.Serialization/CodeDomSerializer.cs +System.ComponentModel.Design.Serialization/CodeDomSerializerBase.cs System.ComponentModel.Design.Serialization/CodeDomSerializerException.cs +System.ComponentModel.Design.Serialization/CollectionCodeDomSerializer.cs +System.ComponentModel.Design.Serialization/ComponentCodeDomSerializer.cs +System.ComponentModel.Design.Serialization/DesignerSerializationManager.cs +System.ComponentModel.Design.Serialization/EnumCodeDomSerializer.cs +System.ComponentModel.Design.Serialization/EventCodeDomSerializer.cs +System.ComponentModel.Design.Serialization/ExpressionContext.cs System.ComponentModel.Design.Serialization/ICodeDomDesignerReload.cs +System.ComponentModel.Design.Serialization/MemberCodeDomSerializer.cs +System.ComponentModel.Design.Serialization/ObjectStatementCollection.cs +System.ComponentModel.Design.Serialization/PrimitiveCodeDomSerializer.cs +System.ComponentModel.Design.Serialization/PropertyCodeDomSerializer.cs +System.ComponentModel.Design.Serialization/RootCodeDomSerializer.cs +System.ComponentModel.Design.Serialization/RootContext.cs +System.ComponentModel.Design.Serialization/SerializeAbsoluteContext.cs +System.ComponentModel.Design.Serialization/StatementContext.cs +System.ComponentModel.Design.Serialization/TypeCodeDomSerializer.cs System.Diagnostics.Design/LogConverter.cs System.Diagnostics.Design/ProcessDesigner.cs System.Diagnostics.Design/ProcessModuleDesigner.cs @@ -105,6 +145,7 @@ System.Windows.Forms.Design/AxWrapperGen.cs System.Windows.Forms.Design/ComponentDocumentDesigner.cs System.Windows.Forms.Design/ComponentTray.cs System.Windows.Forms.Design/ControlBindingsConverter.cs +System.Windows.Forms.Design/ControlDataObject.cs System.Windows.Forms.Design/ControlDesigner.cs System.Windows.Forms.Design/DataMemberFieldConverter.cs System.Windows.Forms.Design/DataMemberFieldEditor.cs @@ -116,16 +157,23 @@ System.Windows.Forms.Design/EventHandlerService.cs System.Windows.Forms.Design/FileNameEditor.cs System.Windows.Forms.Design/FolderNameEditor.cs System.Windows.Forms.Design/FormatStringEditor.cs +System.Windows.Forms.Design/ImageCollectionEditor.cs System.Windows.Forms.Design/ImageIndexEditor.cs System.Windows.Forms.Design/IMenuEditorService.cs -System.Windows.Forms.Design/ImageCollectionEditor.cs +System.Windows.Forms.Design/IMessageReceiver.cs System.Windows.Forms.Design/IOleDragClient.cs System.Windows.Forms.Design/ISelectionUIHandler.cs +System.Windows.Forms.Design/IUISelectionService.cs System.Windows.Forms.Design/ListControlStringCollectionEditor.cs System.Windows.Forms.Design/MenuCommands.cs +System.Windows.Forms.Design/Native.cs System.Windows.Forms.Design/ParentControlDesigner.cs System.Windows.Forms.Design/ScrollableControlDesigner.cs +System.Windows.Forms.Design/SelectionFrame.cs System.Windows.Forms.Design/SelectionRules.cs +System.Windows.Forms.Design/SplitContainerDesigner.cs System.Windows.Forms.Design/StringArrayEditor.cs System.Windows.Forms.Design/StringCollectionEditor.cs System.Windows.Forms.Design/TabPageCollectionEditor.cs +System.Windows.Forms.Design/UISelectionService.cs +System.Windows.Forms.Design/WndProcRouter.cs diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/ChangeLog b/mcs/class/System.Design/System.Windows.Forms.Design/ChangeLog index 0688e970629..1a8205288d7 100644 --- a/mcs/class/System.Design/System.Windows.Forms.Design/ChangeLog +++ b/mcs/class/System.Design/System.Windows.Forms.Design/ChangeLog @@ -1,3 +1,27 @@ +2007-08-29 Ivan N. Zlatev <contact@i-nz.net> + + * CodeDomComponentSerializationService.cs: implemented. + * CollectionCodeDomSerializer.cs: implemented. + * CodeDomDesignerLoader.cs: implemented. + * CodeDomSerializationProvider.cs: implemented. + * ComponentCodeDomSerializer.cs: implemented. + * RootContext.cs: implemented. + * BasicDesignerLoader.cs: implemented. + * DesignerSerializationManager.cs: implemented. + * EnumCodeDomSerializer.cs: implemented. + * SerializeAbsoluteContext.cs: implemented. + * MemberCodeDomSerializer.cs: implemented. + * PrimitiveCodeDomSerializer.cs: implemented. + * CodeDomSerializerBase.cs: implemented. + * CodeDomSerializer.cs: implemented. + * ExpressionContext.cs: implemented. + * EventCodeDomSerializer.cs: implemented. + * TypeCodeDomSerializer.cs: implemented. + * ObjectStatementCollection.cs: implemented. + * RootCodeDomSerializer.cs: implemented. + * PropertyCodeDomSerializer.cs: implemented. + * StatementContext.cs: implemented. + 2007-08-27 Ivan N. Zlatev <contact@i-nz.net> * DataMemberFieldEditor.cs: stubbed. * DataMemberListEditor.cs: stubbed. diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/ComponentTray.cs b/mcs/class/System.Design/System.Windows.Forms.Design/ComponentTray.cs index 0fa616b05d9..edffe2b3a9e 100644 --- a/mcs/class/System.Design/System.Windows.Forms.Design/ComponentTray.cs +++ b/mcs/class/System.Design/System.Windows.Forms.Design/ComponentTray.cs @@ -1,10 +1,10 @@ // -// System.Windows.Forms.Design.ComponentEditorForm.cs +// System.Windows.Forms.Design.ComponentTray // -// Author: -// Dennis Hayes (dennish@raytek.com) -// (C) 2002 Ximian, Inc. http://www.ximian.com +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) // +// (C) 2006-2007 Ivan N. Zlatev // // Permission is hereby granted, free of charge, to any person obtaining @@ -14,10 +14,10 @@ // 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 @@ -27,374 +27,167 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +// STUBS ONLY!!! +// +// + using System; using System.ComponentModel; using System.ComponentModel.Design; +using System.Windows.Forms; using System.Drawing; using System.Drawing.Design; +using System.Collections; namespace System.Windows.Forms.Design { [DesignTimeVisible (false)] [ToolboxItem (false)] - [ProvideProperty ("Location", typeof(IComponent))] - public class ComponentTray : ScrollableControl, IExtenderProvider, ISelectionUIHandler, IOleDragClient + [ProvideProperty ("Location", typeof (IComponent))] + public class ComponentTray : ScrollableControl, IExtenderProvider { - #region Public Instance Constructors - - [MonoTODO] - public ComponentTray (IDesigner mainDesigner, IServiceProvider serviceProvider) - { - throw new NotImplementedException (); - } - - #endregion Public Instance Constructors - - #region Static Constructor - - [MonoTODO] - static ComponentTray () - { - } - - #endregion Static Constructor - - #region Public Instance Properties - - [MonoTODO] - public bool AutoArrange - { - get - { - throw new NotImplementedException (); - } - set - { - throw new NotImplementedException (); - } - } - [MonoTODO] - public int ComponentCount - { - get - { - throw new NotImplementedException (); - } - } + private IServiceProvider _serviceProvider; + private IDesigner _mainDesigner = null; + private bool _showLargeIcons = false; + private bool _autoArrange = false; - [MonoTODO] - public bool ShowLargeIcons + public ComponentTray (IDesigner mainDesigner, IServiceProvider serviceProvider) { - get - { - throw new NotImplementedException (); + if (mainDesigner == null) { + throw new ArgumentNullException ("mainDesigner"); } - set - { - throw new NotImplementedException (); + if (serviceProvider == null) { + throw new ArgumentNullException ("serviceProvider"); } - } - - #endregion Public Instance Properties - - #region Override implementation of ScrollableControl - - [MonoTODO] - protected override void Dispose (bool disposing) - { - throw new NotImplementedException (); - } - - [MonoTODO] - protected override object GetService (Type serviceType) - { - throw new NotImplementedException (); - } - - [MonoTODO] - protected override void WndProc (ref Message m) - { - throw new NotImplementedException (); - } - - [MonoTODO] - protected override void OnDoubleClick (EventArgs e) - { - throw new NotImplementedException (); - } - - [MonoTODO] - protected override void OnDragDrop (DragEventArgs de) - { - throw new NotImplementedException (); - } - - [MonoTODO] - protected override void OnDragEnter (DragEventArgs de) - { - throw new NotImplementedException (); - } - [MonoTODO] - protected override void OnDragLeave (EventArgs e) - { - throw new NotImplementedException (); - } - - [MonoTODO] - protected override void OnDragOver (DragEventArgs de) - { - throw new NotImplementedException (); - } - - [MonoTODO] - protected override void OnGiveFeedback (GiveFeedbackEventArgs gfevent) - { - throw new NotImplementedException (); - } - - [MonoTODO] - protected override void OnLayout (LayoutEventArgs levent) - { - throw new NotImplementedException (); - } - - [MonoTODO] - protected override void OnMouseDown (MouseEventArgs e) - { - throw new NotImplementedException (); + _mainDesigner = mainDesigner; + _serviceProvider = serviceProvider; } - [MonoTODO] - protected override void OnMouseMove (MouseEventArgs e) - { - throw new NotImplementedException (); + public bool AutoArrange { + get { return _autoArrange; } + set { _autoArrange = value; } } - [MonoTODO] - protected override void OnMouseUp (MouseEventArgs e) - { - throw new NotImplementedException (); + public int ComponentCount { + get { return 0; } } - [MonoTODO] - protected override void OnPaint (PaintEventArgs pe) - { - throw new NotImplementedException (); + public bool ShowLargeIcons { + get { return _showLargeIcons; } + set { _showLargeIcons = value; } } - #endregion Override implementation of ScrollableControl - #region Implementation of IExtenderProvider - - [MonoTODO] - bool IExtenderProvider.CanExtend (object component) + public virtual void AddComponent (IComponent component) { - throw new NotImplementedException (); } - #endregion Implementation of IExtenderProvider - - #region Implementation of IOleDragClient - - [MonoTODO] - bool IOleDragClient.AddComponent (IComponent component, string name, bool firstAdd) + protected virtual bool CanCreateComponentFromTool (ToolboxItem tool) { - throw new NotImplementedException (); + return true; } - [MonoTODO] - bool IOleDragClient.CanModifyComponents + protected virtual bool CanDisplayComponent (IComponent component) { - get - { - throw new NotImplementedException (); - } + return false; } - [MonoTODO] - IComponent IOleDragClient.Component + public void CreateComponentFromTool (ToolboxItem tool) { - get - { - throw new NotImplementedException (); - } } - [MonoTODO] - Control IOleDragClient.GetControlForComponent (object component) + protected void DisplayError (Exception e) { - throw new NotImplementedException (); } - [MonoTODO] - Control IOleDragClient.GetDesignerControl () + protected override void Dispose (bool disposing) { - throw new NotImplementedException (); } - [MonoTODO] - bool IOleDragClient.IsDropOk (IComponent component) + public Point GetLocation (IComponent receiver) { - throw new NotImplementedException (); + return new Point (0,0); } - #endregion Implementation of IOleDragClient - - #region Implementation of ISelectionUIHandler - - [MonoTODO] - bool ISelectionUIHandler.BeginDrag (object[] components, SelectionRules rules, int initialX, int initialY) + public void SetLocation (IComponent receiver, Point location) { - throw new NotImplementedException (); } - [MonoTODO] - void ISelectionUIHandler.DragMoved (object[] components, Rectangle offset) + protected override void OnDoubleClick (EventArgs e) { - throw new NotImplementedException (); } - [MonoTODO] - void ISelectionUIHandler.EndDrag (object[] components, bool cancel) + protected override void OnDragDrop (DragEventArgs de) { - throw new NotImplementedException (); } - [MonoTODO] - Rectangle ISelectionUIHandler.GetComponentBounds (object component) + protected override void OnDragEnter (DragEventArgs de) { - throw new NotImplementedException (); } - [MonoTODO] - SelectionRules ISelectionUIHandler.GetComponentRules (object component) + protected override void OnDragLeave (EventArgs e) { - throw new NotImplementedException (); } - [MonoTODO] - Rectangle ISelectionUIHandler.GetSelectionClipRect (object component) + protected override void OnDragOver (DragEventArgs de) { - throw new NotImplementedException (); } - [MonoTODO] - void ISelectionUIHandler.OleDragDrop (DragEventArgs de) + protected override void OnGiveFeedback (GiveFeedbackEventArgs gfevent) { - throw new NotImplementedException (); } - [MonoTODO] - void ISelectionUIHandler.OleDragEnter (DragEventArgs de) + protected override void OnLayout (LayoutEventArgs levent) { - throw new NotImplementedException (); } - [MonoTODO] - void ISelectionUIHandler.OleDragLeave () + protected virtual void OnLostCapture () { - throw new NotImplementedException (); } - [MonoTODO] - void ISelectionUIHandler.OleDragOver (DragEventArgs de) + protected override void OnMouseDown (MouseEventArgs e) { - throw new NotImplementedException (); } - [MonoTODO] - void ISelectionUIHandler.OnSelectionDoubleClick (IComponent component) + protected override void OnMouseMove (MouseEventArgs e) { - throw new NotImplementedException (); } - [MonoTODO] - bool ISelectionUIHandler.QueryBeginDrag (object[] components, SelectionRules rules, int initialX, int initialY) + protected override void OnMouseUp (MouseEventArgs e) { - throw new NotImplementedException (); } - [MonoTODO] - void ISelectionUIHandler.ShowContextMenu (IComponent component) + protected override void OnPaint (PaintEventArgs pe) { - throw new NotImplementedException (); } - #endregion Implementation of ISelectionUIHandler - - - #region Public Instance Methods - - [MonoTODO] - public virtual void AddComponent (IComponent component) + protected virtual void OnSetCursor () { - throw new NotImplementedException (); } - [MonoTODO] public virtual void RemoveComponent (IComponent component) { - throw new NotImplementedException (); - } - - [MonoTODO] - public void CreateComponentFromTool (ToolboxItem tool) - { - throw new NotImplementedException (); - } - - [MonoTODO] - [DesignOnly (true)] - [Category ("Layout")] - [Localizable (false)] - [Browsable (false)] - public Point GetLocation (IComponent receiver) - { - throw new NotImplementedException (); - } - - [MonoTODO] - public void SetLocation (IComponent receiver, Point location) - { - throw new NotImplementedException (); } - #endregion Public Instance Methods - - #region Protected Instance Methods - - [MonoTODO] - protected virtual bool CanCreateComponentFromTool (ToolboxItem tool) - { - throw new NotImplementedException (); - } - - [MonoTODO] - protected virtual bool CanDisplayComponent (IComponent component) - { - throw new NotImplementedException (); - } - - [MonoTODO] - protected void DisplayError (Exception e) + protected override void WndProc (ref Message m) { - throw new NotImplementedException (); + base.WndProc (ref m); } - [MonoTODO] - protected virtual void OnSetCursor () + bool IExtenderProvider.CanExtend (object component) { - throw new NotImplementedException (); + return false; } - [MonoTODO] - protected virtual void OnLostCapture () + protected override object GetService (Type service) { - throw new NotImplementedException (); + if (_serviceProvider != null) { + return _serviceProvider.GetService (service); + } + return null; } - #endregion Protected Instance Methods } } diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/ControlDataObject.cs b/mcs/class/System.Design/System.Windows.Forms.Design/ControlDataObject.cs new file mode 100644 index 00000000000..df7a7d5b2c6 --- /dev/null +++ b/mcs/class/System.Design/System.Windows.Forms.Design/ControlDataObject.cs @@ -0,0 +1,120 @@ +using System; +using System.Windows.Forms; + +namespace System.Windows.Forms.Design +{ + // A IDataObject that supports Control and Control[] format + // + public class ControlDataObject : IDataObject + { + private object _data = null; + private string _format = null; + + public ControlDataObject () + { + _data = null; + _format = null; + } + + public ControlDataObject (Control control) + { + SetData (control); + } + + public ControlDataObject (Control[] controls) + { + SetData (controls); + } + + public object GetData (Type format) + { + return this.GetData (format.ToString ()); + } + + public object GetData (string format) + { + return this.GetData (format, true); + } + + public object GetData (string format, bool autoConvert) + { + if (format == _format) { + return _data; + } + return null; + } + + public bool GetDataPresent (Type format) + { + return this.GetDataPresent (format.ToString()); + } + + public bool GetDataPresent (string format) + { + return this.GetDataPresent (format, true); + } + + public bool GetDataPresent (string format, bool autoConvert) + { + if (format == _format) { + return true; + } + return false; + } + + public string[] GetFormats () + { + return this.GetFormats (true); + } + + public string[] GetFormats (bool autoConvert) + { + string[] formats = new string[2]; + formats[0] = typeof (Control).ToString (); + formats[1] = typeof (Control[]).ToString (); + return formats; + } + + public void SetData (object data) + { + if (data is Control) + this.SetData (typeof (Control), data); + else if (data is Control[]) + this.SetData (typeof (Control[]), data); + } + + public void SetData (Type format, object data) + { + this.SetData (format.ToString (), data); + } + + public void SetData (string format, object data) + { + this.SetData (format, true, data); + } + + public void SetData (string format, bool autoConvert, object data) + { + if (ValidateFormat (format)) { + _data = data; + _format = format; + } + } + + private bool ValidateFormat (string format) + { + bool valid = false; + + string[] formats = GetFormats (); + foreach (string f in formats) { + if (f == format) { + valid = true; + break; + } + } + + return valid; + } + } +} + diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/ControlDesigner.cs b/mcs/class/System.Design/System.Windows.Forms.Design/ControlDesigner.cs index a851e7bd229..ca4b61923be 100644 --- a/mcs/class/System.Design/System.Windows.Forms.Design/ControlDesigner.cs +++ b/mcs/class/System.Design/System.Windows.Forms.Design/ControlDesigner.cs @@ -1,13 +1,10 @@ // -// System.Windows.Forms.Design.ComponentEditorForm.cs +// System.Windows.Forms.Design.ControlDesigner // // Authors: -// Dennis Hayes (dennish@raytek.com) -// Miguel de Icaza (miguel@novell.com) -// -// (C) 2002 Ximian, Inc. http://www.ximian.com -// Copyright (c) 2006 Novell, Inc. +// Ivan N. Zlatev (contact i-nZ.net) // +// (C) 2006-2007 Ivan N. Zlatev // // Permission is hereby granted, free of charge, to any person obtaining @@ -17,10 +14,10 @@ // 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 @@ -30,357 +27,877 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // + using System; -using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; +using System.Windows.Forms; using System.Drawing; -using System.Runtime.InteropServices; +using System.Drawing.Design; +using System.Collections; + -namespace System.Windows.Forms.Design { - public class ControlDesigner : ComponentDesigner +namespace System.Windows.Forms.Design +{ + public class ControlDesigner : ComponentDesigner, IMessageReceiver { - #region Public Instance Constructors + - public ControlDesigner () : base () + private WndProcRouter _messageRouter; + private bool _locked = false; + private bool _mouseDown = false; + private bool _mouseDownFirstMove = false; + private bool _firstMouseMoveInClient = true; + + public ControlDesigner () { } - #endregion Public Instance Constructors +#region Initialization + public override void Initialize (IComponent component) + { + base.Initialize (component); + + if (!(component is Control)) + throw new ArgumentException ("Component is not a Control."); + + _messageRouter = new WndProcRouter ((Control) component, (IMessageReceiver) this); + ((Control)component).WindowTarget = _messageRouter; + + // DT properties + // + this.Visible = true; + this.Enabled = true; + this.Locked = false; + this.AllowDrop = false; + // + // The control properties + // + Control.Enabled = true; + Control.Visible = true; + Control.AllowDrop = false; + + this.Control.DragDrop += new DragEventHandler (OnDragDrop); + this.Control.DragEnter += new DragEventHandler (OnDragEnter); + this.Control.DragLeave += new EventHandler (OnDragLeave); + this.Control.DragOver += new DragEventHandler (OnDragOver); + + // XXX: The control already has a handle? + // + if (Control.IsHandleCreated) { + OnCreateHandle (); + } - #region Static Constructor + } + + public override void InitializeNonDefault () + { + base.InitializeNonDefault (); + } - static ControlDesigner () + // The default implementation of this method sets the component's Text property to + // its name (Component.Site.Name), if the property field is of type string. + // + public override void OnSetComponentDefaults () { - ControlDesigner.InvalidPoint = new Point (int.MinValue, int.MinValue); + if (this.Component != null && this.Component.Site != null) { + PropertyDescriptor propertyDescriptor = TypeDescriptor.GetProperties (this.Component)["Text"]; + if (propertyDescriptor != null && !propertyDescriptor.IsReadOnly && + propertyDescriptor.PropertyType == typeof (string)) { + propertyDescriptor.SetValue (Component, Component.Site.Name); + } + } } +#endregion - #endregion Static Constructor - #region Public Instance Methods +#region Properties and Fields - AccessabilityObject Left + protected static readonly Point InvalidPoint = new Point (int.MinValue, int.MinValue); - [MonoTODO] - public virtual bool CanBeParentedTo (IDesigner parentDesigner) - { - throw new NotImplementedException (); + public virtual Control Control { + get { return (Control) base.Component; } } - [MonoTODO] - public override void OnSetComponentDefaults () - { - throw new NotImplementedException (); + protected virtual bool EnableDragRect { + get { return true; } + } + + public virtual SelectionRules SelectionRules { + get { + if (this.Control == null) + return SelectionRules.None; + + // all controls on the surface are visible + // + SelectionRules selectionRules = SelectionRules.Visible; + + if ((bool)GetValue (this.Component, "Locked") == true) { + selectionRules |= SelectionRules.Locked; + } + else { + DockStyle dockStyle = (DockStyle) this.GetValue (base.Component, "Dock", typeof (DockStyle)); + + switch (dockStyle) { + case DockStyle.Top: + selectionRules |= SelectionRules.BottomSizeable; + break; + case DockStyle.Left: + selectionRules |= SelectionRules.RightSizeable; + break; + case DockStyle.Right: + selectionRules |= SelectionRules.LeftSizeable; + break; + case DockStyle.Bottom: + selectionRules |= SelectionRules.TopSizeable; + break; + case DockStyle.Fill: + break; + default: + selectionRules |= SelectionRules.Moveable; + selectionRules |= SelectionRules.AllSizeable; + break; + } + } + + return selectionRules; + } + } + + public override ICollection AssociatedComponents { + get { + ArrayList components = new ArrayList (); + foreach (Control c in this.Control.Controls) + if (c.Site != null) + components.Add (c); + return components; + } + } + +#if NET_2_0 + protected override IComponent ParentComponent { + get { return this.GetValue (this.Control, "Parent") as Control;} + } +#endif + // TODO: implement ControlDesigner.ControlAccessabilityObject + // + public virtual AccessibleObject AccessibilityObject { + get { + if (accessibilityObj == null) + accessibilityObj = new AccessibleObject (); + + return accessibilityObj; + } } + protected AccessibleObject accessibilityObj; - #endregion Public Instance Methods +#endregion - #region Protected Instance Methods - [MonoTODO] +#region WndProc + + protected void DefWndProc (ref Message m) + { + _messageRouter.ToControl (ref m); + } + protected void BaseWndProc (ref Message m) { - throw new NotImplementedException (); + _messageRouter.ToSystem (ref m); + } + + void IMessageReceiver.WndProc (ref Message m) + { + this.WndProc (ref m); } + + // Keep in mind that messages are recieved for the child controls if routed + // + protected virtual void WndProc (ref Message m) + { + // Filter out kb input + // + if ((Native.Msg) m.Msg >= Native.Msg.WM_KEYFIRST && (Native.Msg) m.Msg <= Native.Msg.WM_KEYLAST) + return; + + // Mouse messages should be routed the control, if GetHitTest (virtual) returns true. + // + if (IsMouseMessage ((Native.Msg) m.Msg) && + this.GetHitTest (new Point (Native.LoWord((int) m.LParam), Native.HiWord (((int) m.LParam))))) { + + this.DefWndProc (ref m); + return; + } - [MonoTODO] - protected void DefWndProc (ref Message m) + switch ((Native.Msg) m.Msg) { + case Native.Msg.WM_CREATE: + this.DefWndProc (ref m); + if (m.HWnd == this.Control.Handle) + OnCreateHandle (); + break; + + case Native.Msg.WM_CONTEXTMENU: + OnContextMenu (Native.LoWord ((int) m.LParam), Native.HiWord ((int) m.LParam)); + break; + + case Native.Msg.WM_SETCURSOR: + if (this.GetHitTest (new Point (Native.LoWord ((int) m.LParam), Native.HiWord ((int) m.LParam)))) + this.DefWndProc (ref m); + else + OnSetCursor (); + break; + + case Native.Msg.WM_SETFOCUS: + this.DefWndProc (ref m); + break; + + case Native.Msg.WM_PAINT: + // Wait for control's WM_PAINT to complete first. + // + this.DefWndProc (ref m); + + Graphics gfx = Graphics.FromHwnd (m.HWnd); + PaintEventArgs args = new PaintEventArgs (gfx, this.Control.Bounds); + OnPaintAdornments (args); + gfx.Dispose (); + args.Dispose (); + break; + + case Native.Msg.WM_NCRBUTTONDOWN: + case Native.Msg.WM_NCMBUTTONDOWN: + case Native.Msg.WM_NCLBUTTONDBLCLK: + case Native.Msg.WM_NCRBUTTONDBLCLK: + break; + + case Native.Msg.WM_LBUTTONDBLCLK: + case Native.Msg.WM_RBUTTONDBLCLK: + case Native.Msg.WM_MBUTTONDBLCLK: + if ((Native.Msg)m.Msg == Native.Msg.WM_LBUTTONDBLCLK) + _mouseButtonDown = MouseButtons.Left; + else if ((Native.Msg)m.Msg == Native.Msg.WM_RBUTTONDBLCLK) + _mouseButtonDown = MouseButtons.Right; + else if ((Native.Msg)m.Msg == Native.Msg.WM_MBUTTONDBLCLK) + _mouseButtonDown = MouseButtons.Middle; + OnMouseDoubleClick (); + this.BaseWndProc (ref m); + break; + + case Native.Msg.WM_MOUSEHOVER: + OnMouseHover (); + break; + + case Native.Msg.WM_LBUTTONDOWN: + case Native.Msg.WM_RBUTTONDOWN: + case Native.Msg.WM_MBUTTONDOWN: + if ((Native.Msg)m.Msg == Native.Msg.WM_LBUTTONDOWN) + _mouseButtonDown = MouseButtons.Left; + else if ((Native.Msg)m.Msg == Native.Msg.WM_RBUTTONDOWN) + _mouseButtonDown = MouseButtons.Right; + else if ((Native.Msg)m.Msg == Native.Msg.WM_MBUTTONDOWN) + _mouseButtonDown = MouseButtons.Middle; + + if (_firstMouseMoveInClient) { + OnMouseEnter (); + _firstMouseMoveInClient = false; + } + this.OnMouseDown (Native.LoWord ((int)m.LParam), Native.HiWord ((int)m.LParam)); + this.BaseWndProc (ref m); + break; + + case Native.Msg.WM_MOUSELEAVE: + _firstMouseMoveInClient = false; + OnMouseLeave (); + this.BaseWndProc (ref m); + break; + + // The WM_CANCELMODE message is sent to cancel certain modes, such as mouse capture. + // For example, the system sends this message to the active window when a dialog box + // or message box is displayed. Certain functions also send this message explicitly to + // the specified window regardless of whether it is the active window. For example, + // the EnableWindow function sends this message when disabling the specified window. + // + case Native.Msg.WM_CANCELMODE: + OnMouseDragEnd (true); + this.DefWndProc (ref m); + break; + + case Native.Msg.WM_LBUTTONUP: + case Native.Msg.WM_RBUTTONUP: + case Native.Msg.WM_NCLBUTTONUP: + case Native.Msg.WM_NCRBUTTONUP: + case Native.Msg.WM_MBUTTONUP: + case Native.Msg.WM_NCMBUTTONUP: + this.OnMouseUp (); + this.BaseWndProc (ref m); + break; + + // MWF Specific msg! - must reach control + // + case Native.Msg.WM_MOUSE_ENTER: + _firstMouseMoveInClient = false; // just so that nothing will get fired in WM_MOUSEMOVE + OnMouseEnter (); + this.DefWndProc (ref m); + break; + + case Native.Msg.WM_MOUSEMOVE: + // If selection is in progress pass the mouse move msg to the primary selection. + // If resizing is in progress pass to the parent of the primary selection (remmember that the selection + // frame is not a control and is drawn in the parent of the primary selection). + // + // Required in order for those 2 operations to continue when the mouse is moving over a control covering + // the one where the action takes place. + // + IUISelectionService uiSelectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService; + ISelectionService selectionServ = this.GetService (typeof (ISelectionService)) as ISelectionService; + IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost; + + + if (uiSelectionServ != null && selectionServ != null && host != null) { + Control primarySelection = selectionServ.PrimarySelection as Control; + Point location = new Point (Native.LoWord ((int)m.LParam), Native.HiWord ((int)m.LParam)); + + if (uiSelectionServ.SelectionInProgress && + this.Component != host.RootComponent && + this.Component != selectionServ.PrimarySelection) { + + location = primarySelection.PointToClient (this.Control.PointToScreen (location)); + Native.SendMessage (primarySelection.Handle, (Native.Msg)m.Msg, m.WParam, Native.LParam (location.X, location.Y)); + } + else if (uiSelectionServ.ResizeInProgress && + // this.Component != host.RootComponent && + this.Control.Parent == ((Control)selectionServ.PrimarySelection).Parent) { + + location = this.Control.Parent.PointToClient (this.Control.PointToScreen (location)); + Native.SendMessage (this.Control.Parent.Handle, (Native.Msg)m.Msg, m.WParam, Native.LParam (location.X, location.Y)); + } + else { + this.OnMouseMove (location.X, location.Y); + } + } + else { + this.OnMouseMove (Native.LoWord ((int)m.LParam), Native.HiWord ((int)m.LParam)); + } + this.BaseWndProc (ref m); + break; + + default: + // Pass everything else to the control and return + // + this.DefWndProc (ref m); + break; + } + } + + // Indicates whether a mouse click at the specified point should be handled by the control. + // + protected virtual bool GetHitTest (Point point) { - throw new NotImplementedException (); + return false; } - [MonoTODO] - protected void DisplayError (Exception e) + private bool IsMouseMessage (Native.Msg msg) { - throw new NotImplementedException (); + if (msg >= Native.Msg.WM_MOUSEFIRST && msg <= Native.Msg.WM_MOUSELAST) + return true; + else if (msg >= Native.Msg.WM_NCLBUTTONDOWN && msg <= Native.Msg.WM_NCMBUTTONDBLCLK) + return true; + else if (msg == Native.Msg.WM_MOUSEHOVER || msg == Native.Msg.WM_MOUSELEAVE) + return true; + else + return false; } +#endregion + - [MonoTODO] - protected void EnableDragDrop (bool value) +#region WndProc Message Handlers + + protected virtual void OnSetCursor () { - throw new NotImplementedException (); } - [MonoTODO] - protected virtual bool GetHitTest (Point point) + // Raises the DoDefaultAction. + // + private void OnMouseDoubleClick () { - throw new NotImplementedException (); + try { + base.DoDefaultAction (); + } + catch (Exception e) { + this.DisplayError (e); + } } - [MonoTODO] - protected void HookChildControls (Control firstChild) + internal virtual void OnMouseDown (int x, int y) { - throw new NotImplementedException (); + _mouseDown = true; + _mouseDownFirstMove = true; + IUISelectionService uiSelection = this.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (uiSelection != null && uiSelection.AdornmentsHitTest (this.Control, x, y)) { + // 1) prevent primary selection from being changed at this point. + // 2) delegate behaviour in the future to the IUISelectionService + } + else { + ISelectionService selectionService = this.GetService (typeof (ISelectionService)) as ISelectionService; + if (selectionService != null) { + selectionService.SetSelectedComponents (new IComponent[] { this.Component }); + } + } } - [MonoTODO] - protected virtual void OnContextMenu (int x, int y) + // Note that this is a pure WM_MOUSEMOVE acceptor + // + internal virtual void OnMouseMove (int x, int y) + { + // Fire the OnMouseEnter if this is the first mousemove in + // the client area. (I have to, because there is no WM_MOUSEENTER msg) + // + if (_mouseDown) { + if (_mouseDownFirstMove) { + OnMouseDragBegin (x, y); + _mouseDownFirstMove = false; + } + else { + OnMouseDragMove (x, y); + } + } + + } + + internal virtual void OnMouseUp () { - throw new NotImplementedException (); + IUISelectionService uiSelection = this.GetService (typeof (IUISelectionService)) as IUISelectionService; + + if (_mouseDown) { + if (uiSelection != null && (uiSelection.SelectionInProgress || uiSelection.ResizeInProgress)) { + uiSelection.MouseDragEnd (false); + } + this.OnMouseDragEnd (false); + _mouseDown = false; + } + else { + if (uiSelection != null && (uiSelection.SelectionInProgress || uiSelection.ResizeInProgress)) { + // If the mouse up happens over the a control which is not defacto participating in + // the selection or resizing in progress, then inform the IUISelectionService of that event + // + uiSelection.MouseDragEnd (false); + } + } } - [MonoTODO] - protected virtual void OnCreateHandle () + protected virtual void OnContextMenu (int x, int y) { - throw new NotImplementedException (); + IMenuCommandService service = this.GetService (typeof(IMenuCommandService)) as IMenuCommandService; + if (service != null) { + service.ShowContextMenu (MenuCommands.SelectionMenu, x, y); + } } - [MonoTODO] - protected virtual void OnDragDrop (DragEventArgs de) + protected virtual void OnMouseEnter () { - throw new NotImplementedException (); } - [MonoTODO] - protected virtual void OnDragEnter (DragEventArgs de) + protected virtual void OnMouseHover () { - throw new NotImplementedException (); } - [MonoTODO] - protected virtual void OnDragLeave (EventArgs e) + protected virtual void OnMouseLeave () { - throw new NotImplementedException (); } - [MonoTODO] - protected virtual void OnDragOver (DragEventArgs de) + // Provides an opportunity to perform additional processing immediately + // after the control handle has been created. + // + protected virtual void OnCreateHandle () { - throw new NotImplementedException (); } - [MonoTODO] - protected virtual void OnGiveFeedback (GiveFeedbackEventArgs e) + // Called after the control is done with the painting so that the designer host + // can paint stuff over it. + // + protected virtual void OnPaintAdornments (PaintEventArgs pe) { - throw new NotImplementedException (); + } +#endregion + + +#region Mouse Dragging + + MouseButtons _mouseButtonDown; + + internal MouseButtons MouseButtonDown { + get { return _mouseButtonDown; } } - [MonoTODO] protected virtual void OnMouseDragBegin (int x, int y) { - throw new NotImplementedException (); + IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (selectionServ != null && ((this.SelectionRules & SelectionRules.Moveable) == SelectionRules.Moveable)) { + // once this is fired the parent control (parentcontroldesigner) will start getting dragover events. + // + selectionServ.DragBegin (); + } } - [MonoTODO] + protected virtual void OnMouseDragMove (int x, int y) + { + } + protected virtual void OnMouseDragEnd (bool cancel) { - throw new NotImplementedException (); } +#endregion - [MonoTODO] - protected virtual void OnMouseDragMove (int x, int y) + +#region Parenting + protected void HookChildControls (Control firstControl) { - throw new NotImplementedException (); + if (firstControl != null) { + foreach (Control control in firstControl.Controls) { + control.WindowTarget = (IWindowTarget) new WndProcRouter (control, (IMessageReceiver) this); + } + } } - [MonoTODO] - protected virtual void OnMouseEnter () + protected void UnHookChildControls (Control firstControl) { - throw new NotImplementedException (); + if (firstControl != null) { + foreach (Control control in firstControl.Controls) { + if (control.WindowTarget is WndProcRouter) + ((WndProcRouter) control.WindowTarget).Dispose (); + } + } } - [MonoTODO] - protected virtual void OnMouseHover () + // Someone please tell me why the hell is this method here? + // What about having ParentControlDesigner.CanParent(...) ? + // + public virtual bool CanBeParentedTo (IDesigner parentDesigner) { - throw new NotImplementedException (); + IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost; + + if (parentDesigner is ParentControlDesigner && + this.Component != host.RootComponent && + !this.Control.Controls.Contains (((ParentControlDesigner)parentDesigner).Control)) { + return true; + } else { + return false; + } } +#endregion - [MonoTODO] - protected virtual void OnMouseLeave () + protected void DisplayError (Exception e) { - throw new NotImplementedException (); + if (e != null) { + IUIService uiService = GetService (typeof (IUIService)) as IUIService; + if (uiService != null) { + uiService.ShowError (e); + } + else { + string errorText = e.Message; + if (errorText == null || errorText == String.Empty) + errorText = e.ToString (); + MessageBox.Show (Control, errorText, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } } - [MonoTODO] - protected virtual void OnPaintAdornments (PaintEventArgs pe) - { - throw new NotImplementedException (); +#region Drag and Drop handling + + // Enables or disables Drag and Drop + // + protected void EnableDragDrop(bool value) + { + if (this.Control != null) { + if (value) { + Control.DragDrop += new DragEventHandler (OnDragDrop); + Control.DragOver += new DragEventHandler (OnDragOver); + Control.DragEnter += new DragEventHandler (OnDragEnter); + Control.DragLeave += new EventHandler (OnDragLeave); + Control.GiveFeedback += new GiveFeedbackEventHandler (OnGiveFeedback); + Control.AllowDrop = true; + } + else { + Control.DragDrop -= new DragEventHandler (OnDragDrop); + Control.DragOver -= new DragEventHandler (OnDragOver); + Control.DragEnter -= new DragEventHandler (OnDragEnter); + Control.DragLeave -= new EventHandler (OnDragLeave); + Control.GiveFeedback -= new GiveFeedbackEventHandler (OnGiveFeedback); + Control.AllowDrop = false; + } + } } - [MonoTODO] - protected virtual void OnSetCursor () + private void OnGiveFeedback (object sender, GiveFeedbackEventArgs e) { - throw new NotImplementedException (); + OnGiveFeedback (e); } - [MonoTODO] - protected void UnhookChildControls (Control firstChild) + private void OnDragDrop (object sender, DragEventArgs e) { - throw new NotImplementedException (); + OnDragDrop (e); } - [MonoTODO] - protected virtual void WndProc (ref Message m) + private void OnDragEnter (object sender, DragEventArgs e) { - throw new NotImplementedException (); + OnDragEnter (e); } - #endregion Protected Instance Methods - - #region Override implementation of ComponentDesigner + private void OnDragLeave (object sender, EventArgs e) + { + OnDragLeave (e); + } - [MonoTODO] - protected override void Dispose (bool disposing) + private void OnDragOver (object sender, DragEventArgs e) { - throw new NotImplementedException (); + OnDragOver (e); } - public override void Initialize (IComponent component) + protected virtual void OnGiveFeedback (GiveFeedbackEventArgs e) { - if (component == null) - throw new ArgumentNullException ("component"); + e.UseDefaultCursors = false; + } - designed_control = component as Control; - - if (designed_control == null) - throw new ArgumentException ("component", "Must derive from Control class"); + protected virtual void OnDragDrop (DragEventArgs e) + { } - [MonoTODO] - public override void InitializeNonDefault () + protected virtual void OnDragEnter (DragEventArgs e) { - throw new NotImplementedException (); } - [MonoTODO] - protected override void PreFilterProperties (IDictionary properties) + protected virtual void OnDragLeave (EventArgs e) { - throw new NotImplementedException (); } - [MonoTODO] - public override ICollection AssociatedComponents { - get { throw new NotImplementedException (); } + protected virtual void OnDragOver (DragEventArgs e) + { } +#endregion - #endregion Override implementation of ComponentDesigner - #region Public Instance Properties +#region Redirected Properties - [MonoTODO] - public virtual AccessibleObject AccessibilityObject { - get { - if (accessibilityObj == null) - accessibilityObj = new ControlDesignerAccessibleObject (this, Control); + // This IDesignerFilter interface method override adds a set of properties + // to this designer's component at design time. This method adds the following + // browsable properties: "Visible", "Enabled", "ContextMenu", "AllowDrop", "Location", + // "Name", "Controls", and "Locked". + // + // XXX: We aren't redirecting Controls + // + protected override void PreFilterProperties (IDictionary properties) + { + base.PreFilterProperties (properties); - return accessibilityObj; + string[] newProperties = { + "Visible", "Enabled", "ContextMenu", "AllowDrop", "Location", "Name", + }; + + Attribute[][] attributes = { + new Attribute[] { new DefaultValueAttribute (true) }, + new Attribute[] { new DefaultValueAttribute (true) }, + new Attribute[] { new DefaultValueAttribute (null) }, + new Attribute[] { new DefaultValueAttribute (false) }, + new Attribute[] { new DefaultValueAttribute (typeof (Point), "0, 0") }, + new Attribute[] {} + }; + + PropertyDescriptor propertyDescriptor = null; + + // If existing redirect each property to the ControlDesigner. + // + for (int i=0; i < newProperties.Length; i++) { + propertyDescriptor = properties[newProperties[i]] as PropertyDescriptor; + if (propertyDescriptor != null) + properties[newProperties[i]] = TypeDescriptor.CreateProperty (typeof (ControlDesigner), + propertyDescriptor, + attributes[i]); } - } - [MonoTODO] - public virtual SelectionRules SelectionRules { - get { throw new NotImplementedException (); } + // This one is a must to have. + // + properties["Locked"] = TypeDescriptor.CreateProperty (typeof (ControlDesigner), "Locked", + typeof(bool), + new Attribute[] { + DesignOnlyAttribute.Yes, + BrowsableAttribute.Yes, + CategoryAttribute.Design, + new DefaultValueAttribute (false), + new DescriptionAttribute("The Locked property determines if we can move or resize the control.") + }); + } - public virtual Control Control { - get { return designed_control; } + // ShadowProperties returns the real property value if there is no "shadow" one set + // Welcome to the land of shadows... :-) + // + private bool Visible { + get { return (bool) base.ShadowProperties["Visible"]; } + set { base.ShadowProperties["Visible"] = value; } } - #endregion Public Instance Properties + private bool Enabled { + get { return (bool) base.ShadowProperties["Enabled"]; } + set { base.ShadowProperties["Enabled"] = value; } + } - #region Protected Instance Properties + private bool Locked { + get { return _locked; } + set { _locked = value; } + } - [MonoTODO] - protected virtual bool EnableDragRect { - get { throw new NotImplementedException (); } + private bool AllowDrop { + get { return (bool)base.ShadowProperties["AllowDrop"]; } + set { base.ShadowProperties["AllowDrop"] = value; } } - #endregion Protected Instance Properties + private string Name { + get { return base.Component.Site.Name; } + set { + if (value != null) + base.Component.Site.Name = value; + } + } - #region Protected Static Fields + private ContextMenu ContextMenu { + get { return (ContextMenu) base.ShadowProperties["ContextMenu"]; } + set { base.ShadowProperties["ContextMenu"] = value; } + } - protected static readonly Point InvalidPoint; - protected AccessibleObject accessibilityObj; + private Point Location { + get { return this.Control.Location; } + set { this.Control.Location = value; } + } +#endregion - #endregion Protected Static Fields - #region Private Instance Fields +#region Utility methods + internal object GetValue (object component, string propertyName) + { + return this.GetValue (component, propertyName, null); + } + + internal object GetValue (object component, string propertyName, Type propertyType) + { + PropertyDescriptor prop = TypeDescriptor.GetProperties (component)[propertyName] as PropertyDescriptor; + if (prop == null) + throw new InvalidOperationException ("Property \"" + propertyName + "\" is missing on " + + component.GetType().AssemblyQualifiedName); + if (propertyType != null && !propertyType.IsAssignableFrom (prop.PropertyType)) + throw new InvalidOperationException ("Types do not match: " + prop.PropertyType.AssemblyQualifiedName + + " : " + propertyType.AssemblyQualifiedName); + return prop.GetValue (component); + } - Control designed_control; + public void SetValue (object component, string propertyName, object value) + { + PropertyDescriptor prop = TypeDescriptor.GetProperties (component)[propertyName] as PropertyDescriptor; - #endregion Private Instance Fields + if (prop == null) + throw new InvalidOperationException ("Property \"" + propertyName + "\" is missing on " + + component.GetType().AssemblyQualifiedName); + if (!prop.PropertyType.IsAssignableFrom (value.GetType ())) + throw new InvalidOperationException ("Types do not match: " + value.GetType ().AssemblyQualifiedName + + " : " + prop.PropertyType.AssemblyQualifiedName); + if (!prop.IsReadOnly) + prop.SetValue (component, value); + } +#endregion - [ComVisibleAttribute(true)] - public class ControlDesignerAccessibleObject : AccessibleObject + protected override void Dispose (bool disposing) { - [MonoTODO] - public ControlDesignerAccessibleObject (ControlDesigner designer, Control control) - { - throw new NotImplementedException (); + if (disposing) { + if (this.Control != null) { + UnHookChildControls (Control); + OnMouseDragEnd (true); + _messageRouter.Dispose (); + this.Control.DragDrop -= new DragEventHandler (OnDragDrop); + this.Control.DragEnter -= new DragEventHandler (OnDragEnter); + this.Control.DragLeave -= new EventHandler (OnDragLeave); + this.Control.DragOver -= new DragEventHandler (OnDragOver); + } } + base.Dispose (true); + } - #region Override implementation of AccessibleObject - [MonoTODO] - public override AccessibleObject GetChild (int index) - { - throw new NotImplementedException (); - } - [MonoTODO] - public override int GetChildCount () - { - throw new NotImplementedException (); - } +#if NET_2_0 + public virtual ControlDesigner InternalControlDesigner (int internalControlIndex) + { + return null; + } - [MonoTODO] - public override AccessibleObject GetFocused () - { - throw new NotImplementedException (); - } + public virtual int NumberOfInternalControlDesigners () + { + return 0; + } - [MonoTODO] - public override AccessibleObject GetSelected () - { - throw new NotImplementedException (); - } + protected bool EnableDesignMode (Control child, string name) + { + if (name == null) + throw new ArgumentNullException ("name"); + if (child == null) + throw new ArgumentNullException ("child"); - [MonoTODO] - public override AccessibleObject HitTest (int x, int y) - { - throw new NotImplementedException (); + bool success = false; + INestedContainer nestedContainer = this.GetService (typeof (INestedContainer)) as INestedContainer; + if (nestedContainer != null) { + nestedContainer.Add (child, name); + success = true; } + return success; + } - [MonoTODO] - public override Rectangle Bounds { - get { throw new NotImplementedException (); } - } +#region NET_2_0 Stubs - [MonoTODO] - public override string DefaultAction { - get { throw new NotImplementedException (); } - } + /* + protected virtual ControlBodyGlyph GetControlGlyph (GlyphSelectionType selectionType) + { + throw new NotImplementedException (); + } - [MonoTODO] - public override string Description { - get { throw new NotImplementedException (); } - } + public virtual GlyphCollection GetGlyphs (GlyphSelectionType selectionType) + { + throw new NotImplementedException (); + } + */ - [MonoTODO] - public override string Name { - get { throw new NotImplementedException (); } - } + public override void InitializeExistingComponent (IDictionary defaultValues) + { + throw new NotImplementedException (); + } - [MonoTODO] - public override AccessibleObject Parent { - get { throw new NotImplementedException (); } - } + public override void InitializeNewComponent (IDictionary defaultValues) + { + throw new NotImplementedException (); + } - [MonoTODO] - public override AccessibleRole Role { - get { throw new NotImplementedException (); } - } + protected virtual void OnDragComplete (DragEventArgs de) + { + throw new NotImplementedException (); + } - [MonoTODO] - public override AccessibleStates State { - get { throw new NotImplementedException (); } - } + public virtual IList SnapLines { + get { throw new NotImplementedException (); } + } - [MonoTODO] - public override string Value { - get { throw new NotImplementedException (); } - } + /* + protected BehaviorService BehaviorService { + get { throw new NotImplementedException (); } + } + */ - #endregion Override implementation of AccessibleObject + public virtual bool ParticipatesWithSnapLines { + get { throw new NotImplementedException (); } } + + public bool AutoResizeHandles { + get { throw new NotImplementedException (); } + set { throw new NotImplementedException (); } + } +#endregion +#endif + + } } diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/DocumentDesigner.cs b/mcs/class/System.Design/System.Windows.Forms.Design/DocumentDesigner.cs index 4be82fbfd2e..55ac06e4eb6 100644 --- a/mcs/class/System.Design/System.Windows.Forms.Design/DocumentDesigner.cs +++ b/mcs/class/System.Design/System.Windows.Forms.Design/DocumentDesigner.cs @@ -1,10 +1,10 @@ // -// System.Windows.Forms.Design.ComponentEditorForm.cs +// System.Windows.Forms.Design.DocumentDesigner // -// Author: -// Dennis Hayes (dennish@raytek.com) -// (C) 2002 Ximian, Inc. http://www.ximian.com +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) // +// (C) 2006-2007 Ivan N. Zlatev // // Permission is hereby granted, free of charge, to any person obtaining @@ -14,10 +14,10 @@ // 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 @@ -28,169 +28,565 @@ // using System; -using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; -using System.Diagnostics; +using System.Windows.Forms; +using System.Drawing; using System.Drawing.Design; +using System.Collections; + + namespace System.Windows.Forms.Design { - [ToolboxItemFilter("System.Windows.Forms")] - public class DocumentDesigner : ScrollableControlDesigner, IRootDesigner, IDesigner, IDisposable, IToolboxUser, IOleDragClient + + public class DocumentDesigner : ScrollableControlDesigner, IRootDesigner, IToolboxUser { - #region Public Instance Constructors - [MonoTODO] + // This is what you *see* + /* + .-------------------------------------. + | Panel to host the designed Control | + |--------------Splitter---------------| + | Panel with a ComponentTray | + |_____________________________________| + + */ + // +#region DesignerViewFrame + public class DesignerViewFrame : System.Windows.Forms.UserControl + { + private System.Windows.Forms.Panel DesignerPanel; + private System.Windows.Forms.Splitter splitter1; + private System.Windows.Forms.Panel ComponentTrayPanel; + private ComponentTray _componentTray; + private Control _designedControl; + + public DesignerViewFrame (Control designedControl, ComponentTray tray) + { + if (designedControl == null) { + throw new ArgumentNullException ("designedControl"); + } + if (tray == null) { + throw new ArgumentNullException ("tray"); + } + // + // The InitializeComponent() call is required for Windows Forms designer support. + // + InitializeComponent(); + + _designedControl = designedControl; + this.SuspendLayout (); + this.DesignerPanel.Controls.Add (designedControl); + this.ResumeLayout (); + + this.ComponentTray = tray; + } + +#region Windows Forms Designer generated code + /// <summary> + /// This method is required for Windows Forms designer support. + /// Do not change the method contents inside the source code editor. The Forms designer might + /// not be able to load this method if it was changed manually. + /// </summary> + private void InitializeComponent() { + this.ComponentTrayPanel = new System.Windows.Forms.Panel(); + this.splitter1 = new System.Windows.Forms.Splitter(); + this.DesignerPanel = new System.Windows.Forms.Panel(); + this.SuspendLayout(); + // + // ComponentTrayPanel + // + this.ComponentTrayPanel.BackColor = System.Drawing.Color.LemonChiffon; + this.ComponentTrayPanel.Dock = System.Windows.Forms.DockStyle.Bottom; + this.ComponentTrayPanel.Location = new System.Drawing.Point(0, 194); + this.ComponentTrayPanel.Name = "ComponentTrayPanel"; + this.ComponentTrayPanel.Size = new System.Drawing.Size(292, 72); + this.ComponentTrayPanel.TabIndex = 1; + this.ComponentTrayPanel.Visible = false; + // + // splitter1 + // + this.splitter1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.splitter1.Location = new System.Drawing.Point(0, 186); + this.splitter1.Name = "splitter1"; + this.splitter1.Size = new System.Drawing.Size(292, 8); + this.splitter1.TabIndex = 2; + this.splitter1.TabStop = false; + this.splitter1.Visible = false; + // + // DesignerPanel + // + this.DesignerPanel.AutoScroll = true; + this.DesignerPanel.BackColor = System.Drawing.Color.White; + this.DesignerPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.DesignerPanel.Location = new System.Drawing.Point(0, 0); + this.DesignerPanel.Name = "DesignerPanel"; + this.DesignerPanel.Size = new System.Drawing.Size(292, 266); + this.DesignerPanel.TabIndex = 0; + this.DesignerPanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.DesignerPanel_MouseUp); + this.DesignerPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.DesignerPanel_MouseMove); + this.DesignerPanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DesignerPanel_MouseDown); + this.DesignerPanel.Paint += new PaintEventHandler (DesignerPanel_Paint); + // + // DesignerViewFrame + // + this.Controls.Add(this.splitter1); + this.Controls.Add(this.ComponentTrayPanel); + this.Controls.Add(this.DesignerPanel); + this.Name = "UserControl1"; + this.Size = new System.Drawing.Size(292, 266); + this.Dock = DockStyle.Fill; + this.ResumeLayout(false); + } + +#endregion + + private bool _mouseDown = false; + private bool _firstMove = false; + + void DesignerPanel_Paint (object sender, PaintEventArgs e) + { + IUISelectionService selectionServ = this.DesignedControl.Site.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (selectionServ != null) + selectionServ.PaintAdornments (this.DesignerPanel, e.Graphics); + } + + void DesignerPanel_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) + { + _mouseDown = true; + _firstMove = true; + } + + void DesignerPanel_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) + { + IUISelectionService selectionServ = this.DesignedControl.Site.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (selectionServ == null) + return; + + selectionServ.SetCursor (e.X, e.Y); + if (_mouseDown) { + if (_firstMove) { + selectionServ.MouseDragBegin (this.DesignerPanel, e.X, e.Y); + _firstMove = false; + } + else { + selectionServ.MouseDragMove (e.X, e.Y); + } + } + else if (selectionServ.SelectionInProgress) { + selectionServ.MouseDragMove (e.X, e.Y); + } + } + + void DesignerPanel_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) + { + IUISelectionService selectionServ = this.DesignedControl.Site.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (_mouseDown) { + if (selectionServ != null) + selectionServ.MouseDragEnd (false); + _mouseDown = false; + } + else if (selectionServ.SelectionInProgress) { + selectionServ.MouseDragEnd (false); + } + } + + // by default the component tray is hidden and essentially should be shown once there + // is a component added to it + // + public void ShowComponentTray () + { + if (!this.ComponentTray.Visible) { + this.ComponentTrayPanel.Visible = true; + this.ComponentTray.Visible = true; + this.splitter1.Visible = true; + } + } + + public void HideComponentTray () + { + if (!this.ComponentTray.Visible) { + this.ComponentTrayPanel.Visible = true; + this.ComponentTray.Visible = true; + this.splitter1.Visible = true; + } + } + + public ComponentTray ComponentTray { + get { return _componentTray; } + set { + this.SuspendLayout (); + this.ComponentTrayPanel.Controls.Remove (_componentTray); + this.ComponentTrayPanel.Controls.Add (value); + this.ResumeLayout (); + _componentTray = value; + _componentTray.Visible = false; + } + } + + public Control DesignedControl { + get { return _designedControl; } + set { + } + } + + protected override void Dispose (bool disposing) + { + if (_designedControl != null) { + this.DesignerPanel.Controls.Remove (_designedControl); + _designedControl = null; + } + + if (_componentTray != null) { + this.ComponentTrayPanel.Controls.Remove (_componentTray); + _componentTray.Dispose (); + _componentTray = null; + } + + base.Dispose (disposing); + } + } +#endregion + + + + + private DesignerViewFrame _designerViewFrame; + public DocumentDesigner () { } - #endregion Public Instance Constructors + private DesignerViewFrame View { + get { return _designerViewFrame; } + } + +#region Initialization + public override void Initialize (IComponent component) + { + base.Initialize (component); + + // FIXME: Remove this code because it will end up in FormDocumentDesigner + if (component is Form) { + ((Form)component).TopLevel = false; + // XXX: File a MWF bug: setting toplevel to false also sets visible to false + ((Form)component).Visible = true; + } + + _designerViewFrame = new DesignerViewFrame (this.Control, new ComponentTray (this, component.Site)); + _designerViewFrame.DesignedControl.Location = new Point (15, 15); + SetValue (this.Component, "Location", new Point (0, 0)); + + IComponentChangeService componentChangeSvc = GetService (typeof (IComponentChangeService)) as IComponentChangeService; + if (componentChangeSvc != null) { + componentChangeSvc.ComponentAdded += new ComponentEventHandler (OnComponentAdded); + componentChangeSvc.ComponentRemoved += new ComponentEventHandler (OnComponentRemoved); + } - #region Static Constructor + InitializeSelectionService (); + } - [MonoTODO] - static DocumentDesigner () + private void InitializeSelectionService () { + IServiceContainer serviceContainer = this.GetService (typeof (IServiceContainer)) as IServiceContainer; + if (serviceContainer.GetService (typeof (ISelectionService)) != null) + serviceContainer.RemoveService (typeof (ISelectionService)); + + UISelectionService selection = new UISelectionService (serviceContainer); + serviceContainer.AddService (typeof (ISelectionService), (ISelectionService) selection); + serviceContainer.AddService (typeof (IUISelectionService), (IUISelectionService) selection); + + selection.SetSelectedComponents (new IComponent[] { this.Component }); } - #endregion Static Constructor + // MSDN says overriden + // + public override void InitializeNonDefault () + { + base.InitializeNonDefault (); + } - #region Override implementation of ScrollableControlDesigner + // MSDN says overriden + // + public override void OnSetComponentDefaults () + { + base.OnSetComponentDefaults (); + } - [MonoTODO] protected override void Dispose (bool disposing) { - throw new NotImplementedException (); + if (disposing) { + if (_designerViewFrame != null) { + _designerViewFrame.Dispose (); + _designerViewFrame = null; + + } + IComponentChangeService componentChangeSvc = GetService (typeof (IComponentChangeService)) as IComponentChangeService; + if (componentChangeSvc != null) { + componentChangeSvc.ComponentAdded -= new ComponentEventHandler (OnComponentAdded); + componentChangeSvc.ComponentRemoved -= new ComponentEventHandler (OnComponentRemoved); + } + } + base.Dispose (disposing); } +#endregion - [MonoTODO] - public override void Initialize (IComponent component) + +#region MSDN says overriden + + protected override void WndProc (ref Message m) { - throw new NotImplementedException (); + base.WndProc (ref m); } - [MonoTODO] protected override void OnContextMenu (int x, int y) { - throw new NotImplementedException (); + base.OnContextMenu (x, y); } - [MonoTODO] protected override void OnCreateHandle () { - throw new NotImplementedException (); + base.OnCreateHandle (); } - - [MonoTODO] - protected override void PreFilterProperties (IDictionary properties) + + protected override void OnDragDrop (DragEventArgs de) + { + base.OnDragDrop (de); + } + + protected override void OnDragEnter (DragEventArgs de) + { + base.OnDragEnter (de); + } + + protected override void OnDragLeave (EventArgs e) + { + base.OnDragLeave (e); + } + + protected override void OnDragOver (DragEventArgs de) + { + base.OnDragOver (de); + } + + protected override void OnGiveFeedback (GiveFeedbackEventArgs e) + { + base.OnGiveFeedback (e); + } + + protected override void OnMouseDragBegin (int x, int y) + { + base.OnMouseDragBegin (x, y); + } + + protected override void OnMouseDragMove (int x, int y) + { + base.OnMouseDragMove (x, y); + } + + protected override void OnMouseDragEnd (bool cancel) + { + base.OnMouseDragEnd (cancel); + } + + protected override void OnMouseEnter () + { + base.OnMouseEnter (); + } + + protected override void OnMouseHover () + { + base.OnMouseHover (); + } + + protected override void OnMouseLeave () { - throw new NotImplementedException (); + base.OnMouseLeave (); } + + protected override void OnPaintAdornments (PaintEventArgs pe) + { + base.OnPaintAdornments (pe); + } + + protected override void OnSetCursor () + { + base.OnSetCursor (); + } + +#endregion - [MonoTODO] - protected override void WndProc (ref Message m) + +#region Components and ComponentTray + + private void OnComponentAdded (object sender, ComponentEventArgs args) { - throw new NotImplementedException (); + if (!(args.Component is Control)) { + this.View.ComponentTray.AddComponent (args.Component); + if (this.View.ComponentTray.ComponentCount > 0) { + if (!this.View.ComponentTray.Visible) + this.View.ShowComponentTray (); + } + } } - [MonoTODO] - public override SelectionRules SelectionRules + private void OnComponentRemoved (object sender, ComponentEventArgs args) { - get - { - throw new NotImplementedException (); + if (!(args.Component is Control)) { + this.View.ComponentTray.RemoveComponent (args.Component); + if (this.View.ComponentTray.ComponentCount == 0) { + if (this.View.ComponentTray.Visible) + this.View.HideComponentTray (); + } } } +#endregion - #endregion Override implementation of ScrollableControlDesigner - #region Internal Instance Methods +#region IRootDesigner - [MonoTODO] - internal virtual bool CanDropComponents (DragEventArgs de) + object IRootDesigner.GetView (ViewTechnology technology) { - throw new NotImplementedException (); +#if NET_2_0 + if (technology != ViewTechnology.Default) + throw new ArgumentException ("Only ViewTechnology.WindowsForms is supported."); +#else + if (technology != ViewTechnology.WindowsForms) + throw new ArgumentException ("Only ViewTechnology.WindowsForms is supported."); +#endif + return _designerViewFrame; } - [MonoTODO] - internal virtual void DoProperMenuSelection (ICollection selComponents) - { - throw new NotImplementedException (); + ViewTechnology[] IRootDesigner.SupportedTechnologies { + get { +#if NET_2_0 + return new ViewTechnology[] { ViewTechnology.Default }; +#else + return new ViewTechnology[] { ViewTechnology.WindowsForms }; +#endif + } } +#endregion - #endregion Internal Instance Methods - #region Protected Instance Methods +#region IToolBoxUser - [MonoTODO] - protected virtual void EnsureMenuEditorService (IComponent c) + // Indicates whether the specified tool is supported by the designer. + // If it is not the tool is disabled in the toolbox. + // + // Used for subclasses, e.g the FormDocumentDesigner won't accept a Form? + // + bool IToolboxUser.GetToolSupported (ToolboxItem tool) { - throw new NotImplementedException (); + return this.GetToolSupported (tool); } - [MonoTODO] protected virtual bool GetToolSupported (ToolboxItem tool) { - throw new NotImplementedException (); + return true; } - [MonoTODO] - protected virtual void ToolPicked (ToolboxItem tool) + + // Handles the behavior that occurs when a user double-clicks a toolbox item. + // + void IToolboxUser.ToolPicked (ToolboxItem tool) { - throw new NotImplementedException (); + this.ToolPicked (tool); } - - #endregion Protected Instance Methods - - #region Implementation of IRootDesigner - - [MonoTODO] - ViewTechnology[] IRootDesigner.SupportedTechnologies + // ToolPicked is called when the user double-clicks on a toolbox item. + // The document designer should create a component for the specified tool. + // Only tools that are enabled in the toolbox will be passed to this method. + // + // I create the component in the parent container of the primary selection. + // If not available I create it in the rootcomponent (this essentially :-) ) + // + protected virtual void ToolPicked (ToolboxItem tool) { - get - { - throw new NotImplementedException (); + ISelectionService selectionSvc = GetService (typeof (ISelectionService)) as ISelectionService; + IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost; + if (selectionSvc != null && host != null) { + IDesigner designer = host.GetDesigner ((IComponent) selectionSvc.PrimarySelection); + if (designer is ParentControlDesigner) + ParentControlDesigner.InvokeCreateTool ((ParentControlDesigner) designer, tool); + else + this.CreateTool (tool); + } + else { + this.CreateTool (tool); } + IToolboxService tbServ = this.GetService (typeof (IToolboxService)) as IToolboxService; + tbServ.SelectedToolboxItemUsed (); } +#endregion - [MonoTODO] - object IRootDesigner.GetView (ViewTechnology technology) - { - throw new NotImplementedException (); + +#region Properties + // A root designer can be resized to the bottom and to the right. + // + public override SelectionRules SelectionRules { + get { + return (SelectionRules.RightSizeable | SelectionRules.BottomSizeable | SelectionRules.Visible); + } } +#endregion - #endregion Implementation of IRootDesigner - #region Implementation of IToolboxUser +#region Metadata filtering and Design-Time properties - [MonoTODO] - bool IToolboxUser.GetToolSupported (ToolboxItem tool) + // MSDN says that this adds the "BackColor" and "Location" browsable design-time propeties. + // + // The reason for overwriting the Location property created by the ControDesigner is that + // the root component is not draggable (e.g a form has a static location in the DesignerViewFrame) + // + protected override void PreFilterProperties (IDictionary properties) { - throw new NotImplementedException (); + base.PreFilterProperties (properties); + + PropertyDescriptor propertyDescriptor = properties["BackColor"] as PropertyDescriptor; + if (propertyDescriptor != null) { + properties["BackColor"] = TypeDescriptor.CreateProperty (typeof (DocumentDesigner), + propertyDescriptor, + new Attribute[] { new DefaultValueAttribute (System.Drawing.SystemColors.Control) }); + } + + propertyDescriptor = properties["Location"] as PropertyDescriptor; + if (propertyDescriptor != null) { + properties["Location"] = TypeDescriptor.CreateProperty (typeof (DocumentDesigner), + propertyDescriptor, + new Attribute[] { new DefaultValueAttribute (typeof (Point), "0, 0") }); + } } - [MonoTODO] - void IToolboxUser.ToolPicked (ToolboxItem tool) - { - throw new NotImplementedException (); + private Color BackColor { + get { return (Color) ShadowProperties["BackColor"]; } + set { + ShadowProperties["BackColor"] = value; + this.Control.BackColor = value; + } + } + + private Point Location { + get { return (Point) ShadowProperties["Location"]; } + set { ShadowProperties["Location"] = value; } } +#endregion - #endregion Implementation of IToolboxUser - #region Implementation of IOleDragClient +#region Misc + protected IMenuEditorService menuEditorService; - [MonoTODO] - Control IOleDragClient.GetControlForComponent (object component) + // Checks for the existence of a menu editor service and creates one if one does not already exist. + // component - The IComponent to ensure has a context menu service. + // XXX: Not sure exactly what this should do... + // + protected virtual void EnsureMenuEditorService (IComponent component) { - throw new NotImplementedException (); + if (this.menuEditorService == null && component is ContextMenu) + menuEditorService = (IMenuEditorService) GetService (typeof (IMenuEditorService)); } +#endregion - #endregion Implementation of IOleDragClient - - [MonoTODO] - protected IMenuEditorService menuEditorService; } } diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/IMessageReceiver.cs b/mcs/class/System.Design/System.Windows.Forms.Design/IMessageReceiver.cs new file mode 100644 index 00000000000..ace5d3fdb2f --- /dev/null +++ b/mcs/class/System.Design/System.Windows.Forms.Design/IMessageReceiver.cs @@ -0,0 +1,39 @@ +// +// System.Windows.Forms.Design.IMessageReceiver +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev + +// +// 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; +using System.Windows.Forms; + +namespace System.Windows.Forms.Design +{ + internal interface IMessageReceiver + { + void WndProc (ref Message m); + } +} diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/IUISelectionService.cs b/mcs/class/System.Design/System.Windows.Forms.Design/IUISelectionService.cs new file mode 100644 index 00000000000..b1e12771bd8 --- /dev/null +++ b/mcs/class/System.Design/System.Windows.Forms.Design/IUISelectionService.cs @@ -0,0 +1,67 @@ +// +// System.Windows.Forms.Design.IUISelectionService +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev + +// +// 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; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace System.Windows.Forms.Design +{ + + + internal interface IUISelectionService + { + bool SelectionInProgress { + get; + } + bool DragDropInProgress { + get; + } + bool ResizeInProgress { + get; + } + + void MouseDragBegin (Control container, int x, int y); + void MouseDragMove (int x, int y); + void MouseDragEnd (bool cancel); + + void DragBegin (); + void DragOver (Control container, int x, int y); + void DragDrop (bool cancel, Control container, int x, int y); + + void PaintAdornments (Control container, Graphics gfx); + bool SetCursor (int x, int y); + + bool AdornmentsHitTest (Control control, int x, int y); + } +} diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/Native.cs b/mcs/class/System.Design/System.Windows.Forms.Design/Native.cs new file mode 100644 index 00000000000..c27a7093841 --- /dev/null +++ b/mcs/class/System.Design/System.Windows.Forms.Design/Native.cs @@ -0,0 +1,216 @@ +// +// System.Windows.Forms.Design.Native +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev +// +// 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; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Reflection; + + +namespace System.Windows.Forms.Design +{ + + internal class Native + { + + private static Type _xplatuiType; + + static Native () + { + Assembly assembly = Assembly.Load (Consts.AssemblySystem_Windows_Forms); + if (assembly == null) + throw new InvalidOperationException ("Can't load System.Windows.Forms assembly."); + + _xplatuiType = assembly.GetType ("System.Windows.Forms.XplatUI"); + if (_xplatuiType == null) + throw new InvalidOperationException ("Can't find the System.Windows.Forms.XplatUI type."); + } + + private static object InvokeMethod (string methodName, object[] args) + { + return InvokeMethod (methodName, args, null); + } + + // will also match types + private static object InvokeMethod (string methodName, object[] args, Type[] types) + { + MethodInfo method = null; + + if (types != null) { + method = _xplatuiType.GetMethod (methodName, BindingFlags.NonPublic | BindingFlags.Static | + BindingFlags.InvokeMethod, null, types, null); + } else { + method = _xplatuiType.GetMethod (methodName, BindingFlags.NonPublic | BindingFlags.Static | + BindingFlags.InvokeMethod); + } + + if (method == null) + throw new InvalidOperationException (methodName + " not found!"); + + return method.Invoke (null, args); + } + + public static void DefWndProc (ref Message m) + { + object[] args = new object[] { m }; + m.Result = (IntPtr) InvokeMethod ("DefWndProc", args); + m = (Message) args[0]; + } + + public static IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam) + { + + Assembly assembly = Assembly.Load (Consts.AssemblySystem_Windows_Forms); + Type refType = assembly.GetType ("System.Windows.Forms.Message&"); + object[] args = new object[] { Message.Create (hwnd, (int)message, wParam, lParam) }; + InvokeMethod ("SendMessage", args, new Type[] { refType }); + return ((Message)args[0]).Result; + } + + public static Point PointToClient (Control control, Point point) + { + if (control == null) + throw new ArgumentNullException ("control"); + + object[] args = new object[] { control.Handle, point.X, point.Y }; + InvokeMethod ("ScreenToClient", args); + return new Point ((int) args[1], (int) args[2]); + } + + public static IntPtr SetParent (IntPtr childHandle, IntPtr parentHandle) + { + return (IntPtr) InvokeMethod ("SetParent", new object[] { childHandle, parentHandle }); + } + + +#region Helpers + public static int HiWord (int dword) + { + // 12345678 -> 12340000 -> 00001234 + return ((dword >> 16) & 0x0000ffff); + } + + public static int LoWord (int dword) + { + // 12345678 -> 00005678 + return (dword & 0x0000ffff); + } + + public static IntPtr LParam (int hiword, int loword) + { + // results [hiword|loword] dword + // + return (IntPtr)((loword << 16) | (hiword & 0x0000FFFF)); + } +#endregion + + public enum Msg { + WM_CREATE = 0x0001, + WM_SETFOCUS = 0x0007, + WM_PAINT = 0X000F, + WM_CANCELMODE = 0x001F, + WM_SETCURSOR = 0x0020, + WM_CONTEXTMENU = 0x007B, + WM_NCHITTEST = 0x0084, + // + // AccessabilityObject + // + WM_GETOBJECT = 0x003D, + // + // Mouse input - Client area + // + WM_MOUSEFIRST = 0x0200, + WM_MOUSEMOVE = 0x0200, + WM_LBUTTONDOWN = 0x0201, + WM_LBUTTONUP = 0x0202, + WM_LBUTTONDBLCLK = 0x0203, + WM_RBUTTONDOWN = 0x0204, + WM_RBUTTONUP = 0x0205, + WM_RBUTTONDBLCLK = 0x0206, + WM_MBUTTONDOWN = 0x0207, + WM_MBUTTONUP = 0x0208, + WM_MBUTTONDBLCLK = 0x0209, + WM_MOUSEWHEEL = 0x020A, + WM_MOUSELAST = 0x020A, + WM_NCMOUSEHOVER = 0x02A0, + WM_MOUSEHOVER = 0x02A1, + WM_NCMOUSELEAVE = 0x02A2, + WM_MOUSELEAVE = 0x02A3, + // + // Mouse input - Non-client area + // + WM_NCMOUSEMOVE = 0x00A0, + WM_NCLBUTTONDOWN = 0x00A1, + WM_NCLBUTTONUP = 0x00A2, + WM_NCLBUTTONDBLCLK = 0x00A3, + WM_NCRBUTTONDOWN = 0x00A4, + WM_NCRBUTTONUP = 0x00A5, + WM_NCRBUTTONDBLCLK = 0x00A6, + WM_NCMBUTTONDOWN = 0x00A7, + WM_NCMBUTTONUP = 0x00A8, + WM_NCMBUTTONDBLCLK = 0x00A9, + // + // Keyboard input + // + WM_KEYFIRST = 0x0100, + WM_KEYDOWN = 0x0100, + WM_KEYUP = 0x0101, + WM_CHAR = 0x0102, + WM_DEADCHAR = 0x0103, + WM_SYSKEYDOWN = 0x0104, + WM_SYSKEYUP = 0x0105, + WM_SYS1CHAR = 0x0106, + WM_SYSDEADCHAR = 0x0107, + WM_KEYLAST = 0x0108, + // + // Scrolling + // + WM_HSCROLL = 0x0114, + WM_VSCROLL = 0x0115, + + // + // IME - International Text + // + WM_IME_SETCONTEXT = 0x0281, + WM_IME_NOTIFY = 0x0282, + WM_IME_CONTROL = 0x0283, + WM_IME_COMPOSITIONFULL = 0x0284, + WM_IME_SELECT = 0x0285, + WM_IME_CHAR = 0x0286, + WM_IME_REQUEST = 0x0288, + WM_IME_KEYDOWN = 0x0290, + WM_IME_KEYUP = 0x0291, + + // MWF Custom msgs + // + WM_MOUSE_ENTER = 0x0401, + } + } +} + diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/ParentControlDesigner.cs b/mcs/class/System.Design/System.Windows.Forms.Design/ParentControlDesigner.cs index acfe91913ee..c9318b172fc 100644 --- a/mcs/class/System.Design/System.Windows.Forms.Design/ParentControlDesigner.cs +++ b/mcs/class/System.Design/System.Windows.Forms.Design/ParentControlDesigner.cs @@ -1,444 +1,640 @@ -//
-// System.Windows.Forms.Design.ComponentEditorForm.cs
-//
-// Author:
-// Dennis Hayes (dennish@raytek.com)
-// (C) 2002 Ximian, Inc. http://www.ximian.com
-//
-
-//
-// 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;
-using System.Collections;
-using System.ComponentModel;
-using System.ComponentModel.Design;
-using System.Diagnostics;
-using System.Drawing;
-using System.Drawing.Design;
-
-namespace System.Windows.Forms.Design
-{
- public class ParentControlDesigner : ControlDesigner, ISelectionUIHandler, IOleDragClient
- {
- #region Public Instance Constructors
-
- [MonoTODO]
- public ParentControlDesigner ()
- {
- throw new NotImplementedException ();
- }
-
- #endregion Public Instance Constructors
-
- #region Static Constructor
-
- static ParentControlDesigner ()
- {
- ParentControlDesigner.StepControls = new BooleanSwitch ("StepControls", "ParentControlDesigner: step added controls");
- }
-
- #endregion Static Constructor
-
- #region Internal Instance Properties
-
- [MonoTODO]
- internal Size ParentGridSize
- {
- get
- {
- throw new NotImplementedException ();
- }
- }
-
- #endregion Internal Instance Properties
-
- #region Protected Instance Properties
-
- [MonoTODO]
- protected virtual Point DefaultControlLocation
- {
- get
- {
- throw new NotImplementedException ();
- }
- }
-
- [MonoTODO]
- protected virtual bool DrawGrid
- {
- get
- {
- throw new NotImplementedException ();
- }
- set
- {
- throw new NotImplementedException ();
- }
- }
-
- [MonoTODO]
- protected Size GridSize
- {
- get
- {
- throw new NotImplementedException ();
- }
- set
- {
- throw new NotImplementedException ();
- }
- }
-
- #endregion Protected Instance Properties
-
- #region Override implementation of ControlDesigner
-
- [MonoTODO]
- protected override void Dispose (bool disposing)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override void Initialize (IComponent component)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnDragDrop (DragEventArgs de)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnDragEnter (DragEventArgs de)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnDragLeave (EventArgs e)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnDragOver (DragEventArgs de)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnGiveFeedback (GiveFeedbackEventArgs e)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnMouseDragBegin (int x, int y)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnMouseDragEnd (bool cancel)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnMouseDragMove (int x, int y)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnMouseEnter ()
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnMouseHover ()
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnMouseLeave ()
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnPaintAdornments (PaintEventArgs pe)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void OnSetCursor ()
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void PreFilterProperties (IDictionary properties)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override void WndProc (ref Message m)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected override bool EnableDragRect
- {
- get
- {
- throw new NotImplementedException ();
- }
- }
-
- #endregion Override implementation of ControlDesigner
-
- #region Private Static Methods
-
- [MonoTODO]
- protected static void InvokeCreateTool (ParentControlDesigner toInvoke, ToolboxItem tool)
- {
- throw new NotImplementedException ();
- }
-
- #endregion Private Static Methods
-
- #region Implementation of IOleDragClient
-
- [MonoTODO]
- bool IOleDragClient.AddComponent (IComponent component, string name, bool firstAdd)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- bool IOleDragClient.CanModifyComponents
- {
- get
- {
- throw new NotImplementedException ();
- }
- }
-
- [MonoTODO]
- IComponent IOleDragClient.Component
- {
- get
- {
- throw new NotImplementedException ();
- }
- }
-
- [MonoTODO]
- Control IOleDragClient.GetControlForComponent (object component)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- Control IOleDragClient.GetDesignerControl ()
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- bool IOleDragClient.IsDropOk (IComponent component)
- {
- throw new NotImplementedException ();
- }
-
- #endregion Implementation of IOleDragClient
-
- #region Implementation of ISelectionUIHandler
-
- [MonoTODO]
- bool ISelectionUIHandler.BeginDrag (object[] components, SelectionRules rules, int initialX, int initialY)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- void ISelectionUIHandler.DragMoved (object[] components, Rectangle offset)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- void ISelectionUIHandler.EndDrag (object[] components, bool cancel)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- Rectangle ISelectionUIHandler.GetComponentBounds (object component)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- SelectionRules ISelectionUIHandler.GetComponentRules (object component)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- Rectangle ISelectionUIHandler.GetSelectionClipRect (object component)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- void ISelectionUIHandler.OleDragDrop (DragEventArgs de)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- void ISelectionUIHandler.OleDragEnter (DragEventArgs de)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- void ISelectionUIHandler.OleDragLeave ()
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- void ISelectionUIHandler.OleDragOver (DragEventArgs de)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- void ISelectionUIHandler.OnSelectionDoubleClick (IComponent component)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- bool ISelectionUIHandler.QueryBeginDrag (object[] components, SelectionRules rules, int initialX, int initialY)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- void ISelectionUIHandler.ShowContextMenu (IComponent component)
- {
- throw new NotImplementedException ();
- }
-
- #endregion Implementation of ISelectionUIHandler
-
- #region Public Instance Methods
-
- [MonoTODO]
- public virtual bool CanParent (Control control)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public virtual bool CanParent (ControlDesigner controlDesigner)
- {
- throw new NotImplementedException ();
- }
-
- #endregion Public Instance Methods
-
- #region Internal Instance Methods
-
- [MonoTODO]
- internal Point GetSnappedPoint (Point pt)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- internal void SetCursor ()
- {
- throw new NotImplementedException ();
- }
-
- #endregion Internal Instance Methods
-
- #region Protected Instance Methods
-
- [MonoTODO]
- protected void CreateTool (ToolboxItem tool)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected void CreateTool (ToolboxItem tool, Point location)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected void CreateTool (ToolboxItem tool, Rectangle bounds)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected virtual IComponent[] CreateToolCore (ToolboxItem tool, int x, int y, int width, int height, bool hasLocation, bool hasSize)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected Control GetControl (object component)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- protected Rectangle GetUpdatedRect (Rectangle originalRect, Rectangle dragRect, bool updateSize)
- {
- throw new NotImplementedException ();
- }
-
- #endregion Protected Instance Methods
-
- #region Private Static Fields
-
- private static BooleanSwitch StepControls;
-
- #endregion Private Static Fields
- }
-}
+// +// System.Windows.Forms.Design.ParentControlDesigner +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Windows.Forms; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Design; +using System.Collections; + + + +namespace System.Windows.Forms.Design + +{ + + public class ParentControlDesigner : ControlDesigner + { + + public ParentControlDesigner () + { + } + + +#region Initialization + + // Settings paths taken from the example at: + // http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.idesigneroptionservice.aspx + // + public override void Initialize (IComponent component) + { + base.Initialize (component); + + this.Control.AllowDrop = true; + + // Initialize the default values of the Design-Time properties. + // + _defaultDrawGrid = true; + _defaultSnapToGrid = true; + _defaultGridSize = new Size (8, 8); + + // If the parent Control of the designed one has a ParentDesigner then inherit the values + // from it's designer. + // + if (this.Control.Parent != null) { + ParentControlDesigner parentDesigner = GetParentControlDesignerOf (Control.Parent); + if (parentDesigner != null) { + _defaultDrawGrid = (bool) GetValue (parentDesigner.Component, "DrawGrid"); + _defaultSnapToGrid = (bool) GetValue (parentDesigner.Component, "SnapToGrid"); + _defaultGridSize = (Size) GetValue (parentDesigner.Component, "GridSize"); + } + } + else { + // Else retrieve them through the IDesignerOptionService (if available) + // + IDesignerOptionService options = GetService (typeof (IDesignerOptionService)) as + IDesignerOptionService; + if (options != null) { + object value = null; + value = options.GetOptionValue (@"WindowsFormsDesigner\General", "DrawGrid"); + if (value is bool) + _defaultDrawGrid = (bool) value; + + value = options.GetOptionValue (@"WindowsFormsDesigner\General", "SnapToGrid"); + if (value is bool) + _defaultSnapToGrid = (bool) value; + + value = options.GetOptionValue (@"WindowsFormsDesigner\General", "GridSize"); + if (value is Size) + _defaultGridSize = (Size) value; + } + } + + // At the end set whatever we've managed to get + // + _drawGrid = _defaultDrawGrid; + _snapToGrid = _defaultSnapToGrid; + _gridSize = _defaultGridSize; + } + + protected override void Dispose (bool disposing) + { + if (disposing) { + EnableDragDrop (false); + OnMouseDragEnd (true); + } + base.Dispose (disposing); + } +#endregion + + +#region IToolboxService Related + + // This is the code that is executed when you drop a tool from the Toolbox in the designer. + // + + protected static void InvokeCreateTool (ParentControlDesigner toInvoke, ToolboxItem tool) + { + if (toInvoke != null) + toInvoke.CreateTool (tool); + } + + protected void CreateTool (ToolboxItem tool) + { + CreateToolCore (tool, DefaultControlLocation.X, DefaultControlLocation.Y, 0, 0, true, false); + } + + protected void CreateTool (ToolboxItem tool, Point location) + { + CreateToolCore (tool, location.X, location.Y, 0, 0, true, false); + } + + protected void CreateTool (ToolboxItem tool, Rectangle bounds) + { + CreateToolCore (tool, bounds.X, bounds.Y, bounds.Width, bounds.Width, true, true); + } + + // Creates a component from a ToolboxItem, sets its location and size if available and snaps it's + // location to the grid. + // + protected virtual IComponent[] CreateToolCore (ToolboxItem tool, int x, int y, int width, int height, + bool hasLocation, bool hasSize) + { + if (tool == null) + throw new ArgumentNullException ("tool"); + + IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost; + IComponent[] components = tool.CreateComponents (host); + + foreach (IComponent component in components) + { + Control control = component as Control; + if (control != null) { + if (hasLocation) + base.SetValue (component, "Location", this.SnapPointToGrid (new Point (x, y))); + else + base.SetValue (component, "Location", this.SnapPointToGrid (this.DefaultControlLocation)); + + if (hasSize) + base.SetValue (component, "Size", new Size (width, height)); + + this.Control.SuspendLayout (); + this.Control.Controls.Add (control); + this.Control.SuspendLayout (); + this.Control.Refresh (); + } + } + ISelectionService selectionServ = this.GetService (typeof (ISelectionService)) as ISelectionService; + if (selectionServ != null) + selectionServ.SetSelectedComponents (components, SelectionTypes.Replace); + return components; + } + +#endregion + + +#region Drag and Drop + + // If the control is not already parented return true + // + public bool CanParent (Control control) + { + if (control != null) + return !control.Contains (this.Control); + + return false; + } + + public bool CanParent (ControlDesigner designer) + { + return CanParent (designer.Control); + } + + protected override void OnGiveFeedback (GiveFeedbackEventArgs e) + { + base.OnGiveFeedback (e); + } + + protected override void OnDragDrop (DragEventArgs e) + { + IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (selectionServ != null) { + // once this is fired the parent control (parentcontroldesigner) will start getting dragover events. + // + Point location = this.SnapPointToGrid (this.Control.PointToClient (new Point (e.X, e.Y))); + selectionServ.DragDrop (false, this.Control, location.X, location.Y); + } + } + + protected override void OnDragEnter (DragEventArgs e) + { + + this.Control.Refresh (); + } + + protected override void OnDragLeave (EventArgs e) + { + this.Control.Refresh (); + } + + protected override void OnDragOver (DragEventArgs e) + { + IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (selectionServ != null) { + // once ControlDesigner.MouseDragBegin is fired this will start getting dragover events. + // + Point location = this.SnapPointToGrid (this.Control.PointToClient (new Point (e.X, e.Y))); + selectionServ.DragOver (this.Control, location.X, location.Y); + } + e.Effect = DragDropEffects.Move; + } +#endregion + + +#region Properties + // The default location where a control is placed, when added to the designer + // + protected virtual Point DefaultControlLocation { + get { return new Point (0, 0); } + } + + + protected override bool EnableDragRect { + get { return true; } + } +#endregion + + +#region Design-Time Properties + + private bool _defaultDrawGrid; + private bool _defaultSnapToGrid; + private Size _defaultGridSize; + private bool _drawGrid; + private bool _snapToGrid; + private Size _gridSize; + + //This method adds the following design-time browsable properties: + // "DrawGrid", "SnapToGrid", and "GridSize". + // + protected override void PreFilterProperties (IDictionary properties) + { + base.PreFilterProperties (properties); + + properties["DrawGrid"] = TypeDescriptor.CreateProperty (typeof (ParentControlDesigner), + "DrawGrid", + typeof (bool), + new Attribute[] { + BrowsableAttribute.Yes, + DesignOnlyAttribute.Yes, + new DescriptionAttribute ( + "Indicates whether or not to draw the positioning grid."), + CategoryAttribute.Design + }); + + properties["SnapToGrid"] = TypeDescriptor.CreateProperty (typeof (ParentControlDesigner), + "SnapToGrid", + typeof (bool), + new Attribute[] { + BrowsableAttribute.Yes, + DesignOnlyAttribute.Yes, + new DescriptionAttribute ( + "Determines if controls should snap to the positioning grid."), + CategoryAttribute.Design + }); + + properties["GridSize"] = TypeDescriptor.CreateProperty (typeof (ParentControlDesigner), + "GridSize", + typeof (Size), + new Attribute[] { + BrowsableAttribute.Yes, + DesignOnlyAttribute.Yes, + new DescriptionAttribute ( + "Determines the size of the positioning grid."), + CategoryAttribute.Design + }); + + } + + + // Informs all children controls' ParentControlDesigners that the grid properties + // have changed and passes them + // + private void PopulateGridProperties () + { + // Control.Invalidate (true) will redraw the control and it's children + // this will cause a WM_PAINT message to be send and the ControlDesigenr will raise + // the OnPaintAdornments, where the grid drawing takes place. + // + // Note that this should be called *after* the grid properties have changed :-) + // + this.Control.Invalidate (false); + + if (this.Control != null) { + ParentControlDesigner designer = null; + foreach (Control control in this.Control.Controls) { + designer = this.GetParentControlDesignerOf (control); + if (designer != null) + designer.OnParentGridPropertiesChanged (this); + } + } + } + + // Called by the parent ParentControlDesigner when it is populating the grid-related + // design-time properties changes + // + private void OnParentGridPropertiesChanged (ParentControlDesigner parentDesigner) + { + SetValue (this.Component, "DrawGrid", (bool) GetValue (parentDesigner.Component, "DrawGrid")); + SetValue (this.Component, "SnapToGrid", (bool) GetValue (parentDesigner.Component, "SnapToGrid")); + SetValue (this.Component, "GridSize", (Size) GetValue (parentDesigner.Component, "GridSize")); + + // Set also the default values to be those, because we should + // match the parent ParentControlDesigner values. + // called recursivly, so I will rather go for slower, but no stack-overflowable code + // + _defaultDrawGrid = (bool) GetValue (parentDesigner.Component, "DrawGrid"); + _defaultSnapToGrid = (bool) GetValue (parentDesigner.Component, "SnapToGrid"); + _defaultGridSize = (Size) GetValue (parentDesigner.Component, "GridSize"); + + this.PopulateGridProperties (); + } + + + // Retrieves the ParentControlDesigner of the specified control if available, + // else returns null. + // + private ParentControlDesigner GetParentControlDesignerOf (Control control) + { + if (control != null) { + IDesignerHost designerHost = GetService (typeof (IDesignerHost)) as IDesignerHost; + if (designerHost != null) { + ParentControlDesigner designer = null; + designer = designerHost.GetDesigner (this.Control.Parent) as ParentControlDesigner; + if (designer != null) + return designer; + } + } + return null; + } + + protected virtual bool DrawGrid { + get { return _drawGrid; } + set { + _drawGrid = value; + + if (value == false) + SetValue (this.Component, "SnapToGrid", false); + + PopulateGridProperties (); + } + } + + private bool SnapToGrid { + get { return _snapToGrid; } + set { + _snapToGrid = value; + PopulateGridProperties (); + } + } + + protected virtual Size GridSize { + get { return _gridSize; } + set { + _gridSize = value; + PopulateGridProperties (); + } + } + + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconshouldpersistresetmethods.asp + // + // The ShouldSerializerPROPERTYNAME determines whether a property has changed from + // the default value and should get serialized. + // + // The ResetPROPERTYNAME resets the property to it's default value (used when + // one right clicks on a property in the property grid and clicks on "Reset". + // + + private bool ShouldSerializeDrawGrid () + { + return DrawGrid != _defaultDrawGrid; + } + + private void ResetDrawGrid () + { + this.DrawGrid = _defaultDrawGrid; + } + + private bool ShouldSerializeSnapToGrid () + { + return _drawGrid != _defaultDrawGrid; + } + + private void ResetSnapToGrid () + { + this.SnapToGrid = _defaultSnapToGrid; + } + + private bool ShouldSerializeGridSize () + { + return GridSize != _defaultGridSize; + } + + private void ResetGridSize () + { + this.GridSize = _defaultGridSize; + } +#endregion + + +#region Design-Time Mouse Drag and Drop + + protected override void OnMouseDragBegin (int x, int y) + { + // do not call base here because the behaviour is specific for the ControlDesgner (does IUISelectionService.DragBegin) + // + + IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (selectionServ != null) { + // once ControlDesigner.MouseDragBegin is fired this will start getting dragover events. + // + Point location = new Point (x, y); + IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost; + if (base.MouseButtonDown == MouseButtons.Middle && host != null && host.RootComponent != this.Control) { + location = this.Control.Parent.PointToClient (this.Control.PointToScreen (new Point (x, y))); + // I have to do this, because I get DragOver events fired for the control I am actually dragging + // + this.Control.AllowDrop = false; + selectionServ.DragBegin (); + } + else { + selectionServ.MouseDragBegin (this.Control, location.X, location.Y); + } + } + } + + protected override void OnMouseDragMove (int x, int y) + { + IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (selectionServ != null) { + Point location = new Point (x, y); + if (!selectionServ.SelectionInProgress) + location = this.SnapPointToGrid (new Point (x, y)); + + selectionServ.MouseDragMove (location.X, location.Y); + } + } + + protected override void OnMouseDragEnd (bool cancel) + { + IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (selectionServ != null) { + if (selectionServ.SelectionInProgress || selectionServ.ResizeInProgress) + selectionServ.MouseDragEnd (cancel); + } + } + + internal override void OnMouseUp () + { + base.OnMouseUp (); + if (!this.Control.AllowDrop) { // check MouseDragBegin for the reason of having this + this.Control.AllowDrop = true; + } + } + + internal override void OnMouseMove (int x, int y) + { + IUISelectionService uiSelection = this.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (uiSelection != null) + uiSelection.SetCursor (x, y); + + base.OnMouseMove (x, y); + } + + // Align the point to the grid + // + private Point SnapPointToGrid (Point location) + { + Rectangle gridSurface = this.Control.Bounds; + Size gridSize = (Size)GetValue (this.Component, "GridSize"); + + if ((bool)GetValue (this.Component, "SnapToGrid")) { + int x = location.X + (gridSize.Width - (location.X % gridSize.Width)); + if (x > gridSurface.Width) + x = gridSurface.Width - gridSize.Width; + + location.X = x; + + int y = location.Y + (gridSize.Height - (location.Y % gridSize.Height)); + if (y > gridSurface.Height) + y = gridSurface.Height - gridSize.Height; + + location.Y = y; + } + return location; + } + +#endregion + + + #region WndProc and Misc Message Handlers + + protected override void WndProc (ref Message m) + { + base.WndProc (ref m); + } + // MSDN says overriden. + // + protected override void OnSetCursor () + { + if (this.Control != null) { + IToolboxService tbService = GetService (typeof (IToolboxService)) as IToolboxService; + if (tbService != null) + tbService.SetCursor (); + else + base.OnSetCursor (); + } + } + + // Draws the design-time grid if DrawGrid == true + // + protected override void OnPaintAdornments (PaintEventArgs pe) + { + base.OnPaintAdornments (pe); + + bool drawGrid; + Size gridSize; + + // in case WM_PAINT is received before the IDesignerFilter is invoked to add + // those properties. + try { + drawGrid = (bool)GetValue (this.Component, "DrawGrid"); + } catch { + drawGrid = this.DrawGrid; + } + try { + gridSize = (Size)GetValue (this.Component, "GridSize"); + } catch { + gridSize = this.GridSize; + } + + if (drawGrid) { + GraphicsState state = pe.Graphics.Save (); + pe.Graphics.TranslateTransform (this.Control.ClientRectangle.X, + this.Control.ClientRectangle.Y); + ControlPaint.DrawGrid (pe.Graphics, this.Control.ClientRectangle, gridSize, this.Control.BackColor); + pe.Graphics.Restore (state); + } + + IUISelectionService selection = this.GetService (typeof (IUISelectionService)) as IUISelectionService; + if (selection != null) + selection.PaintAdornments (this.Control, pe.Graphics); + } + +#endregion + + + protected Control GetControl (object component) + { + IComponent comp = component as IComponent; + + if (comp != null && comp.Site != null) { + IDesignerHost host = comp.Site.GetService (typeof (IDesignerHost)) as IDesignerHost; + if (host != null) { + ControlDesigner designer = host.GetDesigner (comp) as ControlDesigner; + if (designer != null) + return designer.Control; + } + } + return null; + } + +#region NET_2_0 Stubs +#if NET_2_0 +/* + protected virtual bool AllowControlLasso { + get { return false; } + } + + protected virtual bool AllowGenericDragBox { + get { return false; } + } + + public override IList SnapLines { + get { return new object [0]; } + } + + protected ToolboxItem MouseDragTool { + get { return null; } + } + + public override void InitializeNewComponent (IDictionary defaultValues) + { + } + + protected void AddPaddingSnapLines (ref ArrayList snapLines) + { + } + + protected virtual Control GetParentForComponent (IComponent component) + { + } + + protected override ControlBodyGlyph GetControlGlyph (GlyphSelectionType selectionType) + { + } + */ +#endif +#endregion + + } +} diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/ScrollableControlDesigner.cs b/mcs/class/System.Design/System.Windows.Forms.Design/ScrollableControlDesigner.cs index aa3313ea424..266afd8f852 100644 --- a/mcs/class/System.Design/System.Windows.Forms.Design/ScrollableControlDesigner.cs +++ b/mcs/class/System.Design/System.Windows.Forms.Design/ScrollableControlDesigner.cs @@ -1,10 +1,10 @@ // -// System.Windows.Forms.Design.ComponentEditorForm.cs +// System.Windows.Forms.Design.ScrollableControlDesigner // -// Author: -// Dennis Hayes (dennish@raytek.com) -// (C) 2002 Ximian, Inc. http://www.ximian.com +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) // +// (C) 2006-2007 Ivan N. Zlatev // // Permission is hereby granted, free of charge, to any person obtaining @@ -14,10 +14,10 @@ // 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 @@ -27,37 +27,57 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // + using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Windows.Forms; using System.Drawing; +using System.Drawing.Design; +using System.Collections; + + namespace System.Windows.Forms.Design { + public class ScrollableControlDesigner : ParentControlDesigner { - #region Public Instance Constructors - [MonoTODO] public ScrollableControlDesigner () { - throw new NotImplementedException (); } - #endregion Public Instance Constructors - - #region Override implementation of ParentControlDesigner + private const int HTHSCROLL = 6; + private const int HTVSCROLL = 7; - [MonoTODO] - protected override bool GetHitTest (Point pt) + protected override bool GetHitTest (Point point) { - throw new NotImplementedException (); + if (base.GetHitTest (point)) { + return true; + } + + // Check if the user has clicked on the scroll bars and forward the message to + // the ScrollableControl. (Don't filter out the scrolling.). Keep in mind that scrollbars + // will be shown only if ScrollableControl.AutoScroll = true + // + if (this.Control is ScrollableControl && ((ScrollableControl)Control).AutoScroll) { + int hitTestResult = (int) Native.SendMessage (this.Control.Handle, + Native.Msg.WM_NCHITTEST, + IntPtr.Zero, + (IntPtr) Native.LParam (point.X, point.Y)); + if (hitTestResult == HTHSCROLL || hitTestResult == HTVSCROLL) + return true; + } + return false; } - [MonoTODO] + protected override void WndProc (ref Message m) { - throw new NotImplementedException (); + base.WndProc (ref m); + if (m.Msg == (int)Native.Msg.WM_HSCROLL || m.Msg == (int)Native.Msg.WM_VSCROLL) + this.DefWndProc (ref m); } - - #endregion Override implementation of ParentControlDesigner } } diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/SelectionFrame.cs b/mcs/class/System.Design/System.Windows.Forms.Design/SelectionFrame.cs new file mode 100644 index 00000000000..1d8555be747 --- /dev/null +++ b/mcs/class/System.Design/System.Windows.Forms.Design/SelectionFrame.cs @@ -0,0 +1,481 @@ +// +// System.Windows.Forms.Design.SelectionFrame +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev + +// +// 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; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + + +namespace System.Windows.Forms.Design +{ + // This is not a control! + // + internal class SelectionFrame + { + + public SelectionFrame (Control control) + { + if (control == null) + throw new ArgumentNullException ("control"); + + _control = control; + } + + + private Rectangle _bounds; + private Control _control; + private Rectangle[] _handles = new Rectangle[8]; + private GrabHandle _handle = GrabHandle.None; + private const int BORDER_SIZE = 7; + + +#region Properties + private enum GrabHandle { + None = -1, + TopLeft = 0, + TopMiddle, + TopRight, + Right, + BottomRight, + BottomMiddle, + BottomLeft, + Left, + Border // the border surrounding the control. + } + + public Rectangle Bounds { + get { + _bounds.X = _control.Location.X - BORDER_SIZE; + _bounds.Y = _control.Location.Y - BORDER_SIZE; + _bounds.Width = _control.Width + BORDER_SIZE *2; + _bounds.Height = _control.Height + BORDER_SIZE *2; + + return _bounds; + } + set { + _bounds = value; + _control.Bounds = _bounds; + } + } + + private SelectionRules SelectionRules { + get { + SelectionRules result = SelectionRules.AllSizeable; + + if (_control.Site != null) { + IDesignerHost host = _control.Site.GetService (typeof (IDesignerHost)) as IDesignerHost; + if (host != null) { + ControlDesigner designer = host.GetDesigner (_control) as ControlDesigner; + if (designer != null) + result = designer.SelectionRules; + } + } + + return result; + } + } + + public Control Control { + get { return _control; } + set { + if (value != null) + _control = value; + } + } + + public Control Parent { + get { + if (_control.Parent == null) + return _control; + else + return _control.Parent; + } + } + + private GrabHandle GrabHandleSelected { + get { return _handle; } + set { _handle = value; } + } + + private bool PrimarySelection{ + get { + bool result = false; + if (this.Control != null && this.Control.Site != null) { + ISelectionService selection = this.Control.Site.GetService (typeof (ISelectionService)) as ISelectionService; + if (selection != null && selection.PrimarySelection == this.Control) + result = true; + } + return result; + } + } +#endregion + + +#region Drawing + public void OnPaint (Graphics gfx) + { + DrawFrame (gfx); + DrawGrabHandles (gfx); + } + + private void DrawGrabHandles (Graphics gfx) + { + GraphicsState state = gfx.Save(); + gfx.TranslateTransform (this.Bounds.X, this.Bounds.Y); + + for (int i = 0; i < _handles.Length; i++) { + _handles[i].Width = BORDER_SIZE; + _handles[i].Height = BORDER_SIZE; + } + + SelectionRules rules = this.SelectionRules; + bool primarySelection = this.PrimarySelection; + bool enabled = false; + + _handles[(int) GrabHandle.TopLeft].Location = new Point (0,0); + if (this.CheckSelectionRules (rules, SelectionRules.TopSizeable | SelectionRules.LeftSizeable)) + enabled = true; + + ControlPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.TopLeft], primarySelection, enabled); + enabled = false; + + _handles[(int) GrabHandle.TopMiddle].Location = new Point ((this.Bounds.Width - BORDER_SIZE) / 2, 0); + if (this.CheckSelectionRules (rules, SelectionRules.TopSizeable)) + enabled = true; + + ControlPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.TopMiddle], primarySelection, enabled); + enabled = false; + + _handles[(int) GrabHandle.TopRight].Location = new Point (this.Bounds.Width - BORDER_SIZE, 0); + if (this.CheckSelectionRules (rules, SelectionRules.TopSizeable | SelectionRules.RightSizeable)) + enabled = true; + + ControlPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.TopRight], primarySelection, enabled); + enabled = false; + + _handles[(int) GrabHandle.Right].Location = new Point (this.Bounds.Width - BORDER_SIZE, + (this.Bounds.Height - BORDER_SIZE) / 2); + if (this.CheckSelectionRules (rules, SelectionRules.RightSizeable)) + enabled = true; + + ControlPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.Right], primarySelection, enabled); + enabled = false; + + _handles[(int) GrabHandle.BottomRight].Location = new Point (this.Bounds.Width - BORDER_SIZE, + this.Bounds.Height - BORDER_SIZE); + if (this.CheckSelectionRules (rules, SelectionRules.BottomSizeable | SelectionRules.RightSizeable)) + enabled = true; + + ControlPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.BottomRight], primarySelection, enabled); + enabled = false; + + _handles[(int) GrabHandle.BottomMiddle].Location = new Point ((this.Bounds.Width - BORDER_SIZE) / 2, + this.Bounds.Height - BORDER_SIZE); + if (this.CheckSelectionRules (rules, SelectionRules.BottomSizeable)) + enabled = true; + + ControlPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.BottomMiddle], primarySelection, enabled); + enabled = false; + + _handles[(int) GrabHandle.BottomLeft].Location = new Point (0, this.Bounds.Height - BORDER_SIZE); + if (this.CheckSelectionRules (rules, SelectionRules.BottomSizeable | SelectionRules.LeftSizeable)) + enabled = true; + + ControlPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.BottomLeft], primarySelection, enabled); + enabled = false; + + _handles[(int) GrabHandle.Left].Location = new Point (0, (this.Bounds.Height - BORDER_SIZE) / 2); + if (this.CheckSelectionRules (rules, SelectionRules.LeftSizeable)) + enabled = true; + + ControlPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.Left], primarySelection, enabled); + gfx.Restore (state); + } + + protected void DrawFrame (Graphics gfx) + { + Color negativeColor = Color.FromArgb ((byte)~(_control.Parent.BackColor.R), + (byte)~(_control.Parent.BackColor.G), + (byte)~(_control.Parent.BackColor.B)); + Pen pen = new Pen (new HatchBrush (HatchStyle.Percent30, negativeColor, Color.FromArgb (0)), BORDER_SIZE); + gfx.DrawRectangle (pen, this.Control.Bounds); + } +#endregion + + +#region Dragging + private bool _resizing = false; + + + public bool SetCursor (int x, int y) + { + bool modified = false; + + if (!_resizing) { + GrabHandle handle = PointToGrabHandle (this.PointToClient (Control.MousePosition)); + if (handle != GrabHandle.None) + modified = true; + + if (handle == GrabHandle.TopLeft) + Cursor.Current = Cursors.SizeNWSE; + else if (handle == GrabHandle.TopMiddle) + Cursor.Current = Cursors.SizeNS; + else if (handle == GrabHandle.TopRight) + Cursor.Current = Cursors.SizeNESW; + else if (handle == GrabHandle.Right) + Cursor.Current = Cursors.SizeWE; + else if (handle == GrabHandle.BottomRight) + Cursor.Current = Cursors.SizeNWSE; + else if (handle == GrabHandle.BottomMiddle) + Cursor.Current = Cursors.SizeNS; + else if (handle == GrabHandle.BottomLeft) + Cursor.Current = Cursors.SizeNESW; + else if (handle == GrabHandle.Left) + Cursor.Current = Cursors.SizeWE; + else + Cursor.Current = Cursors.Default; + } + return modified; + } + + // container coordinates + public void ResizeBegin (int x, int y) + { + this.GrabHandleSelected = PointToGrabHandle (this.PointToClient (this.Parent.PointToScreen (new Point (x, y)))); + + if (this.GrabHandleSelected != GrabHandle.None) + _resizing = true; + } + + private bool CheckSelectionRules (SelectionRules rules, SelectionRules toCheck) + { + return ((rules & toCheck) == toCheck); + } + + // container coordinates returns deltaBounds + public Rectangle ResizeContinue (int x, int y) + { + //Console.WriteLine ("ResizeContinue: " + x + " : " + y); + //Console.WriteLine ("GrabHandleSelected: " + GrabHandleSelected); + + Rectangle bounds = (Rectangle)TypeDescriptor.GetProperties (_control)["Bounds"].GetValue (_control); + Rectangle deltaBounds = bounds; + Point pointerLocation = new Point (x, y); + SelectionRules rules = this.SelectionRules; + int top, height, left, width = 0; + + if (_resizing && this.GrabHandleSelected != GrabHandle.None && rules != SelectionRules.Locked) { + if (this.GrabHandleSelected == GrabHandle.TopLeft && + CheckSelectionRules (rules, SelectionRules.LeftSizeable | SelectionRules.TopSizeable)) { + + top = _control.Top; + height = _control.Height; + left = _control.Left; + width = _control.Width; + + if (pointerLocation.Y < _control.Bottom) { + top = pointerLocation.Y; + height = _control.Bottom - pointerLocation.Y; + } + if (pointerLocation.X < _control.Right) { + left = pointerLocation.X; + width = _control.Right - pointerLocation.X; + bounds = new Rectangle (left, top, width, height); + } + } + else if (this.GrabHandleSelected == GrabHandle.TopRight && + CheckSelectionRules (rules, SelectionRules.TopSizeable | SelectionRules.RightSizeable)) { + + top = _control.Top; + height = _control.Height; + width = _control.Width; + + if (pointerLocation.Y < _control.Bottom) { + top = pointerLocation.Y; + height = _control.Bottom - pointerLocation.Y; + } + width = pointerLocation.X - _control.Left; + bounds = new Rectangle (_control.Left, top, width, height); + } + else if (GrabHandleSelected == GrabHandle.TopMiddle && CheckSelectionRules (rules, SelectionRules.TopSizeable)) { + if (pointerLocation.Y < _control.Bottom) { + top = pointerLocation.Y; + height = _control.Bottom - pointerLocation.Y; + bounds = new Rectangle (_control.Left, top, _control.Width, height); + } + } + else if (this.GrabHandleSelected == GrabHandle.Right && CheckSelectionRules (rules, SelectionRules.RightSizeable)) { + width = pointerLocation.X - _control.Left; + bounds = new Rectangle (_control.Left, _control.Top, width, _control.Height); + } + else if (this.GrabHandleSelected == GrabHandle.BottomRight && + CheckSelectionRules (rules, SelectionRules.BottomSizeable | SelectionRules.RightSizeable)) { + + width = pointerLocation.X - _control.Left; + height = pointerLocation.Y - _control.Top; + bounds = new Rectangle (_control.Left, _control.Top, width, height); + } + else if (GrabHandleSelected == GrabHandle.BottomMiddle && CheckSelectionRules (rules, SelectionRules.BottomSizeable)) { + height = pointerLocation.Y - _control.Top; + bounds = new Rectangle (_control.Left, _control.Top, _control.Width, height); + } + else if (GrabHandleSelected == GrabHandle.BottomLeft && + CheckSelectionRules (rules, SelectionRules.BottomSizeable | SelectionRules.LeftSizeable)) { + + height = _control.Height; + left = _control.Left; + width = _control.Width; + + if (pointerLocation.X < _control.Right) { + left = pointerLocation.X; + width = _control.Right - pointerLocation.X; + } + height = pointerLocation.Y - _control.Top; + bounds = new Rectangle (left, _control.Top, width, height); + } + else if (GrabHandleSelected == GrabHandle.Left && CheckSelectionRules (rules, SelectionRules.LeftSizeable)) { + if (pointerLocation.X < _control.Right) { + left = pointerLocation.X; + width = _control.Right - pointerLocation.X; + bounds = new Rectangle (left, _control.Top, width, _control.Height); + } + } + + //Console.WriteLine ("bounds: " + bounds.ToString ()); + TypeDescriptor.GetProperties (_control)["Bounds"].SetValue (_control, bounds); + + } + + this.Parent.Refresh (); + deltaBounds.X = bounds.X - deltaBounds.X; + deltaBounds.Y = bounds.Y - deltaBounds.Y; + deltaBounds.Height = bounds.Height - deltaBounds.Height; + deltaBounds.Width = bounds.Width - deltaBounds.Width; + return deltaBounds; + } + + + public void ResizeEnd (bool cancel) + { + this.GrabHandleSelected = GrabHandle.None; + _resizing = false; + } + + public void Resize (Rectangle deltaBounds) + { + SelectionRules rules = this.SelectionRules; + + if (this.CheckSelectionRules (rules, SelectionRules.Locked) || !this.CheckSelectionRules (rules, SelectionRules.Moveable)) + return; + + Rectangle bounds = (Rectangle)TypeDescriptor.GetProperties (_control)["Bounds"].GetValue (_control); + + if (CheckSelectionRules (rules, SelectionRules.LeftSizeable)) { + bounds.X += deltaBounds.X; + bounds.Width += deltaBounds.Width; + } + if (CheckSelectionRules (rules, SelectionRules.RightSizeable) && !CheckSelectionRules (rules, SelectionRules.LeftSizeable)) { + bounds.Y += deltaBounds.Y; + bounds.Width += deltaBounds.Width; + } + if (CheckSelectionRules (rules, SelectionRules.TopSizeable)) { + bounds.Y += deltaBounds.Y; + bounds.Height += deltaBounds.Height; + } + if (CheckSelectionRules (rules, SelectionRules.BottomSizeable) && !CheckSelectionRules (rules, SelectionRules.TopSizeable)) { + bounds.Height += deltaBounds.Height; + } + + TypeDescriptor.GetProperties (_control)["Bounds"].SetValue (_control, bounds); + } +#endregion + + +#region Utility methods + + public bool HitTest (int x, int y) + { + if (PointToGrabHandle (this.PointToClient (this.Parent.PointToScreen (new Point (x, y)))) != GrabHandle.None) + return true; + else + return false; + } + + private GrabHandle PointToGrabHandle (Point pointerLocation) + { + GrabHandle result = GrabHandle.None; + + if (IsCursorOnGrabHandle (pointerLocation, _handles[0])) + result = GrabHandle.TopLeft; + else if (IsCursorOnGrabHandle (pointerLocation, _handles[1])) + result = GrabHandle.TopMiddle; + else if (IsCursorOnGrabHandle (pointerLocation, _handles[2])) + result = GrabHandle.TopRight; + else if (IsCursorOnGrabHandle (pointerLocation, _handles[3])) + result = GrabHandle.Right; + else if (IsCursorOnGrabHandle (pointerLocation, _handles[4])) + result = GrabHandle.BottomRight; + else if (IsCursorOnGrabHandle (pointerLocation, _handles[5])) + result = GrabHandle.BottomMiddle; + else if (IsCursorOnGrabHandle (pointerLocation, _handles[6])) + result = GrabHandle.BottomLeft; + else if (IsCursorOnGrabHandle (pointerLocation, _handles[7])) + result = GrabHandle.Left; + else + result = GrabHandle.None; + + return result; + } + + private bool IsCursorOnGrabHandle (Point pointerLocation, Rectangle handleRectangle) + { + if (pointerLocation.X >= handleRectangle.X && + pointerLocation.X <= handleRectangle.X + handleRectangle.Width && + pointerLocation.Y >= handleRectangle.Y && + pointerLocation.Y <= handleRectangle.Y + handleRectangle.Height) { + return true; + } + return false; + } + + private Point PointToClient (Point screenPoint) + { + Point pointerLocation = this.Parent.PointToClient (screenPoint); + pointerLocation.X = pointerLocation.X - this.Bounds.X; + pointerLocation.Y = pointerLocation.Y - this.Bounds.Y; + return pointerLocation; + } +#endregion + + } +} diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/SplitContainerDesigner.cs b/mcs/class/System.Design/System.Windows.Forms.Design/SplitContainerDesigner.cs new file mode 100644 index 00000000000..7f11d0a7099 --- /dev/null +++ b/mcs/class/System.Design/System.Windows.Forms.Design/SplitContainerDesigner.cs @@ -0,0 +1,86 @@ +// +// System.Windows.Forms.Design.SplitContainerDesigner +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Windows.Forms; +using System.Drawing; +using System.Drawing.Design; +using System.Collections; + + + +namespace System.Windows.Forms.Design +{ + + public class SplitContainerDesigner : ParentControlDesigner + { + + public SplitContainerDesigner () + { + } + + public override void Initialize (IComponent component) + { + base.Initialize (component); + SplitContainer container = (SplitContainer) component; + base.EnableDesignMode (container.Panel1, "Panel1"); + base.EnableDesignMode (container.Panel2, "Panel2"); + } + + public override ControlDesigner InternalControlDesigner (int internalControlIndex) + { + switch (internalControlIndex) { + case 0: + return GetDesigner (((SplitContainer)this.Control).Panel1); + case 1: + return GetDesigner (((SplitContainer)this.Control).Panel2); + } + return null; + } + + private ControlDesigner GetDesigner (IComponent component) + { + IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost; + if (host != null) + return host.GetDesigner (component) as ControlDesigner; + else + return null; + } + + public override int NumberOfInternalControlDesigners () + { + return 2; + } + } +} +#endif diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/UISelectionService.cs b/mcs/class/System.Design/System.Windows.Forms.Design/UISelectionService.cs new file mode 100644 index 00000000000..fa7eb11e246 --- /dev/null +++ b/mcs/class/System.Design/System.Windows.Forms.Design/UISelectionService.cs @@ -0,0 +1,493 @@ +// +// System.Windows.Forms.Design.UISelectionService +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace System.Windows.Forms.Design +{ + + internal class UISelectionService : SelectionService, IUISelectionService + { + + private IServiceProvider _serviceProvider; + + public UISelectionService (IServiceProvider serviceProvider) : base (serviceProvider) + { + if (serviceProvider == null) + throw new ArgumentNullException ("serviceProvider"); + + _serviceProvider = serviceProvider; + } + + private object GetService (Type service) + { + return _serviceProvider.GetService (service); + } + + public bool SelectionInProgress { + get { return _selecting; } + } + + public bool DragDropInProgress { + get { return _dragging; } + } + + public bool ResizeInProgress{ + get { return _resizing; } + } + + + public bool SetCursor (int x, int y) + { + bool modified = false; + // if moving mouse around - set cursor if mouse is hovering a selectionframes' grabhandles + // + SelectionFrame frame = GetSelectionFrameAt (x, y); + if (frame != null && frame.HitTest (x, y) && frame.SetCursor (x, y)) + modified = true; + + return modified; + } + + + public void MouseDragBegin (Control container, int x, int y) + { + // XXX: pass ControlDesigner and not control and check if it is a ParentControlDesigner !!!!!! + // + // * start resizing the selection frame + // * start selecting + // + SelectionFrame frame = GetSelectionFrameAt (x, y); + + if (frame != null && frame.HitTest (x, y)) { + this.SetSelectedComponents (new IComponent[] { frame.Control }); + this.ResizeBegin (x, y); + } + else { + SelectionBegin (container, x, y); + } + } + + public void MouseDragMove (int x, int y) + { + if (_selecting) + SelectionContinue (x, y); + else if (_resizing) + ResizeContinue (x, y); + } + + public void MouseDragEnd (bool cancel) + { + if (_selecting) + SelectionEnd (cancel); + else if (_resizing) + ResizeEnd (cancel); + + if (Cursor.Current != Cursors.Default) + Cursor.Current = Cursors.Default; + } + + +#region Dragging + private bool _dragging = false; + private Point _prevMousePosition; + private bool _firstMove = false; + + // container coordinates (primary selection's) + // + public void DragBegin () + { + _dragging = true; + _firstMove = true; + // TODO: Use the undo/redo mechanism to declare a state change, so that if the dragging is canceled + // the locations and container of the controls will be restored to the one before the dragging + // + if (this.PrimarySelection != null) + ((Control)this.PrimarySelection).DoDragDrop (new ControlDataObject ((Control)this.PrimarySelection), DragDropEffects.All); + } + + // container cordinates + // + public void DragOver (Control container, int x, int y) + { + //Console.WriteLine ("DragOver: " + x + " : " + y); + //Console.WriteLine ("in container: " + container.ToString ()); + if (_dragging) { + if (_firstMove) { + _prevMousePosition = new Point (x, y); + _firstMove = false; + } + else { + int dx = x - _prevMousePosition.X; + int dy = y - _prevMousePosition.Y; + MoveSelection (container, dx, dy); + _prevMousePosition = new Point (x, y); + + // Repaint everything >_< + // + IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost; + if (host != null && host.RootComponent != null) + ((Control)host.RootComponent).Refresh (); + //container.Refresh (); + } + } + } + + // container coordinates + // + public void DragDrop (bool cancel, Control container, int x, int y) + { + if (_dragging) { + // TODO: Handle cancel by requesting an undo operation + // + int dx = x - _prevMousePosition.X; + int dy = y - _prevMousePosition.Y; + + MoveSelection (container, dx, dy); + _dragging = false; + + // Repaint everything + // + IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost; + if (host != null && host.RootComponent != null) + ((Control)host.RootComponent).Refresh (); + // Send mouse up message to the primary selection + // Else for parentcontroldesigner there is no mouseup event and it doesn't set allow drop back to false + // + Native.SendMessage (((Control)this.PrimarySelection).Handle, Native.Msg.WM_LBUTTONUP, (IntPtr) 0, (IntPtr) 0); + } + } + + private void MoveSelection (Control container, int dx, int dy) + { + bool reparent = false; + Control oldParent = null; + + if (((Control)this.PrimarySelection).Parent != container && !this.GetComponentSelected (container)) { + reparent = true; + oldParent = ((Control)this.PrimarySelection).Parent; + } + + // FIXME: Should check selectionstyle per control to determine if it's locked... + // if locked -> don't move + // + ICollection selection = this.GetSelectedComponents (); + foreach (Component component in selection) { + Control control = component as Control; + if (reparent) { + control.Parent.Controls.Remove (control); + container.Controls.Add (control); + } + + PropertyDescriptor property = TypeDescriptor.GetProperties (control)["Location"]; + Point location = (Point) property.GetValue (control); + location.X += dx; + location.Y += dy; + property.SetValue (control, location); + } + + if (reparent) { + oldParent.Invalidate (false); + oldParent.Update (); + } + } +#endregion + + +#region Selection + private bool _selecting = false; + private Control _selectionContainer = null; + private Point _initialMousePosition; + private Rectangle _selectionRectangle; + // XXX + private ArrayList _selectionFrames = new ArrayList (); + + // container coordinates + // + private void SelectionBegin (Control container, int x, int y) + { + //Console.WriteLine ("SelectionBegin"); + _selecting = true; + _selectionContainer = container; + _prevMousePosition = new Point (x, y); + _initialMousePosition = _prevMousePosition; + _selectionRectangle = new Rectangle (x , y, 0, 0); + } + + private void SelectionContinue (int x, int y) + { + //Console.WriteLine ("SelectionContinue"); + if (_selecting) { + // right to right + // + if (x > _selectionRectangle.Right) { + _selectionRectangle.Width = x - _selectionRectangle.X; + } + // right to left + else if (x > _selectionRectangle.X && x < _selectionRectangle.Right && + x < _prevMousePosition.X) { + + _selectionRectangle.Width = x - _selectionRectangle.X; + } + // left to left - f + else if (x < _selectionRectangle.X) { + + // hasn't flipped + if (_prevMousePosition.X > _selectionRectangle.X) { + _selectionRectangle.X = _initialMousePosition.X; + _selectionRectangle.Width = 0; + } + else { + _selectionRectangle.Width += _selectionRectangle.X - x; + _selectionRectangle.X = x; + } + } + // left to right - f + else if (x > _selectionRectangle.X && x < _selectionRectangle.Right && + x > _prevMousePosition.X) { + + if (_prevMousePosition.X < _selectionRectangle.X) { + _selectionRectangle.X = _initialMousePosition.X; + _selectionRectangle.Width = 0; + } + else { + _selectionRectangle.Width -= x - _selectionRectangle.X; + _selectionRectangle.X = x; + } + } + + + if (y > _selectionRectangle.Bottom) { + _selectionRectangle.Height = y - _selectionRectangle.Y; + } + else if (y > _selectionRectangle.Y && y < _selectionRectangle.Bottom && + y < _prevMousePosition.Y) { + + _selectionRectangle.Height = y - _selectionRectangle.Y; + + } + else if (y < _selectionRectangle.Y) { + if (_prevMousePosition.Y > _selectionRectangle.Y) { + _selectionRectangle.Y = _initialMousePosition.Y; + _selectionRectangle.Height = 0; + } + else { + _selectionRectangle.Height += _selectionRectangle.Y - y; + _selectionRectangle.Y = y; + } + } + else if (y > _selectionRectangle.Y && y < _selectionRectangle.Bottom && + y > _prevMousePosition.Y) { + + if (_prevMousePosition.Y < _selectionRectangle.Y) { + _selectionRectangle.Y = _initialMousePosition.Y; + _selectionRectangle.Height = 0; + } + else { + _selectionRectangle.Height -= y - _selectionRectangle.Y; + _selectionRectangle.Y = y; + } + } + + _prevMousePosition.X = x; + _prevMousePosition.Y = y; + + _selectionContainer.Refresh (); + } + } + + private void SelectionEnd (bool cancel) + { + //Console.WriteLine ("SelectionEnd"); + _selecting = false; + ICollection selectedControls = GetControlsIn (_selectionRectangle); + // do not change selection if nothing has changed + // + if (selectedControls.Count != 0) + this.SetSelectedComponents (selectedControls, SelectionTypes.Replace); + + _selectionContainer.Refresh (); + } +#endregion + + +#region Resizing + private SelectionFrame _selectionFrame; + private bool _resizing = false; + + private void ResizeBegin (int x, int y) + { + _resizing = true; + _selectionFrame = this.GetSelectionFrameAt (x, y); + _selectionFrame.ResizeBegin (x, y); + } + + private void ResizeContinue (int x, int y) + { + Rectangle deltaBounds = _selectionFrame.ResizeContinue (x, y); + ICollection selection = this.GetSelectedComponents (); + + foreach (IComponent component in selection) { + if (component is Control) { + SelectionFrame frame = GetSelectionFrameFor ((Control)component); + if (frame != _selectionFrame) + frame.Resize (deltaBounds); + } + } + + } + + private void ResizeEnd (bool cancel) + { + _selectionFrame.ResizeEnd (cancel); + _resizing = false; + } + + + private SelectionFrame GetSelectionFrameAt (int x, int y) + { + SelectionFrame result = null; + + foreach (SelectionFrame frame in _selectionFrames) { + if (frame.Bounds.Contains (new Point (x, y))) { + result = frame; + break; + } + } + + return result; + } + + private SelectionFrame GetSelectionFrameFor (Control control) + { + foreach (SelectionFrame frame in _selectionFrames) { + if (control == frame.Control) + return frame; + } + return null; + } +#endregion + + public bool AdornmentsHitTest (Control control, int x, int y) + { + SelectionFrame frame = GetSelectionFrameAt (x, y); + if (frame != null) + return frame.HitTest (x, y); + + return false; + } + + // This method is called by all ParentControlDesigner.OnPaintAdornments. + // Selection frames are drawn in the parent container of the primary selection + // selection rectangle is drawn in the primary selection + // + public void PaintAdornments (Control container, Graphics gfx) + { + IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost; + + if (host == null || !(this.PrimarySelection is Control)) + return; + + if ((Control)this.PrimarySelection == container) { + if (_selecting) { + Color negativeColor = Color.FromArgb ((byte)~(_selectionContainer.BackColor.R), + (byte)~(_selectionContainer.BackColor.G), + (byte)~(_selectionContainer.BackColor.B)); + DrawSelectionRectangle (gfx, _selectionRectangle, negativeColor); + } + } + else if (((Control)this.PrimarySelection).Parent == container) { + foreach (SelectionFrame frame in _selectionFrames) + frame.OnPaint (gfx); + } + } + + + private void DrawSelectionRectangle (Graphics gfx, Rectangle frame, Color color) + { + Pen pen = new Pen (color); + pen.DashStyle = DashStyle.Dash; + gfx.DrawRectangle (pen, frame); + } + + + protected override void OnSelectionChanged () + { + + ICollection selection = this.GetSelectedComponents (); + + if (_selectionFrames.Count == 0) { + foreach (Component component in selection) { + _selectionFrames.Add (new SelectionFrame ((Control) component)); + } // this code should get executed only once! (when initial primary selection is set) + } else { + int i = 0; + foreach (Component component in selection) { + if (i >= _selectionFrames.Count) + _selectionFrames.Add (new SelectionFrame ((Control) component)); + else + ((SelectionFrame)_selectionFrames[i]).Control = (Control) component; + i++; + } + if (i < _selectionFrames.Count) + _selectionFrames.RemoveRange (i, _selectionFrames.Count - i); + } + // Refresh the whole design surface (including the view) + // + IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost; + Control root = host.RootComponent as Control; + if (root != null) { + if (root.Parent != null) + root.Parent.Refresh (); + else + root.Refresh (); + } + + base.OnSelectionChanged (); + } + + private ICollection GetControlsIn (Rectangle rect) + { + ArrayList selectedControls = new ArrayList (); + + foreach (Control control in _selectionContainer.Controls) { + if (rect.Contains (control.Bounds) || rect.IntersectsWith (control.Bounds)) + selectedControls.Add (control); + } + return selectedControls; + } + + } +} diff --git a/mcs/class/System.Design/System.Windows.Forms.Design/WndProcRouter.cs b/mcs/class/System.Design/System.Windows.Forms.Design/WndProcRouter.cs new file mode 100644 index 00000000000..52aa22df55c --- /dev/null +++ b/mcs/class/System.Design/System.Windows.Forms.Design/WndProcRouter.cs @@ -0,0 +1,117 @@ +// +// System.Windows.Forms.Design.WndProcRouter +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev + +// +// 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; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Windows.Forms; +using System.Drawing; +using System.Drawing.Design; +using System.Collections; + + // Automatically reroutes Messages to the designer + // + +namespace System.Windows.Forms.Design +{ + + internal class WndProcRouter : IWindowTarget, IDisposable + { + private IWindowTarget _oldTarget; + private IMessageReceiver _receiver; + private Control _control; + + public WndProcRouter (Control control, IMessageReceiver receiver) + { + if (control == null) + throw new ArgumentNullException ("control"); + if (receiver == null) + throw new ArgumentNullException ("receiver"); + + _oldTarget = control.WindowTarget; + _control = control; + _receiver = receiver; + } + + public Control Control { + get { return _control; } + } + + public IWindowTarget OldWindowTarget { + get { return _oldTarget; } + } + + // Route the message to the control + // + public void ToControl (ref Message m) + { + //Console.WriteLine ("Control: " + ((Native.Msg)m.Msg).ToString ()); + if (_oldTarget != null) + _oldTarget.OnMessage (ref m); + } + + public void ToSystem (ref Message m) + { + //Console.WriteLine ("System: " + ((Native.Msg)m.Msg).ToString ()); + Native.DefWndProc (ref m); + } + + // Just pass it to the old IWindowTarget + // + void IWindowTarget.OnHandleChange (IntPtr newHandle) + { + if (_oldTarget != null) + _oldTarget.OnHandleChange (newHandle); + } + + // Route the msg to the designer if available, else to + // control itself. + // + void IWindowTarget.OnMessage (ref Message m) + { + //Console.WriteLine ("Message: " + ((Native.Msg)m.Msg).ToString ()); + if (_receiver != null) + _receiver.WndProc (ref m); + else + this.ToControl (ref m); + } + + // Disposes and puts back the old IWindowTarget + // + public void Dispose () + { + if (_control != null) + _control.WindowTarget = _oldTarget; + + _control = null; + _oldTarget = null; + } + + } +} diff --git a/mcs/class/System/ChangeLog b/mcs/class/System/ChangeLog index 0fcbcbd0786..fa394cdb05c 100644 --- a/mcs/class/System/ChangeLog +++ b/mcs/class/System/ChangeLog @@ -1,3 +1,10 @@ +2007-08-29 Ivan N. Zlatev <contact@i-nz.net> + + * System.dll.sources: add DefaultSerializationProviderAttribute.cs, + ComponentSerializationService.cs, MemberRelationship.cs, + SerializationStore.cs, MemberRelationshipService.cs, + DesignerOptionService.cs, ITreeDesigner.cs + 2007-08-29 Atsushi Enomoto <atsushi@ximian.com> * System.dll.sources : added Win32NetworkInterfaceMarshal.cs. diff --git a/mcs/class/System/System.ComponentModel.Design.Serialization/ComponentSerializationService.cs b/mcs/class/System/System.ComponentModel.Design.Serialization/ComponentSerializationService.cs new file mode 100644 index 00000000000..ebb76699f75 --- /dev/null +++ b/mcs/class/System/System.ComponentModel.Design.Serialization/ComponentSerializationService.cs @@ -0,0 +1,68 @@ +// +// System.ComponentModel.Design.Serialization.ComponentSerializationService +// +// Authors: +// Ivan N. Zlatev (contact@i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.ComponentModel; +using System.Collections; +using System.IO; + +namespace System.ComponentModel.Design.Serialization +{ + public abstract class ComponentSerializationService + { + + protected ComponentSerializationService () + { + } + + public abstract SerializationStore CreateStore (); + public abstract ICollection Deserialize (SerializationStore store); + public abstract ICollection Deserialize (SerializationStore store, IContainer container); + public abstract SerializationStore LoadStore (Stream stream); + public abstract void Serialize (SerializationStore store, object value); + public abstract void SerializeAbsolute (SerializationStore store, object value); + public abstract void SerializeMember (SerializationStore store, object owningObject, MemberDescriptor member); + public abstract void SerializeMemberAbsolute (SerializationStore store, object owningObject, MemberDescriptor member); + + public void DeserializeTo (SerializationStore store, IContainer container) + { + DeserializeTo (store, container, true); + } + + public void DeserializeTo (SerializationStore store, IContainer container, bool validateRecycledTypes) + { + DeserializeTo (store, container, validateRecycledTypes, true); + } + + public abstract void DeserializeTo (SerializationStore store, IContainer container, bool validateRecycledTypes, bool applyDefaults); + } +} +#endif diff --git a/mcs/class/System/System.ComponentModel.Design.Serialization/DefaultSerializationProviderAttribute.cs b/mcs/class/System/System.ComponentModel.Design.Serialization/DefaultSerializationProviderAttribute.cs new file mode 100644 index 00000000000..4dd9d2bbba6 --- /dev/null +++ b/mcs/class/System/System.ComponentModel.Design.Serialization/DefaultSerializationProviderAttribute.cs @@ -0,0 +1,67 @@ +// +// System.ComponentModel.Design.Serialization.DefaultSerializationProviderAttribute +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; + +namespace System.ComponentModel.Design.Serialization +{ + + [AttributeUsageAttribute (AttributeTargets.Class, Inherited=false)] + public sealed class DefaultSerializationProviderAttribute : Attribute + { + + private string _providerTypeName; + + public DefaultSerializationProviderAttribute (string providerTypeName) + { + if (providerTypeName == null) + throw new ArgumentNullException ("providerTypeName"); + + _providerTypeName = providerTypeName; + } + + public DefaultSerializationProviderAttribute (Type providerType) + { + if (providerType == null) + throw new ArgumentNullException ("providerType"); + + _providerTypeName = providerType.AssemblyQualifiedName; + } + + public string ProviderTypeName { + get { return _providerTypeName; } + } + } +} +#endif diff --git a/mcs/class/System/System.ComponentModel.Design.Serialization/MemberRelationship.cs b/mcs/class/System/System.ComponentModel.Design.Serialization/MemberRelationship.cs new file mode 100644 index 00000000000..008dba9f1d8 --- /dev/null +++ b/mcs/class/System/System.ComponentModel.Design.Serialization/MemberRelationship.cs @@ -0,0 +1,93 @@ +// +// System.ComponentModel.Design.Serialization.MemberRelationship +// +// Authors: +// Ivan N. Zlatev (contact@i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.CodeDom; +using System.ComponentModel; + +namespace System.ComponentModel.Design.Serialization +{ + public struct MemberRelationship + { + + public static readonly MemberRelationship Empty = new MemberRelationship (); + + private object _owner; + private MemberDescriptor _member; + + public MemberRelationship (object owner, MemberDescriptor member) + { + _owner = owner; + _member = member; + } + + public bool IsEmpty { + get { return (_owner == null); } + } + + public object Owner { + get { return _owner; } + } + + public MemberDescriptor Member { + get { return _member; } + } + + public static bool operator == (MemberRelationship left, MemberRelationship right) + { + if (left.Owner == right.Owner && left.Member == right.Member) + return true; + else + return false; + } + + public static bool operator != (MemberRelationship left, MemberRelationship right) + { + return !(left == right); + } + + public override int GetHashCode () + { + if (_owner != null && _member != null) + return _member.GetHashCode () ^ _owner.GetHashCode (); + return base.GetHashCode (); + } + + public override bool Equals (object o) + { + if (o is MemberRelationship) { + return ((MemberRelationship)o) == this; + } + return false; + } + } +} +#endif diff --git a/mcs/class/System/System.ComponentModel.Design.Serialization/MemberRelationshipService.cs b/mcs/class/System/System.ComponentModel.Design.Serialization/MemberRelationshipService.cs new file mode 100644 index 00000000000..107a8e389e8 --- /dev/null +++ b/mcs/class/System/System.ComponentModel.Design.Serialization/MemberRelationshipService.cs @@ -0,0 +1,140 @@ +// +// System.ComponentModel.Design.Serialization.MemberRelationshipService +// +// Authors: +// Ivan N. Zlatev (contact@i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.CodeDom; +using System.ComponentModel; +using System.Collections; + +namespace System.ComponentModel.Design.Serialization +{ + public abstract class MemberRelationshipService + { + + // MSDN: The default implementation stores relationships in a dictionary using weak references + // so the relationship table does not keep objects alive. + // + private class MemberRelationshipWeakEntry + { + + private WeakReference _ownerWeakRef; + private MemberDescriptor _member; + + public MemberRelationshipWeakEntry (MemberRelationship relation) + { + _ownerWeakRef = new WeakReference (relation.Owner); + _member = relation.Member; + } + + public object Owner { + get { + if (_ownerWeakRef.IsAlive) + return _ownerWeakRef.Target; + return null; + } + } + + public MemberDescriptor Member { + get { return _member; } + } + + public static bool operator == (MemberRelationshipWeakEntry left, MemberRelationshipWeakEntry right) + { + if (left.Owner == right.Owner && left.Member == right.Member) + return true; + else + return false; + } + + public static bool operator != (MemberRelationshipWeakEntry left, MemberRelationshipWeakEntry right) + { + return !(left == right); + } + + public override int GetHashCode () + { + if (this.Owner != null && _member != null) + return _member.GetHashCode () ^ _ownerWeakRef.Target.GetHashCode (); + return base.GetHashCode (); + } + + public override bool Equals (object o) + { + if (o is MemberRelationshipWeakEntry) { + return ((MemberRelationshipWeakEntry) o) == this; + } + return false; + } + } + + private Hashtable _relations; + + protected MemberRelationshipService () + { + _relations = new Hashtable (); + } + + public abstract bool SupportsRelationship (MemberRelationship source, MemberRelationship relationship); + + protected virtual MemberRelationship GetRelationship (MemberRelationship source) + { + if (source.IsEmpty) + throw new ArgumentNullException ("source"); + + MemberRelationshipWeakEntry entry = _relations[new MemberRelationshipWeakEntry (source)] as MemberRelationshipWeakEntry; + if (entry != null) + return new MemberRelationship (entry.Owner, entry.Member); + return MemberRelationship.Empty; + } + + protected virtual void SetRelationship (MemberRelationship source, MemberRelationship relationship) + { + if (source.IsEmpty) + throw new ArgumentNullException ("source"); + + if (!relationship.IsEmpty && !this.SupportsRelationship (source, relationship)) + throw new ArgumentException ("Relationship not supported."); + + _relations[new MemberRelationshipWeakEntry (source)] = new MemberRelationshipWeakEntry (relationship); + } + + public MemberRelationship this [object owner, MemberDescriptor member] { + get { return GetRelationship (new MemberRelationship (owner, member)); } + set { SetRelationship (new MemberRelationship (owner, member), value); } + } + + public MemberRelationship this [MemberRelationship source] { + get { return GetRelationship (source); } + set { SetRelationship (source, value); } + } + } +} +#endif diff --git a/mcs/class/System/System.ComponentModel.Design.Serialization/SerializationStore.cs b/mcs/class/System/System.ComponentModel.Design.Serialization/SerializationStore.cs new file mode 100644 index 00000000000..406b18b181f --- /dev/null +++ b/mcs/class/System/System.ComponentModel.Design.Serialization/SerializationStore.cs @@ -0,0 +1,58 @@ +// +// System.ComponentModel.Design.Serialization.SerializationStore +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.IO; + +namespace System.ComponentModel.Design.Serialization +{ + public abstract class SerializationStore : IDisposable + { + public SerializationStore () + { + } + + public abstract void Close (); + public abstract void Save (Stream stream); + + public void Dispose (bool disposing) + { + if (disposing) + this.Close (); + } + + void IDisposable.Dispose () + { + this.Dispose (true); + } + } +} +#endif diff --git a/mcs/class/System/System.ComponentModel.Design/Changelog b/mcs/class/System/System.ComponentModel.Design/Changelog index 22f534adcf8..28c9f78d24a 100644 --- a/mcs/class/System/System.ComponentModel.Design/Changelog +++ b/mcs/class/System/System.ComponentModel.Design/Changelog @@ -1,3 +1,10 @@ +2007-08-29 Ivan N. Zlatev <contact@i-nz.net> + + * DefaultSerializationProviderAttribute.cs: implemented. + * ComponentSerializationService.cs: implemented. + * MemberRelationship.cs: implemented. + * SerializationStore.cs: implemented. + 2007-06-06 Ivan N. Zlatev <contact@i-nz.net> * IComponentInitialization.cs: New 2.0 interface diff --git a/mcs/class/System/System.ComponentModel.Design/DesignerOptionService.cs b/mcs/class/System/System.ComponentModel.Design/DesignerOptionService.cs new file mode 100644 index 00000000000..601dd5340b6 --- /dev/null +++ b/mcs/class/System/System.ComponentModel.Design/DesignerOptionService.cs @@ -0,0 +1,331 @@ +// +// System.ComponentModel.Design.DesignerOptionService +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006-2007 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.Globalization; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + + public class DesignerOptionService : IDesignerOptionService + { + + public sealed class DesignerOptionCollection : IList, ICollection, IEnumerable + { + // PropertyDescriptor objects are taken directly from the value passed to the CreateOptionCollection method + // and are wrapped in an additional property descriptor that hides the value object from the user. This means + // that any value may be passed into the component parameter of the various PropertyDescriptor methods. The + // value is not recognized and is replaced with the correct value internally. + // + public sealed class WrappedPropertyDescriptor : PropertyDescriptor + { + private PropertyDescriptor _property; + private object _component; + + public WrappedPropertyDescriptor (PropertyDescriptor property, object component) : base (property.Name, new Attribute[0]) + { + _property = property; + _component = component; + } + + public override object GetValue (object ignored) + { + return _property.GetValue (_component); + } + + public override void SetValue (object ignored, object value) + { + _property.SetValue (_component, value); + } + + public override bool CanResetValue (object ignored) + { + return _property.CanResetValue (_component); + } + + public override void ResetValue (object ignored) + { + _property.ResetValue (_component); + } + + public override bool ShouldSerializeValue (object ignored) + { + return _property.ShouldSerializeValue (_component); + } + + public override AttributeCollection Attributes { + get { return _property.Attributes; } + } + + public override bool IsReadOnly { + get { return _property.IsReadOnly; } + } + + public override Type ComponentType { + get { return _property.ComponentType; } + } + + public override Type PropertyType { + get { return _property.PropertyType; } + } + } // WrappedPropertyDescriptor + + private string _name; + private object _propertiesProvider; + private DesignerOptionCollection _parent; + private ArrayList _children; + private DesignerOptionService _optionService; + + internal DesignerOptionCollection (DesignerOptionCollection parent, string name, object propertiesProvider, DesignerOptionService service) + { + _name = name; + _propertiesProvider = propertiesProvider; + _parent = parent; + + if (parent != null) { + if (parent._children == null) + parent._children = new ArrayList (); + parent._children.Add (this); + } + + _children = new ArrayList (); + _optionService = service; + service.PopulateOptionCollection (this); + } + + public bool ShowDialog () + { + return _optionService.ShowDialog (this, _propertiesProvider); + } + + public DesignerOptionCollection this[int index] { + get { return (DesignerOptionCollection) _children[index]; } + } + + public DesignerOptionCollection this[string index] { + get { + foreach (DesignerOptionCollection dc in _children) { + if (String.Compare (dc.Name, index, true, CultureInfo.InvariantCulture) == 0) + return dc; + } + return null; + } + } + + public string Name { + get { return _name; } + } + + public int Count { + get { + if (_children != null) + return _children.Count; + return 0; + } + } + + public DesignerOptionCollection Parent { + get { return _parent; } + } + + public PropertyDescriptorCollection Properties { + get { + // TypeDescriptor.GetProperties gets only the public properties. + // + PropertyDescriptorCollection properties = TypeDescriptor.GetProperties (_propertiesProvider); + ArrayList wrappedProperties = new ArrayList (properties.Count); + + foreach (PropertyDescriptor pd in properties) + wrappedProperties.Add (new WrappedPropertyDescriptor (pd, _propertiesProvider)); + + PropertyDescriptor[] propertyArray = (PropertyDescriptor[]) wrappedProperties.ToArray (typeof (PropertyDescriptor)); + return new PropertyDescriptorCollection (propertyArray); + } + } + + public IEnumerator GetEnumerator () + { + return _children.GetEnumerator (); + } + + public int IndexOf (DesignerOptionCollection item) + { + return _children.IndexOf (item); + } + + public void CopyTo (Array array, int index) + { + _children.CopyTo (array, index); + } + + bool IList.IsFixedSize { + get { return true; } + } + + bool IList.IsReadOnly { + get { return true; } + } + + object IList.this[int index] { + get { return this[index]; } + set { throw new NotSupportedException (); } + } + + bool ICollection.IsSynchronized { + get { return false; } + } + + object ICollection.SyncRoot { + get { return this; } + } + + bool IList.Contains (object item) + { + return _children.Contains (item); + } + + int IList.IndexOf (object item) + { + return _children.IndexOf (item); + } + + int IList.Add (object item) + { + throw new NotSupportedException (); + } + + void IList.Remove (object item) + { + throw new NotSupportedException (); + } + + void IList.RemoveAt (int index) + { + throw new NotSupportedException (); + } + + void IList.Insert (int index, object item) + { + throw new NotSupportedException (); + } + + void IList.Clear () + { + throw new NotSupportedException (); + } + + } // DesignerOptionCollection + + + private DesignerOptionCollection _options; + + protected internal DesignerOptionService () + { + } + + protected DesignerOptionCollection CreateOptionCollection (DesignerOptionCollection parent, string name, Object value) + { + if (name == null) + throw new ArgumentNullException ("name"); + if (parent == null) + throw new ArgumentNullException ("parent"); + if (name == String.Empty) + throw new ArgumentException ("name.Length == 0"); + + return new DesignerOptionCollection (parent, name, value, this); + } + + protected virtual bool ShowDialog (DesignerOptionCollection options, object optionObject) + { + return false; + } + + protected virtual void PopulateOptionCollection (DesignerOptionCollection options) + { + } + + public DesignerOptionCollection Options { + get { + if (_options == null) + _options = new DesignerOptionCollection (null, String.Empty, null, this); + + return _options; + } + } + + + object IDesignerOptionService.GetOptionValue (string pageName, string valueName) + { + if (pageName == null) + throw new ArgumentNullException ("pageName"); + if (valueName == null) + throw new ArgumentNullException ("valueName"); + + PropertyDescriptor property = GetOptionProperty (pageName, valueName); + if (property != null) + return property.GetValue (null); + + return null; + } + + void IDesignerOptionService.SetOptionValue (string pageName, string valueName, object value) + { + if (pageName == null) + throw new ArgumentNullException ("pageName"); + if (valueName == null) + throw new ArgumentNullException ("valueName"); + + PropertyDescriptor property = GetOptionProperty (pageName, valueName); + if (property != null) + property.SetValue (null, value); + } + + // Go to the page and get the property associated with the option name. + // + private PropertyDescriptor GetOptionProperty (string pageName, string valueName) + { + string[] pages = pageName.Split (new char[] { '\\' }); + + DesignerOptionCollection options = this.Options; + foreach (string page in pages) { + options = options[page]; + if (options == null) + return null; + } + + return options.Properties[valueName]; + } + + } +} +#endif diff --git a/mcs/class/System/System.ComponentModel.Design/ITreeDesigner.cs b/mcs/class/System/System.ComponentModel.Design/ITreeDesigner.cs new file mode 100644 index 00000000000..3762d7d4178 --- /dev/null +++ b/mcs/class/System/System.ComponentModel.Design/ITreeDesigner.cs @@ -0,0 +1,49 @@ +// +// System.ComponentModel.Design.ITreeDesigner +// +// Authors: +// Ivan N. Zlatev (contact i-nZ.net) +// +// (C) 2006 Ivan N. Zlatev + +// +// 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. +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.ComponentModel; + +namespace System.ComponentModel.Design +{ + public interface ITreeDesigner : IDesigner, IDisposable + { + ICollection Children { + get; + } + + IDesigner Parent { + get; + } + } +} +#endif diff --git a/mcs/class/System/System.ComponentModel/ChangeLog b/mcs/class/System/System.ComponentModel/ChangeLog index 57d5405a376..7705c3d106b 100644 --- a/mcs/class/System/System.ComponentModel/ChangeLog +++ b/mcs/class/System/System.ComponentModel/ChangeLog @@ -1,3 +1,8 @@ +2007-08-29 Ivan N. Zlatev <contact@i-nz.net> + + * DesignerOptionService.cs: implemented. + * ITreeDesigner.cs: implemented. + 2007-08-25 Ivan N. Zlatev <contact@i-nz.net> * NestedContainer.cs: implemented. diff --git a/mcs/class/System/System.dll.sources b/mcs/class/System/System.dll.sources index aba9e920413..6dd7fd2467e 100644 --- a/mcs/class/System/System.dll.sources +++ b/mcs/class/System/System.dll.sources @@ -217,6 +217,7 @@ System.ComponentModel.Design/ComponentEventHandler.cs System.ComponentModel.Design/ComponentRenameEventArgs.cs System.ComponentModel.Design/ComponentRenameEventHandler.cs System.ComponentModel.Design/DesignerCollection.cs +System.ComponentModel.Design/DesignerOptionService.cs System.ComponentModel.Design/DesignerEventArgs.cs System.ComponentModel.Design/DesignerEventHandler.cs System.ComponentModel.Design/DesignerTransactionCloseEventArgs.cs @@ -253,12 +254,14 @@ System.ComponentModel.Design/IResourceService.cs System.ComponentModel.Design/IRootDesigner.cs System.ComponentModel.Design/ISelectionService.cs System.ComponentModel.Design/IServiceContainer.cs +System.ComponentModel.Design/ITreeDesigner.cs System.ComponentModel.Design/ITypeDescriptorFilterService.cs System.ComponentModel.Design/ITypeResolutionService.cs System.ComponentModel.Design/MenuCommand.cs System.ComponentModel/DesignOnlyAttribute.cs System.ComponentModel.Design/RuntimeLicenseContext.cs System.ComponentModel.Design/SelectionTypes.cs +System.ComponentModel.Design.Serialization/ComponentSerializationService.cs System.ComponentModel.Design.Serialization/ContextStack.cs System.ComponentModel.Design.Serialization/DesignerLoader.cs System.ComponentModel.Design.Serialization/DesignerSerializerAttribute.cs @@ -269,9 +272,13 @@ System.ComponentModel.Design.Serialization/IDesignerSerializationProvider.cs System.ComponentModel.Design.Serialization/IDesignerSerializationService.cs System.ComponentModel.Design.Serialization/INameCreationService.cs System.ComponentModel.Design.Serialization/InstanceDescriptor.cs +System.ComponentModel.Design.Serialization/MemberRelationship.cs +System.ComponentModel.Design.Serialization/MemberRelationshipService.cs System.ComponentModel.Design.Serialization/ResolveNameEventArgs.cs System.ComponentModel.Design.Serialization/ResolveNameEventHandler.cs System.ComponentModel.Design.Serialization/RootDesignerSerializerAttribute.cs +System.ComponentModel.Design.Serialization/SerializationStore.cs +System.ComponentModel.Design.Serialization/DefaultSerializationProviderAttribute.cs System.ComponentModel.Design/ServiceContainer.cs System.ComponentModel.Design/ServiceCreatorCallback.cs System.ComponentModel.Design/StandardCommands.cs |