* System.Windows.Forms/WebBrowserBase.cs: Added WndProc, DrawToBitmap,
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridViewCheckBoxCell.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Author:
23 //      Pedro Martínez Juliá <pedromj@gmail.com>
24 //
25
26
27 #if NET_2_0
28
29 using System;
30 using System.ComponentModel;
31 using System.Drawing;
32 using System.Windows.Forms.VisualStyles;
33
34 namespace System.Windows.Forms {
35
36         public class DataGridViewCheckBoxCell : DataGridViewCell, IDataGridViewEditingCell {
37
38                 private object editingCellFormattedValue;
39                 private bool editingCellValueChanged;
40                 private object falseValue;
41                 private FlatStyle flatStyle;
42                 private object indeterminateValue;
43                 private bool threeState;
44                 private object trueValue;
45                 private Type valueType;
46                 private PushButtonState check_state;
47
48                 public DataGridViewCheckBoxCell ()
49                 {
50                         check_state = PushButtonState.Normal;
51                         editingCellValueChanged = false;
52                         falseValue = null;
53                         flatStyle = FlatStyle.Standard;
54                         indeterminateValue = null;
55                         threeState = false;
56                         trueValue = null;
57                         valueType = null;
58                 }
59
60                 public DataGridViewCheckBoxCell (bool threeState) : this()
61                 {
62                         this.threeState = threeState;
63                 }
64
65                 public virtual object EditingCellFormattedValue {
66                         get { return editingCellFormattedValue; }
67                         set {
68                                 if (FormattedValueType == null || value == null || value.GetType() != FormattedValueType || !(value is Boolean) || !(value is CheckState)) {
69                                         throw new ArgumentException("Cannot set this property.");
70                                 }
71                                 editingCellFormattedValue = value;
72                         }
73                 }
74
75                 public virtual bool EditingCellValueChanged {
76                         get { return editingCellValueChanged; }
77                         set { editingCellValueChanged = value; }
78                 }
79
80                 public override Type EditType {
81                         get { return null; }
82                 }
83
84                 [DefaultValue (null)]
85                 public object FalseValue {
86                         get { return falseValue; }
87                         set { falseValue = value; }
88                 }
89
90                 [DefaultValue (FlatStyle.Standard)]
91                 public FlatStyle FlatStyle {
92                         get { return flatStyle; }
93                         set {
94                                 if (!Enum.IsDefined(typeof(FlatStyle), value)) {
95                                         throw new InvalidEnumArgumentException("Value is not valid FlatStyle.");
96                                 }
97                                 if (value == FlatStyle.Popup) {
98                                         throw new Exception("FlatStyle cannot be set to Popup in this control.");
99                                 }
100                         }
101                 }
102
103                 public override Type FormattedValueType {
104                         get {
105                                 if (ThreeState) {
106                                         return typeof(CheckState);
107                                 }
108                                 return typeof(Boolean);
109                         }
110                 }
111
112                 [DefaultValue (null)]
113                 public object IndeterminateValue {
114                         get { return indeterminateValue; }
115                         set { indeterminateValue = value; }
116                 }
117
118                 [DefaultValue (false)]
119                 public bool ThreeState {
120                         get { return threeState; }
121                         set { threeState = value; }
122                 }
123
124                 [DefaultValue (null)]
125                 public object TrueValue {
126                         get { return trueValue; }
127                         set { trueValue = value; }
128                 }
129
130                 public override Type ValueType {
131                         get {
132                                 if (valueType == null) {
133                                         if (OwningColumn != null && OwningColumn.ValueType != null) {
134                                                 return OwningColumn.ValueType;
135                                         }
136                                         if (ThreeState) {
137                                                 return typeof(CheckState);
138                                         }
139                                         return typeof(Boolean);
140                                 }
141                                 return valueType;
142                         }
143                         set { valueType = value; }
144                 }
145
146                 public override object Clone ()
147                 {
148                         DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell) base.Clone();
149                         cell.editingCellValueChanged = this.editingCellValueChanged;
150                         cell.falseValue = this.falseValue;
151                         cell.flatStyle = this.flatStyle;
152                         cell.indeterminateValue = this.indeterminateValue;
153                         cell.threeState = this.threeState;
154                         cell.trueValue = this.trueValue;
155                         cell.valueType = this.valueType;
156                         return cell;
157                 }
158
159                 public virtual object GetEditingCellFormattedValue (DataGridViewDataErrorContexts context)
160                 {
161                         if (FormattedValueType == null) {
162                                 throw new InvalidOperationException("FormattedValueType is null.");
163                         }
164                         if ((context & DataGridViewDataErrorContexts.ClipboardContent) != 0) {
165                                 return Convert.ToString(Value);
166                         }
167                         if (ThreeState) {
168                                 return (CheckState) Value;
169                         }
170                         return (Boolean) Value;
171                 }
172
173                 public override object ParseFormattedValue (object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
174                 {
175                         if (cellStyle == null) {
176                                 throw new ArgumentNullException("CellStyle is null");
177                         }
178                         if (FormattedValueType == null) {
179                                 throw new FormatException("FormattedValueType is null.");
180                         }
181                         if (formattedValue == null || formattedValue.GetType() != FormattedValueType) {
182                                 throw new ArgumentException("FormattedValue is null or is not instance of FormattedValueType.");
183                         }
184                         
185                         return base.ParseFormattedValue (formattedValue, cellStyle, formattedValueTypeConverter, valueTypeConverter);
186                 }
187
188                 public virtual void PrepareEditingCellForEdit (bool selectAll)
189                 {
190                 }
191
192                 public override string ToString ()
193                 {
194                         return string.Format ("DataGridViewCheckBoxCell {{ ColumnIndex={0}, RowIndex={1} }}", ColumnIndex, RowIndex);
195                 }
196
197                 protected override bool ContentClickUnsharesRow (DataGridViewCellEventArgs e)
198                 {
199                         return this.IsInEditMode;
200                 }
201
202                 protected override bool ContentDoubleClickUnsharesRow (DataGridViewCellEventArgs e)
203                 {
204                         return this.IsInEditMode;
205                 }
206
207                 protected override AccessibleObject CreateAccessibilityInstance ()
208                 {
209                         return new DataGridViewCheckBoxCellAccessibleObject(this);
210                 }
211
212                 protected override Rectangle GetContentBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
213                 {
214                         if (DataGridView == null)
215                                 return Rectangle.Empty;
216
217                         return new Rectangle ((Size.Width - 13) / 2, (Size.Height - 13) / 2, 13, 13);
218                 }
219
220                 [MonoTODO]
221                 protected override Rectangle GetErrorIconBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
222                 {
223                         return Rectangle.Empty;
224                 }
225
226                 protected override object GetFormattedValue (object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
227                 {
228                         if (DataGridView == null)
229                                 return null;
230                         
231                         if (value == falseValue)
232                                 return false;
233                         if (value == trueValue)
234                                 return true;
235                                 
236                         return Convert.ToBoolean (value);
237                 }
238
239                 protected override Size GetPreferredSize (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize)
240                 {
241                         return new Size (21, 20);
242                 }
243
244                 protected override bool KeyDownUnsharesRow (KeyEventArgs e, int rowIndex)
245                 {
246                         // true if the user pressed the SPACE key without modifier keys; otherwise, false
247                         return e.KeyData == Keys.Space;
248                 }
249
250                 protected override bool KeyUpUnsharesRow (KeyEventArgs e, int rowIndex)
251                 {
252                         // true if the user released the SPACE key; otherwise false
253                         return e.KeyData == Keys.Space;
254                 }
255
256                 protected override bool MouseDownUnsharesRow (DataGridViewCellMouseEventArgs e)
257                 {
258                         return (e.Button == MouseButtons.Left);
259                 }
260
261                 protected override bool MouseEnterUnsharesRow (int rowIndex)
262                 {
263                         // true if the cell was the last cell receiving a mouse click; otherwise, false.
264                         return false;
265                 }
266
267                 protected override bool MouseLeaveUnsharesRow (int rowIndex)
268                 {
269                         // true if the button displayed by the cell is in the pressed state; otherwise, false.
270                         return check_state == PushButtonState.Pressed;
271                 }
272
273                 protected override bool MouseUpUnsharesRow (DataGridViewCellMouseEventArgs e)
274                 {
275                         // true if the mouse up was caused by the release of the left mouse button; otherwise false.
276                         return e.Button == MouseButtons.Left;
277                 }
278
279                 protected override void OnContentClick (DataGridViewCellEventArgs e)
280                 {
281                         DataGridViewCellStyle current_style = InheritedStyle;
282                         
283                         bool current = (bool)GetFormattedValue (Value, e.RowIndex, ref current_style, null, null, DataGridViewDataErrorContexts.Parsing);
284                         
285                         if (current)
286                                 Value = falseValue == null ? false : falseValue;
287                         else
288                                 Value = trueValue == null ? true : trueValue;
289                 }
290
291                 protected override void OnContentDoubleClick (DataGridViewCellEventArgs e)
292                 {
293                 }
294
295                 protected override void OnKeyDown (KeyEventArgs e, int rowIndex)
296                 {
297                         // when activated by the SPACE key, this method updates the cell's user interface
298                         if ((e.KeyData & Keys.Space) == Keys.Space) {
299                                 check_state = PushButtonState.Pressed;
300                                 DataGridView.InvalidateCell (this);
301                         }
302                 }
303
304                 protected override void OnKeyUp (KeyEventArgs e, int rowIndex)
305                 {
306                         // when activated by the SPACE key, this method updates the cell's user interface
307                         if ((e.KeyData & Keys.Space) == Keys.Space) {
308                                 check_state = PushButtonState.Normal;
309                                 DataGridView.InvalidateCell (this);
310                         }
311                 }
312
313                 protected override void OnLeave (int rowIndex, bool throughMouseClick)
314                 {
315                         if (check_state != PushButtonState.Normal) {
316                                 check_state = PushButtonState.Normal;
317                                 DataGridView.InvalidateCell (this);
318                         }
319                 }
320
321                 protected override void OnMouseDown (DataGridViewCellMouseEventArgs e)
322                 {
323                         // if activated by depresing the left mouse button, this method updates the cell's user interface
324                         if ((e.Button & MouseButtons.Left) == MouseButtons.Left) {
325                                 check_state = PushButtonState.Pressed;
326                                 DataGridView.InvalidateCell (this);
327                         }
328                 }
329
330                 protected override void OnMouseLeave (int rowIndex)
331                 {
332                         // if the cell's button is not in its normal state, this method causes the cell's user interface to be updated.
333                         if (check_state != PushButtonState.Normal) {
334                                 check_state = PushButtonState.Normal;
335                                 DataGridView.InvalidateCell (this);
336                         }
337                 }
338
339                 protected override void OnMouseMove (DataGridViewCellMouseEventArgs e)
340                 {
341                         if (check_state != PushButtonState.Normal && check_state != PushButtonState.Hot) {
342                                 check_state = PushButtonState.Hot;
343                                 DataGridView.InvalidateCell (this);
344                         }
345                 }
346
347                 protected override void OnMouseUp (DataGridViewCellMouseEventArgs e)
348                 {
349                         // if activated by the left mouse button, this method updates the cell's user interface
350                         if ((e.Button & MouseButtons.Left) == MouseButtons.Left) {
351                                 check_state = PushButtonState.Normal;
352                                 DataGridView.InvalidateCell (this);
353                         }
354                 }
355
356                 protected override void Paint (Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
357                 {
358                         base.Paint (graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
359                 }
360
361                 internal override void PaintPartContent (Graphics graphics, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, object formattedValue)
362                 {
363                         CheckBoxState state;
364                         
365                         if ((bool)formattedValue == false)
366                                 state = (CheckBoxState)check_state;
367                         else if ((bool)formattedValue == true)
368                                 state = (CheckBoxState)((int)check_state + 4);
369                         else
370                                 state = (CheckBoxState)((int)check_state + 8);
371                         
372                         Point p = new Point (cellBounds.X + (Size.Width - 13) / 2, cellBounds.Y + (Size.Height - 13) / 2);
373                         CheckBoxRenderer.DrawCheckBox (graphics, p, state);
374                 }
375                 
376                 protected class DataGridViewCheckBoxCellAccessibleObject : DataGridViewCellAccessibleObject {
377
378                         public DataGridViewCheckBoxCellAccessibleObject (DataGridViewCell owner) : base(owner)
379                         {
380                         }
381
382                         public override string DefaultAction {
383                                 get {
384                                         if (Owner.ReadOnly) {
385                                                 return "";
386                                         }
387                                         // return "Press to check" if the check box is not selected
388                                         // and "Press to uncheck" if the check box is selected
389                                         throw new NotImplementedException();
390                                 }
391                         }
392
393                         public override void DoDefaultAction ()
394                         {
395                                 // change the state of the check box
396                         }
397
398                         public override int GetChildCount ()
399                         {
400                                 return -1;
401                         }
402
403                 }
404
405         }
406
407 }
408
409 #endif