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;
namespace Volian.Controls.Library
{
public delegate void VlnFlexGridEvent(object sender, EventArgs args);
public delegate void VlnFlexGridCursorMovementEvent(object sender, VlnFlexGridCursorMovementEventArgs args);
public partial class VlnFlexGrid : C1.Win.C1FlexGrid.C1FlexGrid
{
public bool HasVScroll
{
get
{
return RTBAPI.HasVertScroll(this);
}
}
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);
}
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;
public E_ViewMode VwMode
{
get { return _vwMode; }
set
{
_vwMode = value;
AllowEditing = _vwMode == E_ViewMode.Edit;
}
}
#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)
{
int height = 0;
CellRange cr = GetMergedRange(row, col);
for (int r = cr.r1; r <= cr.r2; r++)
{
height += (Rows[r].Height == -1) ? Rows.DefaultSize -3 : Rows[r].Height - 3;
}
return height;
}
private int BlankRowSpace()
{
int curRowHeight = (Rows[Row].Height == -1) ? Rows.DefaultSize - 3 : Rows[Row].Height - 3;
int curRowHeightNLines = curRowHeight / (Rows.DefaultSize - 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 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);
blankRowSpace = Math.Min(blankRowSpace, Math.Max(0,cellHeight - dataHeight));
}
}
//Console.WriteLine("BlankRowSpace {0}", blankRowSpace);
return blankRowSpace;
}
//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 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.LeftCenter;
//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.ContentsResized += new ContentsResizedEventHandler(_tableCellEditor_ContentsResized);
_tableCellEditor.HeightChanged += new StepRTBEvent(_tableCellEditor_HeightChanged);
_clpbrdCpyPste = new TableClipBoardFuncts();
//this.Enter += new System.EventHandler(this.Grid_Enter);
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.LeaveEdit += new RowColEventHandler(VlnFlexGrid_LeaveEdit);
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.ValidateEdit += new ValidateEditEventHandler(VlnFlexGrid_ValidateEdit);
this.KeyDown += new KeyEventHandler(VlnFlexGrid_KeyDown);
this.KeyUp +=new KeyEventHandler(VlnFlexGrid_KeyUp);
this.SelChange += new EventHandler(VlnFlexGrid_SelChange);
this.Resize += new EventHandler(VlnFlexGrid_Resize);
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_Resize(object sender, EventArgs e)
{
if (TableCellEditor.Visible)
Volian.Base.Library.vlnStackTrace.ShowStackLocal("VlnFlexGrid_Resize", 1);
}
void VlnFlexGrid_SelChange(object sender, EventArgs e)
{
// Possibilities
// Selection is a single cell
// It is part of a range
// It is
//Console.WriteLine("Where Am I {0} {1} {2}", Selection, GetMergedRange(Row, Col), Selection.Equals(GetMergedRange(Row, Col)));
}
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);
if (e.Style.BackColor != solid)
e.Style.BackColor = solid;
// check whether the cell contains RTF
string rtfText = this.GetDataDisplay(e.Row, e.Col);
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 = Cols[e.Col].Width;
_rtf.Rtf = rtfText;
_rtf.ForeColor = e.Style.ForeColor;
_rtf.BackColor = e.Style.BackColor;
_rtf.Render(e.Graphics, e.Bounds);
//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 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 = this.Styles.Add(StyleName, tmp.Style);
cs.Border.Style = newBorder;
tmp.Style = cs;
}
}
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()
{
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 AdjustGridHeightWidth(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;
//trtb.Rtf = trtb.RtfPrefixForSymbols;
if (tstr != null && tstr.Length > 0)
{
string tsave = tstr;
if (tstr.StartsWith(@"{\rtf"))
trtb.Rtf = tstr; // already RTF text
else
trtb.Text = tstr; // this will convert regular text to RTF text
//if (trtb.Rtf.Contains("SimSun"))
// Console.WriteLine("here's SimSun! :-)");
// 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);
// this will convert the special characters for Bold, Underline, and Italics
// into RTF commands
//VE_Font vf = new VE_Font(this.Font.FontFamily.Name, (int)this.Font.Size, E_Style.None);
trtb.Rtf = trtb.RtfPrefix + ConvertTableText(trtb.Rtf) + "}";
string fromRTF = trtb.Rtf;
trtb.Rtf = trtb.RtfPrefix + ConvertTableText(tstr) + "}";
string fromStr = trtb.Rtf;
if (fromRTF.Contains("SimSun"))
Console.WriteLine("SimSun");
else
Compare(fromRTF, fromStr, tsave);
//ConvertTableText(trtb);
}
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 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 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, 10), fromRTF.Substring(i, 10));
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.AdjustGridHeightWidth(r, c);
}
//this.Refresh();
//Application.DoEvents();
this.AdjustGridControlSize();
SetupCellUserData();
}
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("\n", "\\par\r\n");
rtn = rtn.Replace("\xF2", @"\f1 \u8805?\f0 "); //greater than or equal
rtn = rtn.Replace("\x7F", @"\f1 \u916?\f0 "); // delta
if (rtn.Contains("\xFF"))
rtn = rtn.Replace("\xFF", @"\u160?");
//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 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)
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)
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()
{
this.SelectionMode = SelectionModeEnum.Column;
this.Select(this.Selection.r1, this.Selection.c1);
DialogResult dr = MessageBox.Show("Remove this column?", "Remove Column", MessageBoxButtons.YesNo);
if (dr == DialogResult.Yes)
RemoveColumns(this.Selection.r1, this.Selection.c1, 1);
this.SelectionMode = SelectionModeEnum.Default;
}
public void RemoveSelectedRow()
{
this.SelectionMode = SelectionModeEnum.Row;
this.Select(this.Selection.r1, this.Selection.c1);
DialogResult dr = MessageBox.Show("Remove this Row?", "Remove Row", MessageBoxButtons.YesNo);
if (dr == DialogResult.Yes)
this.RemoveRows(this.Selection.r1, this.Selection.c1, 1);
this.SelectionMode = SelectionModeEnum.Default;
}
private void RemoveRows(int strow, int stcol, int cnt)
{
for (int i = 0; i < cnt; i++)
{
if (this.RowIsInMergeRange(strow))
{
for (int cl = 0; cl < this.Cols.Count; cl++)
{
int idx = this.MergedRanges.IndexOf(strow, cl);
if (idx > -1)
{
CellRange cr = this.MergedRanges[idx];
if (cr.r1 < cr.r2)
this[cr.r1 + 1, cr.c1] = this[cr.r1, cr.c1];
}
cl++;
}
}
this.Rows.Remove(strow);
this.AdjustMergedRows(strow, false, true);
}
this.AdjustGridControlSize();
}
private void RemoveColumns(int strow, int stcol, int cnt)
{
for (int i = 0; i < cnt; i++)
{
if (this.ColIsInMergeRange(stcol))
{
for (int rw = 0; rw < this.Rows.Count; rw++)
{
int idx = this.MergedRanges.IndexOf(rw, stcol);
if (idx > -1)
{
CellRange cr = this.MergedRanges[idx];
if (cr.c1 < cr.c2)
this[cr.r1, cr.c1 + 1] = this[cr.r1, cr.c1];
}
}
}
this.Cols.Remove(stcol);
this.AdjustMergedColumns(stcol, false, true);
}
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.", "Invalid Selection");
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 = (string)(arylst[aryidx++]);
trtb.AdjustWidthForContent();
}
this[r, c] = trtb.Rtf;
this.AdjustGridHeightWidth(r, c);
}
}
}
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 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)
{
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.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 celll, 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
{
// 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);
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);
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
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);
Select(rMinNew, cMinNew, rMaxNew, cMaxNew);
}
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;
}
///
/// 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;
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;
}
}
}