* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ThemeWin32Classic.cs
index a81d71520437145c4eb6d4a67314d2802a3f4ed8..b2d26b3100b4a55b0fb50c5017abb231f03136ee 100644 (file)
 //     Alexander Olk, alex.olk@googlemail.com
 //
 
-
+using System.ComponentModel;
 using System.Drawing;
 using System.Drawing.Drawing2D;
 using System.Drawing.Imaging;
 using System.Drawing.Text;
+using System.Text;
 
 namespace System.Windows.Forms
 {
@@ -83,7 +84,8 @@ namespace System.Windows.Forms
                }
 
                public override void ResetDefaults() {
-                       throw new NotImplementedException("Need to implement ResetDefaults() for Win32 theme");
+                       Console.WriteLine("NOT IMPLEMENTED: ResetDefault()");
+                       //throw new NotImplementedException("Need to implement ResetDefaults() for Win32 theme");
                }
 
                public override bool DoubleBufferingSupported {
@@ -843,41 +845,49 @@ namespace System.Windows.Forms
                
                public override void DataGridPaint (PaintEventArgs pe, DataGrid grid)
                {
-                       // Draw parent rows
-                       if (pe.ClipRectangle.IntersectsWith (grid.parent_rows)) {
-                               pe.Graphics.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor), grid.parent_rows);
-                       }
-
                        DataGridPaintCaption (pe.Graphics, pe.ClipRectangle, grid);
+                       DataGridPaintParentRows (pe.Graphics, pe.ClipRectangle, grid);
                        DataGridPaintColumnHeaders (pe.Graphics, pe.ClipRectangle, grid);
-                       DataGridPaintRowHeaders (pe.Graphics, pe.ClipRectangle, grid);
                        DataGridPaintRows (pe.Graphics, grid.cells_area, pe.ClipRectangle, grid);
 
                        // Paint scrollBar corner
-                       if (grid.vert_scrollbar.Visible && grid.horiz_scrollbar.Visible) {
+                       if (grid.VScrollBar.Visible && grid.HScrollBar.Visible) {
 
-                               Rectangle corner = new Rectangle (grid.ClientRectangle.X + grid.ClientRectangle.Width - grid.horiz_scrollbar.Height,
-                                        grid.ClientRectangle.Y + grid.ClientRectangle.Height - grid.horiz_scrollbar.Height,
-                                        grid.horiz_scrollbar.Height, grid.horiz_scrollbar.Height);
+                               Rectangle corner = new Rectangle (grid.ClientRectangle.X + grid.ClientRectangle.Width - grid.HScrollBar.Width,
+                                                                 grid.ClientRectangle.Y + grid.ClientRectangle.Height - grid.VScrollBar.Height,
+                                                                 grid.VScrollBar.Width, grid.HScrollBar.Height);
 
                                if (pe.ClipRectangle.IntersectsWith (corner)) {
                                        pe.Graphics.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
-                                               corner);
+                                                                  corner);
                                }
                        }
                }
