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