Rich 7bcfafcc8b Move frmErrors when frmLoader is moved
Shutoff SpellCheck for StepRTB
Use using for temporary StepRTB
Use using for vlnFlexGrid
Added debug output to track StepRTBs and vlnFlexGrids in memory
Limit bottom margin to 0 or above
Dispose of roImage after it is done being used
Dispose of Figure after it is done being used.
Use GetJustRODB so that images are not loaded.
Added ErrorHandler if annotation is deleted after a search
Track create, dispose and finalize
Add static variable to control if SpellCheck is used
Use using for temporary StepRTB
Lazy Load SelectionStack
Clean-up on Dispose
Track create, dispose and finalize
Make MyCopyInfo Lazy Loaded
Use using for temporary StepRTB
Add Dispose method for TableCellEditor
Cleanup on Dispose
Only kill MSWord instances that are invisible
2012-07-13 18:34:57 +00:00

4875 lines
154 KiB
C#

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 C1.Win.C1SpellChecker;
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 delegate void VlnFlexGridkeyEvent(object sender, KeyEventArgs args);
public partial class VlnFlexGrid : C1.Win.C1FlexGrid.C1FlexGrid
{
private bool _Disposed = false;
private static int _CountCreated = 0;
private static int _CountDisposed = 0;
private static int _CountFinalized = 0;
private static int IncrementCountCreated
{ get { return ++_CountCreated; } }
private int _CountWhenCreated = IncrementCountCreated;
public static int CountCreated
{ get { return _CountCreated; } }
public static int CountNotDisposed
{ get { return _CountCreated - _CountDisposed; } }
public static int CountNotFinalized
{ get { return _CountCreated - _CountFinalized; } }
private bool _Finalized = false;
~VlnFlexGrid()
{
if(!_Finalized) _CountFinalized++;
_Finalized = true;
}
private C1SpellChecker _SpellChecker;
public C1SpellChecker SpellChecker
{
get { return _SpellChecker; }
set { _SpellChecker = value; }
}
//public string GridStackTrace
//{
// get
// {
// string st = Volian.Base.Library.vlnStackTrace.GetStack();
// st = StripFunnyCharacters(st);
// return st;
// Console.WriteLine(st);
// return st.Replace(@"\","|");
// }
// set
// {
// ;
// }
//}
//private string StripFunnyCharacters(string st)
//{
// StringBuilder sb = new StringBuilder();
// foreach (char c in st)
// {
// if ((c < ' ' || c > 255) && !"\r\n\t".Contains(c.ToString()))
// sb.Append(string.Format("x{0:X4}", (int)c));
// else
// sb.Append(c);
// }
// return sb.ToString();
//}
public bool IsDirty
{
get
{
return IsGridChanged(this._MyItemInfo.MyContent.MyGrid.Data, this.GetXMLData());
}
}
private bool IsGridChanged(string oldXml, string newXml)
{
if (this.TableCellEditor.Text.Contains("<NewID>"))
return false;
XmlDocument XdOld = new XmlDocument();
XdOld.LoadXml(oldXml);
XmlDocument XdNew = new XmlDocument();
XdNew.LoadXml(newXml);
//check volian borders 1st
if (XdNew.SelectSingleNode("C1FlexGrid/Control/MyBorderDetailString").InnerText != XdOld.SelectSingleNode("C1FlexGrid/Control/MyBorderDetailString").InnerText)
return true;
//check row/col sizes 2nd
if (GetRowColSizeString(XdNew) != GetRowColSizeString(XdOld))
return true;
//check for cell data changes 3rd
if (GetCellDataString(XdNew) != GetCellDataString(XdOld))
return true;
//check for cell format changes 4th
if (GetCellFormatString(XdNew) != GetCellFormatString(XdOld))
return true;
//check for merged cells 5th
if (GetCellMergeString(XdNew) != GetCellMergeString(XdOld))
return true;
return false;
}
private string GetRowColSizeString(XmlDocument xd)
{
string defCW = xd.SelectSingleNode("C1FlexGrid/ColumnInfo/DefaultSize").InnerText;
string defRH = xd.SelectSingleNode("C1FlexGrid/RowInfo/DefaultSize").InnerText;
int cols = int.Parse(xd.SelectSingleNode("C1FlexGrid/ColumnInfo/Count").InnerText);
int rows = int.Parse(xd.SelectSingleNode("C1FlexGrid/RowInfo/Count").InnerText);
List<string> rh = new List<string>();
for (int i = 0; i < rows; i++)
rh.Add(defRH);
List<string> cw = new List<string>();
for (int i = 0; i < cols; i++)
cw.Add(defCW);
XmlNodeList nlr = xd.SelectNodes("C1FlexGrid/Rows/Row");
foreach (XmlNode nr in nlr)
{
int idx = int.Parse(nr.Attributes.GetNamedItem("index").InnerText);
rh[idx] = nr.SelectSingleNode("Height").InnerText;
}
XmlNodeList nlc = xd.SelectNodes("C1FlexGrid/Columns/Column");
foreach (XmlNode nc in nlc)
{
int idx = int.Parse(nc.Attributes.GetNamedItem("index").InnerText);
cw[idx] = nc.SelectSingleNode("Width").InnerText;
}
string rhcw = "RowHeights: ";
string sep = string.Empty;
foreach (string s in rh)
{
rhcw += sep + s;
sep = ",";
}
rhcw += " - ColWidths: ";
sep = string.Empty;
foreach (string s in cw)
{
rhcw += sep + s;
sep = ",";
}
return rhcw;
}
private string GetCellDataString(XmlDocument xd)
{
int cols = int.Parse(xd.SelectSingleNode("C1FlexGrid/ColumnInfo/Count").InnerText);
int rows = int.Parse(xd.SelectSingleNode("C1FlexGrid/RowInfo/Count").InnerText);
List<string> datum = new List<string>();
for (int i = 0; i < rows * cols; i++)
datum.Add("|");
XmlNodeList nl = xd.SelectNodes("C1FlexGrid/Cells/Cell/Data");
string data = string.Empty;
foreach (XmlNode xn in nl)
{
RichTextBox rtb = new RichTextBox();
rtb.Rtf = xn.InnerText;
XmlAttribute xa = xn.ParentNode.Attributes.GetNamedItem("index") as XmlAttribute;
string[] rc = xa.InnerText.Split(',');
int r = int.Parse(rc[0]);
int c = int.Parse(rc[1]);
int index = r * cols + c;
datum[index] = "|" + (rtb.Text == "" ? "" : rtb.Text);
}
foreach (string s in datum)
data += s;
return data;
}
private string GetCellFormatString(XmlDocument xd)
{
int cols = int.Parse(xd.SelectSingleNode("C1FlexGrid/ColumnInfo/Count").InnerText);
int rows = int.Parse(xd.SelectSingleNode("C1FlexGrid/RowInfo/Count").InnerText);
List<string> datum = new List<string>();
for (int i = 0; i < rows * cols; i++)
datum.Add("|");
XmlNodeList nl = xd.SelectNodes("C1FlexGrid/Cells/Cell/Data");
string data = string.Empty;
foreach (XmlNode xn in nl)
{
RichTextBox rtb = new RichTextBox();
rtb.Rtf = xn.InnerText;
XmlAttribute xa = xn.ParentNode.Attributes.GetNamedItem("index") as XmlAttribute;
string[] rc = xa.InnerText.Split(',');
int r = int.Parse(rc[0]);
int c = int.Parse(rc[1]);
int index = r * cols + c;
datum[index] = "|" + (rtb.Text == "" ? "" : rtb.Rtf);
}
foreach (string s in datum)
data += s;
return data;
}
private string GetCellMergeString(XmlDocument xd)
{
if(xd.SelectSingleNode("C1FlexGrid/MergedRanges") == null)
return string.Empty;
return xd.SelectSingleNode("C1FlexGrid/MergedRanges").InnerXml;
}
private static GridCopyInfo _MyCopyInfo;
public static GridCopyInfo MyCopyInfo
{
get
{
if (_MyCopyInfo == null)
_MyCopyInfo = new GridCopyInfo();
return _MyCopyInfo;
}
}
private Color _DefaultCellBackgroundcolor;
public Color DefaultCellBackgroundcolor
{
get { return _DefaultCellBackgroundcolor; }
}
private Color _DefaultFixedBackgroundColor;
public Color DefaultFixedBackgroundColor
{
get { return _DefaultFixedBackgroundColor; }
}
public void CopyToCopiedFlexGrid(GridCopyOption myCopyOption)
{
MyCopyInfo.MyCopiedFlexGrid = new VlnFlexGrid(); //make a copy of the grid being copied
using (StringReader sr = new StringReader(this.GetXMLData()))
{
MyCopyInfo.MyCopiedFlexGrid.ReadXml(sr);
this.BorderStyle = C1.Win.C1FlexGrid.Util.BaseControls.BorderStyleEnum.None;
sr.Close();
}
MyCopyInfo.MyCopyOption = myCopyOption;
OnCopyOptionChanged(this, new EventArgs());
switch (MyCopyInfo.MyCopyOption)
{
case GridCopyOption.Row:
MyCopyInfo.MyCopiedCellRange = MyCopyInfo.MyCopiedFlexGrid.GetCellRange(Selection.r1, 0, Selection.r2, Cols.Count - 1);
break;
case GridCopyOption.Column:
MyCopyInfo.MyCopiedCellRange = MyCopyInfo.MyCopiedFlexGrid.GetCellRange(0, Selection.c1, Rows.Count - 1, Selection.c2);
break;
case GridCopyOption.Selection:
MyCopyInfo.MyCopiedCellRange = MyCopyInfo.MyCopiedFlexGrid.GetCellRange(Selection.r1, Selection.c1, Selection.r2, Selection.c2);
break;
default:
break;
}
}
public event VlnFlexGridEvent CopyOptionChanged;
public void OnCopyOptionChanged(object sender, EventArgs args)
{
if (CopyOptionChanged != null) CopyOptionChanged(sender, args);
}
[XmlElement("MyBorders")]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public string MyBorderDetailString
{
get
{
return MyBorders.ConvertToString();
}
set
{
if (value != null)
_MyBorders = VlnBorders.Get(value);
else
_MyBorders = null;
}
}
private VlnBorders _MyBorders;
[XmlIgnore]
public VlnBorders MyBorders
{
get
{
if (_MyBorders == null)
_MyBorders = new VlnBorders(GridLinePattern.Single, Rows.Count, Cols.Count);
return _MyBorders;
}
set { _MyBorders = value; }
}
private ItemInfo _MyItemInfo;
public ItemInfo GetMyItemInfo()
{
return _MyItemInfo;
}
//public ItemInfo MyItemInfo
//{
// get { return _MyItemInfo; }
// set { _MyItemInfo = value; }
//}
public void SetBorders(CellRange myRange,
GridLinePattern top, GridLinePattern middle, GridLinePattern bottom,
GridLinePattern left, GridLinePattern center, GridLinePattern right)
{
for (int r = myRange.r1; r <= myRange.r2; r++)
for (int c = myRange.c1; c <= myRange.c2; c++)
{
CellRange cr = GetMergedRange(r, c);
if (r == myRange.r1) // Top Border
if(top != GridLinePattern.Mixed) MyBorders.HorizontalLines[cr.r1, cr.c1]=top;
if (c == myRange.c1) // Left Border
if(left != GridLinePattern.Mixed) MyBorders.VerticalLines[cr.r1, cr.c1]=left;
if (r == myRange.r2) // Bottom Border
if(bottom != GridLinePattern.Mixed) MyBorders.HorizontalLines[cr.r2 + 1, cr.c2]=bottom;
if (c == myRange.c2) // Right Border
if(right != GridLinePattern.Mixed) MyBorders.VerticalLines[cr.r2, cr.c2 + 1] = right;
if (r == cr.r1 && c == cr.c1) // Look for inside lines
{
if (cr.r1 > myRange.r1 && cr.r1 <= myRange.r2) // Inside Horizontal Top
if (middle != GridLinePattern.Mixed)
{
MyBorders.HorizontalLines[cr.r1, cr.c1] = middle;
MyBorders.HorizontalLines[cr.r1, cr.c2] = middle;
}
if (cr.r2 > myRange.r1 && cr.r2 < myRange.r2) // Inside Horizontal Bottom
if(middle != GridLinePattern.Mixed) MyBorders.HorizontalLines[cr.r2 + 1, cr.c2]=middle;
if (cr.c1 > myRange.c1 && cr.c1 <= myRange.c2) // Inside Vertical Left
if (center != GridLinePattern.Mixed)
{
MyBorders.VerticalLines[cr.r1, cr.c1] = center;
MyBorders.VerticalLines[cr.r2, cr.c1] = center;
}
if (cr.c2 > myRange.c1 && cr.c2 < myRange.c2) // Inside Vertical Right
if(center != GridLinePattern.Mixed) MyBorders.VerticalLines[cr.r2, cr.c2 + 1]=center;
}
c = cr.c2;//Skip to the end of the merged cells
}
}
public void PasteBorders(int r, int c, int br, int bc)
{
MyBorders.HorizontalLines[r, c] = MyCopyInfo.MyCopiedFlexGrid.MyBorders.HorizontalLines[br,bc];
MyBorders.VerticalLines[r, c] = MyCopyInfo.MyCopiedFlexGrid.MyBorders.VerticalLines[br, bc];
MyBorders.HorizontalLines[r+1, c] = MyCopyInfo.MyCopiedFlexGrid.MyBorders.HorizontalLines[br+1, bc];
MyBorders.VerticalLines[r, c+1] = MyCopyInfo.MyCopiedFlexGrid.MyBorders.VerticalLines[br, bc+1];
}
[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;
}
public event VlnFlexGridkeyEvent EnterKeyPressed;
public void OnEnterKeyPressed(object sender, KeyEventArgs args)
{
if (EnterKeyPressed != null) EnterKeyPressed(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;
[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(ContentItem ci)
{
InitializeComponent();
SetupGrid(4, 3); // use a default row and column count
_MyItemInfo = ci.MyItem.MyItemInfo;
}
//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 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 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 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++)
{
using (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;
srtb.AdjustWidthForContent();
//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));
blankColSpace = Math.Min(blankColSpace, Math.Max(0, cellWidth - srtb.Width));
}
}
}
//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 bool _ReadingXml = false;
public bool ReadingXml
{
get { return _ReadingXml; }
}
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");
// To prevent scroll bars from being flashed on/off
// - save an image of the current grid
// - set Visible to false
// - draw the saved grid image
// - do the the load/reload of the grid
// - set Visible back to true.
System.Drawing.Image img = this.CreateImage();
Visible = false;
if (Parent is GridItem)
{
using (Graphics gr = (Parent as GridItem).CreateGraphics())
{
gr.DrawImage(img, Left, Top);
}
}
Clear();
MergedRanges.Clear();
_ReadingXml = true;
//Console.WriteLine("LoadGrid - Before ReadXML");
using (StringReader sr = new StringReader(str))
{
ReadXml(sr);
this.BorderStyle = C1.Win.C1FlexGrid.Util.BaseControls.BorderStyleEnum.None;
sr.Close();
}
//Console.WriteLine("LoadGrid - After ReadXML");
_ReadingXml = false;
Select(-1, -1); // this keeps the cell from being selected when the grid is first displayed
Visible = true;
}
private void SetupGrid(int numrows, int numcols) //C1FlexGrid NewGrid()
{
// setup the default size of each cell in the table/grid
this.Cols.DefaultSize = (int) DPI;
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;
_DefaultCellBackgroundcolor = this.StyleBackColor;
_DefaultFixedBackgroundColor = this.Styles.Fixed.BackColor;
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();
_SpellChecker = _tableCellEditor.SpellCheckerInstance;
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
this.MouseDown += new MouseEventHandler(VlnFlexGrid_MouseDown);
}
private bool _FirstEntry = false;
public bool FirstEntry
{
get { return _FirstEntry; }
set { _FirstEntry = value; }
}
void VlnFlexGrid_MouseDown(object sender, MouseEventArgs e)
{
int left = 0;
int top = 0;
int col = 0;
int row = 0;
int strow = Selection.r1;
int stcol = Selection.c1;
int erow = Selection.r2;
int ecol = Selection.c2;
while (e.X > left && col < Cols.Count)
{
left += Cols[col].Width > 0 ? Cols[col].Width : Cols.DefaultSize;
col++;
}
while (e.Y > top && row < Rows.Count)
{
top += Rows[row].Height > 0 ? Rows[row].Height : Rows.DefaultSize;
row++;
}
col--;
row--;
//Console.WriteLine("Mousedown Selection {0}", Selection);
//Console.WriteLine("Mousedown Row, Col [{0},{1}]", row, col);
erow = Math.Max(erow, row);
ecol = Math.Max(ecol, col);
if (_FirstEntry)
Select(row, col);
else
Select(strow, stcol, erow, ecol);
_FirstEntry = false;
}
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)
{
int newHeight = Hadj + ((Rows[Row].Height < 0) ? Rows.DefaultSize : Rows[Row].Height);
//Rows[Row].Height += Hadj;//= curHeight;
Rows[Row].Height = newHeight;
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;
if (IsRoTable) Select(Rows.Count - 1, Cols.Count - 1);
_tableCellEditor.StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlRight : E_ArrowKeys.Right);
e.Handled = true;
break;
case Keys.Down:
if (e.Shift) return;
if (IsRoTable) Select(Rows.Count - 1, 0);
_tableCellEditor.StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlDown : E_ArrowKeys.Down);
e.Handled = true;
break;
case Keys.Enter:
//if (e.Shift) return;
//Select(Rows.Count - 1, 0);
//_tableCellEditor.StepRTB_ArrowPressed(E_ArrowKeys.Down);
//e.Handled = true;
if (!e.Control && !e.Shift && !e.Alt)
{
OnEnterKeyPressed(sender, e);
}
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;
}
// it does, so draw background
e.DrawCell(DrawCellFlags.Background);
if (rtfText.StartsWith(@"{\rtf"))
{
// Please add a comment if this value needs to be changed
_rtf.Rtf = rtfText;
// draw the RTF text
if (e.Bounds.Width > 0 && e.Bounds.Height > 0)
{
_rtf.Width = e.Bounds.Width - 1; // This has also been -3 which matchs the rener command
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));
}
}
else
_rtf.Text = rtfText;
// spell check unless (we're just measuring)
if (!e.Measuring)
{
CharRangeList errors = SpellChecker.CheckText(_rtf.Text);//(text);
// underline errors
if (errors.Count > 0)
{
CharacterRange[] ranges = new CharacterRange[1];
ranges[0] = new CharacterRange(0, 1);
Pen pn = new Pen(Color.Green, 2);
StringFormat sf = new StringFormat(e.Style.StringFormat);
sf.SetMeasurableCharacterRanges(ranges);
Rectangle rc = e.Style.GetTextRectangle(e.Bounds, null);
Region[] rgns = e.Graphics.MeasureCharacterRanges(_rtf.Text, e.Style.Font, rc, sf);//(text, e.Style.Font, rc, sf);
float btm = rgns[0].GetBounds(e.Graphics).Bottom;
float top = rgns[0].GetBounds(e.Graphics).Top;
int adj = (int)(btm - top);
for (int i = 0; i < errors.Count; i++)
{
// The positioning of the the squigle line does not account for mixed font sizes
// should we support having mixed fonts in the table cells, we will need to add
// logic to support it.
Point ptStart = _rtf.GetPositionFromCharIndex(errors[i].Start);
Point ptEnd = _rtf.GetPositionFromCharIndex(errors[i].Start + errors[i].Length);
SquigleLine(e.Graphics, e.Bounds.Left + ptStart.X, e.Bounds.Top + ptStart.Y + adj, e.Bounds.Left + ptEnd.X);
}
}
}
// and draw border last
//e.DrawCell(DrawCellFlags.Border);
// This can be used to draw more specific borders
DrawCellBorder(e);
// we're done with this cell
e.Handled = true;
}
}
private void SquigleLine(Graphics graphics, int x1, int y1, int x2)
{
for (Point pt = new Point(x1, y1); pt.X + 2 < x2; pt.X += 4)
{
//Console.WriteLine("squiggle point {0}", pt);
graphics.DrawLines(Pens.Red, new Point[]
{
new Point(pt.X, pt.Y),
new Point(pt.X + 2, pt.Y - 2),
new Point(pt.X + 4, pt.Y)
});
}
}
private static Color _BorderColor = Color.Black;
public static Color BorderColor
{
get { return VlnFlexGrid._BorderColor; }
set { VlnFlexGrid._BorderColor = value; }
}
private void DrawCellBorder(C1.Win.C1FlexGrid.OwnerDrawCellEventArgs e)
{
Graphics grGrid =e.Graphics;
Rectangle bounds = e.Bounds;
int row = e.Row;
int col = e.Col;
CellRange cr = GetMergedRange(row, col);
GridLinePattern topSide = MyBorders.HorizontalLines[cr.r1,cr.c1];
GridLinePattern rightOfTopSide = cr.c2 == Cols.Count - 1 ? GridLinePattern.None : MyBorders.HorizontalLines[cr.r1, cr.c2 + 1];
GridLinePattern leftOfTopSide = cr.c1 == 0? GridLinePattern.None : MyBorders.HorizontalLines[cr.r1, cr.c1 - 1];
GridLinePattern leftSide = MyBorders.VerticalLines[cr.r1, cr.c1];
GridLinePattern aboveLeftSide = cr.r1 == 0 ? GridLinePattern.None : MyBorders.VerticalLines[cr.r1 - 1, cr.c1];
GridLinePattern belowLeftSide = cr.r2 == Rows.Count - 1 ? GridLinePattern.None : MyBorders.VerticalLines[cr.r2 + 1, cr.c1];
GridLinePattern bottomSide = MyBorders.HorizontalLines[cr.r2+1, cr.c2];
GridLinePattern rightOfBottomSide = cr.c2 == Cols.Count - 1 ? GridLinePattern.None : MyBorders.HorizontalLines[cr.r2 + 1, cr.c2 + 1];
GridLinePattern rightSide = MyBorders.VerticalLines[cr.r2, cr.c2+1];
GridLinePattern belowRightSide = cr.r2 == Rows.Count - 1 ? GridLinePattern.None : MyBorders.VerticalLines[cr.r2 + 1, cr.c2 + 1];
GridLinePattern none = GridLinePattern.None;
int x1 = bounds.Left;
int y1 = bounds.Top;
int x2 = bounds.Right - 1;
int y2 = bounds.Bottom - 1;
GridItem myGridItem = Parent as GridItem;
Panel myPanel = Parent as Panel;
if (myGridItem == null && myPanel == null) return;
if (row == 0 || col == 0) // Top or Left Edge - Draw on parent
{
using (Graphics grParent = myGridItem != null ? myGridItem.CreateGraphics() : myPanel.CreateGraphics())
{
if (row == 0)
{
if (col == 0)
{
// Draw the top left intersection
DrawIntersection(grParent, Left - 3, Top-1, none, topSide,leftSide, none);
}
// Draw the top right intersection
DrawIntersection(grParent, Left +x2 - 2, Top-1, none, rightOfTopSide,rightSide,topSide);
// Draw the top side on the parent
DrawLine(grParent, topSide, Left + x1, Top + y1 - 1, Left + x2-3, Top + y1 -1);
}
if (col == 0)
{
// Draw the bottom left intersection
DrawIntersection(grParent, Left -3, Top + y2, leftSide,bottomSide,belowLeftSide,none);
// Draw the left side
DrawLine(grParent, leftSide, Left + x1 - 1, Top + y1, Left + x1 - 1, Top + y2-3);
}
}
}
// Draw the bottom right intersection
DrawIntersection(grGrid, x2 - 2, y2, rightSide, rightOfBottomSide, belowRightSide, bottomSide);
// Draw the bottom side
DrawLine(grGrid, bottomSide, x1, y2, x2-3, y2);
// Draw the right side
DrawLine(grGrid, rightSide, x2, y1, x2, y2-3);
}
private static void DrawLine(Graphics gr, GridLinePattern pattern, int x1, int y1, int x2, int y2)
{
if (pattern == GridLinePattern.None) return;
Pen pn = VlnBorders.LinePen(pattern, BorderColor);
DrawLine(gr, pn, pattern, x1, y1, x2, y2);
}
private static void DrawLine(Graphics gr, Pen pn, int x1, int y1, int x2, int y2)
{
DrawLine(gr, pn, GridLinePattern.Single, x1, y1, x2, y2);
}
private static void DrawLine(Graphics gr, Pen pn, GridLinePattern pattern, int x1, int y1, int x2, int y2)
{
int dx = 0;
int dy = 0;
int dblx = 0;
int dbly = 0;
int xThick = 0;
int yThick = 0;
if (x1 == x2) // Vertical Line
{
dx = (int) (-pn.Width / 2);
dblx = -2;
if (pn.Width > 2)
yThick = 1;
}
else // Horizontal Line
{
dy = (int) (-pn.Width / 2);
dbly = -2;
if (pn.Width > 2)
xThick = 1;
}
gr.DrawLine(pn, x1 + dx, y1 + dy, x2 + dx + xThick, y2 + dy + yThick);
if(pattern == GridLinePattern.Double)
gr.DrawLine(pn, x1 + dx +dblx, y1 + dy + dbly, x2 + dx+dblx, y2 + dy+dbly);
}
private static void DrawIntersection(Graphics gr, int x, int y, GridLinePattern up, GridLinePattern right, GridLinePattern down, GridLinePattern left)
{
if (up == GridLinePattern.Double)
if (right == GridLinePattern.Double)
if (down == GridLinePattern.Double)
if (left == GridLinePattern.Double) DrawIntersectionAllDoubles(gr, x, y);
else DrawDrawIntersection3Doubles_URD(gr, x, y);
else // Down is not double
if (left == GridLinePattern.Double) DrawDrawIntersection3Doubles_URL(gr, x, y);
else DrawDrawIntersection2Doubles_UR(gr, x, y, down, left);
else // right is not double
if (down == GridLinePattern.Double)
if (left == GridLinePattern.Double) DrawDrawIntersection3Doubles_UDL(gr, x, y);
else DrawDrawIntersection2Doubles_UD(gr, x, y, right, left);
else // Down is not double
if (left == GridLinePattern.Double) DrawIntersection2Doubles_UL(gr, x, y, right, down);
else DrawIntersectionOneDoubleOrLess(gr, x, y, up, right, down, left);
else
if (right == GridLinePattern.Double)
if (down == GridLinePattern.Double)
if (left == GridLinePattern.Double) DrawDrawIntersection3Doubles_RDL(gr, x, y);
else DrawDrawIntersection2Doubles_RD(gr, x, y, up, left);
else // Down is not double
if (left == GridLinePattern.Double) DrawDrawIntersection2Doubles_RL(gr, x, y, up, down);
else DrawIntersectionOneDoubleOrLess(gr, x, y, up, right, down, left);
else
if (down == GridLinePattern.Double)
if (left == GridLinePattern.Double) DrawDrawIntersection2Doubles_DL(gr, x, y, up, right);
else DrawIntersectionOneDoubleOrLess(gr, x, y, up, right, down, left);
else // These both use the same function with the same parameters
if (left == GridLinePattern.Double) DrawIntersectionOneDoubleOrLess(gr, x, y, up, right, down, left);
else DrawIntersectionOneDoubleOrLess(gr, x, y, up, right, down, left);
}
private static Pen pnDouble = VlnBorders.LinePen(GridLinePattern.Double, BorderColor);
private static Pen pnThick = VlnBorders.LinePen(GridLinePattern.Thick, BorderColor);
private static void DrawIntersectionAllDoubles(Graphics gr, int x, int y)
{
DrawLine(gr, pnDouble, x-1, y, x, y);
DrawLine(gr, pnDouble, x, y - 2, x, y - 3);
DrawLine(gr, pnDouble, x + 2, y - 2, x + 3, y - 2);
DrawLine(gr, pnDouble, x + 2, y, x + 2, y + 1);
}
private static void DrawDrawIntersection3Doubles_URD(Graphics gr, int x, int y)
{
DrawLine(gr, pnDouble, x , y, x, y - 3);
DrawLine(gr, pnDouble, x + 2, y - 2, x + 3, y - 2);
DrawLine(gr, pnDouble, x + 2, y, x + 2, y + 1);
}
private static void DrawDrawIntersection3Doubles_URL(Graphics gr, int x, int y)
{
DrawLine(gr, pnDouble, x, y, x + 2, y);
DrawLine(gr, pnDouble, x -1, y - 2, x , y - 2);
DrawLine(gr, pnDouble, x + 2, y - 2, x + 3, y - 2);
}
private static void DrawDrawIntersection3Doubles_UDL(Graphics gr, int x, int y)
{
DrawLine(gr, pnDouble, x-1, y, x, y);
DrawLine(gr, pnDouble, x , y - 2, x , y - 3);
DrawLine(gr, pnDouble, x + 2, y-3, x + 2, y);
}
private static void DrawDrawIntersection3Doubles_RDL(Graphics gr, int x, int y)
{
DrawLine(gr, pnDouble, x-1, y, x, y);
DrawLine(gr, pnDouble, x, y - 2, x + 2, y - 2);
DrawLine(gr, pnDouble, x + 2, y, x + 2, y + 1);
}
private static void DrawDrawIntersection2Doubles_UR(Graphics gr, int x, int y, GridLinePattern lp1, GridLinePattern lp2)
{
if (lp1 == GridLinePattern.Thick && lp2 == GridLinePattern.Thick)
DrawLine(gr, pnThick, x, y, x + 3, y);
else
{
DrawLine(gr, pnDouble, x, y, x + 2, y);
DrawLine(gr, pnDouble, x , y, x , y - 2);
DrawLine(gr, pnDouble, x + 2, y - 2, x + 3, y - 2);
}
}
private static void DrawDrawIntersection2Doubles_UD(Graphics gr, int x, int y, GridLinePattern lp1, GridLinePattern lp2)
{
if (lp1 == GridLinePattern.Thick && lp2 == GridLinePattern.Thick)
DrawLine(gr, pnThick, x, y, x + 3, y);
else
{
DrawLine(gr, pnDouble, x, y, x, y - 2);
DrawLine(gr, pnDouble, x + 2, y, x + 2, y - 2);
}
}
private static void DrawIntersection2Doubles_UL(Graphics gr, int x, int y, GridLinePattern lp1, GridLinePattern lp2)
{
if (lp1 == GridLinePattern.Thick && lp2 == GridLinePattern.Thick)
DrawLine(gr, pnThick, x, y, x + 3, y);
else
{
DrawLine(gr, pnDouble, x, y, x + 2, y);
DrawLine(gr, pnDouble, x , y - 2, x, y - 3);
DrawLine(gr, pnDouble, x + 2, y, x + 2, y - 2);
}
}
private static void DrawDrawIntersection2Doubles_RD(Graphics gr, int x, int y, GridLinePattern lp1, GridLinePattern lp2)
{
if (lp1 == GridLinePattern.Thick && lp2 == GridLinePattern.Thick)
DrawLine(gr, pnThick, x, y, x + 3, y);
else
{
DrawLine(gr, pnDouble, x, y, x, y - 2);
DrawLine(gr, pnDouble, x, y - 2, x + 2, y - 2);
DrawLine(gr, pnDouble, x + 2, y, x + 2, y + 1);
}
}
private static void DrawDrawIntersection2Doubles_RL(Graphics gr, int x, int y, GridLinePattern lp1, GridLinePattern lp2)
{
if (lp1 == GridLinePattern.Thick && lp2 == GridLinePattern.Thick)
DrawLine(gr, pnThick, x, y, x + 2, y);
else
{
DrawLine(gr, pnDouble, x, y, x + 2, y);
DrawLine(gr, pnDouble, x, y - 2, x + 2, y - 2);
}
}
private static void DrawDrawIntersection2Doubles_DL(Graphics gr, int x, int y, GridLinePattern lp1, GridLinePattern lp2)
{
if (lp1 == GridLinePattern.Thick && lp2 == GridLinePattern.Thick)
DrawLine(gr, pnThick, x, y, x + 2, y);
else
{
DrawLine(gr, pnDouble, x-1, y, x, y);
DrawLine(gr, pnDouble, x, y - 2, x + 2, y - 2);
DrawLine(gr, pnDouble, x + 2, y, x + 2, y - 2);
}
}
private static void DrawIntersectionOneDoubleOrLess(Graphics gr, int x, int y,
GridLinePattern up, GridLinePattern right, GridLinePattern down, GridLinePattern left)
{
Pen pnUp = VlnBorders.LinePen(up, BorderColor);
Pen pnLeft = VlnBorders.LinePen(left, BorderColor);
int widthUpDown = Math.Max(VlnBorders.LineWidth0(up), VlnBorders.LineWidth0(down));
int heightLeftRight = Math.Max(VlnBorders.LineWidth0(left), VlnBorders.LineWidth0(right));
if (heightLeftRight > 0 && widthUpDown > 0)
{
Pen pn = new Pen(BorderColor, widthUpDown);
if(heightLeftRight > 1)
DrawLine(gr, pn, x + 2, y + 1 - heightLeftRight, x + 2, y);
else if(up == GridLinePattern.None) // Work around to set a pixel (actually set two)
DrawLine(gr, pn, x + 2, y, x + 2, y + 1);
}
if (left != GridLinePattern.None)
{
DrawLine(gr, pnLeft, x, y, x + 2 - widthUpDown, y);
if (left == GridLinePattern.Double)
DrawLine(gr, pnLeft, x, y - 2, x + 2 - widthUpDown, y - 2);
}
if (up != GridLinePattern.None)
{
DrawLine(gr, pnUp, x + 2, y - 3 , x + 2, y +1 - heightLeftRight);
if (up == GridLinePattern.Double)
DrawLine(gr, pnUp, x, y - 3, x, y +1 - heightLeftRight);
}
}
#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;
using (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)
{
using (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
/// <summary>
/// Adjust the grid control size based on the cell sizes.
/// </summary>
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);
}
}
public void ConvertTextCellToRTF(int r, int c)
{
using (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)
{
using (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 int TotalColWidths()
{
int cwid = 0;
foreach (Column c in Cols)
{
cwid += ((c.Width > 0) ? c.Width : Cols.DefaultSize);
}
return cwid;
}
/// <summary>
/// This will adjust the column widths of the current table based upon the page width
/// Note: This is for use in creating a new table - not to process an existing table.
/// </summary>
/// <param name="pgWidthPoints"></param>
public void FitTableToPageWidth(int pgWidthPoints)
{
int grdWidth = TotalColWidths();
int pgwidth = (int)((pgWidthPoints / 72) * this._DPI);
if (grdWidth > pgwidth)
{
int difWid = grdWidth - pgwidth;
int colAdj = (difWid / Cols.Count) +(((difWid % Cols.Count) > 0) ? 1 : 0);
foreach (Column c in Cols)
{
int cwid = (c.Width > 0) ? c.Width : Cols.DefaultSize;
if ((cwid - colAdj) > 0)
c.Width = cwid - colAdj;
}
}
}
//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;
// }
// }
// }
//}
#region DEBUG
//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);
//}
#endregion
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);
}
TrimColumnWidths();
RemoveBlankSpaceFromRows();
SetupCellUserData();
this.AdjustGridControlSize();
}
public void FixTableCellsHeightWidth()
{
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 void TrimColumnWidths()
{
for (int c = 0; c < Cols.Count; c++)
{
Select(0, c);
int newColWidth = MinColWidth();
Cols[c].Width = newColWidth;
}
}
private int MinColWidth()
{
int curColWidth = 0;
for (int r = 0; r < Rows.Count; r++)
{
CellRange cr = GetMergedRange(r, Col);
// find the needed cell width
if (Col == cr.c1)
{
using (StepRTB srtb = new StepRTB())
{
srtb.Rtf = GetCellRTFString(cr.r1, cr.c1);
srtb.AdjustWidthForContent();
curColWidth = Math.Max(curColWidth, srtb.Width + 3);
}
}
}
return curColWidth;
}
//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)
{
string rtn = str;
//ShowRawString(str, "ConvertTableText IN");
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");
//ShowRawString(rtn, "ConvertTableText OUT");
return rtn;
}
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
_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)
{
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;
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"))
{
using (StepRTB _rtf = new StepRTB())
{
_rtf.Width = Cols[c].Width;
_rtf.Rtf = rtfText;
CellRange cr = GetCellRange(r, c);
cr.UserData = _rtf.ContentsRectangle.Height;
}
}
}
}
#endregion //Cell Text
#region Merged / Split Range
public void MergeSelection()
{
this.MergedRanges.Add(this.Selection,true);
this.Invalidate();
this.Select(Selection.r1, Selection.c1);
}
public bool IsInMergeRange()
{
C1.Win.C1FlexGrid.CellRange sel = GetMergedRange(this.Selection.r1, this.Selection.c1);
return MergedRanges.Contains(sel);
}
public void SplitSelection(bool bSplitCols)
{
//Console.WriteLine("SplitSelection this.selection {0}", this.Selection);
//Debug_WritelineMySelection();
//C1.Win.C1FlexGrid.CellRange sel = this.GetMergedRange(this.Selection.r1, this.Selection.c1);
//Console.WriteLine("SplitSelection myselection {0}", MySelection);
//foreach (CellRange sel in MySelection)
//{
// //Console.WriteLine("SplitSelection foreach sel {0}", sel);
// if (sel.IsSingleCell)
// this.MergedRanges.Remove(sel);
// if (!(this.MergedRanges.Contains(sel)) && !didit)
// if (bSplitCols)
// SplitSelectionColumns();
// else
// SplitSelectionRows();
// didit = true;
//}
if (bSplitCols)
SplitSelectionColumns();
else
SplitSelectionRows();
//Debug_WritelineMySelection();
//foreach (CellRange sel in MySelection)
//{
// //Console.WriteLine("SplitSelection foreach sel {0}", sel);
// if (this.MergedRanges.Contains(sel))
// SplitMergedRange(sel, bSplitCols);
//}
//this.Refresh();
//RefreshMergeRangeCollection();
this.AdjustGridControlSize();
}
private void SplitMergedRange(CellRange sel, bool bSplitCols)
{
int sR = sel.r1;
int eR = sel.r2;
int sC = sel.c1;
int eC = sel.c2;
if (bSplitCols && (IsMergedCols(sel) && !IsMergedRows(sel)) ||
(!bSplitCols && (IsMergedRows(sel) && !IsMergedCols(sel))))
MergedRanges.Remove(sel);
else
{
CellRange saveSelection = Selection;
if (bSplitCols && IsMergedRows(sel))
{
MergedRanges.Remove(sel);
for (int c = sC; c <= eC; c++)
{
Select(sR, c, eR, c);
MergeSelection();
}
}
else if (!bSplitCols && IsMergedCols(sel))
{
MergedRanges.Remove(sel);
for (int r = sR; r <= eR; r++)
{
Select(r, sC, r, eC);
MergeSelection();
}
}
Select(saveSelection);
}
}
private bool IsMergedRows(CellRange sel)
{
return (sel.r1 != sel.r2);
}
private bool IsMergedCols(CellRange sel)
{
return (sel.c1 != sel.c2);
}
private void SplitSelectionColumns()
{
bool hasNonMergedColumn = false;
//Console.WriteLine("SplitSelectionColumns this.selection {0}", this.Selection);
//Debug_WritelineMySelection();
CellRange cr = this.Selection;
int numSelCols = (cr.c2 - cr.c1) + 1;
foreach (CellRange sel in MySelection)
{
if (!this.MergedRanges.Contains(sel))
hasNonMergedColumn = true;
else
{
CellRange mr = GetMergedRange(sel.r1, sel.c1);
if (mr.c1 == mr.c2)
hasNonMergedColumn = true;
}
}
// for each column in the selection, add a new column
if (hasNonMergedColumn)
{
for (int c = cr.c2; c >= cr.c1; c--)
{
Select(cr.r1, c, cr.r2, c);
InsertColumnAfter();
}
}
// include new columns in selection
this.Select(cr.r1, cr.c1, cr.r2, cr.c2 + ((hasNonMergedColumn) ? numSelCols : 0));
//if a merged range is part of the selectin, try to split it
foreach (CellRange sel in MySelection)
{
//Console.WriteLine("SplitSelection foreach sel {0}", sel);
if (this.MergedRanges.Contains(sel))
SplitMergedRange(sel, true);
}
cr = this.Selection;
if (hasNonMergedColumn)
{
for (int r = 0; r < this.Rows.Count; r++)
for (int c = cr.c1; c <= cr.c2; c += 2)
{
if (!this.IsCellSelected(r, c))
{
CellRange crTmp = GetMergedRange(r, c);
if (crTmp.IsSingleCell)
{
CellRange tcr = this.GetCellRange(r, c, r, c + 1);
this.MergedRanges.Add(tcr);
this.Invalidate();
}
//CellRange tcr = this.GetCellRange(r, c, r, c + 1);
//this.MergedRanges.Add(tcr);
}
}
// Adjust selected column widths
for (int c = cr.c1; c <= cr.c2; c++)
{
int recWidth = (Cols[c].Width < 0) ? Cols.DefaultSize : Cols[c].Width; // this.GetCellRect(cr.r1, c).Width;
int newWidth = Math.Max(recWidth / 2, _minColSplitWidth);
this.Cols[c].Width = newWidth;
//Console.WriteLine("Cell[{0},{1}].Width = {2}", cr.r1, c, recWidth);
//Console.WriteLine("Cell[{0},{1}].NewWidth = {2}", cr.r1, c, newWidth);
}
}
}
private void SplitSelectionRows()
{
bool hasNonMergedRow = false;
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);
foreach (CellRange sel in MySelection)
{
if (!this.MergedRanges.Contains(sel))
hasNonMergedRow = true;
else
{
CellRange mr = GetMergedRange(sel.r1, sel.c1);
if (mr.r1 == mr.r2)
hasNonMergedRow = true;
}
}
// for each row in the selection, add a new row
if (hasNonMergedRow)
{
for (int r = cr.r2; r >= cr.r1; r--)
{
//Console.WriteLine("Inserted new Row at [{0},{1}]", r, cr.c1);
Select(r, cr.c1, r, cr.c2);
InsertRowAfter();
}
}
// include new rows in selection
this.Select(cr.r1, cr.c1, cr.r2 + numSelRows, cr.c2);
//if a merged range is part of the selectin, try to split it
foreach (CellRange sel in MySelection)
{
//Console.WriteLine("SplitSelection foreach sel {0}", sel);
if (this.MergedRanges.Contains(sel))
SplitMergedRange(sel, false);
}
cr = this.Selection;
//Console.WriteLine(" After Insert [{0},{1}] - [{2},{3}]", cr.r1, cr.c1, cr.r2, cr.c2);
if (hasNonMergedRow)
{
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 crTmp = GetMergedRange(r, c);
if (crTmp.IsSingleCell)
{
CellRange tcr = this.GetCellRange(r, c, r + 1, c);
this.MergedRanges.Add(tcr);
this.Invalidate();
}
}
}
// 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)
{
AdjustMergedRows(row, 1, above, removing);
}
private void AdjustMergedRows(int row, int cnt, 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 -= cnt;
crc.Add(cr);
}
}
else
{
if (row <= r.r1)
{
if (row < r.r1)
cr.r1 -= cnt;
cr.r2 -= cnt;
}
crc.Add(cr);
}
}
}
else // adding
foreach (CellRange r in this.MergedRanges)
{
CellRange cr = r;
int inspos = (above) ? row : row - 1;
if (r.ContainsRow(inspos))
{
bool adjustMergeValues = true;
if (cr.r1 == row && cr.r2 == row + cnt -1)
adjustMergeValues = false; // don't add to existing merge range - we will add a new merge range for this copy
for (int insCnt = 0; insCnt < cnt; insCnt++)
{
if ((above && cr.r1 == inspos) || (!above && cr.r2 == inspos))
{
string tstr = "";
int newrow = 0;
if (above)
{
if (this[cr.r1 + cnt, cr.c1] != null)
tstr = this[cr.r1 + cnt, cr.c1].ToString();
newrow = cr.r1;
}
else
{
if (this[cr.r2, cr.c1] != null)
tstr = this[cr.r2, cr.c1].ToString();
newrow = cr.r2 + cnt;
}
if (tstr != null && tstr.Length > 0)
for (int x = cr.c1; x <= cr.c2; x++)
this[newrow, x] = tstr;
}
if (adjustMergeValues) cr.r2++;
}
}
else
{
if (inspos < cr.r1)
{
cr.r1 += cnt;
cr.r2 += cnt;
}
}
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)
{
AdjustMergedColumns(col, 1, left, removing); //adjusting for just one column
}
private void AdjustMergedColumns(int col, int cnt, 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 -= cnt;
crc.Add(cr);
}
}
else
{
if (col < cr.c1)
{
cr.c1-=cnt;
cr.c2-=cnt; }
crc.Add(cr);
}
}
}
else // adding
foreach (CellRange r in this.MergedRanges)
{
CellRange cr = r;
int inspos = (left) ? col : col - 1;
if (r.ContainsCol(inspos))
{
for (int insCnt = 0; insCnt < cnt; insCnt++)
{
string tstr = "";
int newcol = 0;
if (left)
{
if (inspos == cr.c1)
tstr = (this[cr.r1, cr.c1 + 1] == null) ? "" : this[cr.r1, cr.c1 + 1].ToString();
else
tstr = (this[cr.r1, cr.c1] == null) ? "" : 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+=cnt;
cr.c2+=cnt;
}
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;
MyBorders.InsertColumn(newcol);
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);
MyBorders.InsertColumn(colidx);
// 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;
MyBorders.InsertRow(newrow);
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;
MyBorders.InsertRow(rowidx + 1);
this.AdjustMergedRows(rowidx + 1, false, false);
this.AdjustGridControlSize();
}
public bool AllRowsSelected()
{
int maxrow = Selection.r2;
foreach (CellRange cr in MySelection)
maxrow = Math.Max(maxrow, cr.r2);
return (Selection.r1 == 0 && maxrow == Rows.Count - 1);
}
public bool AllColumnsSelected()
{
int maxcol = Selection.c2;
foreach (CellRange cr in MySelection)
maxcol = Math.Max(maxcol, cr.c2);
return (Selection.c1 == 0 && maxcol == Cols.Count - 1);
}
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;
//}
}
MyBorders.DeleteRows(strow, cnt);
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;
//}
}
MyBorders.DeleteColumns(stcol, cnt);
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 Copy/Paste
public void CopyRow()
{
DialogResult dr = DialogResult.Yes;
SelectRow();
if (Selection.r1 != Selection.r2)
{
//dr = MessageBox.Show("You selected a row that includes merged cells.\n\nThese additional rows must be included.\n\nCopy these rows?", "Copy Rows", MessageBoxButtons.YesNo);
dr = MessageBox.Show("Your selection was expanded due to merged cell regions.\n\nContinue with the copy?", "Copy Rows", MessageBoxButtons.YesNo);
}
if (dr == DialogResult.Yes)
CopyToCopiedFlexGrid(GridCopyOption.Row);
}
public void CopyColumn()
{
SelectCol();
DialogResult dr = DialogResult.Yes;
if (Selection.c1 != Selection.c2)
{
//dr = MessageBox.Show("You selected a column that includes merged cells.\n\nThese additional columns must be included.\n\nCopy these columns?", "Copy Columns", MessageBoxButtons.YesNo);
dr = MessageBox.Show("Your selection was expanded due to merged cell regions.\n\nContinue with the copy?", "Copy Columns", MessageBoxButtons.YesNo);
}
if (dr == DialogResult.Yes)
CopyToCopiedFlexGrid(GridCopyOption.Column);
}
public void CopyCellSelection()
{
DialogResult dr = DialogResult.Yes;
CellRange cr = Selection;
MakeSelectionEven();
if (!cr.Equals(Selection))
{
dr = MessageBox.Show("Your selection was expanded due to merged cell regions.\n\nContinue with the copy?", "Copy Selection", MessageBoxButtons.YesNo);
}
if (dr == DialogResult.Yes)
CopyToCopiedFlexGrid(GridCopyOption.Selection);
}
public enum enmPastePos : int
{
Before = 1, Replace = 0, After = -1
}
public void PasteRows(enmPastePos pp)
{
if (MyCopyInfo.MyCopiedFlexGrid == null || MyCopyInfo.MyCopyOption != GridCopyOption.Row) return;
int rowsToAdd = MyCopyInfo.MyCopiedCellRange.r2 - MyCopyInfo.MyCopiedCellRange.r1 + 1;
int colsToAdd = Math.Max((MyCopyInfo.MyCopiedCellRange.c2 - MyCopyInfo.MyCopiedCellRange.c1 + 1) - Cols.Count, 0);
int selR1 = Selection.r1;
int selR2 = Selection.r2;
int rowOffset = selR1 + (pp == enmPastePos.After ?(selR2-selR1)+1 : 0) - MyCopyInfo.MyCopiedCellRange.r1;
// If the rows we are copying has more columns than the current table, then append then needed columns to the grid
if (colsToAdd > 0)
{
Cols.Add(colsToAdd);
AdjustMergedColumns(Cols.Count - 1, colsToAdd, false, false);
MyBorders.InsertColumns(Cols.Count - colsToAdd - 1, colsToAdd);
}
switch (pp)
{
case enmPastePos.Before:
this.Rows.InsertRange(selR1, rowsToAdd);
AdjustMergedRows(selR1, rowsToAdd, true, false);
MyBorders.InsertRows(Rows.Count - rowsToAdd - 1, rowsToAdd);
break;
case enmPastePos.After:
if (selR2+1 < Rows.Count - 1)
{
this.Rows.InsertRange(selR2 + 1, rowsToAdd);
AdjustMergedRows(selR1+1, rowsToAdd, false, false);
}
else
this.Rows.Add(rowsToAdd);
MyBorders.InsertRows(Rows.Count - rowsToAdd - 1, rowsToAdd);
break;
case enmPastePos.Replace:
if (rowsToAdd > Rows.Count - Selection.r1)
{
int numToAdd = rowsToAdd - (Rows.Count = selR1);
this.Rows.Add(numToAdd);
AdjustMergedRows(selR1, numToAdd, false, false);
}
break;
}
RemoveMergedRanges(MyCopyInfo.MyCopiedCellRange.r1 + rowOffset, MyCopyInfo.MyCopiedCellRange.c1, MyCopyInfo.MyCopiedCellRange.r2 + rowOffset, MyCopyInfo.MyCopiedCellRange.c2);
for (int r = MyCopyInfo.MyCopiedCellRange.r1; r <= MyCopyInfo.MyCopiedCellRange.r2; r++)
{
Rows[r + rowOffset].Height = MyCopyInfo.MyCopiedFlexGrid.Rows[r].Height;
for (int c = MyCopyInfo.MyCopiedCellRange.c1; c <= Math.Min(MyCopyInfo.MyCopiedCellRange.c2 + colsToAdd, Cols.Count - 1); c++)
{
CellRange crm = MyCopyInfo.MyCopiedFlexGrid.GetMergedRange(r, c);
if (r == crm.r1 && c == crm.c1)
{
Cols[c].Width = Math.Max(Cols[c].Width, MyCopyInfo.MyCopiedFlexGrid.Cols[c].Width);
CellRange cr = GetCellRange(crm.r1 + rowOffset, crm.c1, crm.r2 + rowOffset, crm.c2);
// if the paste is above - copy merge range for the destination
// if the paste is below - put back the range for the source location
if ((crm.r2 > crm.r1) || (crm.c2 > crm.c1))
MergedRanges.Add(cr);
this[r + rowOffset, c] = MyCopyInfo.MyCopiedFlexGrid[r, c];
MatchStyle(crm, cr);
PasteBorders(r + rowOffset, c, r, c);
// if the paste is above - put back the range for the source location
// if the paste is below - copy merge range for the destination
int r1 = crm.r1 + rowsToAdd - rowOffset;
int r2 = crm.r2 + rowsToAdd - rowOffset;
CellRange ncr = GetCellRange(r1, crm.c1, r2, crm.c2);
if ((crm.r2 > crm.r1) || (crm.c2 > crm.c1))
MergedRanges.Add(ncr);
}
}
}
this.AdjustGridControlSize();
CopyToCopiedFlexGrid(MyCopyInfo.MyCopyOption);
}
private void MatchStyle(CellRange crm, CellRange cr)
{
if (crm.Style != null)
{
ChangeCellAlign(cr, crm.Style.TextAlign);
ChangeCellBorder(cr, crm.Style.Border.Style);
}
//else
//{
// cr.Style = null; // - didn't like the null
//}
}
private void RemoveMergedRanges(int r1, int c1, int r2, int c2)
{
for (int r = r1; r <= r2; r++)
for (int c = c1; c <= c2; c++)
{
CellRange cr = GetMergedRange(r, c);
if (cr.r1 < cr.r2 || cr.c1 < cr.c2)
MergedRanges.Remove(cr);
}
}
public void PasteColumns(enmPastePos pp)
{
if (MyCopyInfo.MyCopiedFlexGrid == null || MyCopyInfo.MyCopyOption != GridCopyOption.Column) return;
int colsToAdd = MyCopyInfo.MyCopiedCellRange.c2 - MyCopyInfo.MyCopiedCellRange.c1 + 1;
int rowsToAdd = Math.Max((MyCopyInfo.MyCopiedCellRange.r2 - MyCopyInfo.MyCopiedCellRange.r1 + 1) - Rows.Count, 0);
int selC1 = Selection.c1;
int selC2 = Selection.c2;
int colOffset = selC1 + (pp == enmPastePos.After ? (selC2-selC1)+1 : 0) - MyCopyInfo.MyCopiedCellRange.c1;
// If the columns we are copying has more rows than the current table, then append the needed rows to the grid
if (rowsToAdd > 0)
{
Rows.Add(rowsToAdd);
AdjustMergedRows(Rows.Count, false, false);
MyBorders.InsertRows(Rows.Count - rowsToAdd - 1,rowsToAdd);
}
switch (pp)
{
case enmPastePos.Before:
this.Cols.InsertRange(selC1, colsToAdd);
AdjustMergedColumns(selC1, colsToAdd, true, false);
MyBorders.InsertColumns(Cols.Count - colsToAdd - 1, colsToAdd);
break;
case enmPastePos.After:
if (selC2+1 < Cols.Count - 1)
{
this.Cols.InsertRange(selC2+1, colsToAdd);
AdjustMergedColumns(selC1+1, colsToAdd, false, false);
}
else
this.Cols.Add(colsToAdd);
MyBorders.InsertColumns(Cols.Count - colsToAdd - 1, colsToAdd);
break;
case enmPastePos.Replace:
if (colsToAdd > Cols.Count - selC1)
{
int numToAdd = colsToAdd - (Cols.Count - selC1);
this.Cols.Add(numToAdd);
AdjustMergedColumns(selC1, numToAdd, true, false);
}
break;
}
RemoveMergedRanges(MyCopyInfo.MyCopiedCellRange.r1, MyCopyInfo.MyCopiedCellRange.c1 + colOffset, MyCopyInfo.MyCopiedCellRange.r2, MyCopyInfo.MyCopiedCellRange.c2 + colOffset);
// Fix the merge ranges
for (int c = MyCopyInfo.MyCopiedCellRange.c1; c <= MyCopyInfo.MyCopiedCellRange.c2; c++)
{
Cols[c + colOffset].Width = MyCopyInfo.MyCopiedFlexGrid.Cols[c].Width;
for (int r = MyCopyInfo.MyCopiedCellRange.r1; r <= Math.Min(MyCopyInfo.MyCopiedCellRange.r2 + rowsToAdd, Rows.Count - 1); r++)
{
CellRange crm = MyCopyInfo.MyCopiedFlexGrid.GetMergedRange(r, c);
if (r == crm.r1 && c == crm.c1)
{
Rows[r].Height = Math.Max(Rows[r].Height, MyCopyInfo.MyCopiedFlexGrid.Rows[r].Height);
CellRange cr = GetCellRange(crm.r1, crm.c1 + colOffset, crm.r2, crm.c2 + colOffset);
// if the paste is to the left - copy merge range for the destination
// if the paste is to the right - put back the range for the source location
if ((crm.r2 > crm.r1) || (crm.c2 > crm.c1))
MergedRanges.Add(cr);
// copy cell text to the destination, copy the style, copy the cell borders
this[r, c + colOffset] = MyCopyInfo.MyCopiedFlexGrid[r, c];
MatchStyle(crm, cr);
PasteBorders(r, c + colOffset, r, c);
// if the paste is to the left - put back the range for the source location
// if the paste is to the right - copy merge range for the destination
int c1 = crm.c1 + colsToAdd - colOffset;
int c2 = crm.c2 + colsToAdd - colOffset;
CellRange ncr = GetCellRange(crm.r1, c1, crm.r2, c2);
if ((crm.r2 > crm.r1) || (crm.c2 > crm.c1))
MergedRanges.Add(ncr);
}
}
}
this.AdjustGridControlSize();
CopyToCopiedFlexGrid(MyCopyInfo.MyCopyOption);
}
public void PasteCopiedCells()
{
// Warn the user that this type of paste will replace the currently selected (highlighted) table cells and give the option to abort.
DialogResult dr = MessageBox.Show("This will replace the cells that are currently selected (highlighted). \n\nContinue with the paste?","Paste Table Cells",MessageBoxButtons.YesNo,MessageBoxIcon.Question);
if (dr == DialogResult.No) return;
int nSelRows = Selection.r2 - Selection.r1 + 1;
int nSelCols = Selection.c2 - Selection.c1 + 1;
int nCpyRows = MyCopyInfo.MyCopiedCellRange.r2 - MyCopyInfo.MyCopiedCellRange.r1 + 1;
int nCpyCols = MyCopyInfo.MyCopiedCellRange.c2 - MyCopyInfo.MyCopiedCellRange.c1 + 1;
int colsToAdd = Math.Max(nCpyCols - nSelCols, 0);
int rowsToAdd = Math.Max(nCpyRows - nSelRows, 0);
int rowOffset = Selection.r1 - MyCopyInfo.MyCopiedCellRange.r1;
int colOffset = Selection.c1 - MyCopyInfo.MyCopiedCellRange.c1;
int selR2 = Selection.r2;
int selC2 = Selection.c2;
// If there are more cells to copy than what is seleceted in the target table
// Add extra rows and columns as needed
if (rowsToAdd > 0)
{
if (selR2 < Rows.Count - 1)
{
this.Rows.InsertRange(selR2 + 1, rowsToAdd);
AdjustMergedRows(selR2 + 1, false, false);
}
else
this.Rows.Add(rowsToAdd);
MyBorders.InsertRows(selR2,rowsToAdd);
}
if (colsToAdd > 0)
{
if (selC2 < Cols.Count - 1)
{
this.Cols.InsertRange(selC2 + 1, colsToAdd);
AdjustMergedColumns(selC2 + 1, false, false);
}
else
this.Cols.Add(colsToAdd);
MyBorders.InsertColumns(selC2,colsToAdd);
}
RemoveMergedRanges(MyCopyInfo.MyCopiedCellRange.r1 + rowOffset, MyCopyInfo.MyCopiedCellRange.c1 + colOffset, MyCopyInfo.MyCopiedCellRange.r2 + rowOffset, MyCopyInfo.MyCopiedCellRange.c2 + colOffset);
for (int c = MyCopyInfo.MyCopiedCellRange.c1; c <= Math.Min(MyCopyInfo.MyCopiedCellRange.c2, Cols.Count - 1 - colOffset); c++)
Cols[c + colOffset].Width = Math.Max(MyCopyInfo.MyCopiedFlexGrid.Cols[c].Width, Cols[c + colOffset].Width);
for (int r = MyCopyInfo.MyCopiedCellRange.r1; r <= Math.Min(MyCopyInfo.MyCopiedCellRange.r2, Rows.Count - 1 - rowOffset); r++)
{
Rows[r + rowOffset].Height = Math.Max(MyCopyInfo.MyCopiedFlexGrid.Rows[r].Height, Rows[r + rowOffset].Height);
for (int c = MyCopyInfo.MyCopiedCellRange.c1; c <= Math.Min(MyCopyInfo.MyCopiedCellRange.c2, Cols.Count - 1 - colOffset); c++)
{
CellRange crm = MyCopyInfo.MyCopiedFlexGrid.GetMergedRange(r, c);
if (r == crm.r1 && c == crm.c1)
{
CellRange cr = GetCellRange(crm.r1 + rowOffset, crm.c1 + colOffset, crm.r2 + rowOffset, crm.c2 + colOffset);
if ((crm.r2 > crm.r1) || (crm.c2 > crm.c1))
MergedRanges.Add(cr);
this[r + rowOffset, c + colOffset] = MyCopyInfo.MyCopiedFlexGrid[r, c];
MatchStyle(crm, cr);
PasteBorders(r + rowOffset, c + colOffset, r, c);
}
}
}
this.AdjustGridControlSize();
CopyToCopiedFlexGrid(MyCopyInfo.MyCopyOption);
}
#endregion // Copy/Paste
#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
/// <summary>
/// Prompts user with Save File dialog.
/// Grid will be saved to an XML file.
/// </summary>
/// <param name="initDir"></param>
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;
}
/// <summary>
/// Prompts user with Save File dialog.
/// Grid will be saved to an Excel file.
/// </summary>
/// <param name="initDir"></param>
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);
}
/// <summary>
/// Prompts user with Open File dialog.
/// XML file will be imported to a table grid.
/// </summary>
/// <param name="initDir"></param>
/// <returns></returns>
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.BorderStyle = C1.Win.C1FlexGrid.Util.BaseControls.BorderStyleEnum.None;
this.KeyActionTab = KeyActionEnum.MoveAcross;
this.AdjustGridControlSize();
rtn = ofd.SafeFileName;
return rtn;
}
/// <summary>
/// Prompts user with Open File dialog.
/// Excel file will be imported to a table grid.
/// </summary>
/// <param name="initDir"></param>
/// <returns></returns>
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;
}
public void ConvertTableROToGrid(string valtext, int rodbid, string roid)
{
VE_Font vefont = _MyItemInfo.GetItemFont();
this.Font = vefont.WindowsFont;
this.MergedRanges.Clear();
this.Clear();
this.IsRoTable = true;
this.ParseTableFromText(valtext, GridLinePattern.Single);
this.AutoSizeCols();
this.AutoSizeRows();
this.MakeRTFcells();
this.RODbId = rodbid;
this.ROID = roid;
}
private Regex _ReplaceSpaceNewLine = new Regex(@"(?<=\\[^' \\?\r\n\t]*) (?=\r\n)");
private Regex _ReplaceTokenSpaceToken = new Regex(@"(?<=\\[^' \\?\r\n\t]*) (?=\\)");
private Regex _RemoveComments = new Regex(@"\\v .*?\\v0( |$)");
private string PrepROTableText(string stepText)
{
// we need to convert some RTF command to DOS so that we can
// figure out the table size
stepText = stepText.Replace("\r", "");
stepText = stepText.Replace("\xF8", @"\'f8");
stepText = stepText.Replace(@"\par ", "\r\n");
stepText = _ReplaceTokenSpaceToken.Replace(stepText, "");
//Change Token Order to match RTB output
stepText = stepText.Replace(@"\v0\b0", @"\b0\v0");
stepText = stepText.Replace(@"\b0\ulnone", @"\ulnone\b0");
stepText = _ReplaceSpaceNewLine.Replace(stepText, "");
// Now change the Unicode symbols to DOS symbols
stepText = stepText.Replace(@"\u8209?", "-");
stepText = stepText.Replace(@"\u9474?", "\xB3"); // Vert Line graphic character
stepText = stepText.Replace(@"\'b0", "\xB0");
stepText = stepText.Replace(@"\up2 ", "\x9566");
stepText = stepText.Replace(@"\up0 ", "\x9567");
stepText = stepText.Replace(@"\ulnone", "\xBB");
stepText = stepText.Replace(@"\ul", "\xAB");
stepText = stepText.Replace(@"\{", "{");
stepText = stepText.Replace(@"\}", "}");
stepText = stepText.Replace(@"\b0", "\xD6");
stepText = stepText.Replace(@"\b", "\xD5");
stepText = stepText.Replace(@"\u160?", "\xA0"); //hard space
stepText = stepText.Replace(@"\u916?", "\x7F"); // delta
stepText = stepText.Replace(@"\u8805?", "\xF2"); //greater than or equal
stepText = stepText.Replace(@"\u8804?", "\xF3"); // less than or equal
stepText = stepText.Replace(@"\u931?", "\xE4"); // sigma
stepText = stepText.Replace(@"\u947?", "\xE7"); // gamma
stepText = stepText.Replace(@"\u9604?", "\xFE"); // accum 2584
stepText = stepText.Replace(@"\u9679?", "\x7"); // bullet 25CF
stepText = stepText.Replace(@"\u8776?", "\xF7"); // approx eq
stepText = stepText.Replace(@"\u8773?", "\xF0"); // similar eq 2245
stepText = stepText.Replace(@"\u8730?", "\xFB"); // square root
stepText = stepText.Replace(@"\u961?", "\xE2"); // rho 3C1
stepText = stepText.Replace(@"\u960?", "\xE3"); // pi
stepText = stepText.Replace(@"\u956?", "\xE6"); // micro
stepText = stepText.Replace(@"\u948?", "\xEB"); // lower case delta
stepText = stepText.Replace(@"\u963?", "\xE5"); // lower case sigma
stepText = stepText.Replace(@"\u274?", "\x90"); // energy, 112
stepText = stepText.Replace(@"\u949?", "\xEE"); // epsilon
stepText = stepText.Replace(@"\u952?", "\xE9"); // theta, 3B8
stepText = stepText.Replace(@"\u8857?", "\xEC"); // dot in oval, 2299
stepText = stepText.Replace(@"\u964?", "\xA8"); // tau, 3C4
stepText = stepText.Replace(@"\u9830?", "\xA9"); // diamond, 2666
stepText = stepText.Replace(@"\u8593?", "\x18"); // Up Arrow - changes to \xff
stepText = stepText.Replace(@"\u8595?", "\x19"); // Down Arrow - changes to \xd6
// Fix "|" followed by a newline - this confuses the table converter
stepText = stepText.Replace(@"|\r\n", @"| \r\n");
stepText = stepText.Replace(@"|\n\r", @"| \n\r");
stepText = stepText.Replace(@"|\n", @"| \n");
// if the entire row is underlined, then remove the underline and insert a row of dashes
stepText = ConvertUnderlineToRow(stepText);
return stepText;
}
private bool IsPrintableTableChar(char c)
{
string printablSymbols = "\xB3\xA0\x7F\xF2\xF3\xE4\xE7\xFE\x07\xF7\xF0\xFB\xE2\xE3\xE6\xEB\xE5\x90\xEE\xE9\xEC\xA8\xA9\x18\x19";
return (((c > '\x1F') && (c < '\x80')) || (printablSymbols.IndexOf(c) >= 0));
}
private string ConvertUnderlineToRow(string stepText)
{
string rtnStr = "";
char[] sep = { '\n' };
string[] lines = stepText.Split(sep);
foreach (string line in lines)
{
int idx = 0;
int chrCnt = 0;
int uOnPos = -1;
int uOffPos = -1;
bool ulineOn = false;
char curChar = line[idx];
string dashRow = "";
while (idx < line.Length && !IsPrintableTableChar(line[idx]))
{
if (line[idx] == '\xAB') //underline ON
{
ulineOn = true;
uOnPos = idx;
}
idx++;
}
while (ulineOn && idx < line.Length)
{
if (IsPrintableTableChar(line[idx]))
{
if (line[idx] == '|' || line[idx] == '\xB3')
{
dashRow += new string('-', chrCnt);
dashRow += "|";
chrCnt = 0;
}
else
chrCnt++;
idx++;
}
else
{
if (line[idx] == '\xBB') //underline OFF
{
uOffPos = idx;
ulineOn = false;
while ((idx < line.Length) && !IsPrintableTableChar(line[idx]))
{
if (line[idx] == '\xAB')
ulineOn = true;
idx++;
}
if (idx == line.Length)
ulineOn = true;
if (!ulineOn)
dashRow = "";
}
else
idx++;
}
}
string curLine = line;
curLine = curLine.Replace('\xB3', '|'); // replace graphic vert bar with DOS vert bar
if (ulineOn && idx == line.Length) // entire line is underlined, remove underline, insert row of dashes
{
curLine = curLine.Replace("\xAB", ""); // remove Underline ON
curLine = curLine.Replace("\xBB", ""); // remove Underline OFF
dashRow += new string('-', chrCnt);
dashRow = "\n" + dashRow;
}
if (rtnStr.Length > 0) rtnStr += "\n";
rtnStr += curLine;
rtnStr += dashRow;
}
return rtnStr;
}
/// <summary>
/// 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.
/// </summary>
/// <param name="txtbuff"></param>
public void ParseTableFromText(string buff,GridLinePattern border)
{
string txtbuff = PrepROTableText(buff);
if (IsRoTable) txtbuff = _RemoveComments.Replace(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<int, int> dicCols = new Dictionary<int, int>();
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);
if (idxst < txtbuff.Length)
{
colPos = idxst - strow;
if (!dicCols.ContainsKey(colPos))
dicCols.Add(colPos, curCol);
else if (curCol > dicCols[colPos])
{
dicCols.Remove(colPos);
dicCols.Add(colPos, curCol);
}
}
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());
//this[r, c] = cellstr.TrimEnd(" \r\n\t".ToCharArray());
CellRange cr = this.GetMergedRange(r, c);
if (cr.r1 != cr.r2)
TrimMergedRangeCellText(cr);
}
}
MyBorders = new VlnBorders(border, Rows.Count, Cols.Count);
}
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;
int neededLines = (nlines - (nrows - 1));
bool bNeedToTrim = (nlines > neededLines);
string jstr = "";
int LinesToGo = neededLines;
if (bNeedToTrim)
{
int numBlanksEnd = 0;
// find the number of blank lines at the end of this table cell
for (int i = nlines-1; i >= 0; i--)
{
if (strary[i].Trim().Length == 0)
numBlanksEnd++;
else
break;
}
int preBlanksLines = 0;
//foreach (string tmpstr in strary)
// we ignore the ending blank lines
// this allows us to include any blank lines that are between text lines
for (int i = 0; i < nlines - numBlanksEnd; i++)
{
string tmpstr = strary[i];
int tlen = tmpstr.Trim().Length;
if (tlen > 0 || (LinesToGo < neededLines))
{
if (jstr.Length > 0) jstr += "\n";
jstr += tmpstr;
LinesToGo--;
}
else if (LinesToGo == (nlines - (nrows - 1)))
preBlanksLines++;
}
while (LinesToGo > 0)
{
// need to put this type of hard space (not \xA0) to hold the newline position
if (preBlanksLines > 0)
{
jstr = "\\~\n" + jstr;
LinesToGo--;
}
if (numBlanksEnd > 0)
{
jstr += "\n\\~";
LinesToGo--;
}
}
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
/// <summary>
/// True if the top and bottom row of the selection is the same for every column
/// </summary>
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()
{
return GetEvenSelection(Selection.r1, Selection.c1, Selection.r2, Selection.c2);
}
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);
}
}
}
}
/// <summary>
/// Returns a list of cells or merged cells within the selection
/// </summary>
public List<CellRange> MySelection
{
get
{
List<CellRange> ranges = new List<CellRange>();
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;
}
}
/// <summary>
/// This is a test to see if MySelection works.
/// </summary>
public void BoldMySelection()
{
foreach (CellRange cr in MySelection)
{
using (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;
}
}
}
public void ShowMySelection()
{
int r1 = MySelection[0].r1;
int r2 = MySelection[0].r2;
int c1 = MySelection[0].c1;
int c2 = MySelection[0].c2;
foreach (CellRange cr in MySelection)
{
r1 = Math.Min(r1, cr.r1);
c1 = Math.Min(c1, cr.c1);
r2 = Math.Max(r2, cr.r2);
c2 = Math.Max(c2, cr.c2);
}
Select(r1,c1,r2,c2);
}
public void Debug_WritelineMySelection()
{
int r1 = MySelection[0].r1;
int r2 = MySelection[0].r2;
int c1 = MySelection[0].c1;
int c2 = MySelection[0].c2;
Console.WriteLine("Initial MySelection[0] {0}", MySelection[0]);
foreach (CellRange cr in MySelection)
{
r1 = Math.Min(r1, cr.r1);
c1 = Math.Min(c1, cr.c1);
r2 = Math.Max(r2, cr.r2);
c2 = Math.Max(c2, cr.c2);
Console.WriteLine("Foreach range ({0},{1}) - ({2},{3})", r1, c1, r2, c2);
}
}
#endregion
}
/// <summary>
/// This is used for storing the grid selection for copy/past Row/Column
/// </summary>
public enum GridCopyOption { Row, Column, Selection };
#region RTF Class for Cell rendering
/// <summary>
/// RTF Should only be used if the contents of the richtextbox are to be converted to an image.
/// </summary>
class RTF : StepRTB
{
// 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
/// <summary>
/// TableCellEditor inherits from a StepRTB and is used as a custom cell editor
/// for the C1FlexGrid control.
/// </summary>
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);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
// start editing: move to cell and activate
public void StartEditing(int row, int col)
{
_initializingEdit = true;
ReadOnly = IsRoTable;
// 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 > ' ' && !ReadOnly)
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");
private SelectedTableCells mySeldTableCellsObject;
private DataObject myDataObject;
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);
//mySeldTableCellsObject = new SelectedTableCells();
//mySeldTableCellsObject.CpbrdCellRange = cr;
// myDataObject = new DataObject(dfmtTableCellRange.Name, mySeldTableCellsObject);
// try
// {
// Clipboard.SetDataObject(myDataObject); //,true);
// }
// catch (Exception ex)
// {
// Console.WriteLine(ex.Message);
// }
}
public ArrayList Get()
{
// Retrieves the data from the clipboard.
IDataObject myRetrievedObject = Clipboard.GetDataObject();
string jj = (string)myRetrievedObject.GetData(DataFormats.Text);
return GetCellStrings(jj);
}
//public CellRange get_cr_Paste()
//{
// mySeldTableCellsObject = new SelectedTableCells();
// CellRange cr = new CellRange();
// SelectedTableCells sc;
// IDataObject myRetrievedObject = Clipboard.GetDataObject();
// try
// {
// //object obj = myRetrievedObject.GetData(dfmtTableCellRange.Name);
// object obj = myRetrievedObject.GetData("TableCellRange");
// //sc = (SelectedTableCells)myRetrievedObject.GetData(dfmtTableCellRange.Name);
// sc = (SelectedTableCells)obj;
// cr = sc.CpbrdCellRange;
// }
// catch (Exception ex)
// {
// Console.WriteLine(ex.Message);
// }
// return cr;
//}
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;
}
}
public class GridCopyInfo
{
private GridCopyOption _MyCopyOption = GridCopyOption.Selection;
public GridCopyOption MyCopyOption
{
get { return _MyCopyOption; }
set
{
//Console.WriteLine("MyCopyOption = {0}", _MyCopyOption);
//if (_MyCopyOption != value)
// Console.WriteLine("Changed Option to {0}", value);
_MyCopyOption = value;
}
}
private VlnFlexGrid _MyCopiedFlexGrid = null;
public VlnFlexGrid MyCopiedFlexGrid
{
get { return _MyCopiedFlexGrid; }
set { _MyCopiedFlexGrid = value; }
}
private CellRange _MyCopiedCellRange;
public CellRange MyCopiedCellRange
{
get { return _MyCopiedCellRange; }
set { _MyCopiedCellRange = value; }
}
}
}