Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLluis Sanchez <lluis@novell.com>2010-03-17 15:35:28 +0300
committerLluis Sanchez <lluis@novell.com>2010-03-17 15:35:28 +0300
commit8fa37870e9cc22ffccdd494fa951b2c3807d7978 (patch)
treebda14806802947c51676c183b08f166878964c40 /main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors
parentf1a8582658af8aeb0f6fa459965a2e4d0684c347 (diff)
parent585086f0ea0a49166046bb8f48d2def87907d0e0 (diff)
Merged MD.Projects into MD.Core, and MD.Projects.Gui, MD.Core.Gui and MD.Components into MD.Ide.
svn path=/trunk/monodevelop/; revision=153730
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors')
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/BooleanEditorCell.cs92
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/CharPropertyEditor.cs73
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/CollectionEditor.cs359
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/ColorEditorCell.cs115
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/DateTimeEditor.cs98
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/DefaultEditor.cs49
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/EnumerationEditorCell.cs144
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/EventEditor.cs135
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/ExpandableObjectEditor.cs65
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FlagsEditorCell.cs205
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FlagsSelectorDialog.cs117
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FloatRange.cs69
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/IntRange.cs103
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TextEditor.cs193
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TextEditorDialog.cs78
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TimeSpanEditor.cs93
16 files changed, 1988 insertions, 0 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/BooleanEditorCell.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/BooleanEditorCell.cs
new file mode 100644
index 0000000000..747735037d
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/BooleanEditorCell.cs
@@ -0,0 +1,92 @@
+//
+// BooleanEditorCell.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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.ComponentModel;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ [PropertyEditorType (typeof (bool))]
+ public class BooleanEditorCell : PropertyEditorCell
+ {
+ static int indicatorSize;
+ static int indicatorSpacing;
+
+ static BooleanEditorCell ()
+ {
+ Gtk.CheckButton cb = new Gtk.CheckButton ();
+ indicatorSize = (int) cb.StyleGetProperty ("indicator-size");
+ indicatorSpacing = (int) cb.StyleGetProperty ("indicator-spacing");
+ }
+
+ public override void GetSize (int availableWidth, out int width, out int height)
+ {
+ width = 20;
+ height = 20;
+ }
+
+ public override void Render (Gdk.Drawable window, Gdk.Rectangle bounds, Gtk.StateType state)
+ {
+ Gtk.ShadowType sh = (bool) Value ? Gtk.ShadowType.In : Gtk.ShadowType.Out;
+ int s = indicatorSize - 1;
+ if (s > bounds.Height)
+ s = bounds.Height;
+ if (s > bounds.Width)
+ s = bounds.Width;
+ Gtk.Style.PaintCheck (Container.Style, window, state, sh, bounds, Container, "checkbutton", bounds.X + indicatorSpacing - 1, bounds.Y + (bounds.Height - s)/2, s, s);
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new BooleanEditor ();
+ }
+ }
+
+ public class BooleanEditor : Gtk.CheckButton, IPropertyEditor
+ {
+ public void Initialize (EditSession session)
+ {
+ if (session.Property.PropertyType != typeof(bool))
+ throw new ApplicationException ("Boolean editor does not support editing values of type " + session.Property.PropertyType);
+ }
+
+ public object Value {
+ get { return Active; }
+ set { Active = (bool) value; }
+ }
+
+ protected override void OnToggled ()
+ {
+ base.OnToggled ();
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/CharPropertyEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/CharPropertyEditor.cs
new file mode 100644
index 0000000000..69019a5214
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/CharPropertyEditor.cs
@@ -0,0 +1,73 @@
+//
+// CharPropertyEditor.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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.ComponentModel;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+
+ [PropertyEditorType (typeof (char))]
+ public class CharPropertyEditor : Gtk.Entry, IPropertyEditor
+ {
+ public CharPropertyEditor ()
+ {
+ MaxLength = 1;
+ HasFrame = false;
+ }
+
+ public void Initialize (EditSession session)
+ {
+ if (session.Property.PropertyType != typeof(char))
+ throw new ApplicationException ("Char editor does not support editing values of type " + session.Property.PropertyType);
+ }
+
+ char last;
+
+ public object Value {
+ get {
+ if (Text.Length == 0)
+ return last;
+ else
+ return Text[0];
+ }
+ set {
+ Text = value.ToString ();
+ last = (char) value;
+ }
+ }
+
+ protected override void OnChanged ()
+ {
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/CollectionEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/CollectionEditor.cs
new file mode 100644
index 0000000000..067e6676e7
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/CollectionEditor.cs
@@ -0,0 +1,359 @@
+/*
+ * CollectionEditor.cs - The base class for the visual type editors
+ *
+ * Part of PropertyGrid - A Gtk# widget that displays and allows
+ * editing of all of an object's public properties
+ *
+ * Authors:
+ * Michael Hutchinson <m.j.hutchinson@gmail.com>
+ *
+ * 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 Gtk;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Collections;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ class CollectionEditor : PropertyEditorCell
+ {
+ //TODO: Support for multiple object types
+ private Type[] types;
+
+ protected override void Initialize ()
+ {
+ base.Initialize ();
+ this.types = new Type[] { EditorManager.GetCollectionItemType (Property.PropertyType) };
+ }
+
+ protected virtual Type[] NewItemTypes ()
+ {
+ return types;
+ }
+
+ public override bool DialogueEdit
+ {
+ get { return true; }
+ }
+
+ public override bool EditsReadOnlyObject {
+ get { return true; }
+ }
+
+ protected override string GetValueText ()
+ {
+ return MonoDevelop.Core.GettextCatalog.GetString ("(Collection)");
+ }
+
+ public override void LaunchDialogue ()
+ {
+ //the Type in the collection
+ IList collection = (IList) Value;
+ string displayName = Property.DisplayName;
+
+ //populate list with existing items
+ ListStore itemStore = new ListStore (typeof (object), typeof (int), typeof (string));
+ for (int i=0; i<collection.Count; i++)
+ itemStore.AppendValues(collection [i], i, collection [i].ToString ());
+
+ #region Building Dialogue
+
+ TreeView itemTree;
+ PropertyGrid grid;
+ TreeIter previousIter = TreeIter.Zero;
+
+ //dialogue and buttons
+ Dialog dialog = new Dialog () {
+ Title = displayName + " Editor",
+ Modal = true,
+ AllowGrow = true,
+ AllowShrink = true,
+ };
+ var toplevel = this.Container.Toplevel as Window;
+ if (toplevel != null)
+ dialog.TransientFor = toplevel;
+
+ dialog.AddActionWidget (new Button (Stock.Cancel), ResponseType.Cancel);
+ dialog.AddActionWidget (new Button (Stock.Ok), ResponseType.Ok);
+
+ //three columns for items, sorting, PropGrid
+ HBox hBox = new HBox ();
+ dialog.VBox.PackStart (hBox, true, true, 5);
+
+ //propGrid at end
+ grid = new PropertyGrid (base.EditorManager) {
+ CurrentObject = null,
+ WidthRequest = 200,
+ ShowHelp = false
+ };
+ hBox.PackEnd (grid, true, true, 5);
+
+ //followed by a ButtonBox
+ VBox buttonBox = new VBox ();
+ buttonBox.Spacing = 6;
+ hBox.PackEnd (buttonBox, false, false, 5);
+
+ //add/remove buttons
+ Button addButton = new Button (new Image (Stock.Add, IconSize.Button));
+ buttonBox.PackStart (addButton, false, false, 0);
+ if (types [0].IsAbstract)
+ addButton.Sensitive = false;
+ Button removeButton = new Button (new Gtk.Image (Stock.Remove, IconSize.Button));
+ buttonBox.PackStart (removeButton, false, false, 0);
+
+ //sorting buttons
+ Button upButton = new Button (new Image (Stock.GoUp, IconSize.Button));
+ buttonBox.PackStart (upButton, false, false, 0);
+ Button downButton = new Button (new Image (Stock.GoDown, IconSize.Button));
+ buttonBox.PackStart (downButton, false, false, 0);
+
+ //Third column has list (TreeView) in a ScrolledWindow
+ ScrolledWindow listScroll = new ScrolledWindow ();
+ listScroll.WidthRequest = 200;
+ listScroll.HeightRequest = 320;
+ hBox.PackStart (listScroll, false, false, 5);
+
+ itemTree = new TreeView (itemStore);
+ itemTree.Selection.Mode = SelectionMode.Single;
+ itemTree.HeadersVisible = false;
+ listScroll.AddWithViewport (itemTree);
+
+ //renderers and attribs for TreeView
+ CellRenderer rdr = new CellRendererText ();
+ itemTree.AppendColumn (new TreeViewColumn ("Index", rdr, "text", 1));
+ rdr = new CellRendererText ();
+ itemTree.AppendColumn (new TreeViewColumn ("Object", rdr, "text", 2));
+
+ #endregion
+
+ #region Events
+
+ addButton.Clicked += delegate {
+ //create the object
+ object instance = System.Activator.CreateInstance (types[0]);
+
+ //get existing selection and insert after it
+ TreeIter oldIter, newIter;
+ if (itemTree.Selection.GetSelected (out oldIter))
+ newIter = itemStore.InsertAfter (oldIter);
+ //or append if no previous selection
+ else
+ newIter = itemStore.Append ();
+ itemStore.SetValue (newIter, 0, instance);
+
+ //select, set name and update all the indices
+ itemTree.Selection.SelectIter (newIter);
+ UpdateName (itemStore, newIter);
+ UpdateIndices (itemStore);
+ };
+
+ removeButton.Clicked += delegate {
+ //get selected iter and the replacement selection
+ TreeIter iter, newSelection;
+ if (!itemTree.Selection.GetSelected (out iter))
+ return;
+
+ newSelection = iter;
+ if (!IterPrev (itemStore, ref newSelection)) {
+ newSelection = iter;
+ if (!itemStore.IterNext (ref newSelection))
+ newSelection = TreeIter.Zero;
+ }
+
+ //new selection. Zeroing previousIter prevents trying to update name of deleted iter.
+ previousIter = TreeIter.Zero;
+ if (itemStore.IterIsValid (newSelection))
+ itemTree.Selection.SelectIter (newSelection);
+
+ //and the removal and index update
+ itemStore.Remove (ref iter);
+ UpdateIndices (itemStore);
+ };
+
+ upButton.Clicked += delegate {
+ TreeIter iter, prev;
+ if (!itemTree.Selection.GetSelected (out iter))
+ return;
+
+ //get previous iter
+ prev = iter;
+ if (!IterPrev (itemStore, ref prev))
+ return;
+
+ //swap the two
+ itemStore.Swap (iter, prev);
+
+ //swap indices too
+ object prevVal = itemStore.GetValue (prev, 1);
+ object iterVal = itemStore.GetValue (iter, 1);
+ itemStore.SetValue (prev, 1, iterVal);
+ itemStore.SetValue (iter, 1, prevVal);
+ };
+
+ downButton.Clicked += delegate {
+ TreeIter iter, next;
+ if (!itemTree.Selection.GetSelected (out iter))
+ return;
+
+ //get next iter
+ next = iter;
+ if (!itemStore.IterNext (ref next))
+ return;
+
+ //swap the two
+ itemStore.Swap (iter, next);
+
+ //swap indices too
+ object nextVal = itemStore.GetValue (next, 1);
+ object iterVal = itemStore.GetValue (iter, 1);
+ itemStore.SetValue (next, 1, iterVal);
+ itemStore.SetValue (iter, 1, nextVal);
+ };
+
+ itemTree.Selection.Changed += delegate {
+ TreeIter iter;
+ if (!itemTree.Selection.GetSelected (out iter)) {
+ removeButton.Sensitive = false;
+ return;
+ }
+ removeButton.Sensitive = true;
+
+ //update grid
+ object obj = itemStore.GetValue (iter, 0);
+ grid.CurrentObject = obj;
+
+ //update previously selected iter's name
+ UpdateName (itemStore, previousIter);
+
+ //update current selection so we can update
+ //name next selection change
+ previousIter = iter;
+ };
+
+ grid.Changed += delegate {
+ TreeIter iter;
+ if (itemTree.Selection.GetSelected (out iter))
+ UpdateName (itemStore, iter);
+ };
+
+ TreeIter selectionIter;
+ removeButton.Sensitive = itemTree.Selection.GetSelected (out selectionIter);
+
+ dialog.ShowAll ();
+ grid.ShowToolbar = false;
+
+ #endregion
+
+ //show and get response
+ ResponseType response = (ResponseType) dialog.Run();
+ dialog.Destroy ();
+
+ //if 'OK' put items back in collection
+ if (response == ResponseType.Ok)
+ {
+ DesignerTransaction tran = CreateTransaction (Instance);
+ object old = collection;
+
+ try {
+ collection.Clear();
+ foreach (object[] o in itemStore)
+ collection.Add (o[0]);
+ EndTransaction (Instance, tran, old, collection, true);
+ }
+ catch {
+ EndTransaction (Instance, tran, old, collection, false);
+ throw;
+ }
+ }
+ }
+
+ //This and EndTransaction are from Mono internal class System.ComponentModel.ReflectionPropertyDescriptor
+ // Lluis Sanchez Gual (lluis@ximian.com), (C) Novell, Inc, MIT X11 license
+ DesignerTransaction CreateTransaction (object obj)
+ {
+ IComponent com = obj as IComponent;
+ if (com == null || com.Site == null) return null;
+
+ IDesignerHost dh = (IDesignerHost) com.Site.GetService (typeof(IDesignerHost));
+ if (dh == null) return null;
+
+ DesignerTransaction tran = dh.CreateTransaction ();
+ IComponentChangeService ccs = (IComponentChangeService) com.Site.GetService (typeof(IComponentChangeService));
+ if (ccs != null)
+ ccs.OnComponentChanging (com, Property);
+ return tran;
+ }
+
+ void EndTransaction (object obj, DesignerTransaction tran, object oldValue, object newValue, bool commit)
+ {
+ if (tran == null) return;
+
+ if (commit) {
+ IComponent com = obj as IComponent;
+ IComponentChangeService ccs = (IComponentChangeService) com.Site.GetService (typeof(IComponentChangeService));
+ if (ccs != null)
+ ccs.OnComponentChanged (com, Property, oldValue, newValue);
+ tran.Commit ();
+ }
+ else
+ tran.Cancel ();
+ }
+
+ static void UpdateIndices (ListStore itemStore)
+ {
+ TreeIter iter;
+ int i = 0;
+ if (!itemStore.GetIterFirst (out iter))
+ return;
+
+ do {
+ itemStore.SetValue (iter, 1, i);
+ i++;
+ } while (itemStore.IterNext (ref iter));
+ }
+
+ static void UpdateName (ListStore itemStore, TreeIter iter)
+ {
+ if (iter.Equals (TreeIter.Zero))
+ return;
+
+ object item = itemStore.GetValue (iter, 0);
+ string name = item.ToString ();
+ if (string.IsNullOrEmpty (name))
+ name = MonoDevelop.Core.GettextCatalog.GetString ("(Empty)");;
+
+ itemStore.SetValue(iter, 2, name);
+ }
+
+ //generally useful function... why not in model already?
+ static bool IterPrev (TreeModel model, ref TreeIter iter)
+ {
+ TreePath tp = model.GetPath (iter);
+ return tp.Prev() && model.GetIter (out iter, tp);
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/ColorEditorCell.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/ColorEditorCell.cs
new file mode 100644
index 0000000000..af94facd33
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/ColorEditorCell.cs
@@ -0,0 +1,115 @@
+//
+// BooleanEditorCell.cs
+//
+// Author:
+// Lluis Sanchez Gual
+// Michael Hutchinson <m.j.hutchinson@gmail.com>
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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.ComponentModel;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ [PropertyEditorType (typeof (System.Drawing.Color))]
+ public class ColorEditorCell: PropertyEditorCell
+ {
+ const int ColorBoxSize = 16;
+ const int ColorBoxSpacing = 3;
+
+ public override void GetSize (int availableWidth, out int width, out int height)
+ {
+ base.GetSize (availableWidth - ColorBoxSize - ColorBoxSpacing, out width, out height);
+ width += ColorBoxSize + ColorBoxSpacing;
+ if (height < ColorBoxSize) height = ColorBoxSize;
+ }
+
+ protected override string GetValueText ()
+ {
+ System.Drawing.Color color = (System.Drawing.Color) Value;
+ //TODO: dropdown known color selector so this does something
+ if (color.IsKnownColor)
+ return color.Name;
+ else if (color.IsEmpty)
+ return "";
+ else
+ return String.Format("#{0:x2}{1:x2}{2:x2}", color.R, color.G, color.B);
+ }
+
+ public override void Render (Gdk.Drawable window, Gdk.Rectangle bounds, Gtk.StateType state)
+ {
+ Gdk.GC gc = new Gdk.GC (window);
+ gc.RgbFgColor = GetColor ();
+ int yd = (bounds.Height - ColorBoxSize) / 2;
+ window.DrawRectangle (gc, true, bounds.X, bounds.Y + yd, ColorBoxSize - 1, ColorBoxSize - 1);
+ window.DrawRectangle (Container.Style.BlackGC, false, bounds.X, bounds.Y + yd, ColorBoxSize - 1, ColorBoxSize - 1);
+ bounds.X += ColorBoxSize + ColorBoxSpacing;
+ bounds.Width -= ColorBoxSize + ColorBoxSpacing;
+ base.Render (window, bounds, state);
+ }
+
+ private Gdk.Color GetColor ()
+ {
+ System.Drawing.Color color = (System.Drawing.Color) Value;
+ //TODO: Property.Converter.ConvertTo() fails: why?
+ return new Gdk.Color (color.R, color.G, color.B);
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new ColorEditor ();
+ }
+ }
+
+ public class ColorEditor : Gtk.ColorButton, IPropertyEditor
+ {
+ public void Initialize (EditSession session)
+ {
+ if (session.Property.PropertyType != typeof(System.Drawing.Color))
+ throw new ApplicationException ("Color editor does not support editing values of type " + session.Property.PropertyType);
+ }
+
+ public object Value {
+ get {
+ int red = (int) (255 * (float) Color.Red / ushort.MaxValue);
+ int green = (int) (255 * (float) Color.Green / ushort.MaxValue);
+ int blue = (int) (255 * (float) Color.Blue / ushort.MaxValue);
+ return System.Drawing.Color.FromArgb (red, green, blue);
+ }
+ set {
+ System.Drawing.Color color = (System.Drawing.Color) value;
+ Color = new Gdk.Color (color.R, color.G, color.B);
+ }
+ }
+
+ protected override void OnColorSet ()
+ {
+ base.OnColorSet ();
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ public event EventHandler ValueChanged;
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/DateTimeEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/DateTimeEditor.cs
new file mode 100644
index 0000000000..0e2f6e1be7
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/DateTimeEditor.cs
@@ -0,0 +1,98 @@
+//
+// DateTimeEditorCell.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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 Gtk;
+using Gdk;
+using System.Text;
+using System.ComponentModel;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ [PropertyEditorType (typeof (DateTime))]
+ public class DateTimeEditorCell: PropertyEditorCell
+ {
+ protected override string GetValueText ()
+ {
+ return ((DateTime)Value).ToLongDateString ();
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new DateTimeEditor ();
+ }
+ }
+
+ public class DateTimeEditor: Gtk.HBox, IPropertyEditor
+ {
+ Gtk.Entry entry;
+ DateTime time;
+
+ public DateTimeEditor()
+ {
+ entry = new Gtk.Entry ();
+ entry.Changed += OnChanged;
+ entry.HasFrame = false;
+ PackStart (entry, true, true, 0);
+ ShowAll ();
+ }
+
+ public void Initialize (EditSession session)
+ {
+ }
+
+ public object Value {
+ get { return time; }
+ set {
+ time = (DateTime) value;
+ entry.Changed -= OnChanged;
+ entry.Text = time.ToString ("G");
+ entry.Changed += OnChanged;
+ }
+ }
+
+ void OnChanged (object o, EventArgs a)
+ {
+ string s = entry.Text;
+
+ foreach (string form in formats) {
+ try {
+ time = DateTime.ParseExact (s, form, null);
+ if (ValueChanged != null)
+ ValueChanged (this, a);
+ break;
+ } catch {
+ }
+ }
+ }
+
+ public event EventHandler ValueChanged;
+
+ static string[] formats = {"u", "G", "g", "d", "T", "t"};
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/DefaultEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/DefaultEditor.cs
new file mode 100644
index 0000000000..f05387164f
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/DefaultEditor.cs
@@ -0,0 +1,49 @@
+/*
+ * DefaultEditor.cs - The default visual 'editor' for types we don't have
+ * an editor for.
+ *
+ * Part of PropertyGrid - A Gtk# widget that displays and allows
+ * editing of all of an object's public properties
+ *
+ * Authors:
+ * Michael Hutchinson <m.j.hutchinson@gmail.com>
+ * Lluis Sanchez Gual
+ *
+ * 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 Gtk;
+using System.ComponentModel;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ public class DefaultEditor : PropertyEditorCell
+ {
+ protected override string GetValueMarkup ()
+ {
+ return "<span foreground=\"grey\">&lt;" + Property.PropertyType.ToString() + "&gt;</span>";
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/EnumerationEditorCell.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/EnumerationEditorCell.cs
new file mode 100644
index 0000000000..f924f87716
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/EnumerationEditorCell.cs
@@ -0,0 +1,144 @@
+//
+// EnumerationEditorCell.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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.Reflection;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ [PropertyEditorType(typeof(System.Enum))]
+ public class EnumerationEditorCell: PropertyEditorCell
+ {
+ protected override string GetValueText ()
+ {
+ if (Value == null)
+ return "";
+
+ string val = Value.ToString ();
+
+ // If the enum value has a Description attribute, return the description
+ foreach (FieldInfo f in Property.PropertyType.GetFields ()) {
+ if (f.Name == val) {
+ DescriptionAttribute att = (DescriptionAttribute) Attribute.GetCustomAttribute (f, typeof(DescriptionAttribute));
+ if (att != null)
+ return att.Description;
+ else
+ return val;
+ }
+ }
+ return val;
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new EnumerationEditor ();
+ }
+ }
+
+ public class EnumerationEditor : Gtk.HBox, IPropertyEditor {
+
+ Gtk.EventBox ebox;
+ Gtk.ComboBoxEntry combo;
+ Array values;
+
+ public EnumerationEditor () : base (false, 0)
+ {
+ }
+
+ public void Initialize (EditSession session)
+ {
+ PropertyDescriptor prop = session.Property;
+
+ if (!prop.PropertyType.IsEnum)
+ throw new ApplicationException ("Enumeration editor does not support editing values of type " + prop.PropertyType);
+
+ values = System.Enum.GetValues (prop.PropertyType);
+ Hashtable names = new Hashtable ();
+ foreach (FieldInfo f in prop.PropertyType.GetFields ()) {
+ DescriptionAttribute att = (DescriptionAttribute) Attribute.GetCustomAttribute (f, typeof(DescriptionAttribute));
+ if (att != null)
+ names [f.Name] = att.Description;
+ else
+ names [f.Name] = f.Name;
+ }
+
+
+ ebox = new Gtk.EventBox ();
+ ebox.Show ();
+ PackStart (ebox, true, true, 0);
+
+ combo = Gtk.ComboBoxEntry.NewText ();
+ combo.Changed += combo_Changed;
+ combo.Entry.IsEditable = false;
+ combo.Entry.CanFocus = false;
+ combo.Entry.HasFrame = false;
+ combo.Entry.HeightRequest = combo.SizeRequest ().Height;
+ combo.Show ();
+ ebox.Add (combo);
+
+ foreach (object value in values) {
+ string str = prop.Converter.ConvertToString (value);
+ if (names.Contains (str))
+ str = (string) names [str];
+ combo.AppendText (str);
+ }
+ }
+
+ protected override void OnDestroyed ()
+ {
+ base.OnDestroyed ();
+ ((IDisposable)this).Dispose ();
+ }
+
+ void IDisposable.Dispose ()
+ {
+ }
+
+ public object Value {
+ get {
+ return values.GetValue (combo.Active);
+ }
+ set {
+ int i = Array.IndexOf (values, value);
+ if (i != -1)
+ combo.Active = i;
+ }
+ }
+
+ public event EventHandler ValueChanged;
+
+ void combo_Changed (object o, EventArgs args)
+ {
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ ebox.TooltipText = Value != null ? Value.ToString () : null;
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/EventEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/EventEditor.cs
new file mode 100644
index 0000000000..a07c47b6ca
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/EventEditor.cs
@@ -0,0 +1,135 @@
+/*
+ * EventEditor.cs - Visual editor for Events
+ *
+ * Part of PropertyGrid - A Gtk# widget that displays and allows
+ * editing of all of an object's public properties
+ *
+ * Authors:
+ * Michael Hutchinson <m.j.hutchinson@gmail.com>
+ * Lluis Sanchez Gual
+ *
+ * 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;
+using System.ComponentModel.Design;
+using System.Collections;
+using Gtk;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ [PropertyEditorType (typeof (Delegate), true)]
+ public class EventEditorCell : PropertyEditorCell
+ {
+ IEventBindingService evtBind;
+
+ protected override void Initialize ()
+ {
+ IComponent comp = Instance as IComponent;
+ evtBind = (IEventBindingService) comp.Site.GetService (typeof (IEventBindingService));
+ base.Initialize ();
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ //get existing method names
+ ICollection IColl = evtBind.GetCompatibleMethods (evtBind.GetEvent (Property)) ;
+ string[] methods = new string [IColl.Count + 1];
+ IColl.CopyTo (methods, 1);
+
+ //add a suggestion
+ methods [0] = evtBind.CreateUniqueMethodName ((IComponent) Instance, evtBind.GetEvent (Property));
+
+ EventEditor combo = new EventEditor (evtBind, methods);
+
+ if (Value != null)
+ combo.Entry.Text = (string) Value;
+
+ combo.WidthRequest = 30; //Don't artificially inflate the width. It expands anyway.
+
+ return combo;
+ }
+
+ }
+
+ class EventEditor: ComboBoxEntry, IPropertyEditor
+ {
+ bool isNull;
+ PropertyDescriptor prop;
+ IEventBindingService evtBind;
+ object component;
+
+ public EventEditor (IEventBindingService evtBind, string[] ops): base (ops)
+ {
+ this.evtBind = evtBind;
+ }
+
+ public void Initialize (EditSession session)
+ {
+ this.prop = session.Property;
+ component = session.Instance;
+ Entry.Destroyed += new EventHandler (entry_Changed);
+ Entry.Activated += new EventHandler (entry_Activated);
+ }
+
+ public object Value {
+ get {
+ //if value was null and new value is empty, leave as null
+ if (Entry.Text.Length == 0 && isNull)
+ return null;
+ else
+ return Entry.Text;
+ }
+ set {
+ isNull = value == null;
+ if (isNull)
+ Entry.Text = "";
+ else
+ Entry.Text = (string) value;
+ }
+ }
+
+ protected override void OnChanged ()
+ {
+ if (component == null)
+ return;
+ entry_Changed (this, null);
+ evtBind.ShowCode ((IComponent) component, evtBind.GetEvent (prop));
+ }
+
+ void entry_Activated (object sender, EventArgs e)
+ {
+ entry_Changed (sender, e);
+ evtBind.ShowCode ((IComponent) component, evtBind.GetEvent (prop));
+ }
+
+ void entry_Changed (object sender, EventArgs e)
+ {
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+
+ public event EventHandler ValueChanged;
+ }
+} \ No newline at end of file
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/ExpandableObjectEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/ExpandableObjectEditor.cs
new file mode 100644
index 0000000000..83b471600a
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/ExpandableObjectEditor.cs
@@ -0,0 +1,65 @@
+/*
+ * ExpandableObjectEditor.cs - Temporary editor until we get expandable object support in main grid
+ *
+ * Part of PropertyGrid - A Gtk# widget that displays and allows
+ * editing of all of an object's public properties
+ *
+ * Authors:
+ * Michael Hutchinson <m.j.hutchinson@gmail.com>
+ * Lluis Sanchez Gual
+ *
+ * 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 Gtk;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Collections;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ class ExpandableObjectEditor : PropertyEditorCell
+ {
+ protected override string GetValueMarkup ()
+ {
+ string val;
+ if (Property.Converter.CanConvertTo (typeof(string)))
+ val = Property.Converter.ConvertToString (Value);
+ else
+ val = Value != null ? Value.ToString () : "";
+
+ return "<b>" + GLib.Markup.EscapeText (val) + "</b>";
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, StateType state)
+ {
+ if (Property.Converter.CanConvertTo (typeof(string)) && Property.Converter.CanConvertFrom (typeof(string)))
+ return new TextEditor ();
+ else
+ return null;
+ }
+
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FlagsEditorCell.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FlagsEditorCell.cs
new file mode 100644
index 0000000000..3f51ea4903
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FlagsEditorCell.cs
@@ -0,0 +1,205 @@
+//
+// FlagsEditorCell.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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 Gtk;
+using System;
+using System.Collections;
+using System.ComponentModel;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors {
+
+ public class FlagsEditorCell: PropertyEditorCell
+ {
+ protected override string GetValueText ()
+ {
+ if (Value == null)
+ return "";
+
+ ulong value = Convert.ToUInt64 (Value);
+ Array values = System.Enum.GetValues (base.Property.PropertyType);
+ string txt = "";
+ foreach (object val in values) {
+ if ((value & Convert.ToUInt64 (value)) != 0) {
+ if (txt.Length > 0) txt += ", ";
+ txt += val.ToString ();
+ }
+ }
+ return txt;
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new FlagsEditor ();
+ }
+ }
+
+ public class FlagsEditor : Gtk.HBox, IPropertyEditor
+ {
+ Hashtable flags;
+ Gtk.Entry flagsLabel;
+ string property;
+ Type propType;
+ Array values;
+
+ public FlagsEditor ()
+ {
+ }
+
+ public void Initialize (EditSession session)
+ {
+ PropertyDescriptor prop = session.Property;
+
+ if (!prop.PropertyType.IsEnum)
+ throw new ApplicationException ("Flags editor does not support editing values of type " + prop.PropertyType);
+
+ Spacing = 3;
+ propType = prop.PropertyType;
+
+ property = prop.Description;
+ if (property == null || property.Length == 0)
+ property = prop.Name;
+
+ // For small enums, the editor is a list of checkboxes inside a frame
+ // For large enums (>5), use a selector dialog.
+
+ values = System.Enum.GetValues (prop.PropertyType);
+
+ if (values.Length < 6)
+ {
+ Gtk.VBox vbox = new Gtk.VBox (true, 3);
+
+ flags = new Hashtable ();
+
+ foreach (object value in values) {
+ Gtk.CheckButton check = new Gtk.CheckButton (value.ToString ());
+ check.TooltipText = value.ToString ();
+ ulong uintVal = Convert.ToUInt64 (value);
+ flags[check] = uintVal;
+ flags[uintVal] = check;
+
+ check.Toggled += FlagToggled;
+ vbox.PackStart (check, false, false, 0);
+ }
+
+ Gtk.Frame frame = new Gtk.Frame ();
+ frame.Add (vbox);
+ frame.ShowAll ();
+ PackStart (frame, true, true, 0);
+ }
+ else
+ {
+ flagsLabel = new Gtk.Entry ();
+ flagsLabel.IsEditable = false;
+ flagsLabel.HasFrame = false;
+ flagsLabel.ShowAll ();
+ PackStart (flagsLabel, true, true, 0);
+
+ Gtk.Button but = new Gtk.Button ("...");
+ but.Clicked += OnSelectFlags;
+ but.ShowAll ();
+ PackStart (but, false, false, 0);
+ }
+ }
+
+ protected override void OnDestroyed ()
+ {
+ base.OnDestroyed ();
+ ((IDisposable)this).Dispose ();
+ }
+
+ void IDisposable.Dispose ()
+ {
+ }
+
+ public object Value {
+ get {
+ return Enum.ToObject (propType, UIntValue);
+ }
+ set {
+ ulong newVal = Convert.ToUInt64 (value);
+ if (flagsLabel != null) {
+ string txt = "";
+ foreach (object val in values) {
+ if ((newVal & Convert.ToUInt64(val)) != 0) {
+ if (txt.Length > 0) txt += ", ";
+ txt += val.ToString ();
+ }
+ }
+ flagsLabel.Text = txt;
+ UIntValue = newVal;
+ }
+ else {
+ for (ulong i = 1; i <= uintValue || i <= newVal; i = i << 1) {
+ if ((uintValue & i) != (newVal & i)) {
+ Gtk.CheckButton check = (Gtk.CheckButton)flags[i];
+ if (check != null)
+ check.Active = !check.Active;
+ }
+ }
+ }
+ }
+ }
+
+ public event EventHandler ValueChanged;
+
+ ulong uintValue;
+
+ ulong UIntValue {
+ get {
+ return uintValue;
+ }
+ set {
+ if (uintValue != value) {
+ uintValue = value;
+ if (ValueChanged != null)
+ ValueChanged (this, EventArgs.Empty);
+ }
+ }
+ }
+
+ void FlagToggled (object o, EventArgs args)
+ {
+ Gtk.CheckButton check = (Gtk.CheckButton)o;
+ ulong val = (ulong)flags[o];
+
+ if (check.Active)
+ UIntValue |= val;
+ else
+ UIntValue &= ~val;
+ }
+
+ void OnSelectFlags (object o, EventArgs args)
+ {
+ using (FlagsSelectorDialog dialog = new FlagsSelectorDialog (null, propType, UIntValue, property)) {
+ if (dialog.Run () == (int) ResponseType.Ok) {
+ Value = Enum.ToObject (propType, dialog.Value);
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FlagsSelectorDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FlagsSelectorDialog.cs
new file mode 100644
index 0000000000..287073b5f9
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FlagsSelectorDialog.cs
@@ -0,0 +1,117 @@
+//
+// FlagsSelectorDialog.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ public class FlagsSelectorDialog: IDisposable
+ {
+ Gtk.TreeView treeView;
+ Gtk.Dialog dialog;
+ Gtk.ListStore store;
+ Gtk.Window parent;
+ ulong flags;
+
+ public FlagsSelectorDialog (Gtk.Window parent, Type enumDesc, ulong flags, string title)
+ {
+ this.flags = flags;
+ this.parent = parent;
+
+ Gtk.ScrolledWindow sc = new Gtk.ScrolledWindow ();
+ sc.HscrollbarPolicy = Gtk.PolicyType.Automatic;
+ sc.VscrollbarPolicy = Gtk.PolicyType.Automatic;
+ sc.ShadowType = Gtk.ShadowType.In;
+ sc.BorderWidth = 6;
+
+ treeView = new Gtk.TreeView ();
+ sc.Add (treeView);
+
+ dialog = new Gtk.Dialog ();
+ dialog.VBox.Add (sc);
+ dialog.AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel);
+ dialog.AddButton (Gtk.Stock.Ok, Gtk.ResponseType.Ok);
+
+ store = new Gtk.ListStore (typeof(bool), typeof(string), typeof(ulong));
+ treeView.Model = store;
+ treeView.HeadersVisible = false;
+
+ Gtk.TreeViewColumn col = new Gtk.TreeViewColumn ();
+
+ Gtk.CellRendererToggle tog = new Gtk.CellRendererToggle ();
+ tog.Toggled += new Gtk.ToggledHandler (OnToggled);
+ col.PackStart (tog, false);
+ col.AddAttribute (tog, "active", 0);
+
+ Gtk.CellRendererText crt = new Gtk.CellRendererText ();
+ col.PackStart (crt, true);
+ col.AddAttribute (crt, "text", 1);
+
+ treeView.AppendColumn (col);
+
+ foreach (object value in System.Enum.GetValues (enumDesc)) {
+ ulong val = Convert.ToUInt64 (value);
+ store.AppendValues (((flags & val) != 0), value.ToString (), val);
+ }
+ }
+
+ public int Run ()
+ {
+ dialog.DefaultWidth = 500;
+ dialog.DefaultHeight = 400;
+ dialog.ShowAll ();
+ dialog.TransientFor = parent;
+ return dialog.Run ();
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+
+ void OnToggled (object s, Gtk.ToggledArgs args)
+ {
+ Gtk.TreeIter iter;
+ if (!store.GetIterFromString (out iter, args.Path))
+ return;
+
+ bool oldValue = (bool) store.GetValue (iter, 0);
+ ulong flag = (ulong) store.GetValue (iter, 2);
+ store.SetValue (iter, 0, !oldValue);
+
+ if (oldValue)
+ flags &= ~flag;
+ else
+ flags |= flag;
+ }
+
+ public ulong Value {
+ get { return flags; }
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FloatRange.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FloatRange.cs
new file mode 100644
index 0000000000..8a3e7134dc
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/FloatRange.cs
@@ -0,0 +1,69 @@
+//
+// FloatRange.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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.ComponentModel;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ [PropertyEditorType (typeof (Double))]
+ [PropertyEditorType (typeof (Single))]
+ public class FloatRange : Gtk.SpinButton, IPropertyEditor
+ {
+ Type propType;
+
+ public FloatRange (): base (0, 0, 0.01)
+ {
+ }
+
+ public void Initialize (EditSession session)
+ {
+ propType = session.Property.PropertyType;
+
+ double min, max;
+
+ if (propType == typeof(double)) {
+ min = Double.MinValue;
+ max = Double.MaxValue;
+ } else if (propType == typeof(float)) {
+ min = float.MinValue;
+ max = float.MaxValue;
+ } else
+ throw new ApplicationException ("FloatRange editor does not support editing values of type " + propType);
+
+ SetRange (min, max);
+
+ Digits = 2;
+ }
+
+ object IPropertyEditor.Value {
+ get { return Convert.ChangeType (base.Value, propType); }
+ set { base.Value = (double) Convert.ChangeType (value, typeof(double)); }
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/IntRange.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/IntRange.cs
new file mode 100644
index 0000000000..ed7bc4fe74
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/IntRange.cs
@@ -0,0 +1,103 @@
+//
+// FlagsSelectorDialog.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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.ComponentModel;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ [PropertyEditorType (typeof (byte))]
+ [PropertyEditorType (typeof (sbyte))]
+ [PropertyEditorType (typeof (Int16))]
+ [PropertyEditorType (typeof (UInt16))]
+ [PropertyEditorType (typeof (Int32))]
+ [PropertyEditorType (typeof (UInt32))]
+ [PropertyEditorType (typeof (Int64))]
+ [PropertyEditorType (typeof (UInt64))]
+ [PropertyEditorType (typeof (Decimal))]
+ public class IntRangeEditor : Gtk.SpinButton, IPropertyEditor
+ {
+ Type propType;
+
+ public IntRangeEditor () : base (0, 0, 1.0)
+ {
+ this.HasFrame = false;
+ }
+
+ public void Initialize (EditSession session)
+ {
+ propType = session.Property.PropertyType;
+
+ double min, max;
+
+ switch (Type.GetTypeCode (propType)) {
+ case TypeCode.Int16:
+ min = (double) Int16.MinValue;
+ max = (double) Int16.MaxValue;
+ break;
+ case TypeCode.UInt16:
+ min = (double) UInt16.MinValue;
+ max = (double) UInt16.MaxValue;
+ break;
+ case TypeCode.Int32:
+ min = (double) Int32.MinValue;
+ max = (double) Int32.MaxValue;
+ break;
+ case TypeCode.UInt32:
+ min = (double) UInt32.MinValue;
+ max = (double) UInt32.MaxValue;
+ break;
+ case TypeCode.Int64:
+ min = (double) Int64.MinValue;
+ max = (double) Int64.MaxValue;
+ break;
+ case TypeCode.UInt64:
+ min = (double) UInt64.MinValue;
+ max = (double) UInt64.MaxValue;
+ break;
+ case TypeCode.Byte:
+ min = (double) Byte.MinValue;
+ max = (double) Byte.MaxValue;
+ break;
+ case TypeCode.SByte:
+ min = (double) SByte.MinValue;
+ max = (double) SByte.MaxValue;
+ break;
+ default:
+ throw new ApplicationException ("IntRange editor does not support editing values of type " + session.Property.PropertyType);
+ }
+
+ SetRange (min, max);
+ }
+
+ object IPropertyEditor.Value {
+ get { return Convert.ChangeType (base.Value, propType); }
+ set { base.Value = (double) Convert.ChangeType (value, typeof(double)); }
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TextEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TextEditor.cs
new file mode 100644
index 0000000000..de866f675d
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TextEditor.cs
@@ -0,0 +1,193 @@
+//
+// TextEditor.cs
+//
+// Author:
+// Lluis Sanchez Gual
+// Michael Hutchinson
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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.ComponentModel;
+
+using Gtk;
+using Gdk;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ [PropertyEditorType (typeof (string))]
+ public class TextEditor: Gtk.HBox, IPropertyEditor
+ {
+ EditSession session;
+ bool disposed;
+ string initialText;
+ Entry entry;
+
+ public TextEditor()
+ {
+ }
+
+ public void Initialize (EditSession session)
+ {
+ this.session = session;
+
+ //if standard values are supported by the converter, then
+ //we list them in a combo
+ if (session.Property.Converter.GetStandardValuesSupported (session))
+ {
+ ListStore store = new ListStore (typeof (string));
+ ComboBoxEntry combo = new ComboBoxEntry (store, 0);
+ PackStart (combo, true, true, 0);
+ combo.Changed += TextChanged;
+ entry = combo.Entry;
+ entry.HeightRequest = combo.SizeRequest ().Height;
+
+ //but if the converter doesn't allow nonstandard values,
+ // then we make the entry uneditable
+ if (session.Property.Converter.GetStandardValuesExclusive (session)) {
+ entry.IsEditable = false;
+ entry.CanFocus = false;
+ }
+
+ //fill the list
+ foreach (object stdValue in session.Property.Converter.GetStandardValues (session)) {
+ store.AppendValues (session.Property.Converter.ConvertToString (session, stdValue));
+ }
+
+ //a value of "--" gets rendered as a --, if typeconverter marked with UsesDashesForSeparator
+ object[] atts = session.Property.Converter.GetType ()
+ .GetCustomAttributes (typeof (StandardValuesSeparatorAttribute), true);
+ if (atts.Length > 0) {
+ string separator = ((StandardValuesSeparatorAttribute)atts[0]).Separator;
+ combo.RowSeparatorFunc = delegate (TreeModel model, TreeIter iter) {
+ return separator == ((string) model.GetValue (iter, 0));
+ };
+ }
+ }
+ // no standard values, so just use an entry
+ else {
+ entry = new Entry ();
+ PackStart (entry, true, true, 0);
+ }
+
+ //either way we have an entry to play with
+ entry.HasFrame = false;
+ entry.Activated += TextChanged;
+
+ if (ShouldShowDialogButton ()) {
+ Button button = new Button ("...");
+ PackStart (button, false, false, 0);
+ button.Clicked += ButtonClicked;
+ }
+
+ Spacing = 3;
+ ShowAll ();
+ }
+
+ protected virtual bool ShouldShowDialogButton ()
+ {
+ //if the object's Localizable, show a dialog, since the text's likely to be more substantial
+ LocalizableAttribute at = (LocalizableAttribute) session.Property.Attributes [typeof(LocalizableAttribute)];
+ return (at != null && at.IsLocalizable);
+ }
+
+ void ButtonClicked (object s, EventArgs a)
+ {
+ using (TextEditorDialog dlg = new TextEditorDialog ()) {
+ dlg.TransientFor = this.Toplevel as Gtk.Window;
+ dlg.Text = entry.Text;
+ if (dlg.Run () == (int) ResponseType.Ok) {
+ entry.Text = dlg.Text;
+ TextChanged (null, null);
+ }
+ }
+ }
+
+ void TextChanged (object s, EventArgs a)
+ {
+ if (initialText == entry.Text)
+ return;
+
+ bool valid = false;
+ if (session.Property.Converter.IsValid (session, entry.Text)) {
+ try {
+ session.Property.Converter.ConvertFromString (session, entry.Text);
+ initialText = entry.Text;
+ if (ValueChanged != null)
+ ValueChanged (this, a);
+ valid = true;
+ } catch {
+ // Invalid format
+ }
+ }
+
+ if (valid)
+ entry.ModifyFg (Gtk.StateType.Normal);
+ else
+ entry.ModifyFg (Gtk.StateType.Normal, new Gdk.Color (255, 0, 0));
+ }
+
+ // Gets/Sets the value of the editor. If the editor supports
+ // several value types, it is the responsibility of the editor
+ // to return values with the expected type.
+ public object Value {
+ get {
+ return session.Property.Converter.ConvertFromString (session, entry.Text);
+ }
+ set {
+ string val = session.Property.Converter.ConvertToString (session, value);
+ initialText = entry.Text;
+ entry.Text = val ?? string.Empty;
+ }
+ }
+
+ protected override void OnDestroyed ()
+ {
+ base.OnDestroyed ();
+ ((IDisposable)this).Dispose ();
+ }
+
+ void IDisposable.Dispose ()
+ {
+ if (!disposed && initialText != entry.Text) {
+ TextChanged (null, null);
+ }
+ disposed = true;
+ }
+
+ // To be fired when the edited value changes.
+ public event EventHandler ValueChanged;
+ }
+
+ public class StandardValuesSeparatorAttribute : Attribute
+ {
+ string separator;
+
+ public string Separator { get { return separator; } }
+
+ public StandardValuesSeparatorAttribute (string separator)
+ {
+ this.separator = separator;
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TextEditorDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TextEditorDialog.cs
new file mode 100644
index 0000000000..a43d26e6a1
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TextEditorDialog.cs
@@ -0,0 +1,78 @@
+//
+// TextEditorDialog.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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.ComponentModel;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ public class TextEditorDialog: IDisposable
+ {
+ Gtk.TextView textview;
+ Gtk.Dialog dialog;
+
+ public TextEditorDialog ()
+ {
+ Gtk.ScrolledWindow sc = new Gtk.ScrolledWindow ();
+ sc.HscrollbarPolicy = Gtk.PolicyType.Automatic;
+ sc.VscrollbarPolicy = Gtk.PolicyType.Automatic;
+ sc.ShadowType = Gtk.ShadowType.In;
+ sc.BorderWidth = 6;
+
+ textview = new Gtk.TextView ();
+ sc.Add (textview);
+
+ dialog = new Gtk.Dialog ();
+ dialog.AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel);
+ dialog.AddButton (Gtk.Stock.Ok, Gtk.ResponseType.Ok);
+ dialog.VBox.Add (sc);
+ }
+
+ public Gtk.Window TransientFor {
+ set { dialog.TransientFor = value; }
+ }
+
+ public string Text {
+ get { return textview.Buffer.Text; }
+ set { textview.Buffer.Text = value; }
+ }
+
+ public int Run ()
+ {
+ dialog.DefaultWidth = 500;
+ dialog.DefaultHeight = 400;
+ dialog.ShowAll ();
+ return dialog.Run ();
+ }
+
+ public void Dispose ()
+ {
+ dialog.Destroy ();
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TimeSpanEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TimeSpanEditor.cs
new file mode 100644
index 0000000000..eaeb855ab3
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid.Editors/TimeSpanEditor.cs
@@ -0,0 +1,93 @@
+//
+// TimeSpanEditorCell.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.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 Gtk;
+using Gdk;
+using System.Text;
+using System.ComponentModel;
+
+namespace MonoDevelop.Components.PropertyGrid.PropertyEditors
+{
+ [PropertyEditorType (typeof (TimeSpan))]
+ public class TimeSpanEditorCell: PropertyEditorCell
+ {
+ protected override string GetValueText ()
+ {
+ return ((TimeSpan)Value).ToString ();
+ }
+
+ protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
+ {
+ return new TimeSpanEditor ();
+ }
+ }
+
+ public class TimeSpanEditor: Gtk.HBox, IPropertyEditor
+ {
+ Gtk.Entry entry;
+ TimeSpan time;
+
+ public TimeSpanEditor()
+ {
+ entry = new Gtk.Entry ();
+ entry.Changed += OnChanged;
+ entry.HasFrame = false;
+ PackStart (entry, true, true, 0);
+ ShowAll ();
+ }
+
+ public void Initialize (EditSession session)
+ {
+ }
+
+ public object Value {
+ get { return time; }
+ set {
+ time = (TimeSpan) value;
+ entry.Changed -= OnChanged;
+ entry.Text = time.ToString ();
+ entry.Changed += OnChanged;
+ }
+ }
+
+ void OnChanged (object o, EventArgs a)
+ {
+ string s = entry.Text;
+
+ try {
+ time = TimeSpan.Parse (s);
+ if (ValueChanged != null)
+ ValueChanged (this, a);
+ } catch {
+ }
+ }
+
+ public event EventHandler ValueChanged;
+ }
+}