2008-03-27 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridColumnStyle.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 //      Jordi Mas i Hernandez <jordi@ximian.com>
24 //      Chris Toshok <toshok@ximian.com>
25 //
26
27 using System.Drawing;
28 using System.ComponentModel;
29 using System.Runtime.InteropServices;
30 using System.Diagnostics;
31
32 namespace System.Windows.Forms
33 {
34         [DesignTimeVisible(false)]
35         [DefaultProperty("Header")]
36         [ToolboxItem(false)]
37         public abstract class DataGridColumnStyle : Component, IDataGridColumnStyleEditingNotificationService
38         {
39                 [ComVisible(true)]
40                 protected class DataGridColumnHeaderAccessibleObject : AccessibleObject
41                 {
42                         #region Local Variables
43                         private new DataGridColumnStyle owner;
44                         #endregion
45
46                         #region Constructors
47 #if NET_2_0
48                         public DataGridColumnHeaderAccessibleObject ()
49                         {
50                         }
51 #endif          
52                         public DataGridColumnHeaderAccessibleObject (DataGridColumnStyle owner)
53                         {
54                                 this.owner = owner;
55                         }
56                         #endregion //Constructors
57
58                         #region Public Instance Properties
59                         [MonoTODO]
60                         public override Rectangle Bounds {
61                                 get {
62                                         throw new NotImplementedException ();
63                                 }
64                         }
65
66                         public override string Name {
67                                 get {
68                                         throw new NotImplementedException ();
69                                 }
70                         }
71
72                         protected DataGridColumnStyle Owner {
73                                 get { return owner; }
74                         }
75
76                         public override AccessibleObject Parent {
77                                 get {
78                                         throw new NotImplementedException ();
79                                 }
80                         }
81
82                         public override AccessibleRole Role {
83                                 get {
84                                         throw new NotImplementedException ();
85                                 }
86                         }
87                         #endregion
88
89                         #region Public Instance Methods
90                         [MonoTODO]
91                         public override AccessibleObject Navigate (AccessibleNavigation navdir)
92                         {
93                                 throw new NotImplementedException ();
94                         }
95                         #endregion Public Instance Methods
96                 }
97
98                 protected class CompModSwitches
99                 {
100                         public CompModSwitches ()
101                         {
102                         }
103
104                         #region Public Instance Methods
105                         [MonoTODO]
106                         public static TraceSwitch DGEditColumnEditing {
107                                 get {
108                                         throw new NotImplementedException ();
109                                 }
110                         }
111                         #endregion Public Instance Methods
112                 }
113                 
114                 internal enum ArrowDrawing
115                 {
116                         No = 0,
117                         Ascending = 1,
118                         Descending = 2
119                 }
120                 
121                 #region Local Variables
122                 internal HorizontalAlignment alignment;
123                 private int fontheight;
124                 internal DataGridTableStyle table_style;
125                 private string header_text;
126                 private string mapping_name;
127                 private string null_text;
128                 private PropertyDescriptor property_descriptor;
129                 private bool _readonly;
130                 private int width;
131                 internal bool is_default;
132                 internal DataGrid grid;
133                 private DataGridColumnHeaderAccessibleObject accesible_object;
134                 private StringFormat string_format_hdr;
135                 static string def_null_text = "(null)";
136                 private ArrowDrawing arrow_drawing = ArrowDrawing.No;
137                 internal bool bound;
138                 #endregion      // Local Variables
139
140                 #region Constructors
141                 public DataGridColumnStyle () : this (null)
142                 {
143                 }
144
145                 public DataGridColumnStyle (PropertyDescriptor prop)
146                 {
147                         property_descriptor = prop;
148
149                         fontheight = -1;
150                         table_style = null;
151                         header_text = string.Empty;
152                         mapping_name  = string.Empty;
153                         null_text = def_null_text;
154                         accesible_object = new DataGridColumnHeaderAccessibleObject (this);
155                         _readonly = prop == null ? false : prop.IsReadOnly;
156                         width = -1;
157                         grid = null;
158                         is_default = false;
159                         alignment = HorizontalAlignment.Left;
160                         string_format_hdr = new StringFormat ();
161                         string_format_hdr.FormatFlags |= StringFormatFlags.NoWrap;
162                         string_format_hdr.LineAlignment  = StringAlignment.Center;
163                         string_format_hdr.Trimming = StringTrimming.Character;
164                 }
165
166                 #endregion
167
168                 #region Public Instance Properties
169                 [Localizable(true)]
170                 [DefaultValue(HorizontalAlignment.Left)]
171                 public virtual HorizontalAlignment Alignment {
172                         get {
173                                 return alignment;
174                         }
175                         set {
176                                 if (value != alignment) {
177                                         alignment = value;
178                                         
179                                         if (table_style != null && table_style.DataGrid != null) {
180                                                 table_style.DataGrid.Invalidate ();
181                                         }
182                                         
183                                         EventHandler eh = (EventHandler)(Events [AlignmentChangedEvent]);
184                                         if (eh != null)
185                                                 eh (this, EventArgs.Empty);
186                                 }
187                         }
188                 }
189
190                 [Browsable(false)]
191                 public virtual DataGridTableStyle DataGridTableStyle {
192                         get { return table_style; }
193                 }
194                 
195                 protected int FontHeight {
196                         get {
197                                 if (fontheight != -1) {
198                                         return fontheight;
199                                 }
200
201                                 if (table_style != null) {
202                                         //return table_style.DataGrid.FontHeight
203                                         return -1;
204                                 }
205
206                                 // TODO: Default Datagrid font height
207                                 return -1;
208                         }
209                 }
210
211                 [Browsable(false)]
212                 public AccessibleObject HeaderAccessibleObject {
213                         get {
214                                 return accesible_object;
215                         }
216                 }
217
218                 [Localizable(true)]
219                 public virtual string HeaderText {
220                         get {
221                                 return header_text;
222                         }
223                         set {
224                                 if (value != header_text) {
225                                         header_text = value;
226                                         
227                                         Invalidate ();
228
229                                         EventHandler eh = (EventHandler)(Events [HeaderTextChangedEvent]);
230                                         if (eh != null)
231                                                 eh (this, EventArgs.Empty);
232                                 }
233                         }
234                 }
235
236
237                 [Editor("System.Windows.Forms.Design.DataGridColumnStyleMappingNameEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
238                 [Localizable(true)]
239 #if NET_2_0
240                 [DefaultValue ("")]
241 #endif
242                 public string MappingName {
243                         get {
244                                 return mapping_name;
245                         }
246                         set {
247                                 if (value != mapping_name) {
248                                         mapping_name = value;
249
250                                         EventHandler eh = (EventHandler)(Events [MappingNameChangedEvent]);
251                                         if (eh != null)
252                                                 eh (this, EventArgs.Empty);
253                                 }
254                         }
255                 }
256
257                 [Localizable(true)]
258                 public virtual string NullText {
259                         get {
260                                 return null_text;
261                         }
262                         set {
263                                 if (value != null_text) {
264                                         null_text = value;
265                                         
266                                         if (table_style != null && table_style.DataGrid != null) {
267                                                 table_style.DataGrid.Invalidate ();
268                                         }
269
270                                         EventHandler eh = (EventHandler)(Events [NullTextChangedEvent]);
271                                         if (eh != null)
272                                                 eh (this, EventArgs.Empty);
273                                 }
274                         }
275                 }
276
277                 [Browsable(false)]
278                 [DefaultValue(null)]
279                 [EditorBrowsable(EditorBrowsableState.Advanced)]
280                 public virtual PropertyDescriptor PropertyDescriptor {
281                         get {
282                                 return property_descriptor;
283                         }
284                         set {
285                                 if (value != property_descriptor) {
286                                         property_descriptor = value;
287
288                                         EventHandler eh = (EventHandler)(Events [PropertyDescriptorChangedEvent]);
289                                         if (eh != null)
290                                                 eh (this, EventArgs.Empty);
291                                 }
292                         }
293                 }
294
295                 [DefaultValue(false)]
296                 public virtual bool ReadOnly {
297                         get {
298                                 return _readonly;
299                         }
300                         set {
301                                 if (value != _readonly) {
302                                         _readonly = value;
303                                         
304                                         if (table_style != null && table_style.DataGrid != null) {
305                                                 table_style.DataGrid.CalcAreasAndInvalidate ();
306                                         }
307                                         
308                                         EventHandler eh = (EventHandler)(Events [ReadOnlyChangedEvent]);
309                                         if (eh != null)
310                                                 eh (this, EventArgs.Empty);
311                                 }
312                         }
313                 }
314
315                 [DefaultValue(100)]
316                 [Localizable(true)]
317                 public virtual int Width {
318                         get {
319                                 return width;
320                         }
321                         set {
322                                 if (value != width) {
323                                         width = value;
324                                         
325                                         if (table_style != null && table_style.DataGrid != null) {
326                                                 table_style.DataGrid.CalcAreasAndInvalidate ();
327                                         }
328
329                                         EventHandler eh = (EventHandler)(Events [WidthChangedEvent]);
330                                         if (eh != null)
331                                                 eh (this, EventArgs.Empty);
332                                 }
333                         }
334                 }
335
336                 #endregion      // Public Instance Properties
337                 
338                 #region Private Instance Properties
339
340                 internal ArrowDrawing ArrowDrawingMode {
341                         get { return arrow_drawing; }
342                         set { arrow_drawing = value; }
343                 }
344                 
345                 internal bool TableStyleReadOnly {
346                         get {
347                                 return table_style != null && table_style.ReadOnly; 
348                         }
349                 }
350                 
351                 internal DataGridTableStyle TableStyle {
352                         set { table_style = value; }
353                 }
354                 
355                 internal bool IsDefault {
356                         get { return is_default; }
357                 }
358                 #endregion Private Instance Properties
359
360                 #region Public Instance Methods
361                 protected internal abstract void Abort (int rowNum);
362
363                 [MonoTODO]
364                 protected void BeginUpdate ()
365                 {
366                 }
367                 
368                 protected void CheckValidDataSource (CurrencyManager value)
369                 {
370                         if (value == null) {
371                                 throw new ArgumentNullException ("CurrencyManager cannot be null");
372                         }
373                         
374                         if (property_descriptor == null) {
375                                 property_descriptor = value.GetItemProperties ()[mapping_name];
376
377 //                              Console.WriteLine ("mapping name = {0}", mapping_name);
378 //                              foreach (PropertyDescriptor prop in value.GetItemProperties ()) {
379 //                                      Console.WriteLine (" + prop = {0}", prop.Name);
380 //                              }
381
382                                 if (property_descriptor == null)
383                                         throw new InvalidOperationException ("The PropertyDescriptor for this column is a null reference");
384
385                                  /*MonoTests.System.Windows.Forms.DataGridColumnStyleTest.GetColumnValueAtRow : System.InvalidOperationException : The 'foo' DataGridColumnStyle cannot be used because it is not associated with a Property or Column in the DataSource.*/
386
387                                 
388                         }
389                 }
390
391                 [MonoTODO]
392                 protected internal virtual void ColumnStartedEditing (Control editingControl)
393                 {
394                 }
395
396                 protected internal abstract bool Commit (CurrencyManager dataSource, int rowNum);
397
398
399                 protected internal virtual void ConcedeFocus ()
400                 {
401                 }
402                 
403                 protected virtual AccessibleObject CreateHeaderAccessibleObject ()
404                 {
405                         return new DataGridColumnHeaderAccessibleObject (this);
406                 }
407
408                 protected internal virtual void Edit (CurrencyManager source, int rowNum,  Rectangle bounds,  bool readOnly)
409                 {
410                         Edit (source, rowNum, bounds, readOnly, string.Empty);
411                 }
412                 
413                 protected internal virtual void Edit (CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText)
414                 {       
415                         Edit (source, rowNum, bounds, readOnly, displayText, true);
416                 }
417
418                 protected internal abstract void Edit (CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText,  bool cellIsVisible);
419
420                 [MonoTODO]
421                 protected void EndUpdate ()
422                 {
423                 }
424
425                 protected internal virtual void EnterNullValue () {}
426                 
427                 protected internal virtual object GetColumnValueAtRow (CurrencyManager source, int rowNum)
428                 {
429                         CheckValidDataSource (source);
430                         if (rowNum >= source.Count)
431                                 return DBNull.Value;
432                         return property_descriptor.GetValue (source [rowNum]);
433                 }
434
435                 protected internal abstract int GetMinimumHeight ();
436
437                 protected internal abstract int GetPreferredHeight (Graphics g, object value);
438
439                 protected internal abstract Size GetPreferredSize (Graphics g,  object value);
440
441                 void IDataGridColumnStyleEditingNotificationService.ColumnStartedEditing (Control editingControl)
442                 {
443                         ColumnStartedEditing (editingControl);
444                 }
445
446                 protected virtual void Invalidate ()
447                 {
448                         if (grid != null)
449                                 grid.InvalidateColumn (this);
450                 }
451
452                 protected internal abstract void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum);
453                 protected internal abstract void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight);
454                 
455                 protected internal virtual void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum,
456                         Brush backBrush,  Brush foreBrush, bool alignToRight) {}
457
458                 protected internal virtual void ReleaseHostedControl () {}
459
460                 public void ResetHeaderText ()
461                 {
462                         HeaderText = string.Empty;
463                 }
464
465                 protected internal virtual void SetColumnValueAtRow (CurrencyManager source, int rowNum,  object value)
466                 {
467                         CheckValidDataSource (source);
468
469                         IEditableObject editable = source [rowNum] as IEditableObject;
470
471                         if (editable != null)
472                                 editable.BeginEdit ();
473
474                         property_descriptor.SetValue (source [rowNum], value);
475
476                         if (editable != null)
477                                 editable.EndEdit ();
478                 }
479
480                 protected virtual void SetDataGrid (DataGrid value)
481                 {
482                         grid = value;
483
484                         property_descriptor = null;
485
486                         if (value != null && value.ListManager != null)
487                                 CheckValidDataSource (value.ListManager);
488                 }
489
490                 protected virtual void SetDataGridInColumn (DataGrid value)
491                 {
492                         SetDataGrid (value);
493                 }
494                 
495                 internal void SetDataGridInternal (DataGrid value)
496                 {
497                         SetDataGridInColumn (value);
498                 }
499
500                 protected internal virtual void UpdateUI (CurrencyManager source, int rowNum, string displayText)
501                 {
502                 }
503
504                 #endregion      // Public Instance Methods
505                 
506                 #region Private Instance Methods
507                 virtual internal void OnMouseDown (MouseEventArgs e, int row, int column) {}
508                 virtual internal void OnKeyDown (KeyEventArgs ke, int row, int column) {}
509                 
510                 internal void PaintHeader (Graphics g, Rectangle bounds, int colNum)
511                 {       
512                         // Background
513                         g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.CurrentHeaderBackColor), 
514                                 bounds);
515                                 
516                         if (!grid.FlatMode) {
517                                 // Paint Borders
518                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlLight),
519                                         bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
520                                 
521                                 if (colNum == 0) {
522                                         g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlLight),
523                                                 bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height);
524                                 } else {
525                                         g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlLight),
526                                                 bounds.X, bounds.Y + 2, bounds.X, bounds.Y + bounds.Height - 2);
527                                 }
528                                 
529                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlDark),
530                                         bounds.X + bounds.Width - 1, bounds.Y + 2 , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 2);
531                         }
532                         
533                         bounds.X += 2;
534                         bounds.Width -= 2;
535
536                         if (arrow_drawing != ArrowDrawing.No)
537                                 bounds.Width -= 16;
538
539                         g.DrawString (HeaderText, DataGridTableStyle.HeaderFont, ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.CurrentHeaderForeColor), 
540                                 bounds, string_format_hdr);
541
542                         if (arrow_drawing != ArrowDrawing.No) {
543                                 // Draw 6 x 6
544                                 Point pnt = new Point (bounds.X + bounds.Width + 4, bounds.Y + ((bounds.Height - 6)/2));
545                                 
546                                 if (arrow_drawing == ArrowDrawing.Ascending) {
547                                         g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y + 6, pnt.X + 3, pnt.Y);
548                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 6, pnt.Y + 6);
549                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 3, pnt.Y);
550                                 } else {
551                                         g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y, pnt.X + 3, pnt.Y + 6);
552                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 6, pnt.Y);
553                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 3, pnt.Y + 6);
554                                 }
555                                 
556                         }
557                 }
558                 
559                 internal void PaintNewRow (Graphics g, Rectangle bounds, Brush backBrush, Brush foreBrush)
560                 {
561                         g.FillRectangle (backBrush, bounds);
562                         PaintGridLine (g, bounds);
563                 }
564                 
565                 internal void PaintGridLine (Graphics g, Rectangle bounds)
566                 {
567                         if (table_style.CurrentGridLineStyle != DataGridLineStyle.Solid) {
568                                 return;
569                         }
570                         
571                         g.DrawLine (ThemeEngine.Current.ResPool.GetPen (table_style.CurrentGridLineColor),
572                                 bounds.X, bounds.Y + bounds.Height - 1, bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
573                         
574                         g.DrawLine (ThemeEngine.Current.ResPool.GetPen (table_style.CurrentGridLineColor),
575                                 bounds.X + bounds.Width - 1, bounds.Y , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height);
576                 }
577                 
578                 #endregion Private Instance Methods
579
580                 #region Events
581                 static object AlignmentChangedEvent = new object ();
582                 static object FontChangedEvent = new object ();
583                 static object HeaderTextChangedEvent = new object ();
584                 static object MappingNameChangedEvent = new object ();
585                 static object NullTextChangedEvent = new object ();
586                 static object PropertyDescriptorChangedEvent = new object ();
587                 static object ReadOnlyChangedEvent = new object ();
588                 static object WidthChangedEvent = new object ();
589
590                 public event EventHandler AlignmentChanged {
591                         add { Events.AddHandler (AlignmentChangedEvent, value); }
592                         remove { Events.RemoveHandler (AlignmentChangedEvent, value); }
593                 }
594
595                 public event EventHandler FontChanged {
596                         add { Events.AddHandler (FontChangedEvent, value); }
597                         remove { Events.RemoveHandler (FontChangedEvent, value); }
598                 }
599
600                 public event EventHandler HeaderTextChanged {
601                         add { Events.AddHandler (HeaderTextChangedEvent, value); }
602                         remove { Events.RemoveHandler (HeaderTextChangedEvent, value); }
603                 }
604
605                 public event EventHandler MappingNameChanged {
606                         add { Events.AddHandler (MappingNameChangedEvent, value); }
607                         remove { Events.RemoveHandler (MappingNameChangedEvent, value); }
608                 }
609
610                 public event EventHandler NullTextChanged {
611                         add { Events.AddHandler (NullTextChangedEvent, value); }
612                         remove { Events.RemoveHandler (NullTextChangedEvent, value); }
613                 }
614
615                 [Browsable(false)]
616                 [EditorBrowsable(EditorBrowsableState.Advanced)]
617                 public event EventHandler PropertyDescriptorChanged {
618                         add { Events.AddHandler (PropertyDescriptorChangedEvent, value); }
619                         remove { Events.RemoveHandler (PropertyDescriptorChangedEvent, value); }
620                 }
621
622                 public event EventHandler ReadOnlyChanged {
623                         add { Events.AddHandler (ReadOnlyChangedEvent, value); }
624                         remove { Events.RemoveHandler (ReadOnlyChangedEvent, value); }
625                 }
626
627                 public event EventHandler WidthChanged {
628                         add { Events.AddHandler (WidthChangedEvent, value); }
629                         remove { Events.RemoveHandler (WidthChangedEvent, value); }
630                 }
631                 #endregion      // Events
632         }
633 }