-               
+
                public override void DataGridPaintCaption (Graphics g, Rectangle clip, DataGrid grid)
                {
                        Rectangle modified_area = clip;
                        modified_area.Intersect (grid.caption_area);
 
                        g.FillRectangle (ResPool.GetSolidBrush (grid.CaptionBackColor),
-                               modified_area);
+                                        modified_area);
 
                        g.DrawString (grid.CaptionText, grid.CaptionFont,
-                               ResPool.GetSolidBrush (grid.CaptionForeColor),
-                               grid.caption_area);             
+                                     ResPool.GetSolidBrush (grid.CaptionForeColor),
+                                     grid.caption_area);
+
+                       if (modified_area.IntersectsWith (grid.back_button_rect)) {
+                               g.DrawImage (grid.back_button_image, grid.back_button_rect);
+                               if (grid.back_button_mouseover) {
+                                       CPDrawBorder3D (g, grid.back_button_rect, grid.back_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
+                               }
+                       }
+                       if (modified_area.IntersectsWith (grid.parent_rows_button_rect)) {
+                               g.DrawImage (grid.parent_rows_button_image, grid.parent_rows_button_rect);
+                               if (grid.parent_rows_button_mouseover) {
+                                       CPDrawBorder3D (g, grid.parent_rows_button_rect, grid.parent_rows_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
+                               }
+                       }
                }
 
                public override void DataGridPaintColumnHeaders (Graphics g, Rectangle clip, DataGrid grid)
@@ -887,13 +897,11 @@ namespace System.Windows.Forms
                        if (grid.CurrentTableStyle.CurrentRowHeadersVisible) { // Paint corner shared between row and column header
                                Rectangle rect_bloc = grid.columnhdrs_area;
                                rect_bloc.Width = grid.RowHeaderWidth;
-                               rect_bloc.Height = grid.ColumnHeadersArea.Height;
                                if (clip.IntersectsWith (rect_bloc)) {
-                                       if (grid.visiblecolumn_count > 0) {
+                                       if (grid.VisibleColumnCount > 0)
                                                g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), rect_bloc);
-                                       }else {
+                                       else
                                                g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), rect_bloc);
-                                       }
                                }
 
                                columns_area.X += grid.RowHeaderWidth;
@@ -915,11 +923,11 @@ namespace System.Windows.Forms
                        rect_columnhdr.Y = columns_area.Y;
                        rect_columnhdr.Height = columns_area.Height;
                        
-                       int column_cnt = grid.first_visiblecolumn + grid.visiblecolumn_count;
-                       for (int column = grid.first_visiblecolumn; column < column_cnt; column++) {
+                       int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
+                       for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
                                
                                col_pixel = grid.GetColumnStartingPixel (column);
-                               rect_columnhdr.X = columns_area.X + col_pixel - grid.horz_pixeloffset;
+                               rect_columnhdr.X = columns_area.X + col_pixel - grid.HorizPixelOffset;
                                rect_columnhdr.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
 
                                if (clip.IntersectsWith (rect_columnhdr) == false)
@@ -944,37 +952,100 @@ namespace System.Windows.Forms
                        
                }
 
