/* * PropertyGrid.cs - PropertyGrid wrapper. Hooks into ISelectionService. * * Authors: * Michael Hutchinson * * Copyright (C) 2005 Michael Hutchinson * * This sourcecode is licenced under The MIT License: * * 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.Design; using Gtk; using System.ComponentModel; using System.Collections; using MonoDevelop.DesignerSupport.PropertyGrid; namespace AspNetEdit.Editor.UI { public class PropertyGrid : Gtk.VBox { private ServiceContainer parentServices = null; private ISelectionService selectionService = null; private IExtenderListService extenderListService = null; private IComponentChangeService changeService = null; private ITypeDescriptorFilterService typeDescriptorFilterService = null; private MonoDevelop.DesignerSupport.PropertyGrid.PropertyGrid grid; private ListStore components; private ComboBox combo; private bool suppressChange = false; public PropertyGrid (ServiceContainer parentServices) { this.parentServices = parentServices; grid = new MonoDevelop.DesignerSupport.PropertyGrid.PropertyGrid (); this.PackEnd (grid, true, true, 0); components = new ListStore (typeof (string), typeof (IComponent)); combo = new ComboBox (components); CellRenderer rdr = new CellRendererText (); combo.PackStart (rdr, true); combo.AddAttribute (rdr, "text", 0); this.PackStart (combo, false, false, 3); //for selecting nothing, i.e. deselect all components.AppendValues (new object[] { "", null} ); combo.Changed += new EventHandler (combo_Changed); InitialiseServices(); } void combo_Changed (object sender, EventArgs e) { if (suppressChange) return; TreeIter t; combo.GetActiveIter(out t); IComponent comp = (IComponent) components.GetValue(t, 1); //Tell everybody about the new selection. We'll hear about this too. selectionService.SetSelectedComponents ((comp == null)? null : new IComponent[] { comp }); } // We need these services to be present, but we cache references for efficiency // Whenever new designer host loaded etc, must reinitialise the services public void InitialiseServices () { //unregister old event handlers if (selectionService != null) selectionService.SelectionChanged -= new EventHandler(selectionService_SelectionChanged); //update references extenderListService = parentServices.GetService (typeof (IExtenderListService)) as IExtenderListService; selectionService = parentServices.GetService (typeof (ISelectionService)) as ISelectionService; changeService = parentServices.GetService (typeof (IComponentChangeService)) as IComponentChangeService; typeDescriptorFilterService = parentServices.GetService (typeof (ITypeDescriptorFilterService)) as ITypeDescriptorFilterService; //register event handlers if (selectionService != null) selectionService.SelectionChanged += new EventHandler (selectionService_SelectionChanged); if (changeService != null) { changeService.ComponentAdded += new ComponentEventHandler (changeService_ComponentAdded); changeService.ComponentRemoved += new ComponentEventHandler (changeService_ComponentRemoved); changeService.ComponentRename += new ComponentRenameEventHandler (changeService_ComponentRename); changeService.ComponentChanged += new ComponentChangedEventHandler (changeService_updateValues); /*TODO: should we also monitor these? changeService.ComponentAdding changeService.ComponentChanging changeService.ComponentRemoving */ } //get existing components for combo list IDesignerHost host = parentServices.GetService (typeof (IDesignerHost)) as IDesignerHost; if (host != null) foreach (IComponent comp in host.Container.Components) changeService_ComponentAdded(host.Container, new ComponentEventArgs (comp)); } void changeService_updateValues (object sender, ComponentChangedEventArgs e) { grid.Refresh (); } void changeService_ComponentRename (object sender, ComponentRenameEventArgs e) { //We just need to rename the right component in the combobox list TreeIter t; components.GetIterFirst (out t); do { if ((IComponent)components.GetValue (t, 1) == e.Component && (string) components.GetValue(t, 0) == e.OldName) { components.SetValue (t, 0, e.NewName); return; } } while (components.IterNext (ref t)); } void changeService_ComponentRemoved (object sender, ComponentEventArgs e) { //remove component from combobox list //need a variable external to foreach so we can pass by ref TreeIter iter; components.GetIterFirst (out iter); do { if ((IComponent) components.GetValue (iter, 1) == e.Component) { components.Remove (ref iter); break; } } while (components.IterNext (ref iter)); } void changeService_ComponentAdded (object sender, ComponentEventArgs e) { //simply add to the combobox list components.AppendValues (new object[] { e.Component.Site.Name, e.Component} ); } private void selectionService_SelectionChanged (object sender, EventArgs e) { //stop combo change event from changing selection again! suppressChange = true; grid.CurrentObject = selectionService.PrimarySelection; TreeIter iter; components.GetIterFirst (out iter); do { if ((IComponent) components.GetValue (iter, 1) == selectionService.PrimarySelection) { combo.SetActiveIter (iter); break; } } while (components.IterNext (ref iter)); suppressChange = false; } } }