using System; using System.ComponentModel; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Runtime.InteropServices; using System.Xml; using System.IO; using Volian.Controls.Library; using VEPROMS.CSLA.Library; using C1.Win.C1FlexGrid; using System.Text.RegularExpressions; using System.Xml.Serialization; namespace Volian.Controls.Library { public delegate void VlnFlexGridEvent(object sender, EventArgs args); public delegate void VlnFlexGridCursorMovementEvent(object sender, VlnFlexGridCursorMovementEventArgs args); public delegate string VlnFlexGridPasteEvent(object sender, VlnFlexGridPasteEventArgs args); public partial class VlnFlexGrid : C1.Win.C1FlexGrid.C1FlexGrid { //[XmlElement("MyBorders")] //[Browsable(false)] //[EditorBrowsable(EditorBrowsableState.Never)] //public string MyBorderDetailString //{ // get // { // return _MyBorderDetail.ToString(); // } // set // { // if (value != null) // _MyBorderDetail = VlnBorderDetail.Get(value); // else // _MyBorderDetail = null; // } //} //private VlnBorderDetail _MyBorderDetail; //[XmlIgnore] //public VlnBorderDetail MyBorderDetail //{ // get { return _MyBorderDetail; } // set { _MyBorderDetail = value; } //} private ItemInfo _MyItemInfo; public ItemInfo MyItemInfo { get { return _MyItemInfo; } set { _MyItemInfo = value; } } [XmlIgnore] public bool HasVScroll { get { return RTBAPI.HasVertScroll(this); } } [XmlIgnore] public bool HasHScroll { get { return RTBAPI.HasHorzScroll(this); } } public event VlnFlexGridEvent OpenAnnotations; public void OnOpenAnnotations(object sender, EventArgs args) { if (OpenAnnotations != null) OpenAnnotations(sender, args); } public event VlnFlexGridCursorMovementEvent CursorMovement; internal void OnCursorMovement(object sender, VlnFlexGridCursorMovementEventArgs args) { if (CursorMovement != null) CursorMovement(sender, args); } public event VlnFlexGridPasteEvent AdjustPastedText; internal string OnAdjustPastedText(object sender, VlnFlexGridPasteEventArgs args) { if (AdjustPastedText != null) return AdjustPastedText(sender, args); return args.Text; } private TableCellEditor _tableCellEditor; public TableCellEditor TableCellEditor { get { return _tableCellEditor; } set { _tableCellEditor = value; } } private TableClipBoardFuncts _clpbrdCpyPste; private int _minColSplitWidth = 10; //private int _minRowSplitHeight = 23; //private int _minSplitColWidth = 10; //private int _minSplitRowHeight = 20; private E_ViewMode _vwMode = E_ViewMode.Edit; [XmlIgnore] internal E_ViewMode VwMode { get { return _vwMode; } set { _vwMode = value; AllowEditing = _vwMode == E_ViewMode.Edit; } } private bool _IsRoTable = false; public bool IsRoTable { get { return _IsRoTable; } set { _IsRoTable = value; } } private int _RODbId; public int RODbId { get { return _RODbId; } set { _RODbId = value; } } private string _ROID; public string ROID { get { return _ROID; } set { _ROID = value; } } private float? _DPI = null; public float? DPI { get { if (_DPI == null) _DPI = 120; return _DPI; } set { if (DPI != value) { _DPI = value; } } } #region Grid Initialize public VlnFlexGrid() { InitializeComponent(); SetupGrid(4, 3); // use a default row and column count } public VlnFlexGrid(int rows, int cols) { InitializeComponent(); SetupGrid(rows, cols); } public VlnFlexGrid(IContainer container) { container.Add(this); InitializeComponent(); SetupGrid(1, 1); } //public VlnFlexGrid(IContainer container) //{ // container.Add(this); // InitializeComponent(); // _tableCellEditor = new TableCellEditor(this); // _tableCellEditor.ContentsResized += new ContentsResizedEventHandler(_tableCellEditor_ContentsResized); //} //void _tableCellEditor_ContentsResized(object sender, ContentsResizedEventArgs e) //{ // if (_tableCellEditor._initializingEdit) return; // CellRange cr = GetMergedRange(Row, Col); // int oH = cr.UserData == null? 0 : (int)cr.UserData; // int nH = _tableCellEditor.ContentsRectangle.Height; // int Hadj = (nH - oH); // cr.UserData = _tableCellEditor.ContentsRectangle.Height; // int cellHeight = GetCellHeight(Row,Col); // int cellheightNLines = cellHeight / (Rows.DefaultSize - 3); // int nHNLines = nH / (Rows.DefaultSize - 3); // if (Hadj != 0) // { // int curHeight = (Rows[Row].Height == -1) ? Rows.DefaultSize : Rows[Row].Height; // //if (Hadj > 0 && cellHeight <= oH) // if (Hadj > 0 && cellheightNLines < nHNLines) // curHeight += (Rows.DefaultSize - 3); // if (Hadj < 0 && CanReduceRow()) // curHeight -= (Rows.DefaultSize-3); // Rows[Row].Height = curHeight; // AdjustGridControlSize(); // } // //cr.UserData = _tableCellEditor.ContentsRectangle.Height; // //int mh = GetMaxRowHeight(); // ////Rows[Row].Height = mh + 2; // //int h = 0; // //if (cr.r1 == cr.r2 && cr.c1 == cr.c2) // // h = Rows[Row].Height - 2; // //else // //{ // // for (int r = cr.r1; r <= cr.r2; r++) // // h += Rows[r].Height - 2; // //} // //Rows[Row].Height += (mh - h); // ////AdjustGridControlSize(); //} private int GetCellHeight(int row, int col) { return GetRangeHeight(GetMergedRange(row, col))-3; } public int GetRangeHeight(CellRange cr) { int height = 0; for (int r = cr.r1; r <= cr.r2; r++) height += (Rows[r].Height == -1) ? Rows.DefaultSize : Rows[r].Height; return height; } public int GetRangeTop(CellRange cr) { int top = 0; for (int r = 0; r < cr.r1; r++) top += (Rows[r].Height == -1) ? Rows.DefaultSize : Rows[r].Height; return top; } public int GetRangeWidth(CellRange cr) { int width = 0; for (int c = cr.c1; c <= cr.c2; c++) width += (Cols[c].Width == -1) ? Cols.DefaultSize : Cols[c].Width; return width; } public int GetRangeLeft(CellRange cr) { int left = 0; for (int c = 0; c < cr.c1; c++) left += (Cols[c].Width == -1) ? Cols.DefaultSize : Cols[c].Width; return left; } public int GetRangeRowsMin(CellRange cr) { int rowsMin = 1 + cr.r2 - cr.r1; for (int c = cr.c1; c <= cr.c2; c++) { int rows = 0; for (int r = cr.r1; r <= cr.r2; r++) { CellRange chk = GetMergedRange(r, c); if (chk.r1 == r && chk.c1 == c) rows++; } rowsMin = Math.Min(rowsMin, rows); } return rowsMin; } public int GetRangeRowsMax(CellRange cr) { int rowsMax = 0; for (int c = cr.c1; c <= cr.c2; c++) { int rows = 0; for (int r = cr.r1; r <= cr.r2; r++) { CellRange chk = GetMergedRange(r, c); if (chk.r1 == r && chk.c1 == c) rows++; } rowsMax = Math.Max(rowsMax, rows); } return rowsMax; } public int GetRangeColsMin(CellRange cr) { int colsMin = 1 + cr.c2 - cr.c1; for (int r = cr.r1; r <= cr.r2; r++) { int cols = 0; for (int c = cr.c1; c <= cr.c2; c++) { CellRange chk = GetMergedRange(r, c); if (chk.r1 == r && chk.c1 == c) cols++; } colsMin = Math.Min(colsMin, cols); } return colsMin; } public int GetRangeColsMax(CellRange cr) { int colsMax = 0; for (int c = cr.c1; c <= cr.c2; c++) { int cols = 0; for (int r = cr.r1; r <= cr.r2; r++) { CellRange chk = GetMergedRange(r, c); if (chk.r1 == r && chk.c1 == c) cols++; } colsMax = Math.Max(colsMax, cols); } return colsMax; } public string GetRangeRowList(CellRange cr) { StringBuilder sb = new StringBuilder(); string sep = ""; for (int r = cr.r1; r <= cr.r2; r++) { CellRange crm = GetMergedRange(r, cr.c1); if (crm.r1 == r) { sb.Append(sep + r.ToString()); sep = "."; } r = crm.r2; } return sb.ToString(); } private int GetCellWidth(int row, int col) { int width = 0; CellRange cr = GetMergedRange(row, col); for (int c = cr.c1; c <= cr.c2; c++) { width += (Cols[c].Width == -1) ? Cols.DefaultSize - 3 : Cols[c].Width -3; } return width; } private int BlankRowSpace() { int curRowHeight = (Rows[Row].Height == -1) ? Rows.DefaultSize - 3 : Rows[Row].Height - 3; if (curRowHeight <= (Rows.DefaultSize - 3)) return 0; // never have row less than default height int blankRowSpace = curRowHeight; for (int c = 0; c < Cols.Count; c++) { CellRange cr = GetMergedRange(Row, c); if (Row >= cr.r1 && Row <= cr.r2) { int cellHeight = GetCellHeight(Row, c); int dataHeight = (cr.UserData == null) ? cellHeight : (int)cr.UserData; int ud = dataHeight / (Rows.DefaultSize - 3); //if (cellHeight < dataHeight) // Console.WriteLine("r {0}, c {1}, cell{2}, data{3}", Row, c, cellHeight, dataHeight); blankRowSpace = Math.Min(blankRowSpace, Math.Max(0,cellHeight - dataHeight)); } } //Console.WriteLine("BlankRowSpace {0}", blankRowSpace); return blankRowSpace; } private int BlankColSpace() { int curColWidth = (Cols[Col].Width == -1) ? Cols.DefaultSize - 3 : Cols[Col].Width - 3; //int curRowHeightNLines = curRowHeight / (Rows.DefaultSize - 3); if (curColWidth <= Cols.DefaultSize - 3) return 0; // never have col less than default width int blankColSpace = curColWidth; for (int r = 0; r < Rows.Count; r++) { StepRTB srtb = new StepRTB(); CellRange cr = GetMergedRange(r, Col); srtb.Rtf = GetCellRTFString(cr.r1,cr.c1); if (Col >= cr.c1 && Col <= cr.c2) { int cellWidth = GetCellWidth(r, Col); srtb.Width = cellWidth; Application.DoEvents(); //int mergeCellHeightNLines = cellHeight / (Rows.DefaultSize - 3); //int dataHeight = (cr.UserData == null) ? cellHeight : (int)cr.UserData; //int ud = dataHeight / (Rows.DefaultSize - 3); //if (cellHeight < dataHeight) // Console.WriteLine("r {0}, c {1}, cell{2}, data{3}", Row, c, cellHeight, dataHeight); blankColSpace = Math.Min(blankColSpace, Math.Max(0, cellWidth - srtb.MaxTextWidth)); } } //Console.WriteLine("BlankRowSpace {0}", blankRowSpace); return blankColSpace; } //private bool CanReduceRow() //{ // int curRowHeight = (Rows[Row].Height == -1) ? Rows.DefaultSize - 3 : Rows[Row].Height -3; // int curRowHeightNLines = curRowHeight / (Rows.DefaultSize - 3); // bool bReduce = (curRowHeight > (Rows.DefaultSize - 3)); // if (bReduce) // { // for (int c = 0; c < Cols.Count; c++) // { // CellRange cr = GetMergedRange(Row, c); // if (Row >= cr.r1 && Row <= cr.r2) // { // int mergeCellHeightNLines = GetCellHeight(Row, c) / (Rows.DefaultSize - 3); // //int ud = (cr.UserData == null) ? 0 : (int)cr.UserData; // //if ((c != Col) && curRowHeight <= ud && ud >= mergeCellHeight) // // bReduce = false; // int ud = ((cr.UserData == null) ? 0 : (int)cr.UserData) / (Rows.DefaultSize - 3); // if ((c != Col) && curRowHeightNLines <= ud && ud >= mergeCellHeightNLines) // bReduce = false; // } // } // } // //Console.WriteLine("canreduce {0}, {1}", Row, bReduce); // return bReduce; //} //private int GetMaxRowHeight() //{ // int maxRTFHeight = _minRowSplitHeight; //Rows.DefaultSize;// the smallest a row can be // Console.WriteLine("================================================================="); // for (int c = 0; c < Cols.Count; c++) // { // CellRange cr = GetMergedRange(Row, c);//GetCellRange(Row, c); // maxRTFHeight = Math.Max(maxRTFHeight, (int)cr.UserData); // if (c==0) // Console.WriteLine("Height in Row[{0}] = {1}", Row, Rows[Row].Height); // Console.WriteLine("UserData Cell[{0},{1}] = {2}", Row, c, cr.UserData); // } // return maxRTFHeight; //} //private bool IsInMergeRange(int row, int col) //{ // //foreach (CellRange cr in this.MergedRanges) // //{ // // if (cr.Contains(row, col)) // // return true; // in a merged range // //} // CellRange cr = GetMergedRange(row, col); // return (cr.r1 == row && cr.c1 == col); //} private static Regex _ReplaceVESymbFix = new Regex(@"({\\f[0-9]+[^ ]* )(VESymbFix)(;})"); private static Regex _ReplaceArialUnicodeMS = new Regex(@"({\\f[0-9]+[^ ]* )(Arial Unicode MS)(;})"); private static Regex _ReplaceTextFont = new Regex(@"({\\f[0-9]+[^ ]* )(?((?!VESymbFix)(?!Arial Unicode MS))([^;]*)|(!!!!))(;})"); public void LoadGrid(ItemInfo itemInfo) { MyItemInfo = itemInfo; string str = itemInfo.MyContent.MyGrid.Data; VE_Font vefont = MyItemInfo.GetItemFont(); FontFamily ff = StepRTB.MyFontFamily ?? vefont.WindowsFont.FontFamily; // TODO: Does not change fixed font. if (StepRTB.MySymbolFontName != "VESymbFix") str = _ReplaceVESymbFix.Replace(str, "$1" + StepRTB.MySymbolFontName + "$3"); if (StepRTB.MySymbolFontName != "Arial Unicode MS") str = _ReplaceArialUnicodeMS.Replace(str, "$1" + StepRTB.MySymbolFontName + "$3"); str = _ReplaceTextFont.Replace(str, "$1" + ff.Name + "$4"); using (StringReader sr = new StringReader(str)) { ReadXml(sr); sr.Close(); } } private void SetupGrid(int numrows, int numcols) //C1FlexGrid NewGrid() { // setup the default size of each cell in the table/grid this.Cols.DefaultSize = 40; this.Rows.DefaultSize = 20; // setup the number of rows and columns this.Rows.Count = numrows; this.Cols.Count = numcols; // make all the cell editable this.Rows.Fixed = 0; this.Cols.Fixed = 0; this.DrawMode = DrawModeEnum.OwnerDraw; this.ScrollBars = ScrollBars.None; // grid styles this.Styles.EmptyArea.BackColor = Color.Transparent; this.Styles.EmptyArea.Border.Style = BorderStyleEnum.None; this.Styles.Normal.Border.Color = Color.Black; this.Styles.Normal.TextAlign = C1.Win.C1FlexGrid.TextAlignEnum.LeftTop; //SetupCellStyles(); this.FocusRect = FocusRectEnum.Solid; this.Styles.Highlight.BackColor = Color.LightCyan; this.Styles.Highlight.ForeColor = Color.Black; this.Styles.Focus.BackColor = Color.LightCyan; this.HighLight = HighLightEnum.WithFocus; this.AllowMerging = C1.Win.C1FlexGrid.AllowMergingEnum.Custom; this.AllowResizing = C1.Win.C1FlexGrid.AllowResizingEnum.Both; _tableCellEditor = new TableCellEditor(this); _tableCellEditor.HeightChanged += new StepRTBEvent(_tableCellEditor_HeightChanged); _clpbrdCpyPste = new TableClipBoardFuncts(); this.AfterResizeRow += new C1.Win.C1FlexGrid.RowColEventHandler(this.Grid_AfterResize); this.StartEdit += new C1.Win.C1FlexGrid.RowColEventHandler(this._StartEdit); this.AfterEdit += new C1.Win.C1FlexGrid.RowColEventHandler(this._AfterEdit); this.AfterScroll += new C1.Win.C1FlexGrid.RangeEventHandler(this._AfterScroll); this.AfterResizeColumn += new C1.Win.C1FlexGrid.RowColEventHandler(this.Grid_AfterResize); this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this._KeyPress); this.OwnerDrawCell += new OwnerDrawCellEventHandler(this.Grid_OwnerDrawCell); this.LeaveCell += new EventHandler(VlnFlexGrid_LeaveCell); this.KeyDown += new KeyEventHandler(VlnFlexGrid_KeyDown); this.KeyUp +=new KeyEventHandler(VlnFlexGrid_KeyUp); TableCellEditor.EditMode = TableCellEditor.Visible; // need to comment out for compile for only jsj - 07FEB2011 } void _tableCellEditor_HeightChanged(object sender, EventArgs args) { if (_tableCellEditor._initializingEdit || !_tableCellEditor.Visible) return; int curHeight = GetCellHeight(Row, Col);//(Rows[Row].Height == -1) ? Rows.DefaultSize : Rows[Row].Height; CellRange cr = GetMergedRange(Row, Col); int oH = cr.UserData == null ? curHeight : (int)cr.UserData; int nH = _tableCellEditor.Height; //.ContentsRectangle.Height; int Hadj = (nH - curHeight);//oH); cr.UserData = _tableCellEditor.Height; //.ContentsRectangle.Height; //int cellHeight = GetCellHeight(Row, Col); //int cellheightNLines = cellHeight / (Rows.DefaultSize - 3); //int nHNLines = nH / (Rows.DefaultSize - 3); if (Hadj != 0) { //if (Hadj > 0 && cellHeight <= oH) //if (Hadj > 0 && cellheightNLines < nHNLines) // curHeight += (Rows.DefaultSize - 3); //if (Hadj < 0 && CanReduceRow()) // curHeight -= (Rows.DefaultSize - 3); int blankRowSpace = BlankRowSpace(); if (Hadj < 0) Hadj = -Math.Min(-Hadj, blankRowSpace); //if (Hadj > 0) // Console.WriteLine("r {0}, nh {1}, curh{2}", Row, nH, curHeight); if (Hadj != 0) { Rows[Row].Height += Hadj;//= curHeight; AdjustGridControlSize(); } } } void VlnFlexGrid_KeyUp(object sender, KeyEventArgs e) { if (e.Control) { if (e.Alt) { switch (e.KeyCode) { case Keys.M: OnOpenAnnotations(this, new EventArgs()); e.Handled = true; break; default: break; } } } } void VlnFlexGrid_KeyDown(object sender, KeyEventArgs e) { switch (e.KeyCode) { case Keys.Left: if (e.Shift) return; _tableCellEditor.StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlLeft : E_ArrowKeys.Left); e.Handled = true; break; case Keys.Up: if (e.Shift) return; _tableCellEditor.StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlUp : E_ArrowKeys.Up); e.Handled = true; break; case Keys.Right: if (e.Shift) return; _tableCellEditor.StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlRight : E_ArrowKeys.Right); e.Handled = true; break; case Keys.Down: if (e.Shift) return; _tableCellEditor.StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlDown : E_ArrowKeys.Down); e.Handled = true; break; } } void VlnFlexGrid_LeaveCell(object sender, EventArgs e) { //CellStyle csd = this.CursorCell.StyleDisplay; //CellStyle cs = this.GetCellRange(Row, Col).Style; //if (cs != null) //{ // Console.WriteLine("LeaveCell Style = {0}", cs.Name); // Console.WriteLine("LeaveCell StyleDisplay = {0}", csd.Name); // cs.ForeColor = Color.Black; //} CellStyle cs = this.Styles["Focus"]; cs.ForeColor = Color.Black; cs = this.Styles["Highlight"]; cs.ForeColor = Color.Black; } //void VlnFlexGrid_LeaveEdit(object sender, RowColEventArgs e) //{ // //Console.WriteLine("LeaveEdit Style = {0}", this.GetCellRange(e.Row, e.Col).Style.Name); // this.GetCellRange(e.Row, e.Col).Style.ForeColor = Color.Black; //} private void Grid_OwnerDrawCell(object sender, C1.Win.C1FlexGrid.OwnerDrawCellEventArgs e) { using (RTF _rtf = new RTF()) { // use nearest solid color // (the RTF control doesn't dither, and doesn't support transparent backgrounds) Color solid = e.Graphics.GetNearestColor(e.Style.BackColor); DPI = e.Graphics.DpiX; if (e.Style.BackColor != solid) e.Style.BackColor = solid; // check whether the cell contains RTF string rtfText = this.GetDataDisplay(e.Row, e.Col).Replace(@"\~", @"\u160?"); GridItem gi = Parent as GridItem; if (gi != null) { DisplayText dt = new DisplayText(gi.MyItemInfo, rtfText, true); rtfText = dt.StartText; } if (rtfText.StartsWith(@"{\rtf")) { // it does, so draw background e.DrawCell(DrawCellFlags.Background); // draw the RTF text if (e.Bounds.Width > 0 && e.Bounds.Height > 0) { _rtf.Width = e.Bounds.Width - 3; _rtf.Rtf = rtfText; CellRange cr = GetMergedRange(e.Row, e.Col); cr.UserData = _rtf.Height; int hAdjust = 0; int hDiff = e.Bounds.Height - _rtf.Height; if (hDiff < 0) { Rows[e.Row].Height = _rtf.Height + 4; AdjustGridControlSize(); hDiff = 0; } if (e.Style != null) { switch (e.Style.TextAlign) { case TextAlignEnum.CenterBottom: case TextAlignEnum.GeneralBottom: case TextAlignEnum.LeftBottom: case TextAlignEnum.RightBottom: hAdjust = hDiff; break; case TextAlignEnum.CenterCenter: case TextAlignEnum.GeneralCenter: case TextAlignEnum.LeftCenter: case TextAlignEnum.RightCenter: hAdjust = hDiff / 2; break; default: break; } } if (IsRoTable) { _rtf.ForeColor = Color.Red; } else { _rtf.ForeColor = e.Style.ForeColor; } _rtf.BackColor = e.Style.BackColor; _rtf.Render(e.Graphics, new Rectangle(e.Bounds.X+1,e.Bounds.Y + hAdjust,e.Bounds.Width-3,e.Bounds.Height)); //CellRange cr = GetCellRange(e.Row, e.Col); //Console.WriteLine("ownerDraw UserData [{0},{1}] = {2}", cr.r1, cr.c1, _rtf.ContentsRectangle.Height); //cr.UserData = _rtf.ContentsRectangle.Height; } // and draw border last e.DrawCell(DrawCellFlags.Border); // This can be used to draw more specific borders // DrawCellBorder(e.Graphics, e.Bounds,e.Row,e.Col); // we're done with this cell e.Handled = true; } } } private void DrawCellBorder(Graphics graphics, Rectangle rectangle, int row, int col) { int x1 = rectangle.Left; int y1 = rectangle.Top; int x2 = rectangle.Right - 1; int y2 = rectangle.Bottom - 1; if (row == 0) graphics.DrawLine(Pens.Black, x1, y1, x2, y1); if (col == 0) graphics.DrawLine(Pens.Black, x1, y1, x1, y2); graphics.DrawLine(Pens.Black, x1, y2, x2, y2); graphics.DrawLine(Pens.Black, x2, y1, x2, y2); // Double line attribute the Bottom of the first row // if(row == 0) // graphics.DrawLine(Pens.Black, x1, y2-2, x2, y2-2); } #endregion //Grid Initialize #region Grid and Cell Styles public void ChangeBackgroundColor(string bckgndColor) { CellRange cr = this.Selection; if (!bckgndColor.EndsWith(";")) bckgndColor+=";"; string strBckgndColor = string.Format("BackColor:{0}", bckgndColor); for (int rw = cr.r1; rw <= cr.r2; rw++) for (int cl = cr.c1; cl <= cr.c2; cl++) { CellRange tmp = this.GetCellRange(rw, cl, rw, cl); string StyleName = string.Format("R{0}C{1}Style", rw, cl); CellStyle cs = this.Styles.Add(StyleName, tmp.Style); cs.ParseString(strBckgndColor); tmp.Style = cs; } } public void ToggleCellTextAlignment() { // only used in test program CellRange cr = this.Selection; StepRTB srtb = new StepRTB(); srtb.Rtf = this.GetCellRTFString(cr.r1, cr.c1); srtb.SelectAll(); int align = (int)srtb.SelectionAlignment; align = (align + 1) % 3; srtb.SelectionAlignment = (HorizontalAlignment)align; this.PutCellRTFString(cr.r1, cr.c1, srtb.Rtf); } public void RTFTextAlignment(CellRange cr, HorizontalAlignment ha) { StepRTB srtb = new StepRTB(); for (int rw = cr.r1; rw <= cr.r2; rw++) for (int cl = cr.c1; cl <= cr.c2; cl++) { srtb.Rtf = this.GetCellRTFString(rw, cl); srtb.SelectAll(); srtb.SelectionAlignment = ha; this.PutCellRTFString(rw, cl, srtb.Rtf); } } public void SetTableBorder(C1.Win.C1FlexGrid.Util.BaseControls.BorderStyleEnum border) { this.BorderStyle = border; this.AdjustGridControlSize(); } public void ChangeCellAlign(CellRange cr, TextAlignEnum newAlign) { for (int rw = cr.r1; rw <= cr.r2; rw++) for (int col = cr.c1; col <= cr.c2; col++) { CellRange tmp = this.GetCellRange(rw, col, rw, col); string StyleName = string.Format("R{0}C{1}Style", rw, col); CellStyle cs = null; if (Styles.Contains(StyleName)) cs = Styles[StyleName]; else cs = this.Styles.Add(StyleName, tmp.Style); cs.TextAlign = newAlign; tmp.Style = cs; } } public void ChangeCellBorder(CellRange cr, BorderStyleEnum newBorder) { for (int rw = cr.r1; rw <= cr.r2; rw++) for (int col = cr.c1; col <= cr.c2; col++) { CellRange tmp = this.GetCellRange(rw, col, rw, col); string StyleName = string.Format("R{0}C{1}Style", rw, col); CellStyle cs = null; if (Styles.Contains(StyleName)) cs = Styles[StyleName]; else cs = this.Styles.Add(StyleName, tmp.Style); cs.Border.Style = newBorder; tmp.Style = cs; } } public void ListStyles() { for (int r = 0; r < Rows.Count; r++) for (int c = 0; c < Cols.Count; c++) { CellRange cr = GetMergedRange(r, c); if (cr.r1 == r && cr.c1 == c) { if (cr.Style != null) Console.WriteLine("{0}, {1}, {2}, {3}", r, c, cr.Style.Name, cr.Style.BackColor); } } } //public void VerticalCenterText() //{ // StepRTB myStepRTB = new StepRTB(); // CellRange selRange = this.Selection; // for (int r = selRange.r1; r <= selRange.r2; r++) // for (int c = selRange.c1; c <= selRange.c2; c++) // { // CellRange mr = this.GetMergedRange(r, c); // if (mr.r1 == r) // { // int editHeight = (int)mr.UserData; // int cellHeight = GetCellHeight(mr.r1, mr.c1); // if (editHeight < cellHeight) // { // myStepRTB.Rtf = (string)mr.Data; // RTBAPI.SetSpaceBefore(myStepRTB, (cellHeight - editHeight) / 2); // PutCellRTFString(mr.r1, mr.c1, myStepRTB.Rtf); // } // } // } //} //public void VerticalTopText() //{ // StepRTB myStepRTB = new StepRTB(); // CellRange selRange = this.Selection; // for (int r = selRange.r1; r <= selRange.r2; r++) // for (int c = selRange.c1; c <= selRange.c2; c++) // { // CellRange mr = this.GetMergedRange(r, c); // if (mr.r1 == r) // { // myStepRTB.Rtf = (string)mr.Data; // RTBAPI.SetSpaceBefore(myStepRTB, 0); // PutCellRTFString(mr.r1, mr.c1, myStepRTB.Rtf); // } // } //} //public void VerticalBottomText() //{ // StepRTB myStepRTB = new StepRTB(); // CellRange selRange = this.Selection; // for (int r = selRange.r1; r <= selRange.r2; r++) // for (int c = selRange.c1; c <= selRange.c2; c++) // { // CellRange mr = this.GetMergedRange(r, c); // if (mr.r1 == r) // { // int editHeight = (int)mr.UserData; // int cellHeight = GetCellHeight(mr.r1, mr.c1); // if (editHeight < cellHeight) // { // myStepRTB.Rtf = (string)mr.Data; // RTBAPI.SetSpaceBefore(myStepRTB, (cellHeight - editHeight)); // PutCellRTFString(mr.r1, mr.c1, myStepRTB.Rtf); // } // } // } //} //public void SetupCellStyles() //{ // //CellStyle cs; // //cs = this.Styles.Add("Dotted"); // //cs.Border.Style = BorderStyleEnum.Dotted; // //cs = this.Styles.Add("Double"); // //cs.Border.Style = BorderStyleEnum.Double; // //cs = this.Styles.Add("Fillet"); // //cs.Border.Style = BorderStyleEnum.Fillet; // //cs = this.Styles.Add("Flat"); // //cs.Border.Style = BorderStyleEnum.Flat; // //cs = this.Styles.Add("Groove"); // //cs.Border.Style = BorderStyleEnum.Groove; // //cs = this.Styles.Add("Inset"); // //cs.Border.Style = BorderStyleEnum.Inset; // //cs = this.Styles.Add("None"); // //cs.Border.Style = BorderStyleEnum.None; // //cs = this.Styles.Add("Raised"); // //cs.Border.Style = BorderStyleEnum.Raised; // //cs = this.Styles.Add("CenterRight"); // //cs.TextAlign = TextAlignEnum.RightCenter; //.LeftCenter; // this is being ignored - probably due to RTF conversion // //cs = this.Styles.Add("Yellow"); // //cs.BackColor = Color.Yellow; // //cs = this.Styles.Add("Margins"); // //cs.Margins.Bottom = 5; // //cs.Margins.Top = 10; // //cs.Margins.Left = 15; // //cs.Margins.Right = 20; //} #endregion //Grid and Cell Styles #region Grid Size Adjustments /// /// Adjust the grid control size based on the cell sizes. /// public void AdjustGridControlSize() { if (Parent is GridItem ? (Parent as GridItem).Initializing : false ) return; int difW = this.Width - this.ClientSize.Width; int difH = this.Height - this.ClientSize.Height; int wid = 0; if (this != null) { foreach (C1.Win.C1FlexGrid.Column col in this.Cols) wid += (col.Width >= 0) ? col.Width : this.Cols.DefaultSize; int height = 0; foreach (C1.Win.C1FlexGrid.Row row in this.Rows) //height += (row.Height >= 0) ? row.Height : this.Rows.DefaultSize + 2; height += (row.Height >= 0) ? row.Height : this.Rows.DefaultSize; this.Size = new Size(wid + difW, height + difH); } //this.Refresh(); } public void ConvertTextCellToRTF(int r, int c) { StepRTB trtb = new StepRTB(); string tstr = null; bool dummyCharWidth = false; bool AllowWidthShrink = false; trtb.SetTableGridCellRTFPrefix(this.Font); trtb.Clear(); tstr = (string)this[r, c]; trtb.Font = this.Font; if (tstr != null && tstr.Length > 0) { string tsave = tstr; // regular text has special characters to toggle Bold, Underline, and Italics // we need to subtract the width of these characters (allow column/row to shrink) //AllowWidthShrink = RemoveBoldUlineItalicChars(trtb.Rtf); AllowWidthShrink = tstr.Contains("#Link:"); // this will convert the special characters for Bold, Underline, and Italics // into RTF commands //trtb.Rtf = trtb.RtfPrefix + ConvertTableText(trtb.Rtf) + "}"; //string fromRTF = trtb.Rtf; //string prefix = trtb.RtfPrefix; //if (tstr.Contains("#Link:")) prefix += @"{\colortbl ;\red255\green0\blue0;}"; //if (tstr.Contains("#Link:")) // Console.WriteLine("here"); //string jText = trtb.RtfPrefix + ConvertTableText(tstr) + @"\par}"; //trtb.Rtf = jText; trtb.Rtf = trtb.RtfPrefix + ConvertTableText(tstr) + @"\par}"; //string fromStr = trtb.Rtf; //if (fromRTF.Contains("SimSun")) // Console.WriteLine("SimSun"); //else // Compare(fromRTF, fromStr, tsave); } else { trtb.Text = "X"; // this is to trick steprtf in giving a char width to fit one character // note that a space character was too small. dummyCharWidth = true; } // find the needed cell width trtb.AdjustWidthForContent(); if (dummyCharWidth) { trtb.Text = ""; // clear out the dummy character before saving dummyCharWidth = false; } this[r, c] = trtb.Rtf; // save the cleaned up and processed cell text as RTF this.Select(r, c, false); CellRange sel = this.Selection; //sel.UserData = trtb.ContentsRectangle.Height; // Now adjust the Height and Width in the defined merge ranges AdjustMergeRangeHeightWidth(r, c, trtb, tstr, AllowWidthShrink); //// Now see the the selected row,col is in the defined merge ranges //bool mrgrows = false; //bool mrgcols = false; //foreach (CellRange cr in this.MergedRanges) //{ // if (cr.Contains(r, c)) // { // if (cr.c1 != cr.c2) // mrgcols = true; // in a range of merged columns // if (cr.r1 != cr.r2) // mrgrows = true; // in a range of merged rows // continue; // } //} //if (!mrgcols || !mrgrows) //{ // // IF the row of the selected cell is NOT in merged range // // then go ahead and adjust the row height (if needed) // if (!mrgrows) // { // // add adjustment for grid and cell borders // int newheight = trtb.Height + 3; // //Console.WriteLine("{0} {1} {2} '{3}'", r, c, newheight,trtb.Text); // if (newheight > this.Rows[r].Height) // { // //Console.WriteLine("1 Row {0} Old Height = {1}, New Height = {2}", r, Rows[r].Height, newheight); // this.Rows[r].Height = newheight; // } // } // // IF the column of the selected cell is NOT in merged range // // then go ahead and adjust the column width (if needed) // if (!mrgcols) // { // // add adjustment for grid and cell borders // int newwidth = trtb.Width + 2; // if (newwidth > this.Cols[c].Width || AllowWidthShrink || r == 0) // this.Cols[c].Width = newwidth; // } //} //if (mrgrows && tstr != null) //{ // CellRange cr = GetMergedRange(r, c); // //Console.WriteLine("grid[{0},{1}] merge = {2}", r, c,cr); // if (cr.r1 == r && cr.c1 == c) // { // // if in merged rows, then make sure the cell's height is large enough // string[] strary = tstr.Split("\n".ToCharArray()); // // count number of lines of text // int nlines = strary.Length; // // count number of rows in merge range // int nrows = (cr.r2 - cr.r1) + 1; // //Console.WriteLine("2 Row {0} Height = {1}", cr.r1, Rows[cr.r1].Height); // while (nlines > nrows) // { // // add length to first row in merged range // int h = this.Rows[cr.r1].Height; // int defH = Rows.DefaultSize - 3; // //h = (h == -1) ? _minRowHeight * 2 : h + _minRowHeight; // h = (h == -1) ? (defH * 2) + 3 : h + defH; // //h = (h == -1) ? (Rows.DefaultSize + 2) * 2 : h + Rows.DefaultSize + 2; // //Console.WriteLine("3 Row {0} Old Height = {1}, New Height = {2}", cr.r1, Rows[cr.r1].Height, h); // this.Rows[cr.r1].Height = h; // nrows++; // } // } //} } private void AdjustCellHeightWidth(int r, int c) { StepRTB trtb = new StepRTB(); string tstr = null; bool dummyCharWidth = false; bool AllowWidthShrink = false; trtb.SetTableGridCellRTFPrefix(this.Font); trtb.Clear(); trtb.Font = this.Font; trtb.Rtf = (string)this[r, c]; tstr = trtb.Text; if (tstr != null && tstr.Length > 0) AllowWidthShrink = tstr.Contains("#Link:"); else { trtb.Text = "X"; // this is to trick steprtf in giving a char width to fit one character // note that a space character was too small. dummyCharWidth = true; } // find the needed cell width trtb.AdjustWidthForContent(); if (dummyCharWidth) { trtb.Text = ""; // clear out the dummy character before saving dummyCharWidth = false; } this.Select(r, c, false); CellRange sel = this.Selection; // Now adjust the Height and Width in the defined merge ranges AdjustMergeRangeHeightWidth(r, c, trtb, tstr, AllowWidthShrink); } private void AdjustMergeRangeHeightWidth(int r, int c, StepRTB trtb, string tstr, bool AllowWidthShrink) { bool mrgrows = false; bool mrgcols = false; foreach (CellRange cr in this.MergedRanges) { if (cr.Contains(r, c)) { if (cr.c1 != cr.c2) mrgcols = true; // in a range of merged columns if (cr.r1 != cr.r2) mrgrows = true; // in a range of merged rows continue; } } if (!mrgcols || !mrgrows) { // IF the row of the selected cell is NOT in merged range // then go ahead and adjust the row height (if needed) if (!mrgrows) { // add adjustment for grid and cell borders int newheight = trtb.Height + 3; //Console.WriteLine("{0} {1} {2} '{3}'", r, c, newheight,trtb.Text); if (newheight > this.Rows[r].Height) { //Console.WriteLine("1 Row {0} Old Height = {1}, New Height = {2}", r, Rows[r].Height, newheight); this.Rows[r].Height = newheight; } } // IF the column of the selected cell is NOT in merged range // then go ahead and adjust the column width (if needed) if (!mrgcols) { // add adjustment for grid and cell borders int newwidth = trtb.Width + 3; // 2; if (newwidth > (this.Cols[c].Width == -1 ? this.Cols.DefaultSize : this.Cols[c].Width) || AllowWidthShrink || r == 0) this.Cols[c].Width = newwidth; } } if (mrgrows && tstr != null) { CellRange cr = GetMergedRange(r, c); if (cr.r1 == r && cr.c1 == c) { // if in merged rows, then make sure the cell's height is large enough string[] strary = tstr.Split("\n".ToCharArray()); // count number of lines of text int nlines = strary.Length; // count number of rows in merge range int nrows = (cr.r2 - cr.r1) + 1; //Console.WriteLine("2 Row {0} Height = {1}", cr.r1, Rows[cr.r1].Height); while (nlines > nrows) { // add length to first row in merged range int h = this.Rows[cr.r1].Height; int defH = Rows.DefaultSize - 3; h = (h == -1) ? (defH * 2) + 3 : h + defH; this.Rows[cr.r1].Height = h; nrows++; } } } } //private void AdjustCellHeightWidth(int r, int c) //{ // StepRTB trtb = new StepRTB(); // string tstr = null; // bool dummyCharWidth = false; // bool AllowWidthShrink = false; // trtb.SetTableGridCellRTFPrefix(this.Font); // trtb.Clear(); // trtb.Font = this.Font; // trtb.Rtf = (string)this[r, c]; // tstr = trtb.Text; // if (tstr != null && tstr.Length > 0) // AllowWidthShrink = tstr.Contains("#Link:"); // else // { // trtb.Text = "X"; // this is to trick steprtf in giving a char width to fit one character // // note that a space character was too small. // dummyCharWidth = true; // } // // find the needed cell width // trtb.AdjustWidthForContent(); // if (dummyCharWidth) // { // trtb.Text = ""; // clear out the dummy character before saving // dummyCharWidth = false; // } // this.Select(r, c, false); // CellRange sel = this.Selection; // // Now see the the selected row,col is in the defined merge ranges // bool mrgrows = false; // bool mrgcols = false; // foreach (CellRange cr in this.MergedRanges) // { // if (cr.Contains(r, c)) // { // if (cr.c1 != cr.c2) // mrgcols = true; // in a range of merged columns // if (cr.r1 != cr.r2) // mrgrows = true; // in a range of merged rows // continue; // } // } // if (!mrgcols || !mrgrows) // { // // IF the row of the selected cell is NOT in merged range // // then go ahead and adjust the row height (if needed) // if (!mrgrows) // { // // add adjustment for grid and cell borders // int newheight = trtb.Height + 3; // //Console.WriteLine("{0} {1} {2} '{3}'", r, c, newheight,trtb.Text); // if (newheight > this.Rows[r].Height) // { // //Console.WriteLine("1 Row {0} Old Height = {1}, New Height = {2}", r, Rows[r].Height, newheight); // this.Rows[r].Height = newheight; // } // } // // IF the column of the selected cell is NOT in merged range // // then go ahead and adjust the column width (if needed) // if (!mrgcols) // { // // add adjustment for grid and cell borders // int newwidth = trtb.Width + 2; // if (newwidth > this.Cols[c].Width || AllowWidthShrink || r == 0) // this.Cols[c].Width = newwidth; // } // } // if (mrgrows && tstr != null) // { // CellRange cr = GetMergedRange(r, c); // if (cr.r1 == r && cr.c1 == c) // { // // if in merged rows, then make sure the cell's height is large enough // string[] strary = tstr.Split("\n".ToCharArray()); // // count number of lines of text // int nlines = strary.Length; // // count number of rows in merge range // int nrows = (cr.r2 - cr.r1) + 1; // //Console.WriteLine("2 Row {0} Height = {1}", cr.r1, Rows[cr.r1].Height); // while (nlines > nrows) // { // // add length to first row in merged range // int h = this.Rows[cr.r1].Height; // int defH = Rows.DefaultSize - 3; // h = (h == -1) ? (defH * 2) + 3 : h + defH; // this.Rows[cr.r1].Height = h; // nrows++; // } // } // } //} private void Compare(string fromRTF, string fromStr, string rawstr) { int istart = fromRTF.IndexOf(" ",fromRTF.IndexOf("viewkind")); int jstart = fromStr.IndexOf(" ",fromStr.IndexOf("viewkind")); for (int i = istart; i < fromRTF.Length; i++) { int j = i - istart + jstart; //else if (fromRTF[i] != fromStr[j]) if (fromRTF[i] != fromStr[j]) { if (fromRTF.Substring(i, 1) == @"~" && fromStr.Substring(j, 3) == @"'a0") { //i++; jstart += 2; } else { Console.WriteLine("fromStr:\r\n'{0}'\r\nfromRTF:\r\n'{1}'", fromStr, fromRTF); ShowRawString(rawstr, "rawstr"); Console.WriteLine("Str:'{0}' , RTF:'{1}'", fromStr.Substring(j, Math.Min(10,fromStr.Length-j-1)), fromRTF.Substring(i, Math.Min(10,fromRTF.Length-i-1))); return; } } } } private void ShowRawString(string str, string title) { Console.WriteLine("Raw Start --{0}:\n", title); foreach (char c in str) { int ic= (int)c; if (c!='\n'&&( ic > 126 || ic < 32)) Console.Write("<<{0:x4}>>", ic); else Console.Write(c); } Console.WriteLine("\n-- Raw End:{0}", title); } private void Grid_AfterResize(object sender, C1.Win.C1FlexGrid.RowColEventArgs e) { this.AdjustGridControlSize(); } #endregion // Grid Size Adjustments #region Cell Text public void MakeRTFcells() { // This will spin through all the cells in the grid: // - convert the text to RTF if needed // - adjust the grid dimensions based on the cell info. for (int r = 0; r < this.Rows.Count; r++) { this.Rows[r].Height = Rows.DefaultSize;//_minRowHeight;//20;//10; for (int c = 0; c < this.Cols.Count; c++) this.ConvertTextCellToRTF(r, c); } //this.Refresh(); //Application.DoEvents(); this.AdjustGridControlSize(); SetupCellUserData(); //RemoveBlankSpaceFromColumns(); RemoveBlankSpaceFromRows(); } public void FixTableCellsHeightWidth() { //StepRTB trtb = new StepRTB(); ////trtb.SetTableGridCellRTFPrefix(this.Font); //trtb.Font = this.Font; //// This will spin through all the cells in the grid: //// - adjust the grid dimensions based on the cell info. //for (int r = 0; r < this.Rows.Count; r++) //{ // this.Rows[r].Height = Rows.DefaultSize;//_minRowHeight;//20;//10; // for (int c = 0; c < this.Cols.Count; c++) // { // trtb.Clear(); // trtb.Rtf = (string)this[r, c]; // this.AdjustCellHeightWidth(r, c, trtb); // } //} //this.AdjustGridControlSize(); //SetupCellUserData(); RemoveBlankSpaceFromColumns(); RemoveBlankSpaceFromRows(); } private void RemoveBlankSpaceFromRows() { for (int r = 0; r < Rows.Count; r++) { Select(r, 0); int blankRowSpace = BlankRowSpace(); if (blankRowSpace > 0) Rows[r].Height -= blankRowSpace; } } private void RemoveBlankSpaceFromColumns() { for (int c = 0; c < Cols.Count; c++) { Select(0, c); int blankColSpace = BlankColSpace(); if (blankColSpace > 0) Cols[c].Width -= blankColSpace; } } //private bool RemoveBoldUlineItalicChars(string str) //{ // int rtn = 0; // // Underline next word // rtn += str.IndexOf(@"\'17"); // // Bold next word // rtn += str.IndexOf(@"\'13"); // // Italics On // rtn += str.IndexOf(@"\'1B4"); // // Italics Off // rtn += str.IndexOf(@"\'1B5"); // // underline On // rtn += str.IndexOf(@"\'ab"); // // underline Off // rtn += str.IndexOf(@"\'bb"); // return rtn > 0; //} //private string ConvertTableText(string str, VE_Font vf) private string ConvertTableText(string str) { string rtn = str; //ShowRawString(str, "ConvertTableText IN"); //if (!str.StartsWith(@"{\rtf")) //{ rtn = rtn.Replace(@"START]\v0", @"START]\cf1\v0"); rtn = rtn.Replace(@"\v #Link:", @"\cf0\v #Link:"); rtn = rtn.Replace("\n", "\\par\r\n"); rtn = rtn.Replace("\xB3", @"\f1\u9474?\f0"); // Vert Bar rtn = rtn.Replace("\xF2", @"\f1\u8805?\f0 "); // greater than or equal rtn = rtn.Replace("\x7F", @"\f1\u916?\f0 "); // delta rtn = rtn.Replace("\xF3", @"\f1\u8804?\f0 "); // less than or equal rtn = rtn.Replace("\xE4", @"\f1\u931?\f0 "); // sigma rtn = rtn.Replace("\xE7", @"\f1\u947?\f0 "); // gamma rtn = rtn.Replace("\xFE", @"\f1\u9604?\f0 "); // accum 2584 rtn = rtn.Replace("\x7", @"\f1\u9679?\f0 "); // bullet 25CF rtn = rtn.Replace("\xF7", @"\f1\u8776?\f0 "); // approx eq rtn = rtn.Replace("\xF0", @"\f1\u8773?\f0 "); // similar eq 2245 rtn = rtn.Replace("\xFB", @"\f1\u8730?\f0 "); // square root rtn = rtn.Replace("\xE2", @"\f1\u961?\f0 "); // rho 3C1 rtn = rtn.Replace("\xE3", @"\f1\u960?\f0 "); // pi rtn = rtn.Replace("\xE6", @"\f1\u956?\f0 "); // micro rtn = rtn.Replace("\xEB", @"\f1\u948?\f0 "); // lower case delta rtn = rtn.Replace("\xE5", @"\f1\u963?\f0 "); // lower case sigma rtn = rtn.Replace("\x90", @"\f1\u274?\f0 "); // energy, 112 rtn = rtn.Replace("\xEE", @"\f1\u949?\f0 "); // epsilon rtn = rtn.Replace("\xE9", @"\f1\u952?\f0 "); // theta, 3B8 rtn = rtn.Replace("\xEC", @"\f1\u8857?\f0 "); // dot in oval, 2299 rtn = rtn.Replace("\xA8", @"\f1\u964?\f0 "); // tau, 3C4 rtn = rtn.Replace("\xA9", @"\f1\u9830?\f0 "); // diamond, 2666 rtn = rtn.Replace("\x18", @"\f1\u8593?\f0 "); // Up Arrow rtn = rtn.Replace("\x19", @"\f1\u8595?\f0 "); // Down Arrow rtn = rtn.Replace("\xFF", @"\u160?"); // hardspace //rtn = rtn.Replace(@"\'a0", @"\u160?"); //rtn = rtn.Replace("\xff", @"\u160?"); //rtn = rtn.Replace("\xA0", @"\u160?"); // underline On rtn = rtn.Replace("\xab", @"\ul"); // underline Off rtn = rtn.Replace("\xbb", @"\ulnone"); //rtn = rtn.Replace("\xef\xe6", @"\up2 "); //rtn = rtn.Replace("\xef\xe7", @"\up0 "); rtn = rtn.Replace("\x9566", @"\up2 "); rtn = rtn.Replace("\x9567", @"\up0 "); rtn = rtn.Replace("{", @"\{"); rtn = rtn.Replace("}", @"\}"); rtn = rtn.Replace("\xd5", @"\b"); rtn = rtn.Replace("\xd6", @"\b0"); //} //else //{ // // Underline next word // rtn = SomethingNextWord(rtn, @"\'17", @"\ul ", @"\ulnone "); // // Bold next word // rtn = SomethingNextWord(rtn, @"\'13", @"\b ", @"\b0 "); // // Italics On // rtn = rtn.Replace(@"\'1B4", @"\i "); // // Italics Off // rtn = rtn.Replace(@"\'1B5", @"\i0 "); // // underline On // rtn = rtn.Replace(@"\'ab", @"\ul"); // // underline Off // rtn = rtn.Replace(@"\'bb", @"\ulnone"); // rtn = rtn.Replace(@"\'ef\'e6", @"\up2 "); // rtn = rtn.Replace(@"\'ef\'e7", @"\up0 "); // rtn = rtn.Replace(@"\'f2", @"\f1 \u8805?\f0 "); //greater than or equal // //rtn = rtn.Replace("\xB0 ", @"\'b0 "); // //rtn = rtn.Replace("\x2552", "\\b "); // //rtn = rtn.Replace("\x2553", "\\b0 "); // rtn = rtn.Replace(@"\'d5", @"\b"); // rtn = rtn.Replace(@"\'d6", @"\b0"); // //rtn = rtn.Replace("\xA0", @"\u160?"); // //rtn = rtn.Replace(@"\'a0", @"\u160?"); // rtn = rtn.Replace(@"\'ff", @"\u160?"); // //rtn = rtn.Replace("\xFF", @"\u160?"); // //rtn = rtn.Replace(@"\~", @"\u160?"); // rtn = rtn.Replace("\x7F", @"\f1 \u916?\f0 "); // delta //} //ShowRawString(rtn, "ConvertTableText OUT"); return rtn; } //private void ConvertTableText(StepRTB srtb) //{ // string[] symb = { @"\'f2"}; // string str = srtb.Rtf; // // Underline next word // str = SomethingNextWord(str, @"\'17", @"\ul ", @"\ulnone "); // // Bold next word // str = SomethingNextWord(str, @"\'13", @"\b ", @"\b0 "); // // Italics On // str = str.Replace(@"\'1B4", @"\i "); // // Italics Off // str = str.Replace(@"\'1B5", @"\i0 "); // // underline On // str = str.Replace(@"\'ab", @"\ul"); // // underline Off // str = str.Replace(@"\'bb", @"\ulnone"); // str = str.Replace(@"\'ef\'e6", @"\up2 "); // str = str.Replace(@"\'ef\'e7", @"\up0 "); // str = str.Replace(@"\'d5", @"\b"); // str = str.Replace(@"\'d6", @"\b0"); // str = str.Replace("\xA0", @"\u160?"); // str = str.Replace("\x7F", @"\u916?"); // VE_Font vf = new VE_Font(this.Font.FontFamily.Name,(int)this.Font.Size,E_Style.None); // DisplayText dt = new DisplayText(str,vf, true); // srtb.Rtf = str; // //srtb.SelectionStart = 0; // //foreach (string s in symb) // //{ // // int idx = srtb.Rtf.LastIndexOf(s, srtb.Rtf.Length-1); // // while (idx >= 0) // // { // // srtb.Rtf = srtb.Rtf.Remove(idx, s.Length); // // srtb.SelectionStart = idx; // // srtb.InsertSymbol(s); // // idx = srtb.Rtf.LastIndexOf(s,idx); // // } // //} // //rtn = rtn.Replace("\xf2 ", @"\u8805?"); //greater than or equal // //rtn = rtn.Replace("\xA0", @"\u160?"); // //rtn = rtn.Replace("\x7F", @"\u916?"); //} // This converts Underline or bold next word character to the corresponding on/off commands private static string SomethingNextWord(string str, string nxtwordcmd, string cmdOn, string cmdOff) { string rtn = ""; int bidx = 0; int fidx = str.IndexOf(nxtwordcmd, bidx); char[] term = " \r\n\x02".ToCharArray(); while (fidx > 0) { rtn += str.Substring(bidx, fidx - bidx) + cmdOn; bidx = fidx + 4; if (bidx < str.Length) { fidx = str.IndexOfAny(term, bidx); if (fidx > 0) { rtn += str.Substring(bidx, fidx - bidx) + cmdOff + str.Substring(fidx, 1); bidx = fidx + 1; } } if (bidx < str.Length) fidx = str.IndexOf(nxtwordcmd, bidx); else fidx = -1; } if (bidx < str.Length) rtn += str.Substring(bidx); return rtn; } private void _StartEdit(object sender, C1.Win.C1FlexGrid.RowColEventArgs e) { // start editing the cell with the custom editor //CellStyle cs = this.Styles["Focus"]; ////CellStyle cs=this.GetCellRange(e.Row, e.Col).StyleNew; ////cs.Name = string.Format("R{0}C{1}", e.Row, e.Col); //cs.ForeColor = Color.White; //cs = this.Styles["Highlight"]; //cs.ForeColor = Color.LightCyan; ////Console.WriteLine("Style = {0}",cs.Name); _tableCellEditor.StartEditing(e.Row, e.Col); e.Cancel = true; } // after edit handler (built-in editors) private void _AfterEdit(object sender, C1.Win.C1FlexGrid.RowColEventArgs e) { //Console.WriteLine("Style = {0}", this.GetCellRange(e.Row, e.Col).Style.Name); this.GetCellRange(e.Row, e.Col).Style.ForeColor = Color.Black; this.AdjustGridControlSize(); } // if the custom editor is visible, make it follow the cell being edited private void _AfterScroll(object sender, C1.Win.C1FlexGrid.RangeEventArgs e) { this._tableCellEditor.UpdatePosition(); } // save last key pressed for the custom editor private void _KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) { this._tableCellEditor.SetPendingKey(e.KeyChar); } public string GetCellRTFString(int row, int col) { string rtnstr = ""; foreach (CellRange r in this.MergedRanges) { if (r.ContainsRow(row) && r.ContainsCol(col)) { rtnstr = (string)this[r.r1, r.c1]; return rtnstr; } } rtnstr = (string)this[row, col]; return rtnstr; } public void PutCellRTFString(int row, int col, string str) { foreach (CellRange r in this.MergedRanges) { if (r.ContainsRow(row) && r.ContainsCol(col)) { this[r.r1, r.c1] = str; return; } } this[row, col] = str; return; } public void ClearSelectedCellText() { CellRange cr = this.Selection; //DialogResult dr = MessageBox.Show("Clear Selected cells?", "Clear", MessageBoxButtons.YesNo); //if (dr == DialogResult.Yes) cr.Clear(ClearFlags.Content); } public void SetupCellUserData() { for (int r = 0; r < Rows.Count; r++) for (int c = 0; c < Cols.Count; c++) { string rtfText = GetDataDisplay(r, c); if (rtfText.StartsWith(@"{\rtf")) { RTF _rtf = new RTF(); _rtf.Width = Cols[c].Width; _rtf.Rtf = rtfText; CellRange cr = GetCellRange(r, c); cr.UserData = _rtf.ContentsRectangle.Height; //Console.WriteLine("ownerDraw UserData [{0},{1}] = {2}", cr.r1, cr.c1, _rtf.ContentsRectangle.Height); } } } #endregion //Cell Text #region Merged / Split Range public void MergeSelection() { this.MergedRanges.Add(this.Selection); this.Invalidate(); } public bool IsInMergeRange() { C1.Win.C1FlexGrid.CellRange sel = GetMergedRange(this.Selection.r1, this.Selection.c1); return MergedRanges.Contains(sel); } public void SplitSelection(bool bSplitCols) { C1.Win.C1FlexGrid.CellRange sel = this.GetMergedRange(this.Selection.r1, this.Selection.c1); if (this.MergedRanges.Contains(sel)) this.MergedRanges.Remove(sel); else //split cells { if (bSplitCols) SplitSelectionColumns(); else SplitSelectionRows(); } this.Refresh(); this.AdjustGridControlSize(); } private void SplitSelectionColumns() { CellRange cr = this.Selection; int numSelCols = (cr.c2 - cr.c1) + 1; // for each column in the selection, add a new column for (int c = cr.c2; c >= cr.c1; c--) InsertColumnAfter(); // include new columns in selection this.Select(cr.r1, cr.c1, cr.r2, cr.c2 + numSelCols); cr = this.Selection; for (int r = 0; r < this.Rows.Count; r++) for (int c = cr.c1; c <= cr.c2; c += 2) { if (!this.IsCellSelected(r, c)) { //this.Select(r, c, r, c + 1); CellRange tcr = this.GetCellRange(r, c, r, c+1); this.MergedRanges.Add(tcr); } } //this.Select(cr); // Adjust selected column widths for (int c = cr.c1; c <= cr.c2; c++) { int recWidth = this.GetCellRect(cr.r1, c).Width; this.Cols[c].Width = Math.Max(recWidth / 2, _minColSplitWidth); //Console.WriteLine("Cell[{0},{1}].Width = {2}", cr.r1, c, recWidth); } } private void SplitSelectionRows() { CellRange cr = this.Selection; int numSelRows = (cr.r2 - cr.r1) + 1; //Console.WriteLine("numSelRows = {0}", numSelRows); //Console.WriteLine("Inital Selection [{0},{1}] - [{2},{3}]", cr.r1, cr.c1, cr.r2, cr.c2); // for each row in the selection, add a new row for (int r = cr.r2; r >= cr.r1; r--) { //Console.WriteLine("Inserted new Row at [{0},{1}]", r, cr.c1); InsertRowAfter(); } // include new rows in selection this.Select(cr.r1, cr.c1, cr.r2 + numSelRows, cr.c2); cr = this.Selection; //Console.WriteLine(" After Insert [{0},{1}] - [{2},{3}]", cr.r1, cr.c1, cr.r2, cr.c2); for (int c = 0; c < this.Cols.Count; c++) for (int r = cr.r1; r <= cr.r2; r += 2) { if (!this.IsCellSelected(r, c)) { CellRange tcr = this.GetCellRange(r, c, r + 1, c); this.MergedRanges.Add(tcr); //Console.WriteLine("cellrange {0}", tcr); //Console.WriteLine("merge [{0},{1}] - [{2},{3}]", r, c, r + 1, c); } } // Adjust selected Row Heights for (int r = cr.r1; r <= cr.r2; r++) { int recHeight = this.GetCellRect(r, cr.c1).Height; this.Rows[r].Height = Math.Max(recHeight / 2, Rows.DefaultSize); //this.Rows[r].Height = Math.Max(recHeight / 2, _minRowSplitHeight); //Console.WriteLine("Cell[{0},{1}].Height = {2}", r, cr.c1, recHeight); } //foreach (CellRange crng in this.MergedRanges) // Console.WriteLine("merge ranges [{0},{1}] - [{2},{3}]", crng.r1, crng.c1, crng.r2, crng.c2); } private void AdjustMergedRows(int row, bool above, bool removing) { CellRangeCollection crc = new CellRangeCollection(this); if (removing) { foreach (CellRange r in this.MergedRanges) { CellRange cr = r; if (r.ContainsRow(row)) { if (r.TopRow != r.BottomRow) { cr.r2--; crc.Add(cr); } } else { if (row <= r.r1) { if (row < r.r1) cr.r1--; cr.r2--; } crc.Add(cr); } } } else // adding foreach (CellRange r in this.MergedRanges) { CellRange cr = r; int inspos = (above) ? row : row - 1; if (r.ContainsRow(inspos)) { if ((above && cr.r1 == inspos) || (!above && cr.r2 == inspos)) { string tstr = ""; int newrow = 0; if (above) { if (this[cr.r1 + 1, cr.c1] != null) tstr = this[cr.r1 + 1, cr.c1].ToString(); newrow = cr.r1; } else { if (this[cr.r2, cr.c1] != null) tstr = this[cr.r2, cr.c1].ToString(); newrow = cr.r2 + 1; } if (tstr != null && tstr.Length > 0) for (int x = cr.c1; x <= cr.c2; x++) this[newrow, x] = tstr; } cr.r2++; } else { if (inspos < cr.r1) { cr.r1++; cr.r2++; } } crc.Add(cr); } this.MergedRanges.Clear(); foreach (CellRange r in crc) { if ((r.r1 != r.r2) || (r.c1 != r.c2)) this.MergedRanges.Add(r); } } private void AdjustMergedColumns(int col, bool left, bool removing) { CellRangeCollection crc = new CellRangeCollection(this); if (removing) { foreach (CellRange r in this.MergedRanges) { CellRange cr = r; if (r.ContainsCol(col)) { if (r.LeftCol != r.RightCol) { cr.c2--; crc.Add(cr); } } else { if (col < cr.c1) { cr.c1--; cr.c2--; } crc.Add(cr); } } } else // adding foreach (CellRange r in this.MergedRanges) { CellRange cr = r; int inspos = (left) ? col : col - 1; if (r.ContainsCol(inspos)) { string tstr = ""; int newcol = 0; if (left) { if (inspos == cr.c1) tstr = this[cr.r1, cr.c1 + 1].ToString(); else tstr = this[cr.r1, cr.c1].ToString(); newcol = cr.c1; } else { if (this[cr.r1, cr.c2] != null) tstr = this[cr.r1, cr.c2].ToString(); newcol = cr.c2 + 1; } for (int x = cr.r1; x <= cr.r2; x++) this[x, newcol] = tstr; cr.c2++; } else if (col <= r.c1) { cr.c1++; cr.c2++; } crc.Add(cr); } this.MergedRanges.Clear(); foreach (CellRange r in crc) { if ((r.r1 != r.r2) || (r.c1 != r.c2)) this.MergedRanges.Add(r); } } private bool RowIsInMergeRange(int row) { bool rtn = false; if (row >= 0) { CellRange cr = this.Selection; rtn = true; int c = cr.c1; while (rtn && (c <= cr.c2)) { int idx = this.MergedRanges.IndexOf(row, c); rtn = (idx > -1); c++; } } return rtn; } private bool ColIsInMergeRange(int col) { bool rtn = false; if (col >= 0) { CellRange cr = this.Selection; //rtn = true; int r = cr.r1; while (!rtn && (r <= cr.r2)) { int idx = this.MergedRanges.IndexOf(col, r); rtn = (idx > -1); r++; } } return rtn; } #endregion //Merged / Split Range #region Grid Add and Remove Row / Column private int GetRowInsertPosition(Boolean before) { int rtnrow; CellRange selcr = this.Selection; CellRange cr = selcr; int idx = this.MergedRanges.IndexOf(cr.r1, cr.c2); if (idx > -1) cr = this.MergedRanges[idx]; // we want first or last row in merge range rtnrow = (before) ? cr.r1 : cr.r2; // The following is an adjustment needed when we are copying an entire row that includes some merged cells if (selcr.c1 != selcr.c2) { while (!before && rtnrow > selcr.r2) rtnrow--; while (before && rtnrow < selcr.r2) rtnrow++; } return rtnrow; } private int GetColInsertPosition(Boolean before) { int rtncol; CellRange selcr = this.Selection; CellRange cr = selcr; int idx = this.MergedRanges.IndexOf(cr.r1, cr.c2); if (idx > -1) cr = this.MergedRanges[idx]; // we want the first of last col in merge range rtncol = (before) ? cr.c1 : cr.c2; // The following is an adjustment needed when we are copying an entire column that includes some merged cells if (selcr.r1 != selcr.r2) { while (!before && rtncol > selcr.c2) rtncol--; while (before && rtncol < selcr.c2) rtncol++; } return rtncol; } public void InsertColumnBefore() { int newcol = this.GetColInsertPosition(true); this.Cols.Insert(newcol); // set new column width to same width as column from where it was inserted this.Cols[newcol].Width = this.Cols[newcol + 1].Width; this.AdjustMergedColumns(newcol, true, false); this.AdjustGridControlSize(); } public void InsertColumnAfter() { int colidx = this.GetColInsertPosition(false); if (colidx == this.Cols.Count - 1) // last column this.Cols.Add(1); else this.Cols.Insert(colidx + 1); // set new column width to same width as column from where it was inserted this.Cols[colidx + 1].Width = this.Cols[colidx].Width; this.AdjustMergedColumns(colidx + 1, false, false); this.AdjustGridControlSize(); } public void InsertRowBefore() { int newrow = this.GetRowInsertPosition(true); this.Rows.Insert(newrow); // set new row Height to same heidht as row from where it was inserted this.Rows[newrow].Height = (Rows[newrow + 1].Height == -1) ? Rows.DefaultSize : Rows[newrow + 1].Height; //this.Rows[newrow].Height = this.Rows[newrow + 1].Height; this.AdjustMergedRows(newrow, true, false); this.AdjustGridControlSize(); } public void InsertRowAfter() { int rowidx = this.GetRowInsertPosition(false); if (rowidx == this.Rows.Count - 1) // last row this.Rows.Add(1); else this.Rows.Insert(rowidx + 1); // set new row Height to same heidht as row from where it was inserted this.Rows[rowidx + 1].Height = (Rows[rowidx].Height == -1) ? Rows.DefaultSize : Rows[rowidx].Height; //this.Rows[rowidx + 1].Height = this.Rows[rowidx].Height; this.AdjustMergedRows(rowidx + 1, false, false); this.AdjustGridControlSize(); } public void RemoveSelectedColumn() { string msg = ""; string title = ""; CellRange saveCR = Selection; this.SelectionMode = SelectionModeEnum.ColumnRange; //this.Select(this.Selection.r1, this.Selection.c1); this.Select(0,Selection.c1,Rows.Count-1,Selection.c2); this.SelectionMode = SelectionModeEnum.Default; if (Selection.c1 != Selection.c2) { msg = "Remove selected columns?"; title = "Delete Columns"; } else { msg = "Remove this column?"; title = "Delete Column"; } DialogResult dr = MessageBox.Show(msg, title, MessageBoxButtons.YesNo); if (dr == DialogResult.Yes) RemoveSelectedCells();//RemoveColumns(this.Selection.r1, this.Selection.c1, 1); else Select(saveCR); } public void RemoveSelectedRow() { string msg = ""; string title = ""; CellRange saveCR = Selection; this.SelectionMode = SelectionModeEnum.RowRange; //this.Select(this.Selection.r1, this.Selection.c1,); this.Select(Selection.r1,0,Selection.r2,Cols.Count-1); this.SelectionMode = SelectionModeEnum.Default; if (Selection.r1 != Selection.r2) { msg = "Remove selected rows?"; title = "Delete Rows"; } else { msg = "Remove this row?"; title = "Delete Row"; } DialogResult dr = MessageBox.Show(msg, title, MessageBoxButtons.YesNo); if (dr == DialogResult.Yes) this.RemoveSelectedCells();//this.RemoveRows(this.Selection.r1, this.Selection.c1, 1); else Select(saveCR); } private void RemoveRows(int strow, int stcol, int cnt) { bool mergedRow = false; for (int i = 0; i < cnt; i++) { //if (this.RowIsInMergeRange(strow)) //{ for (int cl = 0; cl < this.Cols.Count && !mergedRow; cl++) { int idx = this.MergedRanges.IndexOf(strow, cl); if (idx > -1) { CellRange cr = this.MergedRanges[idx]; if (cr.r1 < cr.r2) mergedRow = true; //this[cr.r1 + 1, cr.c1] = this[cr.r1, cr.c1]; } cl++; } //} this.Rows.Remove(strow); this.AdjustMergedRows(strow, false, true); if (mergedRow) { cnt++; mergedRow = false; } } this.AdjustGridControlSize(); } private void RemoveColumns(int strow, int stcol, int cnt) { bool mergedCol = false; for (int i = 0; i < cnt; i++) { //if (this.ColIsInMergeRange(stcol)) //{ for (int rw = 0; rw < this.Rows.Count && !mergedCol; rw++) { int idx = this.MergedRanges.IndexOf(rw, stcol); if (idx > -1) { CellRange cr = this.MergedRanges[idx]; if (cr.c1 < cr.c2) mergedCol = true; //this[cr.r1, cr.c1 + 1] = this[cr.r1, cr.c1]; } } //} this.Cols.Remove(stcol); this.AdjustMergedColumns(stcol, false, true); if (mergedCol) { cnt++; mergedCol = false; } } this.AdjustGridControlSize(); } public void RemoveSelectedCells() { bool didremove = false; int lastRow = this.Rows.Count - 1; int lastCol = this.Cols.Count - 1; CellRange cr = this.Selection; // r2 is last row (or in merge range containing last row) // r1 is first row or r1-m (m is in merge range) is first row // we can remove columns c1 through c2 int idx = this.MergedRanges.IndexOf(cr.r2, cr.c2); CellRange mr = new CellRange(); if (idx > -1) mr = this.MergedRanges[idx]; if (cr.r2 == lastRow || idx > -1 && mr.r2 == lastRow)//RowIsInMergeRange(grd,cr.r2)) { if (cr.r1 == 0 || this.RowIsInMergeRange(cr.r1 - 1)) { this.RemoveColumns(cr.r1, cr.c1, cr.RightCol - cr.LeftCol + 1);// remove selected columns didremove = true; } } // c2 is last column (or in merge range containing last column) // c1 is first column or c1-m (m is merge range) is first column // we can remove rows r1 through r2 if (cr.c2 == lastCol || idx > -1 && mr.c2 == lastCol)//ColIsInMergeRange(grd,cr.c1-1)) { if (cr.c1 == 0 || this.ColIsInMergeRange(cr.c1 - 1)) { // remove selected rows this.RemoveRows(cr.r1, cr.c1, cr.BottomRow - cr.TopRow + 1); didremove = true; } } if (!didremove) MessageBox.Show("Cannot Removed Part of a Row or Column.\n\nNote: This function allows you to delete one or more rows/columns at time.", "Invalid Selection",MessageBoxButtons.OK,MessageBoxIcon.Hand); return; } #endregion //Grid Add and Remove Row / Column #region Clipboard public void ClipBoardCopyRow() { this.SelectionMode = SelectionModeEnum.Row; this.Select(this.Selection.r1, 0, this.Selection.r2, this.Cols.Count - 1, true); DialogResult dr = MessageBox.Show("Copy these Rows?", "Copy Rows", MessageBoxButtons.YesNo); if (dr == DialogResult.Yes) _clpbrdCpyPste.Put(this.Selection); this.SelectionMode = SelectionModeEnum.Default; } public void ClipBoardCopyColumn() { this.SelectionMode = SelectionModeEnum.Column; this.Select(0, this.Selection.c1, this.Rows.Count - 1, this.Selection.c2, true); DialogResult dr = MessageBox.Show("Copy these columns?", "Copy Columns", MessageBoxButtons.YesNo); if (dr == DialogResult.Yes) _clpbrdCpyPste.Put(this.Selection); this.SelectionMode = SelectionModeEnum.Default; } public void ClipBoardCopySelection() { this.Select(this.Selection.r1, this.Selection.c1, this.Selection.r2, this.Selection.c2); DialogResult dr = MessageBox.Show("Copy Selected Cells?", "Copy Selection", MessageBoxButtons.YesNo); if (dr == DialogResult.Yes) _clpbrdCpyPste.Put(this.Selection); } private void CopyTextFromCellRange(ArrayList arylst, int srow, int scol, int erow, int ecol) { StepRTB trtb = new StepRTB(); int aryidx = 0; for (int r = srow; r <= erow; r++) { for (int c = scol; c <= ecol; c++) { if (aryidx >= arylst.Count) trtb.Text = ""; else { trtb.Rtf = OnAdjustPastedText(this, new VlnFlexGridPasteEventArgs((string)(arylst[aryidx++]))); trtb.AdjustWidthForContent(); } this[r, c] = trtb.Rtf; //this.ConvertTextCellToRTF(r, c); this.AdjustCellHeightWidth(r, c); } } FixTableCellsHeightWidth(); } public enum enmPastePos : int { Before = 1, Replace = 0, After = -1 } public void ClipBoardPasteRows(enmPastePos pp) { // Get a list of strings representing the text (rtf text) in each cell // that was saved to the clipboard (row/column order) ArrayList aryCellList = _clpbrdCpyPste.Get(); if (aryCellList != null && aryCellList.Count > 0) { // Since we're pasting an entire row, make sure the current selection includes // all the columns to ensure proper logic path when inserting a new (empty) row this.SelectionMode = SelectionModeEnum.Row; this.Select(this.Selection.r1, 0, this.Selection.r2, this.Cols.Count - 1, true); this.SelectionMode = SelectionModeEnum.Default; // get row/column starting position in which new rows will be added int startrow = this.Selection.r1 + ((pp == enmPastePos.After) ? 1 : 0); int startcol = this.Selection.c1; // get the number of rows needed based on what was save to the clipboard int numrows = Math.Max(1, (aryCellList.Count / this.Cols.Count)); // insert that number of new rows. if (pp != enmPastePos.Replace) // insert new rows before or after for (int r = 0; r < numrows; r++) if (pp == enmPastePos.After) // create new rows after this.InsertRowAfter(); else this.InsertRowBefore(); // copy each grid cell text (aryCellList) into the newly inserted rows CopyTextFromCellRange(aryCellList, startrow, startcol, startrow + numrows - 1, startcol + this.Cols.Count - 1); this.AdjustGridControlSize(); } } public void ClipBoardPasteColumns(enmPastePos pp) { // Get a list of strings representing the text (rtf text) in each cell // that was saved to the clipboard (row/column order) ArrayList aryCellList = _clpbrdCpyPste.Get(); if (aryCellList != null && aryCellList.Count > 0) { // Since we're pasting an entire column, make sure the current selection includes // all the rows to ensure proper logic path when inserting a new (empty) column this.SelectionMode = SelectionModeEnum.Column; this.Select(0, this.Selection.c1, this.Rows.Count - 1, this.Selection.c2, true); this.SelectionMode = SelectionModeEnum.Default; // get row/column starting position in which new rows will be added int startrow = 0;//grd.Selection.r1+((pp == enmPastePos.After) ? 1 : 0); int startcol = this.Selection.c1 + ((pp == enmPastePos.After) ? 1 : 0); // get the number of columns needed based on what was save to the clipboard int numcols = Math.Max(1, (aryCellList.Count / this.Rows.Count)); // insert that number of new columns. if (pp != enmPastePos.Replace) // insert new columns before or after for (int c = 0; c < numcols; c++) if (pp == enmPastePos.After) // create new columns after this.InsertColumnAfter(); else this.InsertColumnBefore(); // copy each grid cell text (aryCellList) into the newly inserted colmns this.CopyTextFromCellRange(aryCellList, startrow, startcol, startrow + this.Rows.Count - 1, startcol + numcols - 1); this.AdjustGridControlSize(); } } public void ClipBoardPasteIntoSelection() { // Get a list of strings representing the text (rtf text) in each cell // that was saved to the clipboard (row/column order) ArrayList aryCellList = _clpbrdCpyPste.Get(); if (aryCellList != null && aryCellList.Count > 0) { // copy each grid cell text (aryCellList) into the selected cells this.CopyTextFromCellRange(aryCellList, this.Selection.r1, this.Selection.c1, this.Selection.r2, this.Selection.c2); this.AdjustGridControlSize(); } } #endregion //Clipboard #region Selection public bool SelectNextCell() { int r = this.Row; int c = this.Col; CellRange cr = GetMergedRange(r, c); do { c = cr.c2 + 1; if (c >= this.Cols.Count) { r = r + 1; c = 0; if (r >= this.Rows.Count) return false; } cr = GetMergedRange(r, c); } while (r != cr.r1 || c != cr.c1); Select(r, c); return true; } public bool SelectPrevCell() { int r = this.Row; int c = this.Col; CellRange cr = GetMergedRange(r, c); do { c = cr.c1 - 1; if (c < 0) { r = r - 1; c = this.Cols.Count-1; if (r < 0) return false; } cr = GetMergedRange(r, c); c = cr.c1; } while (r != cr.r1); Select(r, c); return true; } #endregion #region SearchableText public string GetSearchableText() { StringBuilder sb = new StringBuilder(); int r = 0; int c = 0; int w = Cols.Count; int h = Rows.Count; while (r < h) { CellRange cr = GetMergedRange(r, c); if (cr.r1 == r && cr.c1 == c) { if (this[r, c] != null) { string strp = DisplayText.StaticStripRtfCommands((string)this[r, c]); sb.Append(strp.Replace("\r\n", " ")); } sb.Append("\r\n"); } c = c + 1; if (c == w) { c = 0; r = r + 1; } } return sb.ToString(); } #endregion #region Import / Export Grid /// /// Prompts user with Save File dialog. /// Grid will be saved to an XML file. /// /// public void ExportToXML(string initDir) { SaveFileDialog sfd = new SaveFileDialog(); sfd.DefaultExt = ".xml"; sfd.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.* "; //sfd.InitialDirectory = @"C:\Development\SampleTableData"; sfd.InitialDirectory = initDir; sfd.Title = "Save XML File"; sfd.ShowDialog(); this.WriteXml(sfd.FileName); } public string GetXMLData() { string retstr = null; using (StringWriter sw = new StringWriter()) { this.WriteXml(sw); retstr = sw.GetStringBuilder().ToString(); sw.Close(); } return retstr; } /// /// Prompts user with Save File dialog. /// Grid will be saved to an Excel file. /// /// public void ExportToExcel(string initDir) { SaveFileDialog sfd = new SaveFileDialog(); sfd.DefaultExt = ".xls"; sfd.Filter = "Excel files (*.xls)|*.xls|All files (*.*)|*.* "; //sfd.InitialDirectory = @"C:\Development\SampleTableData"; sfd.InitialDirectory = initDir; sfd.Title = "Save Excel File"; sfd.ShowDialog(); this.SaveExcel(sfd.FileName); } /// /// Prompts user with Open File dialog. /// XML file will be imported to a table grid. /// /// /// public string ImportXML(string initDir) { string rtn = ""; OpenFileDialog ofd = new OpenFileDialog(); ofd.DefaultExt = ".xml"; ofd.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.* "; //ofd.InitialDirectory = @"C:\Development\SampleTableData"; ofd.InitialDirectory = initDir; ofd.Multiselect = false; ofd.Title = "Select XML File"; ofd.ShowDialog(); this.Clear(); this.MergedRanges.Clear(); this.ReadXml(ofd.FileName); this.KeyActionTab = KeyActionEnum.MoveAcross; this.AdjustGridControlSize(); rtn = ofd.SafeFileName; return rtn; } /// /// Prompts user with Open File dialog. /// Excel file will be imported to a table grid. /// /// /// public string ImportExcel(string initDir) { string rtn = ""; //VlnFlexGrid grd = rbtDefaultTable.Checked ? vlnFlexGrid2 : vlnFlexGrid3; //GetActiveGrid(); OpenFileDialog ofd = new OpenFileDialog(); ofd.DefaultExt = ".xls"; ofd.Filter = "Excel files (*.xls)|*.xls|All files (*.*)|*.*"; //ofd.InitialDirectory = @"C:\Development\SampleTableData"; ofd.InitialDirectory = initDir; ofd.Multiselect = false; ofd.Title = "Select Excel File"; ofd.ShowDialog(); this.Clear(); this.MergedRanges.Clear(); this.LoadExcel(ofd.FileName); this.AdjustGridControlSize(); rtn = ofd.SafeFileName; return rtn; } /// /// This will parse a string containing the ascii text of the old style VE-PROMS (16-bit) tables. /// It will find the number of rows and columns base on newlines, vertical bars, and dashes. /// Then it will parse the the text, place them in cells, and attempt to merge cells were needed. /// /// public void ParseTableFromText(string txtbuff) { int curRow = 0; int curCol = 0; int maxRow = 0; int maxCol = 0; // Get Max Rows and Max Cols char[] test = "|\n\x02".ToCharArray(); int idx = 0; int idxst = 0; int colPos = 0; int strow = 0; Dictionary dicCols = new Dictionary(); do { idx = txtbuff.IndexOfAny(test, idxst); if (idx > -1) { switch (txtbuff[idx]) { case '|': // end of a column colPos = idxst - strow; if (!dicCols.ContainsKey(colPos)) dicCols.Add(colPos, curCol); else if (curCol > dicCols[colPos]) { dicCols.Remove(colPos); dicCols.Add(colPos, curCol); } curCol++; break; case '\x02': case '\n': // end of a row colPos = idxst - strow; if (!dicCols.ContainsKey(colPos)) dicCols.Add(colPos, curCol); else if (curCol > dicCols[colPos]) { dicCols.Remove(colPos); dicCols.Add(colPos, curCol); } curRow++; strow = idx + 1; if (curCol > maxCol) maxCol = curCol; curCol = 0; break; } idxst = idx + 1; if (idxst >= txtbuff.Length) idx = -1; } } while (idx != -1); maxRow = curRow; // +1; curRow = 0; curCol = 0; // The resulting Table Grid size in rows and columns this.Cols.Count = maxCol + 1; this.Rows.Count = maxRow + 1; // make all rows and columns editable this.Rows.Fixed = 0; this.Cols.Fixed = 0; // TableCellInfo is used to assign merge ranges // Make a two dimensional array of TableCellinfo the same size as the table grid TableCellInfo[,] tci = new TableCellInfo[maxRow + 1, maxCol + 1]; for (int r = 0; r <= maxRow; r++) for (int c = 0; c <= maxCol; c++) tci[r, c] = new TableCellInfo(); // Read in each cell of the grid idx = 0; idxst = 0; colPos = 0; strow = 0; int prevCol = 0; int tstidx = 0; string tstr = ""; bool incRow = false; do { idx = txtbuff.IndexOfAny(test, idxst); if (idx > -1) { switch (txtbuff[idx]) { case '|': // end of column colPos = idxst - strow; // based on the position of the | char, find what column we are in. // note that this will tell us if any columns to the left were merged // the while loop will flag cell that need to be merged curCol = dicCols[colPos]; while (curCol > prevCol + 1) { tci[curRow, prevCol].MergeColRight = true; prevCol++; } prevCol = curCol; // parse out the text to be placed in the table cell tstr = txtbuff.Substring(idxst, idx - idxst); if (tstr.Length == 0) tstr += " "; // test for a string of '-' characters for (tstidx = 0; (tstidx < tstr.Length) && (tstr[tstidx] == '-'); tstidx++) ; if (tstidx < tstr.Length) // not a full line (row) of '-' chars { // take a peek at the start of the next piece of table text to parse // if it starts with a '-' char, then flag to merge the columns up to // this point with the same columns in the next row if (idx < txtbuff.Length - 1 && txtbuff[idx + 1] == '-') { for (int c = curCol; c >= 0; c--) if (!tci[curRow, c].ColEnd) tci[curRow, c].MergeRowBellow = true; } // if this column is in a merged grouping of rows, // get the cell text in the first cell of the merged grouping of cells // we will append the newly parsed text to this cell's text. int rw = curRow; while (rw - 1 >= 0 && tci[rw - 1, curCol].MergeRowBellow) rw--; int cl = curCol; while (cl - 1 >= 0 && tci[rw, cl-1].MergeColRight) cl--; //string jstr = (string)this[rw, curCol]; string jstr = (string)this[rw, cl]; if (jstr == null) jstr = tstr; else jstr += ((cl==curCol)? "\n" : "") + tstr; // multi line cell //jstr += "\n" + tstr; // multi line cell //this[rw, curCol] = jstr; this[rw, cl] = jstr; //// take a peek at the start of the next piece of table text to parse //// if it starts with a '-' char, then flag to merge the columns up to //// this point with the same columns in the next row //if (idx < txtbuff.Length - 1 && txtbuff[idx + 1] == '-') //{ // for (int c = curCol; c >= 0; c--) // if (!tci[curRow, c].ColEnd) // tci[curRow, c].MergeRowBellow = true; //} //int tcol = dicCols[idx]; //// if were are that the end of the 16-bit text line, but not in the last column, //// merge the remaining columns to the right //if (curCol < tcol) //{ // for (int i = curCol; i <= tcol; i++) // tci[curRow, i].MergeColRight = true; //} } else // parsed text contains all dashes { tci[curRow, curCol].ColEnd = true; incRow = true; } break; case '\x02': // end of file case '\n': // new line of 16-bit table text colPos = idxst - strow; curCol = dicCols[colPos]; // see what column we are in - new line might occure before last grid column strow = idx + 1; // parse out the cell text tstr = txtbuff.Substring(idxst, idx - idxst); if (tstr.EndsWith("\r")) // strip off carrage return tstr = tstr.Substring(0, tstr.Length - 1); tstr = tstr.TrimEnd(" ".ToCharArray()); if (tstr.Length == 0) tstr += " "; // test for a string of '-' characters for (tstidx = 0; (tstidx < tstr.Length) && (tstr[tstidx] == '-'); tstidx++) ; if (tstidx < tstr.Length) // not a full line (row) of '-' chars { //curCol = dicCols[colPos]; while (curCol > prevCol + 1) { tci[curRow, prevCol].MergeColRight = true; prevCol++; } // if this column is in a merged grouping of rows, // get the cell text in the first cell of the merged grouping of cells // we will append the newly parsed text to this cell's text. int rw = curRow; while (rw - 1 >= 0 && tci[rw - 1, curCol].MergeRowBellow) rw--; int cl = curCol; while (cl - 1 >= 0 && tci[rw, cl-1].MergeColRight) cl--; //string jstr = (string)this[rw, curCol]; string jstr = (string)this[rw, cl]; if (jstr == null) jstr = tstr; else jstr += ((cl == curCol) ? "\n" : "") + tstr; // multi line cell //jstr += "\n" + tstr; // multi line cell //this[rw, curCol] = jstr; this[rw, cl] = jstr; } else if (tstr.Length > 0) // parsed text is all dash characters { incRow = true; if (curRow > 0) // merge the column in the previous row with this one tci[curRow - 1, curCol].MergeRowBellow = false; } // if were are that the end of the 16-bit text line, but not in the last column, // merge the remaining columns to the right if ((curCol < maxCol) && (tstidx < tstr.Length)) { for (int i = curCol; i < maxCol; i++) tci[curRow, i].MergeColRight = true; } if (incRow) curRow++; curCol = 0; incRow = false; break; } idxst = idx + 1; if (idxst >= txtbuff.Length) idx = -1; } else if (idxst < txtbuff.Length - 1) // handle any remaining text not yet parsed { // find the curent column and merge remaining columns to the right colPos = idxst - strow; curCol = dicCols.Count==0?0:dicCols[colPos]; while (curCol > prevCol + 1) { tci[curRow, prevCol].MergeColRight = true; prevCol++; } // parse out the remaining text tstr = txtbuff.Substring(idxst); tstr = tstr.TrimEnd(" ".ToCharArray()); if (tstr.Length == 0) tstr += " "; // test for a string of '-' characters for (tstidx = 0; (tstidx < tstr.Length) && (tstr[tstidx] == '-'); tstidx++) ; if (tstidx < tstr.Length) { // if this column is in a merged grouping of rows, // get the cell text in the first cell of the merged grouping of cells // we will append the newly parsed text to this cell's text. int rw = curRow; while (rw - 1 >= 0 && tci[rw - 1, curCol].MergeRowBellow) rw--; int cl = curCol; while (cl - 1 >= 0 && tci[rw, cl-1].MergeColRight) cl--; //string jstr = (string)this[rw, curCol]; string jstr = (string)this[rw, cl]; if (jstr == null) jstr = tstr; else jstr += ((cl == curCol) ? "\n" : "") + tstr; // multi line cell //jstr += "\n" + tstr; // multi line cell //this[rw, curCol] = jstr; this[rw, cl] = jstr; } } } while (idx != -1); // we are done parsing the 16-bit text. // now set the merge ranges in the table grid, based on the // information saved in that two dimensional array of TableCellinfo this.Rows.Count = curRow + 1; this.AllowMerging = C1.Win.C1FlexGrid.AllowMergingEnum.Custom; maxRow = curRow; int rR = 0; int rC = 0; for (int r = 0; r <= maxRow; r++) for (int c = 0; c <= maxCol; c++) { if (tci[r, c].MergeColRight) { rC = c; while ((rC < maxCol) && (tci[r, rC].MergeColRight)) rC++; if (rC > c) { this.MergedRanges.Add(this.GetCellRange(r, c, r, rC)); string cellstr = this[r, c].ToString(); for (int x = c + 1; x <= rC; x++) this[r, x] = cellstr; c = rC; } } } for (int c = 0; c <= maxCol; c++) for (int r = 0; r <= maxRow; r++) { if (tci[r, c].MergeRowBellow) { rR = r; while ((rR < maxRow) && (tci[rR, c].MergeRowBellow)) rR++; if (rR > r) { this.MergedRanges.Add(this.GetCellRange(r, c, rR, c)); string cellstr = this[r, c].ToString(); for (int x = r + 1; x <= rR; x++) this[x, c] = cellstr; r = rR; } } } for (int c = 0; c <= maxCol; c++) for (int r = 0; r <= maxRow; r++) { if (this[r, c] != null) { string cellstr = this[r, c].ToString(); this[r, c] = cellstr.TrimEnd(" \r\n\t".ToCharArray()); CellRange cr = this.GetMergedRange(r, c); if (cr.r1 != cr.r2) TrimMergedRangeCellText(cr); } } } //private Regex _RemoveComments = new Regex(@"\\v .*?\\v0( |$)"); //public void ParseTableFromText2(string rtfText) //{ // //string txtbuff = _RemoveComments.Replace(rtfText, ""); // string txtbuff = ""; // int curRow = 0; // int curCol = 0; // int maxRow = 0; // int maxCol = 0; // // Get Max Rows and Max Cols // char[] test = "|\n\x02".ToCharArray(); // int idx = 0; // int idxst = 0; // int colPos = 0; // int strow = 0; // Dictionary dicCols = new Dictionary(); // //Dictionary dicCols2 = new Dictionary(); // //If this is not a table ro, then process the RTF version of the text so as to caputure Link references // if (!this.IsRoTable) // txtbuff = rtfText; // else // txtbuff = _RemoveComments.Replace(rtfText, ""); // do // { // idx = txtbuff.IndexOfAny(test, idxst); // if (idx > -1) // { // switch (txtbuff[idx]) // { // case '|': // end of a column // colPos = idxst - strow; // if (!dicCols.ContainsKey(colPos)) // dicCols.Add(colPos, curCol); // else if (curCol > dicCols[colPos]) // { // dicCols.Remove(colPos); // dicCols.Add(colPos, curCol); // } // curCol++; // break; // case '\x02': // case '\n': // end of a row // colPos = idxst - strow; // if (!dicCols.ContainsKey(colPos)) // dicCols.Add(colPos, curCol); // else if (curCol > dicCols[colPos]) // { // dicCols.Remove(colPos); // dicCols.Add(colPos, curCol); // } // curRow++; // strow = idx + 1; // if (curCol > maxCol) // maxCol = curCol; // curCol = 0; // break; // } // idxst = idx + 1; // if (idxst >= txtbuff.Length) // idx = -1; // } // } while (idx != -1); // maxRow = curRow + 1; // curRow = 0; // curCol = 0; // // The resulting Table Grid size in rows and columns // this.Cols.Count = maxCol + 1; // this.Rows.Count = maxRow + 1; // // make all rows and columns editable // this.Rows.Fixed = 0; // this.Cols.Fixed = 0; // // TableCellInfo is used to assign merge ranges // // Make a two dimensional array of TableCellinfo the same size as the table grid // TableCellInfo[,] tci = new TableCellInfo[maxRow + 1, maxCol + 1]; // for (int r = 0; r <= maxRow; r++) // for (int c = 0; c <= maxCol; c++) // tci[r, c] = new TableCellInfo(); // // Read in each cell of the grid // idx = 0; // idxst = 0; // colPos = 0; // strow = 0; // int prevCol = 0; // int tstidx = 0; // string tstr = ""; // bool incRow = false; // ////If this is not a table ro, then process the RTF version of the text so as to caputure Link references // //if (!this.IsRoTable) // // txtbuff = rtfText; // do // { // idx = txtbuff.IndexOfAny(test, idxst); // if (idx > -1) // { // switch (txtbuff[idx]) // { // case '|': // end of column // colPos = idxst - strow; // // based on the position of the | char, find what column we are in. // // note that this will tell us if any columns to the left were merged // // the while loop will flag cell that need to be merged // curCol = dicCols[colPos]; // while (curCol > prevCol + 1) // { // tci[curRow, prevCol].MergeColRight = true; // prevCol++; // } // prevCol = curCol; // // parse out the text to be placed in the table cell // tstr = txtbuff.Substring(idxst, idx - idxst); // if (tstr.Length == 0) // tstr += " "; // // test for a string of '-' characters // for (tstidx = 0; (tstidx < tstr.Length) && (tstr[tstidx] == '-'); tstidx++) ; // if (tstidx < tstr.Length) // not a full line (row) of '-' chars // { // // if this column is in a merged grouping of rows, // // get the cell text in the first cell of the merged grouping of cells // // we will append the newly parsed text to this cell's text. // int rw = curRow; // while (rw - 1 >= 0 && tci[rw - 1, curCol].MergeRowBellow) rw--; // int cl = curCol; // while (cl - 1 >= 0 && tci[rw, cl - 1].MergeColRight) cl--; // //string jstr = (string)this[rw, curCol]; // string jstr = (string)this[rw, cl]; // if (jstr == null) // jstr = tstr; // else // jstr += ((cl == curCol) ? "\n" : "") + tstr; // multi line cell // //jstr += "\n" + tstr; // multi line cell // //this[rw, curCol] = jstr; // this[rw, cl] = jstr; // // take a peek at the start of the next piece of table text to parse // // if it starts with a '-' char, then flag to merge the columns up to // // this point with the same columns in the next row // if (idx < txtbuff.Length - 1 && txtbuff[idx + 1] == '-') // { // for (int c = curCol; c >= -0; c--) // if (!tci[curRow, c].ColEnd) // tci[curRow, c].MergeRowBellow = true; // } // } // else // parsed text contains all dashes // { // tci[curRow, curCol].ColEnd = true; // incRow = true; // } // break; // case '\x02': // end of file // case '\n': // new line of 16-bit table text // colPos = idxst - strow; // // see what column we are in - new line might occure before last grid column // curCol = dicCols[colPos]; // strow = idx + 1; // // parse out the cell text // tstr = txtbuff.Substring(idxst, idx - idxst); // if (tstr.EndsWith("\r")) // strip off carrage return // tstr = tstr.Substring(0, tstr.Length - 1); // tstr = tstr.TrimEnd(" ".ToCharArray()); // if (tstr.Length == 0) // tstr += " "; // // test for a string of '-' characters // for (tstidx = 0; (tstidx < tstr.Length) && (tstr[tstidx] == '-'); tstidx++) ; // if (tstidx < tstr.Length) // not a full line (row) of '-' chars // { // // if this column is in a merged grouping of rows, // // get the cell text in the first cell of the merged grouping of cells // // we will append the newly parsed text to this cell's text. // int rw = curRow; // while (rw - 1 >= 0 && tci[rw - 1, curCol].MergeRowBellow) rw--; // int cl = curCol; // while (cl - 1 >= 0 && tci[rw, cl - 1].MergeColRight) cl--; // //string jstr = (string)this[rw, curCol]; // string jstr = (string)this[rw, cl]; // if (jstr == null) // jstr = tstr; // else // jstr += ((cl == curCol) ? "\n" : "") + tstr; // multi line cell // //jstr += "\n" + tstr; // multi line cell // //this[rw, curCol] = jstr; // this[rw, cl] = jstr; // } // else if (tstr.Length > 0) // parsed text is all dash characters // { // incRow = true; // if (curRow > 0) // merge the column in the previous row with this one // tci[curRow - 1, curCol].MergeRowBellow = false; // } // // if were are that the end of the 16-bit text line, but not in the last column, // // merge the remaining columns to the right // if ((curCol < maxCol) && (tstidx < tstr.Length)) // { // for (int i = curCol; i < maxCol; i++) // tci[curRow, i].MergeColRight = true; // } // if (incRow) // curRow++; // curCol = 0; // incRow = false; // break; // } // idxst = idx + 1; // if (idxst >= txtbuff.Length) // idx = -1; // } // else if (idxst < txtbuff.Length - 1) // handle any remaining text not yet parsed // { // // find the curent column and merge remaining columns to the right // colPos = idxst - strow; // curCol = dicCols[colPos]; // while (curCol > prevCol + 1) // { // tci[curRow, prevCol].MergeColRight = true; // prevCol++; // } // // parse out the remaining text // tstr = txtbuff.Substring(idxst); // tstr = tstr.TrimEnd(" ".ToCharArray()); // if (tstr.Length == 0) // tstr += " "; // // test for a string of '-' characters // for (tstidx = 0; (tstidx < tstr.Length) && (tstr[tstidx] == '-'); tstidx++) ; // if (tstidx < tstr.Length) // { // // if this column is in a merged grouping of rows, // // get the cell text in the first cell of the merged grouping of cells // // we will append the newly parsed text to this cell's text. // int rw = curRow; // while (rw - 1 >= 0 && tci[rw - 1, curCol].MergeRowBellow) rw--; // int cl = curCol; // while (cl - 1 >= 0 && tci[rw, cl - 1].MergeColRight) cl--; // //string jstr = (string)this[rw, curCol]; // string jstr = (string)this[rw, cl]; // if (jstr == null) // jstr = tstr; // else // jstr += ((cl == curCol) ? "\n" : "") + tstr; // multi line cell // //jstr += "\n" + tstr; // multi line cell // //this[rw, curCol] = jstr; // this[rw, cl] = jstr; // } // } // } while (idx != -1); // // we are done parsing the 16-bit text. // // now set the merge ranges in the table grid, based on the // // information saved in that two dimensional array of TableCellinfo // this.Rows.Count = curRow + 1; // this.AllowMerging = C1.Win.C1FlexGrid.AllowMergingEnum.Custom; // maxRow = curRow; // int rR = 0; // int rC = 0; // for (int r = 0; r <= maxRow; r++) // for (int c = 0; c <= maxCol; c++) // { // if (tci[r, c].MergeColRight) // { // rC = c; // while ((rC < maxCol) && (tci[r, rC].MergeColRight)) rC++; // if (rC > c) // { // this.MergedRanges.Add(this.GetCellRange(r, c, r, rC)); // string cellstr = this[r, c].ToString(); // for (int x = c + 1; x <= rC; x++) // this[r, x] = cellstr; // c = rC; // } // } // } // for (int c = 0; c <= maxCol; c++) // for (int r = 0; r <= maxRow; r++) // { // if (tci[r, c].MergeRowBellow) // { // rR = r; // while ((rR < maxRow) && (tci[rR, c].MergeRowBellow)) rR++; // if (rR > r) // { // this.MergedRanges.Add(this.GetCellRange(r, c, rR, c)); // string cellstr = this[r, c].ToString(); // for (int x = r + 1; x <= rR; x++) // this[x, c] = cellstr; // r = rR; // } // } // } // for (int c = 0; c <= maxCol; c++) // for (int r = 0; r <= maxRow; r++) // { // if (this[r, c] != null) // { // string cellstr = this[r, c].ToString(); // this[r, c] = cellstr.TrimEnd(" \r\n\t".ToCharArray()); // CellRange cr = this.GetMergedRange(r, c); // if (cr.r1 != cr.r2) // TrimMergedRangeCellText(cr); // } // } //} private void TrimMergedRangeCellText(CellRange cr) { // count number of newlines string cellstr = this[cr.r1, cr.c1].ToString(); string[] strary = cellstr.Split("\n".ToCharArray()); int nlines = strary.Length; // count number of rows in merge range int nrows = (cr.r2 - cr.r1) + 1; // if nlines > rows then trim blank lines from top bool bNeedToTrim = (nlines > nrows); string jstr = ""; foreach (string tmpstr in strary) { int tlen = tmpstr.Trim().Length; if (!bNeedToTrim || tlen > 0) { if (jstr.Length > 0) jstr += "\n"; jstr += tmpstr; } else nlines--; bNeedToTrim = (tlen == 0 && nlines > nrows); } this[cr.r1, cr.c1] = jstr; } #endregion //Import / Export Grid #region Bug Work Around protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e) { // Note: this fixes a bug that happens when the grid has more rows than columns // notified ComponentOne of the problem 6/25/09 via Email try { base.OnMouseDown(e); } catch (Exception ex) { while (ex != null) { Console.WriteLine("{0} {1} {2}", ex.GetType().Name, ex.Message, ex.StackTrace); ex = ex.InnerException; } } } #endregion //Bug Work Around //public void CenterTheCellText() //{ // // Cannot use this type of text allignment with RTF text cells // CellRange cr = this.Selection; // for (int rw = cr.r1; rw <= cr.r2; rw++) // for (int col = cr.c1; col <= cr.c2; col++) // { // CellRange tmp = this.GetCellRange(rw, col, rw, col); // string StyleName = string.Format("R{0}C{1}Style", rw, col); // CellStyle cs = this.Styles.Add(StyleName, tmp.Style); // cs.TextAlign = TextAlignEnum.CenterCenter; // tmp.Style = cs; // } //} #region Uneven Selections /// /// True if the top and bottom row of the selection is the same for every column /// public bool EvenSelection { get { if (Selection.c1 < 0 || Selection.c2 < 0 || Selection.r1 < 0 || Selection.r2 < 0) return true; // Even if there is no selection if (Selection.IsSingleCell) return true; // One cell by definition is Even int cMin = MinimumColumn(Selection.r1, Selection.c1); // Get the left column of the top row int cMax = MaximumColumn(Selection.r1, Selection.c2); // Get the right column of the top row for (int r = Selection.r1 + 1; r <= Selection.r2; r++) { // Uneven if the top row in this column doesn't match the first column if (MinimumColumn(r, Selection.c1) != cMin) return false; // Uneven if the bottom row in this column doesn't match the first column if (MaximumColumn(r, Selection.c2) != cMax) return false; } int rMin = MinimumRow(Selection.r1, Selection.c1); // Get the top row of the left column int rMax = MaximumRow(Selection.r2, Selection.c1); // Get the bottom row of the left column for (int c = Selection.c1 + 1; c <= Selection.c2; c++) { // Uneven if the top row in this column doesn't match the first column if (MinimumRow(Selection.r1, c) != rMin) return false; // Uneven if the bottom row in this column doesn't match the first column if (MaximumRow(Selection.r2, c) != rMax) return false; } return true; } } public void MakeSelectionEven() { if (Selection.IsSingleCell) return; // One cell by definition is Even MakeSelectionEven(Selection.r1, Selection.c1, Selection.r2, Selection.c2); } public void SelectRow() { MakeSelectionEven(Selection.r1, 0, Selection.r2, Cols.Count - 1); } public void SelectCol() { MakeSelectionEven(0, Selection.c1, Rows.Count - 1, Selection.c2); } public void MakeSelectionEven(int r1,int c1, int r2, int c2) { if (c1 < 0 || c2 < 0 || r1 < 0 || r2 < 0) return; // if there is no selection don't bother CellRange cr = GetEvenSelection(r1, c1, r2, c2); Select(cr); } public CellRange GetEvenSelection(int r1, int c1, int r2, int c2) { int cMinNew = MinimumColumn(r1, c1); // Get the left column of the top row int cMaxNew = MaximumColumn(r1, c2); // Get the right column of the top row int rMinNew = MinimumRow(r1, c1); // Get the top row of the left column int rMaxNew = MaximumRow(r2, c1); // Get the bottom row of the left column int cMin = cMinNew; int cMax = cMaxNew; int rMin = rMinNew; int rMax = rMaxNew; do { cMin = cMinNew; cMax = cMaxNew; rMin = rMinNew; rMax = rMaxNew; for (int r = rMin; r <= rMax; r++) { // Uneven if the top row in this column doesn't match the first column int myMin = MinimumColumn(r, cMin); if (myMin < cMinNew) cMinNew = myMin; // Uneven if the bottom row in this column doesn't match the first column int myMax = MaximumColumn(r, cMax); if (myMax > cMaxNew) cMaxNew = myMax; } for (int c = cMinNew; c <= cMaxNew; c++) { // if the top row in this column is less than the minimum save it int myMin = MinimumRow(rMin, c); if (myMin < rMinNew) rMinNew = myMin; // Uneven if the bottom row in this column doesn't match the first column int myMax = MaximumRow(rMax, c); if (myMax > rMax) rMaxNew = myMax; } } while (cMinNew < cMin || cMaxNew > cMax || rMinNew < rMin || rMaxNew > rMax); CellRange cr = GetCellRange(rMinNew, cMinNew, rMaxNew, cMaxNew); return cr; } private int MinimumColumn(int r, int c) { return GetMergedRange(r, c).c1; } private int MaximumColumn(int r, int c) { return GetMergedRange(r, c).c2; } private int MinimumRow(int r, int c) { return GetMergedRange(r, c).r1; } private int MaximumRow(int r, int c) { return GetMergedRange(r, c).r2; } public Color StyleBackColor { get {return Styles.Normal.BackColor;} set { Styles.Normal.BackColor = value; Styles.Alternate.BackColor = value; for (int c = 0; c < Cols.Count; c++) for (int r = 0; r < Rows.Count; r++) { CellRange cr = GetMergedRange(r, c); if (cr.Style != null && cr.Style.BackColor != value && cr.Style.Name != "Fixed") { cr.Style.BackColor = value; //Console.WriteLine("{0}, {1}, {2}, {3}", r, c, cr.Style.Name, cr.Style.BackColor); } } } } /// /// Returns a list of cells or merged cells within the selection /// public List MySelection { get { List ranges = new List(); for (int c = Selection.c1; c <= Selection.c2; c++) for (int r = Selection.r1; r <= Selection.r2; r++) { CellRange cr = GetMergedRange(r, c); if (!ranges.Contains(cr)) ranges.Add(cr); } //} return ranges; } } /// /// This is a test to see if MySelection works. /// public void BoldMySelection() { foreach (CellRange cr in MySelection) { StepRTB rtb = new StepRTB(); rtb.Rtf = GetCellRTFString(cr.r1, cr.c1); rtb.SelectAll(); rtb.SelectionFont = new Font(rtb.SelectionFont, FontStyle.Bold); this[cr.r1, cr.c1] = rtb.Rtf; } } #endregion } #region RTF Class for Cell rendering class RTF : StepRTB //RichTextBox { // messages used by RichEd20.dll internal const int WM_USER = 0x0400, EM_FORMATRANGE = WM_USER + 57; // FORMATRANGE is used by RichEd20.dll to render RTF internal struct FORMATRANGE { internal IntPtr hdc, hdcTarget; internal Rectangle rc, rcPage; internal int cpMin, cpMax; } // render the control directly into a given Graphics object // (this does not honor clipping set in the target Graphics object; it that is // a problem, use the RenderClipped method instead). public void Render(Graphics g, Rectangle rc) { // convert rect from pixels to twips rc.X = (int)(rc.X * 1440 / g.DpiX); rc.Y = (int)(rc.Y * 1440 / g.DpiY); rc.Width = rc.X + (int)((rc.Width) * 1440 / g.DpiX); rc.Height = rc.Y + (int)((rc.Height) * 1440 / g.DpiY); // get dc IntPtr hdc = g.GetHdc(); // set up FORMATRANGE struct FORMATRANGE fmt = new FORMATRANGE(); fmt.hdc = fmt.hdcTarget = hdc; fmt.rc = fmt.rcPage = rc; fmt.cpMin = 0; fmt.cpMax = -1; // render RTF int render = 1; SendMessageFormatRange(Handle, EM_FORMATRANGE, render, ref fmt); // clean up SendMessage(Handle, EM_FORMATRANGE, render, 0); // done with dc g.ReleaseHdc(hdc); } // render RTF into a Graphics object using a temporary bitmap to ensure // clipping works correctly. public void RenderClipped(Graphics g, Rectangle rc) { // create temp bitmap Rectangle rcSrc = new Rectangle(0, 0, rc.Width, rc.Height); using (Bitmap bmp = new Bitmap(rc.Width, rc.Height)) { // render RTF into bitmap using (Graphics gBmp = Graphics.FromImage(bmp)) { Render(gBmp, rcSrc); // transfer bitmap to original Graphics object // (this honors clipping set in the target Graphics object) g.DrawImage(bmp, rc, rcSrc, GraphicsUnit.Pixel); } } } // SendMessage [DllImport("USER32.DLL", CharSet = CharSet.Auto)] static private extern int SendMessage( IntPtr hWnd, uint wMsg, int wParam, int lParam); [DllImport("USER32.DLL", CharSet = CharSet.Auto, EntryPoint = "SendMessage")] static private extern int SendMessageFormatRange( IntPtr hWnd, uint wMsg, int wParam, ref FORMATRANGE lParam); } #endregion //RTF Class for Cell rendering # region TableCellInfo for text parse class TableCellInfo { private bool _MergeRowBellow; public bool MergeRowBellow { get { return _MergeRowBellow; } set { _MergeRowBellow = value; } } private bool _MergeColRight; public bool MergeColRight { get { return _MergeColRight; } set { _MergeColRight = value; } } private bool _ColEnd; public bool ColEnd { get { return _ColEnd; } set { _ColEnd = value; } } private string _Text; public string Text { get { return _Text; } set { _Text = value; } } } #endregion //TableCellInfo for text parse #region TableCellEditor /// /// TableCellEditor inherits from a StepRTB and is used as a custom cell editor /// for the C1FlexGrid control. /// public class TableCellEditor : StepRTB //System.Windows.Forms.RichTextBox //System.Windows.Forms.TextBox // System.Windows.Forms.ComboBox { private VlnFlexGrid _owner; private int _row, _col; private char _pendingKey; private bool _cancel; public bool _initializingEdit; // constructor: attach to owner grid public TableCellEditor(VlnFlexGrid owner) { Visible = false; AutoSize = false; BackColor = Color.SkyBlue; BorderStyle = BorderStyle.None; ScrollBars = RichTextBoxScrollBars.None; _initializingEdit = false; _pendingKey = (char)0; _cancel = false; _owner = owner; _owner.Controls.Add(this); this.CursorMovement += new StepRTBCursorMovementEvent(TableCellEditor_CursorMovement); this.CursorKeyPress += new StepRTBCursorKeysEvent(TableCellEditor_CursorKeyPress); this.Leave += new EventHandler(_editor_Leave); //this.HeightChanged += new StepRTBEvent(_HeightChanged); } // start editing: move to cell and activate public void StartEditing(int row, int col) { _initializingEdit = true; // save coordinates of cell being edited _row = row; _col = col; //this.Clear(); //jsj // assume we'll save the edits _cancel = false; // move editor over the current cell Rectangle rc = _owner.GetCellRect(row, col, true); rc.Width--; rc.Height--; Bounds = rc; // initialize control content Text = ""; FindAllLinks(); // jsj 1-5-2011 if (_pendingKey > ' ') Text = _pendingKey.ToString(); else if (_owner[row, col] != null) { string tmp = _owner[row, col].ToString(); if (tmp.StartsWith(@"{\rtf")) Rtf = tmp.Replace(@"\~",@"\u160?"); else Text = tmp; } Select(Text.Length, 0); Size sz = new Size(rc.Width, rc.Height); //this.Size = sz; this.Width = rc.Width; // make editor visible Visible = true; // and get the focus //Select(); Focus(); _initializingEdit = false; } void TableCellEditor_CursorKeyPress(object sender, KeyEventArgs args) { //throw new Exception("The method or operation is not implemented."); } void TableCellEditor_CursorMovement(object sender, StepRTBCursorMovementEventArgs args) { int row = _owner.Selection.r1; int col = _owner.Selection.c1; CellRange cr = _owner.GetMergedRange(row, col); //Console.WriteLine("keystroke {0} selection {1},{2}", args.Key, row, col); //vlnStackTrace.ShowStack("keystroke {0} selection {1},{2}", args.Key, row, col); _owner.Select(); // See if we are in a merged range of cells. // if so, use the merged range instead of the selected range // so that we can jump to the top/bottom/left/right of the range // before attempting the move to the next grid cell. //int idx = _owner.MergedRanges.IndexOf(row, col); //if (idx > -1) cr = _owner.MergedRanges[idx]; switch (args.Key) { case VEPROMS.CSLA.Library.E_ArrowKeys.CtrlDown: case VEPROMS.CSLA.Library.E_ArrowKeys.Down: row = cr.r2; if (row < _owner.Rows.Count - 1) _owner.Select(_owner.GetMergedRange(row + 1, col)); else _owner.OnCursorMovement(this, new VlnFlexGridCursorMovementEventArgs(args.Key)); break; case VEPROMS.CSLA.Library.E_ArrowKeys.CtrlLeft: case VEPROMS.CSLA.Library.E_ArrowKeys.Left: col = cr.c1; if (col > 0) _owner.Select(_owner.GetMergedRange(row, col - 1)); else if(row > 0) _owner.Select(_owner.GetMergedRange(row - 1, _owner.Cols.Count - 1)); else _owner.OnCursorMovement(this, new VlnFlexGridCursorMovementEventArgs(args.Key)); break; case VEPROMS.CSLA.Library.E_ArrowKeys.CtrlRight: case VEPROMS.CSLA.Library.E_ArrowKeys.Right: col = cr.c2; if (col < _owner.Cols.Count - 1) _owner.Select(_owner.GetMergedRange(row, col + 1)); else if (cr.r2 < _owner.Rows.Count - 1) { CellRange crDest = _owner.GetMergedRange(cr.r2 + 1, 0); if (cr.r2 < crDest.r1) // It will move to the correct place _owner.Select(crDest); else if (crDest.r2 < _owner.Rows.Count) _owner.Select(_owner.GetMergedRange(crDest.r2 + 1, 0)); else _owner.OnCursorMovement(this, new VlnFlexGridCursorMovementEventArgs(args.Key)); } else _owner.OnCursorMovement(this, new VlnFlexGridCursorMovementEventArgs(args.Key)); break; case VEPROMS.CSLA.Library.E_ArrowKeys.CtrlUp: case VEPROMS.CSLA.Library.E_ArrowKeys.Up: row = cr.r1; if (row > 0) _owner.Select(_owner.GetMergedRange(row - 1, col)); else _owner.OnCursorMovement(this, new VlnFlexGridCursorMovementEventArgs(args.Key)); break; default: break; } //Console.WriteLine("selection {0}", _owner.Selection); //_owner.Focus(); // focus was jumping out of the grid this keeps it in. } // after edit handler (custom editor) void _editor_Leave(object sender, EventArgs e) { _owner.Invalidate(); _owner.AdjustGridControlSize(); } //void _HeightChanged(object sender, EventArgs args) //{ // _owner.Invalidate(); //} // save key that started the editing mode public void SetPendingKey(char chr) { _pendingKey = chr; } // expose internal variables public bool Cancel { get { return _cancel; } } public int Row { get { return _row; } } public int Col { get { return _col; } } // move editor after the grid has scrolled public void UpdatePosition() { // get cell rect now Rectangle rcCell = _owner.GetCellRect(_row, _col, false); // intersect with scrollable part of the grid Rectangle rcScroll = _owner.ClientRectangle; rcScroll.X = _owner.Cols[_owner.Cols.Fixed].Left; rcScroll.Y = _owner.Rows[_owner.Rows.Fixed].Top; rcScroll.Width -= rcScroll.X; rcScroll.Height -= rcScroll.Y; rcCell = Rectangle.Intersect(rcCell, rcScroll); // and move the control if (rcCell.Width > 0) rcCell.Width--; if (rcCell.Height > 0) rcCell.Height--; Bounds = rcCell; Size sz = new Size(_owner.GetCellRect(_row, _col).Width, _owner.GetCellRect(_row, _col).Height); this.Size = sz; } // lost focus: hide the editor override protected void OnLeave(System.EventArgs e) { // base processing base.OnLeave(e); // copy text to owner grid if (!_cancel) { _owner[_row, _col] = Rtf; //Text; } // no more pending keys _pendingKey = (char)0; // done for now, hide editor Visible = false; } // we will handle the Tab key ourselves override protected bool IsInputKey(Keys keyData) { if (keyData == Keys.Tab) return true; return base.IsInputKey(keyData); } //// some keys end the editing //override protected void OnKeyDown(System.Windows.Forms.KeyEventArgs e) //{ // switch (e.KeyCode) // { // case Keys.Escape: // cancel edits // _cancel = true; // _owner.Select(); // e.Handled = true; // return; // case Keys.Enter: // finish editing // case Keys.Tab: // case Keys.Up: // case Keys.Down: // case Keys.PageUp: // case Keys.PageDown: // _owner.Select(); // e.Handled = true; // MoveCursor(e.KeyCode); // return; // default: // default processing // base.OnKeyDown(e); // return; // } //} //// move cursor after done editing //protected void MoveCursor(Keys key) //{ // int row = _owner.Row; // int col = _owner.Col; // switch (key) // { // case Keys.Tab: col++; break; // case Keys.Up: row--; break; // //case Keys.Return: row++; break; // case Keys.Down: row++; break; // //case Keys.PageUp: row -= 10; break; // //case Keys.PageDown: row += 10; break; // } // // validate new selection // if (row < _owner.Rows.Fixed) row = _owner.Rows.Fixed; // if (col < _owner.Cols.Fixed) col = _owner.Cols.Fixed; // if (row > _owner.Rows.Count - 1) row = _owner.Rows.Count - 1; // if (col > _owner.Cols.Count - 1) col = _owner.Cols.Count - 1; // // apply new selection // _owner.Select(row, col); //} //// suppress some keys to avoid annoying beep //override protected void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e) //{ // switch (e.KeyChar) // { // case (char)27: // Keys.Escape: // case (char)13: // Keys.Enter: // case (char)9: // Keys.Tab: // e.Handled = true; // return; // } // base.OnKeyPress(e); //} } #endregion // TableCellEditor #region TableClipBoardFuncts Class class TableClipBoardFuncts { DataFormats.Format dfmtTableCellRange = DataFormats.GetFormat("TableCellRange"); public TableClipBoardFuncts() { //mySeldTableCellsObject = new DataObject(dfmtTableCellRange.Name, seldTableCells); } public void Put(CellRange cr) { // Copies myObject into the clipboard. // Clip get the value (text) of all the cells in the selected range // This is saved as one RTF string. Clipboard.SetDataObject(cr.Clip, true); // the "true" make the copy persistent //Console.WriteLine("\nClip: '{0}' \n'{1}'", cr.Clip,cr.DataDisplay); } public ArrayList Get() { // Retrieves the data from the clipboard. IDataObject myRetrievedObject = Clipboard.GetDataObject(); string jj = (string)myRetrievedObject.GetData(DataFormats.Text); return GetCellStrings(jj); } private ArrayList GetCellStrings(string instr) { // The table cells placed on the clipboard is saved as one long RTF string. // "\r\n\t" defines a cell border // "\r\n\r" defines beginning of next line (row) // This function will separate each cell text and place them in an array. // This allow the clipboard information to be pasted independently from // how it was selected. // Bug fix: the CellRange.Clip (see cr.clip in the Put() function above) is replacing // new lines with spaces. We need to put them back. instr = instr.Replace(@"}} \", "}}\r\n\\"); string tstr = ""; // this will contain the parsed out cell text ArrayList arylstCellStrings = new ArrayList(); int sidx = 0; // start index int tidx = 0; if (instr != null) { int idx = instr.IndexOf(@"{\rtf",sidx+1); // cell boarder while (idx > 0) { tstr = instr.Substring(sidx, idx - sidx); tstr = tstr.Substring(0, tstr.LastIndexOf('}') + 1); //Console.WriteLine("\ntstr: '{0}'", tstr); arylstCellStrings.Add(tstr); sidx = idx; idx = instr.IndexOf(@"{\rtf",sidx+1); } if (sidx < instr.Length) { tstr = instr.Substring(sidx); arylstCellStrings.Add(tstr); } } return arylstCellStrings; } //private ArrayList GetCellStrings(string instr) //{ // // The table cells placed on the clipboard is saved as one long RTF string. // // "\r\n\t" defines a cell border // // "\r\n\r" defines beginning of next line (row) // // This function will separate each cell text and place them in an array. // // This allow the clipboard information to be pasted independently from // // how it was selected. // string tstr = ""; // this will contain the parsed out cell text // ArrayList arylstCellStrings = new ArrayList(); // int sidx = 0; // start index // int tidx = 0; // if (instr != null) // { // int idx = instr.IndexOf("\r\n\t"); // cell boarder // if (idx < 0) idx = instr.IndexOf("\r\n\r"); // new line (needed for multiple lines in one cell) // while (idx > 0) // { // tstr = instr.Substring(sidx, idx - sidx); // tidx = tstr.IndexOf("\r\n\r"); // if (tidx > 0) // { // idx = instr.IndexOf("\r\n\r", sidx); // tstr = instr.Substring(sidx, idx - sidx); // } // arylstCellStrings.Add(tstr.Substring(tstr.IndexOf("{\\rtf"))); // sidx = idx + 3; // if (sidx < instr.Length) // { // idx = instr.IndexOf("\r\n\t", sidx); // if (idx < 0) idx = instr.IndexOf("\r\n\r", sidx); // } // } // if (sidx < instr.Length) // { // tstr = instr.Substring(sidx); // arylstCellStrings.Add(tstr.Substring(tstr.IndexOf("{\\rtf"))); // } // } // return arylstCellStrings; //} } [Serializable] public class SelectedTableCells : Object { private CellRange _cpbrdCellRange; public CellRange CpbrdCellRange { get { return _cpbrdCellRange; } set { _cpbrdCellRange = value; } } public SelectedTableCells() { } } #endregion // TableClipBoardFuncts Class public class VlnFlexGridCursorMovementEventArgs { private E_ArrowKeys _Key; public E_ArrowKeys Key { get { return _Key; } set { _Key = value; } } public VlnFlexGridCursorMovementEventArgs(E_ArrowKeys key) { _Key = key; } } public class VlnFlexGridPasteEventArgs { private string _Text; public string Text { get { return _Text; } set { _Text = value; } } public VlnFlexGridPasteEventArgs(string text) { _Text = text; } } }