-               public override void DataGridPaintRowHeaders (Graphics g, Rectangle clip, DataGrid grid)
+               public override void DataGridPaintParentRows (Graphics g, Rectangle clip, DataGrid grid)
                {
-                       Rectangle rowhdrs_area_complete = grid.rowhdrs_area;
-                       rowhdrs_area_complete.Height = grid.rowhdrs_maxheight;
                        Rectangle rect_row = new Rectangle ();
-                       rect_row.X = grid.RowHeadersArea.X;                     
-                       int rowcnt = grid.FirstVisibleRow + grid.VisibleRowCount;
-                       Rectangle not_usedarea = rowhdrs_area_complete;                 
 
-                       if (rowcnt < grid.RowsCount) { // Paint one row more for partial rows
-                               rowcnt++;
-                       }
+                       rect_row.X = grid.ParentRowsArea.X;
+                       rect_row.Width = grid.ParentRowsArea.Width;
+                       rect_row.Height = (grid.CaptionFont.Height + 3);
 
-                       g.SetClip (grid.rowhdrs_area);
-                       for (int row = grid.FirstVisibleRow; row < rowcnt; row++) {
+                       g.SetClip (grid.ParentRowsArea);
 
-                               rect_row.Width = grid.RowHeadersArea.Width;
-                               rect_row.Height = grid.rows[row].Height;
-                               rect_row.Y = grid.RowHeadersArea.Y + grid.rows[row].VerticalOffset - grid.rows[grid.FirstVisibleRow].VerticalOffset;
+                       object[] parentRows = grid.dataSourceStack.ToArray();
+                       
+                       Region current_clip;
+                       for (int row = 0; row < parentRows.Length; row++) {
+                               rect_row.Y = grid.ParentRowsArea.Y + row * rect_row.Height;
 
-                               if (clip.IntersectsWith (rect_row)) {
-                                       DataGridPaintRowHeader (g, rect_row, row, grid);                                        
-                               }
+                               if (clip.IntersectsWith (rect_row) == false)
+                                       continue;
+
+                               current_clip = new Region (rect_row);
+                               current_clip.Intersect (clip);
+                               g.Clip = current_clip;
+
+                               DataGridPaintParentRow (g, rect_row, (DataGridDataSource)parentRows[parentRows.Length - row - 1], grid);
+
+                               current_clip.Dispose ();
                        }
                        
                        g.ResetClip ();
-                       not_usedarea.Height = grid.rowhdrs_maxheight - grid.RowHeadersArea.Height;
-                       not_usedarea.Y = grid.RowHeadersArea.Y + grid.RowHeadersArea.Height;
-                       g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
                }
-               
+
+               public override void DataGridPaintParentRow (Graphics g, Rectangle bounds, DataGridDataSource row, DataGrid grid)
+               {
+                       //Console.WriteLine ("drawing parent row {0}", row);
+
+                       // Background
+                       g.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
+                                        bounds);
+
+                       Font bold_font = new Font (grid.Font.FontFamily, grid.Font.Size, grid.Font.Style | FontStyle.Bold);
+                       // set up some standard string formating variables
+                       StringFormat text_format = new StringFormat();
+                       text_format.LineAlignment = StringAlignment.Center;
+                       text_format.Alignment = StringAlignment.Near;
+
+                       string table_name = ((ITypedList)row.view.DataView).GetListName (null) + ": ";
+
+                       Rectangle       text_rect;
+                       Size            text_size;
+
+                       text_size = g.MeasureString (table_name, bold_font).ToSize();
+                       text_rect = new Rectangle(new Point(bounds.X + 3, bounds.Y + bounds.Height - text_size.Height), text_size);
+
+                       //Console.WriteLine ("drawing text at {0}", text_rect);
+
+                       g.DrawString (table_name,
+                                     bold_font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
+
+                       foreach (PropertyDescriptor pd in ((ICustomTypeDescriptor)row.view).GetProperties()) {
+                               if (typeof(IBindingList).IsAssignableFrom (pd.PropertyType))
+                                       continue;
+
+                               text_rect.X += text_rect.Size.Width + 5;
+
+                               string text = String.Format ("{0}: {1}",
+                                                            pd.Name,
+                                                            pd.GetValue (row.view));
+
+                               text_rect.Size = g.MeasureString (text, grid.Font).ToSize();
+                               text_rect.Y = bounds.Y + bounds.Height - text_rect.Height; // XXX
+
+                               //Console.WriteLine ("drawing text at {0}", text_rect);
+
+                               g.DrawString (text,
+                                             grid.Font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
+                       }
+
+                       if (grid.FlatMode == false) {
+                               
+                               // Paint Borders
+                               g.DrawLine (ResPool.GetPen (ColorControlLight),
+                                       bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
+       
+                               g.DrawLine (ResPool.GetPen (ColorControlLight),
+                                       bounds.X, bounds.Y + 1, bounds.X, bounds.Y + bounds.Height - 1);
+       
+                               g.DrawLine (ResPool.GetPen (ColorControlDark),
+                                       bounds.X + bounds.Width - 1, bounds.Y + 1 , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
+       
+                               g.DrawLine (ResPool.GetPen (ColorControlDark),
+                                       bounds.X, bounds.Y + bounds.Height -1, bounds.X + bounds.Width, bounds.Y  + bounds.Height -1);
+                       }
+               }
+
                public override void DataGridPaintRowHeaderArrow (Graphics g, Rectangle bounds, DataGrid grid) 
                {               
                        Point[] arrow = new Point[3];
@@ -1003,62 +1074,42 @@ namespace System.Windows.Forms
 
                public override void DataGridPaintRowHeader (Graphics g, Rectangle bounds, int row, DataGrid grid)
                {
+                       bool is_add_row = grid.ShowEditRow && row == grid.Rows.Length - 1;
+                       bool is_current_row = row == grid.CurrentCell.RowNumber;
+
                        // Background
                        g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor),
                                bounds);
-                               
-                       if (grid.FlatMode == false) {
-                               
-                               // Paint Borders
-                               g.DrawLine (ResPool.GetPen (ColorControlLight),
-                                       bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
-       
-                               g.DrawLine (ResPool.GetPen (ColorControlLight),
-                                       bounds.X, bounds.Y + 1, bounds.X, bounds.Y + bounds.Height - 1);
-       
-                               g.DrawLine (ResPool.GetPen (ColorControlDark),
-                                       bounds.X + bounds.Width - 1, bounds.Y + 1 , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
-       
-                               g.DrawLine (ResPool.GetPen (ColorControlDark),
-                                       bounds.X, bounds.Y + bounds.Height -1, bounds.X + bounds.Width, bounds.Y  + bounds.Height -1);
-                       }
 
-                       if (grid.ShowEditRow && grid.RowsCount > 0 && row == grid.RowsCount  && !(row == grid.CurrentCell.RowNumber && grid.is_changing == true)) {
-                               
-                               g.DrawString ("*", grid.font_newrow, ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
-                                       bounds);
-                               
-                       } else {
-                               // Draw arrow
-                               if (row == grid.CurrentCell.RowNumber) {
-       
-                                       if (grid.is_changing == true) {
-                                               g.DrawString ("...", grid.Font,
-                                                       ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
-                                                       bounds);
-       
-                                       } else {
-                                               
-                                               Rectangle rect = new Rectangle (bounds.X - 2, bounds.Y, 18, 18);                                                                                        
-                                               DataGridPaintRowHeaderArrow (g, rect, grid);
-                                       }
+                       // Draw arrow
+                       if (is_current_row) {
+                               if (grid.IsChanging) {
+                                       g.DrawString ("...", grid.Font,
+                                                     ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
+                                                     bounds);
+                               } else {
+                                       Rectangle rect = new Rectangle (bounds.X - 2, bounds.Y, 18, 18);
+                                       DataGridPaintRowHeaderArrow (g, rect, grid);
                                }
                        }
+                       else if (is_add_row) {
+                               g.DrawString ("*", grid.Font, ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
+                                             bounds);
+                       }
 
-                       if (grid.CurrentTableStyle.HasRelations) {
-                               bounds.X += bounds.Width / 2;
-                               bounds.Width /= 2;
+                       if (grid.FlatMode == false && !is_add_row) {
+                               // Paint Borders
+                               g.DrawLine (ResPool.GetPen (ColorControlLight),
+                                           bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
 
-                               if (grid.IsExpanded (row)) {
-                                       g.DrawString ("-", grid.Font,
-                                                     ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
-                                                     bounds);
-                               }
-                               else {
-                                       g.DrawString ("+", grid.Font,
-                                                     ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
-                                                     bounds);
-                               }
+                               g.DrawLine (ResPool.GetPen (ColorControlLight),
+                                           bounds.X, bounds.Y + 1, bounds.X, bounds.Y + bounds.Height - 1);
+
+                               g.DrawLine (ResPool.GetPen (ColorControlDark),
+                                           bounds.X + bounds.Width - 1, bounds.Y + 1 , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
+
+                               g.DrawLine (ResPool.GetPen (ColorControlDark),
+                                           bounds.X, bounds.Y + bounds.Height -1, bounds.X + bounds.Width, bounds.Y  + bounds.Height -1);
                        }
                }
                
@@ -1066,47 +1117,160 @@ namespace System.Windows.Forms
                {
                        Rectangle rect_row = new Rectangle ();
                        Rectangle not_usedarea = new Rectangle ();
-                       rect_row.X = cells.X;
 
-                       int rowcnt = grid.FirstVisibleRow + grid.VisibleRowCount;
+                       int rowcnt = grid.VisibleRowCount;
                        
-                       if (grid.ShowEditRow && grid.RowsCount > 0) {
-                               rowcnt--;
-                       }                       
+                       bool showing_add_row = false;
 
-                       if (rowcnt < grid.RowsCount) { // Paint one row more for partial rows
-                               rowcnt++;
-                       }                       
-                       
-                       rect_row.Width = cells.Width;
-                       for (int row = grid.FirstVisibleRow; row < rowcnt; row++) {                                                             
-                               rect_row.Height = grid.rows[row].Height;
-                               rect_row.Y = cells.Y + grid.rows[row].VerticalOffset - grid.rows[grid.FirstVisibleRow].VerticalOffset;
-                               if (clip.IntersectsWith (rect_row)) {
-                                       DataGridPaintRow (g, row, rect_row, false, clip, grid);
+                       if (grid.ListManager.Count < grid.Rows.Length) {
+                               /* the table has an add row */
+
+                               if (grid.FirstVisibleRow + grid.VisibleRowCount >= grid.Rows.Length) {
+                                       showing_add_row = true;
                                }
                        }
 
-                       // XXX
-                       if (grid.ShowEditRow && grid.RowsCount > 0 && grid.FirstVisibleRow + grid.VisibleRowCount == grid.RowsCount + 1) {
-                               rect_row.Y = cells.Y + ((rowcnt - grid.FirstVisibleRow) * grid.RowHeight);
+                       rect_row.Width = cells.Width;
+                       for (int r = 0; r < rowcnt; r++) {
+                               int row = grid.FirstVisibleRow + r;
+                               if (row == grid.Rows.Length - 1)
+                                       rect_row.Height = grid.Rows[row].Height;
+                               else
+                                       rect_row.Height = grid.Rows[row + 1].VerticalOffset - grid.Rows[row].VerticalOffset;
+                               rect_row.Y = cells.Y + grid.Rows[row].VerticalOffset - grid.Rows[grid.FirstVisibleRow].VerticalOffset;
                                if (clip.IntersectsWith (rect_row)) {
-                                       DataGridPaintRow (g, rowcnt, rect_row, true, clip, grid);
+                                       if (grid.CurrentTableStyle.HasRelations
+                                           && !(showing_add_row && row == grid.Rows.Length - 1))
+                                               DataGridPaintRelationRow (g, row, rect_row, false, clip, grid);
+                                       else
+                                               DataGridPaintRow (g, row, rect_row, showing_add_row && row == grid.Rows.Length - 1, clip, grid);
                                }
                        }
 
-
+                       // XXX this should be moved elsewhere and turned into 1 g.FillRectangle call, not grid.Rows.Length separate calls
                        not_usedarea.Height = cells.Y + cells.Height - rect_row.Y - rect_row.Height;
                        not_usedarea.Y = rect_row.Y + rect_row.Height;
-                       not_usedarea.Width = rect_row.Width = cells.Width;
-                       not_usedarea.X = cells.X;
+                       not_usedarea.Width = cells.Width + grid.RowHeadersArea.Width;
+                       not_usedarea.X = 0;
 
                        g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
                }
-               
-               public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
-                                                      Rectangle clip, DataGrid grid)
-               {                       
+
+               public override void DataGridPaintRelationRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
+                                                              Rectangle clip, DataGrid grid)
+               {
+                       Rectangle rect_header;
+                       Rectangle icon_bounds = new Rectangle ();
+                       Pen pen = ThemeEngine.Current.ResPool.GetPen (grid.CurrentTableStyle.ForeColor);
+
+                       /* paint the header if it's visible and intersects the clip */
+                       if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
+                               rect_header = row_rect;
+                               rect_header.Width = grid.RowHeaderWidth;
+                               row_rect.X += grid.RowHeaderWidth;
+                               if (clip.IntersectsWith (rect_header)) {
+                                       DataGridPaintRowHeader (g, rect_header, row, grid);
+                               }
+
+                               icon_bounds = rect_header;
+                               icon_bounds.X += icon_bounds.Width / 2;
+                               icon_bounds.Y += 3;
+                               icon_bounds.Width = 8;
+                               icon_bounds.Height = 8;
+
+                               g.DrawRectangle (pen, icon_bounds);
+
+                               /* the - part of the icon */
+                               g.DrawLine (pen,
+                                           icon_bounds.X + 2, icon_bounds.Y + icon_bounds.Height / 2,
+                                           icon_bounds.X + icon_bounds.Width - 2, icon_bounds.Y + icon_bounds.Height / 2);
+                                           
+                               if (!grid.IsExpanded (row)) {
+                                       /* the | part of the icon */
+                                       g.DrawLine (pen,
+                                                   icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + 2,
+                                                   icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height - 2);
+                               }
+                       }
+
+                       Rectangle nested_rect = row_rect;
+
+                       if (grid.Rows[row].IsExpanded)
+                               nested_rect.Height -= grid.Rows[row].RelationHeight;
+
+                       DataGridPaintRowContents (g, row, nested_rect, is_newrow, clip, grid);
+
+                       if (grid.Rows[row].IsExpanded) {
+                               // XXX we should create this in the
+                               // datagrid and cache it for use by
+                               // the theme instead of doing it each
+                               // time through here
+                               string[] relations = grid.CurrentTableStyle.Relations;
+                               StringBuilder relation_builder = new StringBuilder ("");
+
+                               for (int i = 0; i < relations.Length; i ++) {
+                                       if (i > 0)
+                                               relation_builder.Append ("\n");
+
+                                       relation_builder.Append (relations[i]);
+                               }
+                               string relation_text = relation_builder.ToString ();
+
+                               StringFormat string_format = new StringFormat ();
+                               string_format.FormatFlags |= StringFormatFlags.NoWrap;
+
+
+                               //Region prev_clip = g.Clip;
+                               //Region current_clip;
+                               Rectangle rect_cell = row_rect;
+
+                               rect_cell.X = row_rect.X + grid.GetColumnStartingPixel (grid.FirstVisibleColumn) - grid.HorizPixelOffset;
+                               rect_cell.Y += nested_rect.Height;
+                               rect_cell.Height = grid.Rows[row].RelationHeight;
+                               rect_cell.Width = 0;
+
+                               int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
+                               for (int column = grid.FirstVisibleColumn; column < column_cnt; column++)
+                                       rect_cell.Width += grid.CurrentTableStyle.GridColumnStyles[column].Width;
+
+                               g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (grid.CurrentTableStyle.BackColor),
+                                                rect_cell);
+
+
+                               /* draw the line leading from the +/- to the relation area */
+                               Rectangle outline = grid.Rows[row].relation_area;
+                               outline.Y = rect_cell.Y;
+                               outline.Height --;
+
+                               g.DrawLine (pen,
+                                           icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height,
+                                           icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2);
+
+                               g.DrawLine (pen,
+                                           icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2,
+                                           outline.X, outline.Y + outline.Height / 2);
+
+                               g.DrawRectangle (pen, outline);
+
+                               g.DrawString (relation_text, grid.LinkFont, ResPool.GetSolidBrush (grid.LinkColor),
+                                             outline, string_format);
+
+                               if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
+                                       Rectangle not_usedarea = new Rectangle ();
+                                       not_usedarea.X = rect_cell.X + rect_cell.Width;
+                                       not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width;
+                                       not_usedarea.Y = row_rect.Y;
+                                       not_usedarea.Height = row_rect.Height;
+                                       if (clip.IntersectsWith (not_usedarea))
+                                               g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
+                                                                not_usedarea);
+                               }
+                       }
+               }
+
+               public override void DataGridPaintRowContents (Graphics g, int row, Rectangle row_rect, bool is_newrow,
+                                                              Rectangle clip, DataGrid grid)
+               {
                        Rectangle rect_cell = new Rectangle ();
                        int col_pixel;
                        Color backcolor, forecolor;
@@ -1136,12 +1300,12 @@ namespace System.Windows.Forms
                        foreBrush = ResPool.GetSolidBrush (forecolor);
 
                        // PaintCells at row, column
-                       int column_cnt = grid.first_visiblecolumn + grid.visiblecolumn_count;
-                       for (int column = grid.first_visiblecolumn; column < column_cnt; column++) {
+                       int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
+                       for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
 
                                col_pixel = grid.GetColumnStartingPixel (column);
 
-                               rect_cell.X = row_rect.X + col_pixel - grid.horz_pixeloffset;
+                               rect_cell.X = row_rect.X + col_pixel - grid.HorizPixelOffset;
                                rect_cell.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
 
                                if (clip.IntersectsWith (rect_cell)) {
@@ -1177,6 +1341,22 @@ namespace System.Windows.Forms
                                                         not_usedarea);
                        }
                }
+
+               public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
+                                                      Rectangle clip, DataGrid grid)
+               {                       
+                       /* paint the header if it's visible and intersects the clip */
+                       if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
+                               Rectangle rect_header = row_rect;
+                               rect_header.Width = grid.RowHeaderWidth;
+                               row_rect.X += grid.RowHeaderWidth;
+                               if (clip.IntersectsWith (rect_header)) {
+                                       DataGridPaintRowHeader (g, rect_header, row, grid);
+                               }
+                       }
+
+                       DataGridPaintRowContents (g, row, row_rect, is_newrow, clip, grid);
+               }
                
                #endregion // Datagrid
                
@@ -3530,7 +3710,7 @@ namespace System.Windows.Forms
                public  override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control) 
                {
                        StringFormat format = new StringFormat ();
-                       format.Trimming = StringTrimming.EllipsisWord;
+                       format.Trimming = StringTrimming.EllipsisCharacter;
                        format.LineAlignment = StringAlignment.Center;
                        if (control.TextAlign == ToolBarTextAlign.Underneath)
                                format.Alignment = StringAlignment.Center;
@@ -3555,30 +3735,25 @@ namespace System.Windows.Forms
                                if (clip_rectangle.Right == control.Right) {
                                        dc.DrawLine (SystemPens.ControlDark, clip_rectangle.Right - 1, 1, clip_rectangle.Right - 1, control.Bottom - 1);
                                }
-                       } else if (control.Divider) {
+                       } else {
 
-                               if (control.Appearance == ToolBarAppearance.Flat &&
-                                               control.Parent != null && control.Parent.BackgroundImage != null) {
-                                       using (TextureBrush b = new TextureBrush (control.Parent.BackgroundImage, WrapMode.Tile)) {
-                                               dc.FillRectangle (b, clip_rectangle);
+                               if (control.Appearance == ToolBarAppearance.Flat && control.Parent != null) {
+                                       if (control.Parent.BackgroundImage != null) {
+                                               using (TextureBrush b = new TextureBrush (control.Parent.BackgroundImage, WrapMode.Tile))
+                                                       dc.FillRectangle (b, clip_rectangle);
+                                       } else {
+                                               dc.FillRectangle (ResPool.GetSolidBrush (control.Parent.BackColor), clip_rectangle);
                                        }
                                } else {
                                        dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
                                }
 
-                               if (clip_rectangle.Y < 2) {
+                               if (control.Divider && clip_rectangle.Y < 2) {
                                        if (clip_rectangle.Y < 1) {
                                                dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, 0, clip_rectangle.Right, 0);
                                        }
                                        dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
                                }
-                       } else {
-                               if (control.Appearance == ToolBarAppearance.Flat &&
-                                               control.Parent != null && control.Parent.BackgroundImage != null) {
-                                       using (TextureBrush b = new TextureBrush (control.Parent.BackgroundImage, WrapMode.Tile)) {
-                                               dc.FillRectangle (b, clip_rectangle);
-                                       }
-                               }
                        }
 
                        foreach (ToolBarButton button in control.Buttons)
@@ -3707,10 +3882,14 @@ namespace System.Windows.Forms
                                        CPDrawImageDisabled (dc, button.Image, x, y, ColorControl);
                        }
 
+                       Rectangle text_rect = button.TextRectangle;
+                       if (text_rect.Width <= 0 || text_rect.Height <= 0)
+                               return;
+
                        if (button.Enabled)
-                               dc.DrawString (button.Text, control.Font, SystemBrushes.ControlText, button.TextRectangle, format);
+                               dc.DrawString (button.Text, control.Font, SystemBrushes.ControlText, text_rect, format);
                        else
-                               CPDrawStringDisabled (dc, button.Text, control.Font, control.BackColor, button.TextRectangle, format);
+                               CPDrawStringDisabled (dc, button.Text, control.Font, control.BackColor, text_rect, format);
                }
 
                // Grip width for the ToolBar
@@ -5138,6 +5317,7 @@ namespace System.Windows.Forms
                                default:
                                case ScrollButton.Down:
                                        int x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
+                                       int y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
                                        if (x_middle == 1)
                                                x_middle = 2;
                                        
@@ -5153,12 +5333,7 @@ namespace System.Windows.Forms
                                        }
                                        
                                        arrow [0].X = rect.X + x_middle;
-                                       arrow [0].Y = rect.Bottom - triangle_height - 1;
-                                       if (arrow [0].Y > rect.Height)
-                                               arrow [0].Y = rect.Bottom - 3;
-                                       
-                                       if (arrow [0].Y - 1 == rect.Y)
-                                               arrow [0].Y += 1;
+                                       arrow [0].Y = rect.Y + y_middle + triangle_height / 2;
                                        
                                        arrow [1].X = arrow [0].X + triangle_height - 1;
                                        arrow [1].Y = arrow [0].Y - triangle_height + 1;
@@ -5179,15 +5354,17 @@ namespace System.Windows.Forms
                                                        arrow [2].X += 1;
                                                }
                                        }
-                                       
-                                       
                                        break;
                                        
                                case ScrollButton.Up:
                                        x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
+                                       y_middle = (int)Math.Round (rect.Height / 2.0f);
                                        if (x_middle == 1)
                                                x_middle = 2;
                                        
+                                       if (y_middle == 1)
+                                               y_middle = 2;
+                                       
                                        if (rect.Height < 8) {
                                                triangle_height = 2;
                                                fill_rect = false;
@@ -5198,12 +5375,7 @@ namespace System.Windows.Forms
                                        }
                                        
                                        arrow [0].X = rect.X + x_middle;
-                                       arrow [0].Y = rect.Y + triangle_height;
-                                       if (arrow [0].Y > rect.Height)
-                                               arrow [0].Y = 2;
-                                               
-                                       if (arrow [0].Y + 1 == rect.Bottom - 1)
-                                               arrow [0].Y -= 1;
+                                       arrow [0].Y = rect.Y + y_middle - triangle_height / 2;
                                        
                                        arrow [1].X = arrow [0].X + triangle_height - 1;
                                        arrow [1].Y = arrow [0].Y + triangle_height - 1;
@@ -5223,11 +5395,10 @@ namespace System.Windows.Forms
                                                        arrow [2].X += 1;
                                                }
                                        }
-                                       
                                        break;
                                        
                                case ScrollButton.Left:
-                                       int y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
+                                       y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
                                        if (y_middle == 1)
                                                y_middle = 2;