1042 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			1042 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System.Collections.Generic;
 | 
						|
using System.Drawing;
 | 
						|
 | 
						|
namespace DevComponents.DotNetBar.SuperGrid
 | 
						|
{
 | 
						|
    internal class MergeScan
 | 
						|
    {
 | 
						|
        #region Private variables
 | 
						|
 | 
						|
        private GridContainer _GridContainer;
 | 
						|
        private GridPanel _GridPanel;
 | 
						|
 | 
						|
        private List<CellRange> _ScanItems;
 | 
						|
        private List<DisplayRange> _LastDrs;
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Public properties
 | 
						|
 | 
						|
        #region ScanItems
 | 
						|
 | 
						|
        ///<summary>
 | 
						|
        /// ScanItems
 | 
						|
        ///</summary>
 | 
						|
        public List<CellRange> ScanItems
 | 
						|
        {
 | 
						|
            get { return (GetScanItems()); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        ///<summary>
 | 
						|
        /// MergeScan
 | 
						|
        ///</summary>
 | 
						|
        ///<param name="gridContainer"></param>
 | 
						|
        public MergeScan(GridContainer gridContainer)
 | 
						|
        {
 | 
						|
            _GridContainer = gridContainer;
 | 
						|
            _GridPanel = _GridContainer.GridPanel;
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetScanItems
 | 
						|
 | 
						|
        internal List<CellRange> GetScanItems()
 | 
						|
        {
 | 
						|
            if (_GridContainer != null && _GridPanel != null)
 | 
						|
            {
 | 
						|
                int rowCount = GetRowCount();
 | 
						|
 | 
						|
                if (rowCount > 0)
 | 
						|
                {
 | 
						|
                    SuperGridControl sg = _GridPanel.SuperGrid;
 | 
						|
 | 
						|
                    if (sg.NeedMergeLayout == true)
 | 
						|
                        _GridContainer.NeedMergeLayout = true;
 | 
						|
 | 
						|
                    if (_GridContainer.NeedMergeLayout == true ||
 | 
						|
                        _GridContainer.DisplayedMergeLayoutCount != sg.DisplayedMergeLayoutCount)
 | 
						|
                    {
 | 
						|
                        _ScanItems = GetDisplayedScanItems();
 | 
						|
 | 
						|
                        _GridContainer.NeedMergeLayout = false;
 | 
						|
                        _GridContainer.DisplayedMergeLayoutCount = sg.DisplayedMergeLayoutCount;
 | 
						|
 | 
						|
                        sg.PostInternalMouseMove();
 | 
						|
                        sg.DeactivateNonModalEditor();
 | 
						|
                    }
 | 
						|
 | 
						|
                    return (_ScanItems);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (null);
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetRowCount
 | 
						|
 | 
						|
        private int GetRowCount()
 | 
						|
        {
 | 
						|
            if (_GridPanel.VirtualMode == true)
 | 
						|
                return (_GridPanel.VirtualRowCount);
 | 
						|
 | 
						|
            return (_GridContainer.Rows.Count);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDisplayedScanItems
 | 
						|
 | 
						|
        private List<CellRange> GetDisplayedScanItems()
 | 
						|
        {
 | 
						|
            List<DisplayRange> drs = GetDisplayRanges();
 | 
						|
 | 
						|
            if (drs != null)
 | 
						|
            {
 | 
						|
                _GridPanel.SuperGrid.DoGetDisplayRangesEvent(_GridContainer, ref drs);
 | 
						|
 | 
						|
                if (drs != null && drs.Count > 0)
 | 
						|
                    return (GetCellRanges(drs));
 | 
						|
            }
 | 
						|
 | 
						|
            return (null);
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetDisplayRanges
 | 
						|
 | 
						|
        private List<DisplayRange> GetDisplayRanges()
 | 
						|
        {
 | 
						|
            GridPanel panel = _GridContainer as GridPanel;
 | 
						|
 | 
						|
            int frCount = 0;
 | 
						|
            int fcCount = 0;
 | 
						|
 | 
						|
            if (panel != null)
 | 
						|
            {
 | 
						|
                frCount = panel.FrozenRowCount;
 | 
						|
 | 
						|
                GridColumn lastColumn = panel.Columns.GetLastVisibleFrozenColumn();
 | 
						|
 | 
						|
                if (lastColumn != null)
 | 
						|
                    fcCount = panel.Columns.GetDisplayIndex(lastColumn) + 1;
 | 
						|
            }
 | 
						|
 | 
						|
            DisplayRange dr = new DisplayRange();
 | 
						|
 | 
						|
            if (GetRowRange(dr) > 1 | GetColumnRange(dr) > 1)
 | 
						|
            {
 | 
						|
                List<DisplayRange> drs;
 | 
						|
 | 
						|
                if (frCount == 0 && fcCount == 0)
 | 
						|
                {
 | 
						|
                    drs = new List<DisplayRange>();
 | 
						|
                    drs.Add(dr);
 | 
						|
                }
 | 
						|
                else if (frCount != 0 && fcCount != 0)
 | 
						|
                {
 | 
						|
                    drs = new List<DisplayRange>(4);
 | 
						|
 | 
						|
                    drs.Add(GetNewRange(dr, 0, frCount, 0, fcCount));
 | 
						|
                    drs.Add(GetNewRange(dr, 0, frCount, fcCount, dr.ColumnCount));
 | 
						|
                    drs.Add(GetNewRange(dr, frCount, dr.RowCount, 0, fcCount));
 | 
						|
                    drs.Add(GetNewRange(dr, frCount, dr.RowEnd, fcCount, dr.ColumnCount));
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    drs = new List<DisplayRange>(2);
 | 
						|
 | 
						|
                    if (frCount != 0)
 | 
						|
                    {
 | 
						|
                        int n = (dr.RowStart < frCount ? frCount : dr.RowStart);
 | 
						|
 | 
						|
                        drs.Add(GetNewRange(dr, 0, frCount, dr.ColumnStart, dr.ColumnCount));
 | 
						|
                        drs.Add(GetNewRange(dr, n, dr.RowCount, dr.ColumnStart, dr.ColumnCount));
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        int n = (dr.ColumnStart < fcCount ? fcCount : dr.ColumnStart);
 | 
						|
 | 
						|
                        drs.Add(GetNewRange(dr, dr.RowStart, dr.RowCount, 0, fcCount));
 | 
						|
                        drs.Add(GetNewRange(dr, dr.RowStart, dr.RowCount, n, dr.ColumnCount));
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                return (drs);
 | 
						|
            }
 | 
						|
 | 
						|
            return (null);
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetRowRange
 | 
						|
 | 
						|
        private int GetRowRange(DisplayRange dr)
 | 
						|
        {
 | 
						|
            int rowCount = GetRowCount();
 | 
						|
 | 
						|
            if (rowCount < 50)
 | 
						|
            {
 | 
						|
                dr.RowStart = 0;
 | 
						|
                dr.RowEnd = rowCount;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                Rectangle t = _GridContainer.SuperGrid.ViewRect;
 | 
						|
 | 
						|
                dr.RowEnd = _GridContainer.FirstOnScreenRowIndex;
 | 
						|
                dr.RowStart = GetPreviousRowIndex(dr.RowEnd);
 | 
						|
 | 
						|
                bool fpass = false;
 | 
						|
 | 
						|
                for (int i = dr.RowStart; i < rowCount; i++)
 | 
						|
                {
 | 
						|
                    GridContainer item = GetRow(i);
 | 
						|
 | 
						|
                    if (item != null && item.Visible == true)
 | 
						|
                    {
 | 
						|
                        Rectangle r = item.BoundsRelative;
 | 
						|
 | 
						|
                        if (item.IsVFrozen == false)
 | 
						|
                            r.Y -= _GridContainer.VScrollOffset;
 | 
						|
 | 
						|
                        if (r.Y > t.Bottom)
 | 
						|
                        {
 | 
						|
                            if (fpass == true)
 | 
						|
                                break;
 | 
						|
 | 
						|
                            fpass = true;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    dr.RowEnd = i;
 | 
						|
                }
 | 
						|
 | 
						|
                dr.RowEnd = GetNextRowIndex(dr.RowEnd) + 1;
 | 
						|
            }
 | 
						|
 | 
						|
            return (dr.RowCount);
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetPreviousRowIndex
 | 
						|
 | 
						|
        private int GetPreviousRowIndex(int index)
 | 
						|
        {
 | 
						|
            if ((uint)index < GetRowCount())
 | 
						|
            {
 | 
						|
                for (int i = index - 1; i >= 0; i--)
 | 
						|
                {
 | 
						|
                    GridContainer row = GetRow(i);
 | 
						|
 | 
						|
                    if (row != null && row.Visible == true)
 | 
						|
                        return (i);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (index);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetNextRowIndex
 | 
						|
 | 
						|
        private int GetNextRowIndex(int index)
 | 
						|
        {
 | 
						|
            int rowCount = GetRowCount();
 | 
						|
 | 
						|
            if ((uint)index < rowCount)
 | 
						|
            {
 | 
						|
                for (int i = index + 1; i < rowCount; i++)
 | 
						|
                {
 | 
						|
                    GridContainer row = GetRow(i);
 | 
						|
 | 
						|
                    if (row != null && row.Visible == true)
 | 
						|
                        return (i);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (index);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetColumnRange
 | 
						|
 | 
						|
        private int GetColumnRange(DisplayRange dr)
 | 
						|
        {
 | 
						|
            GridColumnCollection columns = _GridPanel.Columns;
 | 
						|
            int colCount = columns.Count;
 | 
						|
 | 
						|
            dr.ColumnStart = 0;
 | 
						|
            dr.ColumnCount = colCount;
 | 
						|
 | 
						|
            if (colCount > 10)
 | 
						|
            {
 | 
						|
                int[] map = columns.DisplayIndexMap;
 | 
						|
 | 
						|
                for (int i = 0; i < map.Length; i++)
 | 
						|
                {
 | 
						|
                    int index = map[i];
 | 
						|
                    GridColumn column = columns[index];
 | 
						|
 | 
						|
                    if (column.Visible == true)
 | 
						|
                    {
 | 
						|
                        if (column.IsOnScreen == true && column.IsHFrozen == false)
 | 
						|
                            break;
 | 
						|
 | 
						|
                        dr.ColumnStart = i;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                dr.ColumnEnd = dr.ColumnStart;
 | 
						|
 | 
						|
                for (int i = dr.ColumnStart + 1; i < map.Length; i++)
 | 
						|
                {
 | 
						|
                    int index = map[i];
 | 
						|
                    GridColumn column = columns[index];
 | 
						|
 | 
						|
                    if (column.Visible == true)
 | 
						|
                    {
 | 
						|
                        dr.ColumnEnd = i;
 | 
						|
 | 
						|
                        if (column.IsOnScreen == false)
 | 
						|
                            break;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                dr.ColumnEnd++;
 | 
						|
            }
 | 
						|
 | 
						|
            return (dr.ColumnCount);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetNewRange
 | 
						|
 | 
						|
        private DisplayRange GetNewRange(DisplayRange dr,
 | 
						|
            int rowStart, int rowCount, int columnStart, int columnCount)
 | 
						|
        {
 | 
						|
            DisplayRange ndr = new DisplayRange();
 | 
						|
 | 
						|
            ndr.RowStart = rowStart;
 | 
						|
            ndr.RowCount = rowCount;
 | 
						|
 | 
						|
            if (ndr.RowEnd > dr.RowEnd)
 | 
						|
                ndr.RowEnd = dr.RowEnd;
 | 
						|
 | 
						|
            ndr.ColumnStart = columnStart;
 | 
						|
            ndr.ColumnCount = columnCount;
 | 
						|
 | 
						|
            if (ndr.ColumnEnd > dr.ColumnEnd)
 | 
						|
                ndr.ColumnEnd = dr.ColumnEnd;
 | 
						|
 | 
						|
            return (ndr);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetCellRanges
 | 
						|
 | 
						|
        private List<CellRange> GetCellRanges(List<DisplayRange> drs)
 | 
						|
        {
 | 
						|
            List<CellRange> cellRanges = null;
 | 
						|
 | 
						|
            if (_GridPanel.SuperGrid.EditorActive == true || LastScanIsValid(drs) == true)
 | 
						|
            {
 | 
						|
                cellRanges = _ScanItems;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                foreach (DisplayRange dr in drs)
 | 
						|
                {
 | 
						|
                    List<CellRange> crs = UpdateMergeRange(dr);
 | 
						|
 | 
						|
                    if (crs != null)
 | 
						|
                    {
 | 
						|
                        if (cellRanges != null)
 | 
						|
                            cellRanges.InsertRange(0, crs);
 | 
						|
                        else
 | 
						|
                            cellRanges = crs;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                _LastDrs = drs;
 | 
						|
            }
 | 
						|
            
 | 
						|
            if (cellRanges != null)
 | 
						|
            {
 | 
						|
                _GridContainer.SuperGrid.BoundsUpdateCount++;
 | 
						|
 | 
						|
                foreach (CellRange cr in cellRanges)
 | 
						|
                    cr.BackBounds = GetDisplayBounds(cr);
 | 
						|
 | 
						|
                _GridContainer.GridPanel.UpdateSelectionCount();
 | 
						|
            }
 | 
						|
 | 
						|
            return (cellRanges);
 | 
						|
        }
 | 
						|
 | 
						|
        #region LastScanIsValid
 | 
						|
 | 
						|
        private bool LastScanIsValid(List<DisplayRange> drs)
 | 
						|
        {
 | 
						|
            if (_GridContainer.NeedMergeLayout == false)
 | 
						|
            {
 | 
						|
                if (_LastDrs != null)
 | 
						|
                {
 | 
						|
                    if (drs.Count == _LastDrs.Count)
 | 
						|
                    {
 | 
						|
                        for (int i = 0; i < drs.Count; i++)
 | 
						|
                        {
 | 
						|
                            if (drs[i].IsRangeEqualTo(_LastDrs[i]) == false)
 | 
						|
                                return (false);
 | 
						|
                        }
 | 
						|
 | 
						|
                        return (true);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region UpdateMergeRange
 | 
						|
 | 
						|
        private List<CellRange> UpdateMergeRange(DisplayRange dr)
 | 
						|
        {
 | 
						|
            UpdateMergeFlags(dr);
 | 
						|
            UpdateMergeCount(dr);
 | 
						|
 | 
						|
            List<CellRange> cellRanges = null;
 | 
						|
 | 
						|
            if (_GridContainer.SuperGrid.DoGetCellRangesEvent(_GridContainer, dr, ref cellRanges) == false)
 | 
						|
                cellRanges = GetCellMergeRanges(dr);
 | 
						|
 | 
						|
            if (cellRanges != null)
 | 
						|
                PostProcessCellRanges(cellRanges);
 | 
						|
 | 
						|
            _GridContainer.SuperGrid.DoUpdateCellDisplayRangesEvent(_GridContainer, dr, ref cellRanges);
 | 
						|
 | 
						|
            return (cellRanges);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region UpdateMergeFlags
 | 
						|
 | 
						|
        private void UpdateMergeFlags(DisplayRange dr)
 | 
						|
        {
 | 
						|
            GridRow lastRow = null;
 | 
						|
 | 
						|
            for (int i = dr.RowStart; i < dr.RowEnd; i++)
 | 
						|
            {
 | 
						|
                GridContainer item = GetRow(i);
 | 
						|
 | 
						|
                if (item != null && item.Visible == true)
 | 
						|
                {
 | 
						|
                    GridRow row = item as GridRow;
 | 
						|
 | 
						|
                    if (row != null)
 | 
						|
                    {
 | 
						|
                        SetHMergeFlags(row, dr);
 | 
						|
                        SetVMergeFlags(row, lastRow, dr);
 | 
						|
                    }
 | 
						|
 | 
						|
                    lastRow = row;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region SetHMergeFlags
 | 
						|
 | 
						|
        private void SetHMergeFlags(GridRow row, DisplayRange dr)
 | 
						|
        {
 | 
						|
            GridPanel panel = _GridContainer.GridPanel;
 | 
						|
            GridColumnCollection columns = panel.Columns;
 | 
						|
 | 
						|
            int[] map = columns.DisplayIndexMap;
 | 
						|
 | 
						|
            GridCell lastCell = null;
 | 
						|
 | 
						|
            for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++)
 | 
						|
            {
 | 
						|
                int index = map[i];
 | 
						|
 | 
						|
                GridColumn column = columns[index];
 | 
						|
 | 
						|
                if (column.Visible == true)
 | 
						|
                {
 | 
						|
                    GridCell cell = row[index];
 | 
						|
 | 
						|
                    if (cell != null)
 | 
						|
                    {
 | 
						|
                        if (lastCell != null)
 | 
						|
                        {
 | 
						|
                            if (_GridContainer.SuperGrid.NeedMergeLayout == true ||
 | 
						|
                                cell.MergeUpdateCount != _GridContainer.MergeUpdateCount ||
 | 
						|
                                lastCell.MergeUpdateCount != _GridContainer.MergeUpdateCount)
 | 
						|
                            {
 | 
						|
                                bool merged = false;
 | 
						|
 | 
						|
                                if (CanHMergeCells(panel, column, lastCell.GridColumn))
 | 
						|
                                    merged = CanMergeValues(cell, lastCell);
 | 
						|
 | 
						|
                                cell.MergedLeft = merged;
 | 
						|
                                lastCell.MergedRight = merged;
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                        else
 | 
						|
                        {
 | 
						|
                            cell.MergedLeft = false;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    lastCell = cell;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region CanHMergeCells
 | 
						|
 | 
						|
        private bool CanHMergeCells(
 | 
						|
            GridPanel panel, GridColumn column1, GridColumn column2)
 | 
						|
        {
 | 
						|
            return (IsHCellMerge(panel, column1.CellMergeMode, CellMergeMode.HorizontalLeft) &&
 | 
						|
                    IsHCellMerge(panel, column2.CellMergeMode, CellMergeMode.HorizontalRight));
 | 
						|
        }
 | 
						|
 | 
						|
        #region IsHCellMerge
 | 
						|
 | 
						|
        private bool IsHCellMerge(GridPanel panel, CellMergeMode cMode, CellMergeMode tMode)
 | 
						|
        {
 | 
						|
            if (cMode == CellMergeMode.NotSet)
 | 
						|
                cMode = panel.CellMergeMode;
 | 
						|
 | 
						|
            return ((cMode & tMode) == tMode);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CanVMergeCells
 | 
						|
 | 
						|
        private bool CanVMergeCells(GridPanel panel, GridColumn column)
 | 
						|
        {
 | 
						|
            return (IsVCellMerge(panel, column.CellMergeMode));
 | 
						|
        }
 | 
						|
 | 
						|
        #region IsVCellMerge
 | 
						|
 | 
						|
        private bool IsVCellMerge(GridPanel panel, CellMergeMode mode)
 | 
						|
        {
 | 
						|
            if (mode == CellMergeMode.NotSet)
 | 
						|
                mode = panel.CellMergeMode;
 | 
						|
 | 
						|
            return ((mode & CellMergeMode.Vertical) == CellMergeMode.Vertical);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SetVMergeFlags
 | 
						|
 | 
						|
        private void SetVMergeFlags(GridRow row, GridRow lastRow, DisplayRange dr)
 | 
						|
        {
 | 
						|
            GridPanel panel = _GridContainer.GridPanel;
 | 
						|
            GridColumnCollection columns = panel.Columns;
 | 
						|
 | 
						|
            int[] map = columns.DisplayIndexMap;
 | 
						|
 | 
						|
            for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++)
 | 
						|
            {
 | 
						|
                int index = map[i];
 | 
						|
 | 
						|
                GridColumn column = columns[index];
 | 
						|
 | 
						|
                if (column.Visible == true)
 | 
						|
                {
 | 
						|
                    GridCell cell = row[index];
 | 
						|
 | 
						|
                    if (cell != null)
 | 
						|
                    {
 | 
						|
                        if (lastRow != null)
 | 
						|
                        {
 | 
						|
                            GridCell lastCell = lastRow[index];
 | 
						|
 | 
						|
                            if (lastRow.Rows.Count <= 0 || lastRow.Expanded == false)
 | 
						|
                            {
 | 
						|
                                if (lastCell != null)
 | 
						|
                                {
 | 
						|
                                    if (_GridContainer.SuperGrid.NeedMergeLayout == true ||
 | 
						|
                                        cell.MergeUpdateCount != _GridContainer.MergeUpdateCount ||
 | 
						|
                                        cell.MergeUpdateCount != row.MergeUpdateCount ||
 | 
						|
                                        lastCell.MergeUpdateCount != _GridContainer.MergeUpdateCount ||
 | 
						|
                                        lastCell.MergeUpdateCount != lastRow.MergeUpdateCount)
 | 
						|
                                    {
 | 
						|
                                        bool merged = false;
 | 
						|
 | 
						|
                                        if (CanVMergeCells(panel, column) == true)
 | 
						|
                                            merged = CanMergeValues(cell, lastCell);
 | 
						|
 | 
						|
                                        cell.MergedTop = merged;
 | 
						|
                                        lastCell.MergedBottom = merged;
 | 
						|
                                    }
 | 
						|
                                }
 | 
						|
                                else
 | 
						|
                                {
 | 
						|
                                    cell.MergedTop = false;
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                            else
 | 
						|
                            {
 | 
						|
                                if (lastCell != null)
 | 
						|
                                    lastCell.MergedBottom = false;
 | 
						|
 | 
						|
                                cell.MergedTop = false;
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CanMergeValues
 | 
						|
 | 
						|
        private bool CanMergeValues(GridCell cell1, GridCell cell2)
 | 
						|
        {
 | 
						|
            if (cell1.IsValueNull || cell2.IsValueNull)
 | 
						|
            {
 | 
						|
                if (cell1.Value == cell2.Value)
 | 
						|
                    return (cell1.AllowNullMerge & cell2.AllowNullMerge);
 | 
						|
 | 
						|
                return (false);
 | 
						|
            }
 | 
						|
 | 
						|
            string s1 = cell1.FormattedValue;
 | 
						|
            string s2 = cell2.FormattedValue;
 | 
						|
 | 
						|
            return (s1.Equals(s2));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region UpdateMergeCount
 | 
						|
 | 
						|
        private void UpdateMergeCount(DisplayRange dr)
 | 
						|
        {
 | 
						|
            GridPanel panel = _GridContainer.GridPanel;
 | 
						|
            GridColumnCollection columns = panel.Columns;
 | 
						|
 | 
						|
            int[] map = columns.DisplayIndexMap;
 | 
						|
 | 
						|
            for (int i = dr.RowStart; i < dr.RowEnd; i++)
 | 
						|
            {
 | 
						|
                GridContainer item = GetRow(i);
 | 
						|
 | 
						|
                if (item != null && item.Visible == true)
 | 
						|
                {
 | 
						|
                    GridRow row = item as GridRow;
 | 
						|
 | 
						|
                    if (row != null)
 | 
						|
                    {
 | 
						|
                        row.MergeUpdateCount = _GridContainer.MergeUpdateCount;
 | 
						|
 | 
						|
                        for (int j = dr.ColumnStart; j < dr.ColumnEnd; j++)
 | 
						|
                        {
 | 
						|
                            int index = map[j];
 | 
						|
 | 
						|
                            GridCell cell = row[index];
 | 
						|
 | 
						|
                            if (cell != null)
 | 
						|
                                cell.MergeUpdateCount = _GridContainer.MergeUpdateCount;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetCellMergeRanges
 | 
						|
 | 
						|
        private List<CellRange> GetCellMergeRanges(DisplayRange dr)
 | 
						|
        {
 | 
						|
            switch (_GridPanel.CellMergeOrder)
 | 
						|
            {
 | 
						|
                case CellMergeOrder.HorizontalThenVertical:
 | 
						|
                    return (MergeHCells(dr));
 | 
						|
 | 
						|
                default:
 | 
						|
                    return (MergeVCells(dr));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region MergeVCells
 | 
						|
 | 
						|
        private List<CellRange> MergeVCells(DisplayRange dr)
 | 
						|
        {
 | 
						|
            List<CellRange> cellRanges = new List<CellRange>();
 | 
						|
 | 
						|
            GridColumnCollection columns = _GridContainer.GridPanel.Columns;
 | 
						|
            int[] map = columns.DisplayIndexMap;
 | 
						|
 | 
						|
            for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++)
 | 
						|
            {
 | 
						|
                int index = map[i];
 | 
						|
                GridColumn column = columns[index];
 | 
						|
 | 
						|
                if (column.Visible == true)
 | 
						|
                {
 | 
						|
                    CellRange cr = null;
 | 
						|
 | 
						|
                    for (int j = dr.RowStart; j < dr.RowEnd; j++)
 | 
						|
                    {
 | 
						|
                        GridRow row = GetRow(j);
 | 
						|
 | 
						|
                        if (row != null && row.Visible == true && row.IsTempInsertRow == false)
 | 
						|
                        {
 | 
						|
                            GridCell cell = row.GetCell(index);
 | 
						|
 | 
						|
                            if (cell != null)
 | 
						|
                            {
 | 
						|
                                if (cell.MergedTop == true)
 | 
						|
                                {
 | 
						|
                                    if (cr == null)
 | 
						|
                                        cr = new CellRange(j, i);
 | 
						|
                                    else
 | 
						|
                                        cr.RowEnd = j + 1;
 | 
						|
                                }
 | 
						|
                                else
 | 
						|
                                {
 | 
						|
                                    OutputVCellRange(cellRanges, cr, map);
 | 
						|
 | 
						|
                                    cr = new CellRange(j, i);
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    OutputVCellRange(cellRanges, cr, map);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (cellRanges);
 | 
						|
        }
 | 
						|
 | 
						|
        #region OutputVCellRange
 | 
						|
 | 
						|
        private void OutputVCellRange(
 | 
						|
            List<CellRange> cellRanges, CellRange cr, int[] map)
 | 
						|
        {
 | 
						|
            if (cr != null)
 | 
						|
            {
 | 
						|
                for (int i = 0; i < cellRanges.Count; i++)
 | 
						|
                {
 | 
						|
                    CellRange crn = cellRanges[i];
 | 
						|
 | 
						|
                    if (crn.ColumnEnd == cr.ColumnStart)
 | 
						|
                    {
 | 
						|
                        if (crn.RowStart == cr.RowStart && crn.RowEnd == cr.RowEnd)
 | 
						|
                        {
 | 
						|
                            GridRow row = GetRow(cr.RowStart);
 | 
						|
 | 
						|
                            if (row != null)
 | 
						|
                            {
 | 
						|
                                if (row[map[crn.ColumnEnd - 1]].MergedRight == true)
 | 
						|
                                {
 | 
						|
                                    crn.ColumnEnd = cr.ColumnEnd;
 | 
						|
                                    cr = null;
 | 
						|
                                }
 | 
						|
                                else
 | 
						|
                                {
 | 
						|
                                    if (crn.RowStart == crn.RowEnd && crn.ColumnStart == crn.ColumnEnd)
 | 
						|
                                        cellRanges.RemoveAt(i);
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                            break;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                if (cr != null)
 | 
						|
                    cellRanges.Add(cr);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MergeHCells
 | 
						|
 | 
						|
        private List<CellRange> MergeHCells(DisplayRange dr)
 | 
						|
        {
 | 
						|
            List<CellRange> cellRanges = new List<CellRange>();
 | 
						|
 | 
						|
            GridColumnCollection columns = _GridPanel.Columns;
 | 
						|
            int[] map = columns.DisplayIndexMap;
 | 
						|
 | 
						|
            for (int j = dr.RowStart; j < dr.RowEnd; j++)
 | 
						|
            {
 | 
						|
                GridRow row = GetRow(j);
 | 
						|
 | 
						|
                if (row != null && row.Visible == true && row.IsTempInsertRow == false)
 | 
						|
                {
 | 
						|
                    CellRange cr = null;
 | 
						|
 | 
						|
                    for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++)
 | 
						|
                    {
 | 
						|
                        int index = map[i];
 | 
						|
 | 
						|
                        GridColumn column = columns[index];
 | 
						|
 | 
						|
                        if (column.Visible == true)
 | 
						|
                        {
 | 
						|
                            GridCell cell = row[index];
 | 
						|
 | 
						|
                            if (cell != null)
 | 
						|
                            {
 | 
						|
                                if (cell.MergedLeft == true)
 | 
						|
                                {
 | 
						|
                                    if (cr == null)
 | 
						|
                                        cr = new CellRange(j, i);
 | 
						|
                                    else
 | 
						|
                                        cr.ColumnEnd = i + 1;
 | 
						|
                                }
 | 
						|
                                else
 | 
						|
                                {
 | 
						|
                                    OutputHCellRange(cellRanges, cr, map);
 | 
						|
 | 
						|
                                    cr = new CellRange(j, i);
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    OutputHCellRange(cellRanges, cr, map);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (cellRanges);
 | 
						|
        }
 | 
						|
 | 
						|
        #region OutputHCellRange
 | 
						|
 | 
						|
        private void OutputHCellRange(
 | 
						|
            List<CellRange> cellRanges, CellRange cr, int[] map)
 | 
						|
        {
 | 
						|
            if (cr != null)
 | 
						|
            {
 | 
						|
                for (int i = 0; i < cellRanges.Count; i++)
 | 
						|
                {
 | 
						|
                    CellRange crn = cellRanges[i];
 | 
						|
 | 
						|
                    if (crn.RowEnd == cr.RowStart)
 | 
						|
                    {
 | 
						|
                        if (crn.ColumnStart == cr.ColumnStart && crn.ColumnEnd == cr.ColumnEnd)
 | 
						|
                        {
 | 
						|
                            GridRow row = GetRow(crn.RowEnd - 1);
 | 
						|
 | 
						|
                            if (row != null)
 | 
						|
                            {
 | 
						|
                                if (row[map[crn.ColumnEnd - 1]].MergedBottom == true)
 | 
						|
                                {
 | 
						|
                                    crn.RowEnd = cr.RowEnd;
 | 
						|
                                    cr = null;
 | 
						|
                                }
 | 
						|
                                else
 | 
						|
                                {
 | 
						|
                                    if (crn.RowStart == crn.RowEnd && crn.ColumnStart == crn.ColumnEnd)
 | 
						|
                                        cellRanges.RemoveAt(i);
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                            break;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                if (cr != null)
 | 
						|
                    cellRanges.Add(cr);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region PostProcessCellRanges
 | 
						|
 | 
						|
        private void PostProcessCellRanges(List<CellRange> cellRanges)
 | 
						|
        {
 | 
						|
            if (cellRanges != null)
 | 
						|
            {
 | 
						|
                for (int i = cellRanges.Count - 1; i >= 0; i--)
 | 
						|
                {
 | 
						|
                    CellRange cr = cellRanges[i];
 | 
						|
 | 
						|
                    if (cr.ColumnCount <= 1 && cr.RowCount <= 1)
 | 
						|
                    {
 | 
						|
                        cellRanges.RemoveAt(i);
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        if (cr.FormattedValue == null)
 | 
						|
                        {
 | 
						|
                            GridCell cell = GetRow(cr.RowStart)[_GridPanel.Columns.DisplayIndexMap[cr.ColumnStart]];
 | 
						|
 | 
						|
                            if (cell != null)
 | 
						|
                            {
 | 
						|
                                string s = cell.FormattedValue;
 | 
						|
 | 
						|
                                cell.SuperGrid.DoGetCellRangeFormattedValueEvent((GridContainer)cell.GridRow.Parent, cr, ref s);
 | 
						|
 | 
						|
                                cr.FormattedValue = s;
 | 
						|
                            }
 | 
						|
                            else
 | 
						|
                            {
 | 
						|
                                cr.FormattedValue = "";
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDisplayBounds
 | 
						|
 | 
						|
        private Rectangle GetDisplayBounds(CellRange cr)
 | 
						|
        {
 | 
						|
            Rectangle r = Rectangle.Empty;
 | 
						|
 | 
						|
            if (cr != null)
 | 
						|
            {
 | 
						|
                GridPanel panel = _GridContainer.GridPanel;
 | 
						|
                int[] map = panel.Columns.DisplayIndexMap;
 | 
						|
 | 
						|
                int rowHeight = 200;
 | 
						|
 | 
						|
                for (int ri = cr.RowStart; ri < cr.RowEnd; ri++)
 | 
						|
                {
 | 
						|
                    GridRow row = GetRow(ri);
 | 
						|
 | 
						|
                    if (row.Visible == true)
 | 
						|
                    {
 | 
						|
                        for (int ci = cr.ColumnStart; ci < cr.ColumnEnd; ci++)
 | 
						|
                        {
 | 
						|
                            int index = map[ci];
 | 
						|
 | 
						|
                            GridCell cell = row.GetCell(index);
 | 
						|
 | 
						|
                            if (cell != null)
 | 
						|
                            {
 | 
						|
                                r = (r.IsEmpty == true)
 | 
						|
                                        ? cell.BackBounds
 | 
						|
                                        : Rectangle.Union(r, cell.BackBounds);
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
 | 
						|
                        if (rowHeight > row.FixedRowHeight)
 | 
						|
                            rowHeight = row.FixedRowHeight;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                if (r.IsEmpty == false)
 | 
						|
                    r = AdjustMergeRect(panel, map, r, cr, rowHeight);
 | 
						|
            }
 | 
						|
 | 
						|
            return (r);
 | 
						|
        }
 | 
						|
 | 
						|
        #region AdjustMergeRect
 | 
						|
 | 
						|
        private Rectangle AdjustMergeRect(GridPanel panel,
 | 
						|
            int[] map, Rectangle r, CellRange cr, int rowHeight)
 | 
						|
        {
 | 
						|
            Rectangle r2 = r;
 | 
						|
            Rectangle t = _GridContainer.SViewRect;
 | 
						|
 | 
						|
            if (r.IntersectsWith(t))
 | 
						|
                r.Intersect(t);
 | 
						|
 | 
						|
            if (r.Width > 0 && r.Height > 0)
 | 
						|
            {
 | 
						|
                if (r2.Y < t.Y)
 | 
						|
                {
 | 
						|
                    if (r.Height < rowHeight)
 | 
						|
                    {
 | 
						|
                        r.Y = r.Bottom - rowHeight;
 | 
						|
                        r.Height = rowHeight;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                else if (r2.Bottom > t.Bottom)
 | 
						|
                {
 | 
						|
                    if (r.Height < rowHeight)
 | 
						|
                        r.Height = rowHeight;
 | 
						|
                }
 | 
						|
 | 
						|
                GridColumn cols = panel.Columns[map[cr.ColumnStart]];
 | 
						|
                GridColumn cole = panel.Columns[map[cr.ColumnEnd - 1]];
 | 
						|
 | 
						|
                if (r2.X < t.X && cole.Bounds.X < t.X)
 | 
						|
                {
 | 
						|
                    if (r.Width < cole.BoundsRelative.Width)
 | 
						|
                    {
 | 
						|
                        r.X = r2.Right - cole.BoundsRelative.Width;
 | 
						|
                        r.Width = cole.BoundsRelative.Width;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                else if (r2.Right > t.Right && cols.Bounds.Right > r.Right)
 | 
						|
                {
 | 
						|
                    if (r.Width < cols.BoundsRelative.Width)
 | 
						|
                    {
 | 
						|
                        r.X = r2.X;
 | 
						|
                        r.Width = cols.BoundsRelative.Width;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (r);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetRow
 | 
						|
 | 
						|
        private GridRow GetRow(int index)
 | 
						|
        {
 | 
						|
            return (_GridPanel.VirtualMode == true)
 | 
						|
                       ? _GridPanel.VirtualRows[index]
 | 
						|
                       : _GridContainer.Rows[index] as GridRow;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
    }
 | 
						|
}
 |