* TreeView.cs: Don't draw the selected node when we lose
[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 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                 #endregion      // Local Variables
135
136                 #region Constructors
137                 public DataGridColumnStyle ()
138                 {
139                         CommmonConstructor ();
140                         property_descriptor = null;
141                 }
142
143                 public DataGridColumnStyle (PropertyDescriptor prop)
144                 {
145                         CommmonConstructor ();
146                         property_descriptor = prop;
147                 }
148
149                 private void CommmonConstructor ()
150                 {
151                         fontheight = -1;
152                         table_style = null;
153                         header_text = string.Empty;
154                         mapping_name  = string.Empty;
155                         null_text = def_null_text;
156                         accesible_object = new DataGridColumnHeaderAccessibleObject (this);
157                         _readonly = false;
158                         width = -1;
159                         grid = null;
160                         is_default = false;
161                         alignment = HorizontalAlignment.Left;
162                         string_format_hdr = new StringFormat ();
163                         string_format_hdr.FormatFlags |= StringFormatFlags.NoWrap;
164                         string_format_hdr.LineAlignment  = StringAlignment.Center;
165                 }
166
167                 #endregion
168
169                 #region Public Instance Properties
170                 [Localizable(true)]
171                 [DefaultValue(HorizontalAlignment.Left)]
172                 public virtual HorizontalAlignment Alignment {
173                         get {
174                                 return alignment;
175                         }
176                         set {                           
177                                 if (value != alignment) {
178                                         alignment = value;
179                                         
180                                         if (table_style != null && table_style.DataGrid != null) {
181                                                 table_style.DataGrid.Invalidate ();
182                                         }
183                                         
184                                         if (AlignmentChanged != null) {
185                                                 AlignmentChanged (this, EventArgs.Empty);
186                                         }                                       
187                                 }
188                         }
189                 }
190
191                 [Browsable(false)]
192                 public virtual DataGridTableStyle DataGridTableStyle {
193                         get {
194                                 return table_style;
195                         }                       
196                 }
197                 
198                 protected int FontHeight {
199                         get {
200                                 if (fontheight != -1) {
201                                         return fontheight;
202                                 }
203
204                                 if (table_style != null) {
205                                         //return table_style.DataGrid.FontHeight
206                                         return -1;
207                                 }
208
209                                 // TODO: Default Datagrid font height
210                                 return -1;
211                         }
212                 }
213
214                 [Browsable(false)]
215                 public AccessibleObject HeaderAccessibleObject {
216                         get {
217                                 return accesible_object;
218                         }
219                 }
220
221                 [Localizable(true)]
222                 public virtual string HeaderText {
223                         get {
224                                 return header_text;
225                         }
226                         set {
227                                 if (value != header_text) {
228                                         header_text = value;
229                                         
230                                         if (table_style != null && table_style.DataGrid != null) {
231                                                 table_style.DataGrid.Invalidate ();
232                                         }
233
234                                         if (HeaderTextChanged != null) {
235                                                 HeaderTextChanged (this, EventArgs.Empty);
236                                         }
237                                 }
238                         }
239                 }
240
241                 [Editor("System.Windows.Forms.Design.DataGridColumnStyleMappingNameEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
242                 [Localizable(true)]
243                 public string MappingName {
244                         get {
245                                 return mapping_name;
246                         }
247                         set {
248                                 if (value != mapping_name) {
249                                         mapping_name = value;
250
251                                         if (MappingNameChanged != null) {
252                                                 MappingNameChanged (this, EventArgs.Empty);
253                                         }
254                                 }
255                         }
256                 }
257
258                 [Localizable(true)]
259                 public virtual string NullText {
260                         get {
261                                 return null_text;
262                         }
263                         set {
264                                 if (value != null_text) {
265                                         null_text = value;
266                                         
267                                         if (table_style != null && table_style.DataGrid != null) {
268                                                 table_style.DataGrid.Invalidate ();
269                                         }
270
271                                         if (NullTextChanged != null) {
272                                                 NullTextChanged (this, EventArgs.Empty);
273                                         }
274                                 }
275                         }
276                 }
277
278                 [Browsable(false)]
279                 [DefaultValue(null)]
280                 [EditorBrowsable(EditorBrowsableState.Advanced)]
281                 public virtual PropertyDescriptor PropertyDescriptor {
282                         get {
283                                 return property_descriptor;
284                         }
285                         set {
286                                 if (value != property_descriptor) {
287                                         property_descriptor = value;                                    
288
289                                         if (PropertyDescriptorChanged != null) {
290                                                 PropertyDescriptorChanged (this, EventArgs.Empty);
291                                         }
292                                 }
293                         }
294                 }
295
296                 [DefaultValue(false)]
297                 public virtual bool ReadOnly  {
298                         get {
299                                 return _readonly;
300                         }
301                         set {
302                                 if (value != _readonly) {
303                                         _readonly = value;
304                                         
305                                         if (table_style != null && table_style.DataGrid != null) {
306                                                 table_style.DataGrid.CalcAreasAndInvalidate ();
307                                         }
308                                         
309                                         if (ReadOnlyChanged != null) {
310                                                 ReadOnlyChanged (this, EventArgs.Empty);
311                                         }
312                                 }
313                         }
314                 }
315
316                 [DefaultValue(100)]
317                 [Localizable(true)]
318                 public virtual int Width {
319                         get {
320                                 return width;
321                         }
322                         set {
323                                 if (value != width) {
324                                         width = value;
325                                         
326                                         if (table_style != null && table_style.DataGrid != null) {
327                                                 table_style.DataGrid.CalcAreasAndInvalidate ();
328                                         }
329
330                                         if (WidthChanged != null) {
331                                                 WidthChanged (this, EventArgs.Empty);
332                                         }
333                                 }
334                         }
335                 }
336
337                 #endregion      // Public Instance Properties
338                 
339                 #region Private Instance Properties
340
341                 internal ArrowDrawing ArrowDrawingMode {
342                         get { return arrow_drawing; }
343                         set { arrow_drawing = value; }
344                 }
345                 
346                 // The logic seems to be that: 
347                 // - If DataGrid.ReadOnly is true all the tables and columns are readonly ignoring other settings
348                 // - If DataGridTableStyle.ReadOnly is true all columns are readonly ignoring other settings
349                 // - If DataGrid.ReadOnly and DataGridTableStyle.ReadOnly are false, the columns settings are mandatory
350                 //
351                 internal bool ParentReadOnly {
352                         get {                           
353                                 if (grid != null) {
354                                         if (grid.ReadOnly == true) {
355                                                 return true;
356                                         }
357                                         
358                                         if (grid.ListManager != null && grid.ListManager.CanAddRows == false) {
359                                                 return true;
360                                         }                               
361                                 }
362                                 
363                                 if (table_style != null) {
364                                         if (table_style.ReadOnly == true) {
365                                                 return true;
366                                         }
367                                 }
368                                 
369                                 return false;
370                         }
371                 }
372                 
373                 internal DataGridTableStyle TableStyle {
374                         set { table_style = value; }
375                 }
376                 
377                 internal bool IsDefault {
378                         get { return is_default; }
379                 }
380                 #endregion Private Instance Properties
381
382                 #region Public Instance Methods
383                 protected internal abstract void Abort (int rowNum);
384
385                 [MonoTODO]
386                 protected void BeginUpdate ()
387                 {
388
389                 }
390                 
391                 protected void CheckValidDataSource (CurrencyManager value)
392                 {
393                         if (value == null) {
394                                 throw new ArgumentNullException ("CurrencyManager cannot be null");
395                         }
396                         
397                         if (property_descriptor == null) {
398                                 throw new ApplicationException ("The PropertyDescriptor for this column is a null reference");
399                         }
400                 }
401
402                 [MonoTODO]
403                 protected internal virtual void ColumnStartedEditing (Control editingControl)
404                 {
405
406                 }
407
408                 protected internal abstract bool Commit (CurrencyManager dataSource, int rowNum);
409
410
411                 protected internal virtual void ConcedeFocus ()
412                 {
413
414                 }
415                 
416                 protected virtual AccessibleObject CreateHeaderAccessibleObject ()
417                 {
418                         return new DataGridColumnHeaderAccessibleObject (this);
419                 }
420
421                 protected internal virtual void Edit (CurrencyManager source, int rowNum,  Rectangle bounds,  bool readOnly)
422                 {
423                         Edit (source, rowNum, bounds, readOnly, string.Empty);
424                 }
425                 
426                 protected internal virtual void Edit (CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string instantText)
427                 {       
428                         Edit (source, rowNum, bounds, readOnly, instantText, true);
429                 }
430
431                 protected internal abstract void Edit (CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly,   string instantText,  bool cellIsVisible);
432
433
434                 [MonoTODO]
435                 protected void EndUpdate ()
436                 {
437
438                 }
439
440                 protected internal virtual void EnterNullValue () {}
441                 
442                 protected internal virtual object GetColumnValueAtRow (CurrencyManager source, int rowNum)
443                 {                       
444                         CheckValidDataSource (source);
445                         return property_descriptor.GetValue (source.GetItem (rowNum));
446                 }
447
448                 protected internal abstract int GetMinimumHeight ();
449
450                 protected internal abstract int GetPreferredHeight (Graphics g, object value);
451
452                 protected internal abstract Size GetPreferredSize (Graphics g,  object value);
453
454                 void  IDataGridColumnStyleEditingNotificationService.ColumnStartedEditing (Control editingControl)
455                 {
456
457                 }
458
459                 protected virtual void Invalidate ()
460                 {
461                         grid.grid_drawing.InvalidateColumn (this);
462                 }
463
464                 protected internal abstract void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum);
465                 protected internal abstract void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight);
466                 
467                 protected internal virtual void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum,
468                         Brush backBrush,  Brush foreBrush, bool alignToRight) {}
469
470                 protected internal virtual void ReleaseHostedControl () {}
471
472                 public void ResetHeaderText ()
473                 {
474                         HeaderText = string.Empty;
475                 }
476
477                 protected internal virtual void SetColumnValueAtRow (CurrencyManager source, int rowNum,  object value)
478                 {
479                         CheckValidDataSource (source);
480                         property_descriptor.SetValue (source.GetItem (rowNum), value);                  
481                 }
482
483                 protected virtual void SetDataGrid (DataGrid value)
484                 {
485                         grid = value;
486                         
487                         if (property_descriptor != null || value == null || value.ListManager == null) {
488                                 return;
489                         }
490                         
491                         PropertyDescriptorCollection propcol = value.ListManager.GetItemProperties ();
492                         for (int i = 0; i < propcol.Count ; i++) {
493                                 if (propcol[i].Name == mapping_name) {
494                                         property_descriptor = propcol[i];
495                                         break;
496                                 }
497                         }                       
498                 }
499
500                 protected virtual void SetDataGridInColumn (DataGrid value)
501                 {
502                         SetDataGrid (value);
503                 }
504                 
505                 internal void SetDataGridInternal (DataGrid value)
506                 {
507                         SetDataGridInColumn (value);
508                 }
509
510                 protected internal virtual void UpdateUI (CurrencyManager source, int rowNum, string instantText)
511                 {
512
513                 }
514                 #endregion      // Public Instance Methods
515                 
516                 #region Private Instance Methods
517                 virtual internal void OnMouseDown (MouseEventArgs e, int row, int column) {}
518                 virtual internal void OnKeyDown (KeyEventArgs ke, int row, int column) {}
519                 
520                 internal void PaintHeader (Graphics g, Rectangle bounds, int colNum)
521                 {       
522                         // Background
523                         g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.CurrentHeaderBackColor), 
524                                 bounds);
525                                 
526                         if (grid.FlatMode == false) {                   
527                         
528                                 // Paint Borders
529                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlLight),                 
530                                         bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
531                                 
532                                 if (colNum == 0) {      
533                                         g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlLight),
534                                                 bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height);
535                                 } else {
536                                         g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlLight),
537                                                 bounds.X, bounds.Y + 2, bounds.X, bounds.Y + bounds.Height - 2);
538                                 }
539                                 
540                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlDark),
541                                         bounds.X + bounds.Width - 1, bounds.Y + 2 , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 2);
542                         }
543                         
544                         bounds.X += 2;
545                         bounds.Width -= 2;
546                         g.DrawString (HeaderText, DataGridTableStyle.HeaderFont, ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.CurrentHeaderForeColor), 
547                                 bounds, string_format_hdr);
548
549                         if (arrow_drawing != ArrowDrawing.No) {
550                                 // Draw 6 x 6
551                                 Point pnt = new Point (bounds.X + bounds.Width  - 12, bounds.Y + ((bounds.Height - 6)/2));
552                                 
553                                 if (arrow_drawing == ArrowDrawing.Ascending) {
554                                         g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y + 6, pnt.X + 3, pnt.Y);
555                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 6, pnt.Y + 6);
556                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 3, pnt.Y);
557                                 } else {
558                                         g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y, pnt.X + 3, pnt.Y + 6);
559                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 6, pnt.Y);
560                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 3, pnt.Y + 6);
561                                 }
562                                 
563                         }
564                 }
565                                 
566                 internal void PaintNewRow (Graphics g, Rectangle bounds, Brush backBrush, Brush foreBrush)
567                 {
568                         g.FillRectangle (backBrush, bounds);
569                         PaintGridLine (g, bounds);
570                 }
571                 
572                 internal void PaintGridLine (Graphics g, Rectangle bounds)
573                 {
574                         if (table_style.CurrentGridLineStyle != DataGridLineStyle.Solid) {
575                                 return;
576                         }
577                         
578                         g.DrawLine (ThemeEngine.Current.ResPool.GetPen (table_style.CurrentGridLineColor),
579                                 bounds.X, bounds.Y + bounds.Height - 1, bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
580                         
581                         g.DrawLine (ThemeEngine.Current.ResPool.GetPen (table_style.CurrentGridLineColor),
582                                 bounds.X + bounds.Width - 1, bounds.Y , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height);
583                 }
584                 
585                 #endregion Private Instance Methods
586
587
588                 #region Events
589                 public event EventHandler AlignmentChanged;
590                 public event EventHandler FontChanged;
591                 public event EventHandler HeaderTextChanged;
592                 public event EventHandler MappingNameChanged;
593                 public event EventHandler NullTextChanged;
594
595                 [Browsable(false)]
596                 [EditorBrowsable(EditorBrowsableState.Advanced)]
597                 public event EventHandler PropertyDescriptorChanged;
598                 public event EventHandler ReadOnlyChanged;
599                 public event EventHandler WidthChanged;
600                 #endregion      // Events
601         }
602 }