* Makefile.am:
[monodevelop.git] / main / src / addins / MonoDevelop.DesignerSupport / MonoDevelop.DesignerSupport.PropertyGrid.Editors / FlagsEditorCell.cs
blob9d9b035b515b7715473355ab2e45e35db75ecf38
1 //
2 // FlagsEditorCell.cs
3 //
4 // Author:
5 // Lluis Sanchez Gual
6 //
7 // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using Gtk;
30 using System;
31 using System.Collections;
32 using System.ComponentModel;
34 namespace MonoDevelop.DesignerSupport.PropertyGrid.PropertyEditors {
36 public class FlagsEditorCell: PropertyEditorCell
38 protected override string GetValueText ()
40 if (Value == null)
41 return "";
43 ulong value = Convert.ToUInt64 (Value);
44 Array values = System.Enum.GetValues (base.Property.PropertyType);
45 string txt = "";
46 foreach (object val in values) {
47 if ((value & Convert.ToUInt64 (value)) != 0) {
48 if (txt.Length > 0) txt += ", ";
49 txt += val.ToString ();
52 return txt;
55 protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
57 return new FlagsEditor ();
61 public class FlagsEditor : Gtk.HBox, IPropertyEditor
63 Hashtable flags;
64 Gtk.Tooltips tips;
65 Gtk.Entry flagsLabel;
66 string property;
67 Type propType;
68 Array values;
70 public FlagsEditor ()
74 public void Initialize (EditSession session)
76 PropertyDescriptor prop = session.Property;
78 if (!prop.PropertyType.IsEnum)
79 throw new ApplicationException ("Flags editor does not support editing values of type " + prop.PropertyType);
81 Spacing = 3;
82 propType = prop.PropertyType;
84 property = prop.Description;
85 if (property == null || property.Length == 0)
86 property = prop.Name;
88 // For small enums, the editor is a list of checkboxes inside a frame
89 // For large enums (>5), use a selector dialog.
91 values = System.Enum.GetValues (prop.PropertyType);
93 if (values.Length < 6)
95 Gtk.VBox vbox = new Gtk.VBox (true, 3);
97 tips = new Gtk.Tooltips ();
98 flags = new Hashtable ();
100 foreach (object value in values) {
101 Gtk.CheckButton check = new Gtk.CheckButton (value.ToString ());
102 tips.SetTip (check, value.ToString (), value.ToString ());
103 ulong uintVal = Convert.ToUInt64 (value);
104 flags[check] = uintVal;
105 flags[uintVal] = check;
107 check.Toggled += FlagToggled;
108 vbox.PackStart (check, false, false, 0);
111 Gtk.Frame frame = new Gtk.Frame ();
112 frame.Add (vbox);
113 frame.ShowAll ();
114 PackStart (frame, true, true, 0);
116 else
118 flagsLabel = new Gtk.Entry ();
119 flagsLabel.IsEditable = false;
120 flagsLabel.HasFrame = false;
121 flagsLabel.ShowAll ();
122 PackStart (flagsLabel, true, true, 0);
124 Gtk.Button but = new Gtk.Button ("...");
125 but.Clicked += OnSelectFlags;
126 but.ShowAll ();
127 PackStart (but, false, false, 0);
131 protected override void OnDestroyed ()
133 base.OnDestroyed ();
134 ((IDisposable)this).Dispose ();
137 void IDisposable.Dispose ()
139 if (tips != null) {
140 tips.Destroy ();
141 tips = null;
145 public object Value {
146 get {
147 return Enum.ToObject (propType, UIntValue);
149 set {
150 ulong newVal = Convert.ToUInt64 (value);
151 if (flagsLabel != null) {
152 string txt = "";
153 foreach (object val in values) {
154 if ((newVal & Convert.ToUInt64(val)) != 0) {
155 if (txt.Length > 0) txt += ", ";
156 txt += val.ToString ();
159 flagsLabel.Text = txt;
160 UIntValue = newVal;
162 else {
163 for (ulong i = 1; i <= uintValue || i <= newVal; i = i << 1) {
164 if ((uintValue & i) != (newVal & i)) {
165 Gtk.CheckButton check = (Gtk.CheckButton)flags[i];
166 if (check != null)
167 check.Active = !check.Active;
174 public event EventHandler ValueChanged;
176 ulong uintValue;
178 ulong UIntValue {
179 get {
180 return uintValue;
182 set {
183 if (uintValue != value) {
184 uintValue = value;
185 if (ValueChanged != null)
186 ValueChanged (this, EventArgs.Empty);
191 void FlagToggled (object o, EventArgs args)
193 Gtk.CheckButton check = (Gtk.CheckButton)o;
194 ulong val = (ulong)flags[o];
196 if (check.Active)
197 UIntValue |= val;
198 else
199 UIntValue &= ~val;
202 void OnSelectFlags (object o, EventArgs args)
204 using (FlagsSelectorDialog dialog = new FlagsSelectorDialog (null, propType, UIntValue, property)) {
205 if (dialog.Run () == (int) ResponseType.Ok) {
206 Value = Enum.ToObject (propType, dialog.Value);