5097 lines
		
	
	
		
			164 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			5097 lines
		
	
	
		
			164 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;
 | |
| using Volian.Base.Library;
 | |
| 
 | |
| 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 vlnPanel : Panel
 | |
| 	{
 | |
| 		private int _Opacity = 128;
 | |
| 		//public int Opacity
 | |
| 		//{
 | |
| 		//  get { return _Opacity; }
 | |
| 		//  set	{ _Opacity = value; }
 | |
| 		//}
 | |
| 
 | |
| 		public vlnPanel()
 | |
| 		{
 | |
| 			InitializeComponent();
 | |
| 		}
 | |
| 
 | |
| 		public vlnPanel(IContainer container)
 | |
| 		{
 | |
| 			container.Add(this);
 | |
| 			InitializeComponent();
 | |
| 		}
 | |
| 		//protected override CreateParams CreateParams
 | |
| 		//{
 | |
| 		//  get
 | |
| 		//  {
 | |
| 		//    CreateParams prams = base.CreateParams;
 | |
| 		//    prams.ExStyle |= 0x020; // transparent
 | |
| 		//    return prams;
 | |
| 		//  }
 | |
| 		//}
 | |
| 		//protected override void OnPaint(PaintEventArgs pe)
 | |
| 		//{
 | |
| 		//  pe.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(_Opacity, this.BackColor)), this.ClientRectangle);
 | |
| 		//}
 | |
| 	}
 | |
| 
 | |
|   public partial class VlnFlexGrid : C1.Win.C1FlexGrid.C1FlexGrid
 | |
|   {
 | |
| 		private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 | |
| 		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();
 | |
| 		//}
 | |
| 		private DocVersionInfo _MyDVI = null;
 | |
| 
 | |
| 		public DocVersionInfo MyDVI
 | |
| 		{
 | |
| 			get 
 | |
| 			{
 | |
| 				ItemInfo procInfo = _MyItemInfo.MyProcedure as ItemInfo; //_MyEditItem.MyItemInfo.MyProcedure as ItemInfo;
 | |
| 				if (procInfo == null) 
 | |
| 					_MyDVI = null;
 | |
| 				else
 | |
| 					_MyDVI = procInfo.ActiveParent as DocVersionInfo;
 | |
| 				return _MyDVI; 
 | |
| 			}
 | |
| 		}
 | |
| 		private static UserInfo _MyUserInfo = null;
 | |
| 		public static UserInfo MyUserInfo
 | |
| 		{
 | |
| 			get { return _MyUserInfo; }
 | |
| 			set
 | |
| 			{
 | |
| 				_MyUserInfo = value;
 | |
| 				GridItem.MyUserInfo = value;
 | |
| 			}
 | |
| 		}
 | |
| 		public bool IsDirty
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				return IsGridChanged(this._MyItemInfo.MyContent.MyGrid.Data, this.GetXMLData(), true);
 | |
| 			}
 | |
| 		}
 | |
| 		private bool IsGridChanged(string oldXml, string newXml, bool checkFormat)
 | |
| 		{
 | |
| 			if (this.TableCellEditor.Text.Contains("<NewID>"))
 | |
| 				return false;
 | |
| 			XmlDocument XdOld = new XmlDocument();
 | |
| 			XdOld.LoadXml(AdjustHeightAndWidthForDPI(oldXml));
 | |
| 			XmlDocument XdNew = new XmlDocument();
 | |
| 			XdNew.LoadXml(AdjustHeightAndWidthForDPI(newXml));
 | |
| 			//check volian borders 1st
 | |
| 			if (checkFormat && XdNew.SelectSingleNode("C1FlexGrid/Control/MyBorderDetailString").InnerText != XdOld.SelectSingleNode("C1FlexGrid/Control/MyBorderDetailString").InnerText)
 | |
| 				return true;
 | |
| 			//check row/col sizes 2nd
 | |
| 			if (checkFormat && ( 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 (checkFormat && GetCellFormatString(XdNew) != GetCellFormatString(XdOld))
 | |
| 				return true;
 | |
| 			//check for text alignment changes 5th
 | |
| 			// put check in for bug fix B2014-106
 | |
| 			if (checkFormat && GetCellTextAlignString(XdNew) != GetCellTextAlignString(XdOld))
 | |
| 				return true;
 | |
| 			//check for merged cells 6th
 | |
| 			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 = ColumnCount(xd);
 | |
| 			int rows = RowCount(xd);
 | |
| 			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 int ColumnCount(XmlDocument xd)
 | |
| 		{
 | |
| 			XmlNode xn = xd.SelectSingleNode("C1FlexGrid/ColumnInfo/Count");
 | |
| 			int cols = 0;
 | |
| 			if (xn != null)
 | |
| 				cols = int.Parse(xn.InnerText);
 | |
| 			else
 | |
| 			{
 | |
| 				XmlNodeList nl = xd.SelectNodes("C1FlexGrid/Columns/Column");
 | |
| 				cols = nl.Count;
 | |
| 			}
 | |
| 			return cols;
 | |
| 		}
 | |
| 		private int RowCount(XmlDocument xd)
 | |
| 		{
 | |
| 			XmlNode xn = xd.SelectSingleNode("C1FlexGrid/RowInfo/Count");
 | |
| 			int rows = 0;
 | |
| 			if (xn != null)
 | |
| 				rows = int.Parse(xn.InnerText);
 | |
| 			else
 | |
| 			{
 | |
| 				XmlNodeList nl = xd.SelectNodes("C1FlexGrid/Rows/Row");
 | |
| 				rows = nl.Count;
 | |
| 			}
 | |
| 			return rows;
 | |
| 		}
 | |
| 		private string GetCellDataString(XmlDocument xd)
 | |
| 		{
 | |
| 			int cols = ColumnCount(xd);
 | |
| 			int rows = RowCount(xd);
 | |
| 			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 = ColumnCount(xd);
 | |
| 			int rows = RowCount(xd);
 | |
| 			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 string GetCellTextAlignString(XmlDocument xd)
 | |
| 		{
 | |
| 			// Note that I could not save (and later compare) the entire Definition string
 | |
| 			// because the xml for the old and new table was always different. 
 | |
| 			// The old xml table data would have, for example "white" for the background color, while
 | |
| 			// the new xml table data would have "255,255,255" for the background color.
 | |
| 			// Therefore this check is specific for only the TextAlign setting - jsj 9-30-2014
 | |
| 			XmlNodeList nl = xd.SelectNodes("C1FlexGrid/Styles/Style/Definition");
 | |
| 			string data = string.Empty;
 | |
| 			foreach (XmlNode xn in nl)
 | |
| 			{
 | |
| 				string str = xn.InnerText;
 | |
| 				string[] splStr = str.Split(';');
 | |
| 				foreach (string s in splStr)
 | |
| 					if (s.StartsWith("TextAlign:"))
 | |
| 					data += "|" + s; // only save the TextAlign setting
 | |
| 			}
 | |
| 			return data;
 | |
| 		}
 | |
| 		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 bool TopRowHasBorder()
 | |
| 	  {
 | |
| 		  for (int c = 0; c < Cols.Count; c++)
 | |
| 			  if (MyBorders.HorizontalLines[0, c] != GridLinePattern.None) return true;
 | |
| 		  return false;
 | |
| 	  }
 | |
| 		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]+[^ ]* )(FreeMono)(;})");  // FreeMono is now used for the edit screen only.  VESymbFix and Consolas are used for printing
 | |
|         private static Regex _ReplaceArialUnicodeMS = new Regex(@"({\\f[0-9]+[^ ]* )(" + Volian.Base.Library.vlnFont.ProportionalSymbolFont + @")(;})");  // C2017-036 get best available proportional font for symbols
 | |
| 		// B2017-173 VESymFix font was being replaced by the table's default font, causing empty squares for the symbols (pre FreeMono font) in tables
 | |
|       //C2017-036 Added FreeSerif which may be used if Arial Unicode MS is not available
 | |
|         private static Regex _ReplaceTextFont = new Regex(@"({\\f[0-9]+[^ ]* )(?((?!FreeMono)(?!FreeSerif)(?!Arial Unicode MS)(?!VESymbFix))([^;]*)|(!!!!))(;})");  // FreeMono is now used for the edit screen only.  VESymbFix and Consolas are used for printing
 | |
| 	  private bool FontIsFixed(Font myFont)
 | |
| 	  {
 | |
| 		  Graphics grph = Graphics.FromHwnd(this.Handle);
 | |
| 		  SizeF sfW = grph.MeasureString("W", myFont);
 | |
| 		  SizeF sfE = grph.MeasureString("!", myFont);
 | |
| 		  if (sfW.Width == sfE.Width) return true;
 | |
| 		  return false;
 | |
| 	  }
 | |
| 	  public void LoadGrid(ItemInfo itemInfo)
 | |
| 	  {
 | |
| 			int profileDepth = ProfileTimer.Push(">>>> VlnFlexGrid.LoadGrid");
 | |
| 		  _MyItemInfo = itemInfo;
 | |
| 		  string str = itemInfo.MyContent.MyGrid.Data;
 | |
| 			VE_Font vefont = _MyItemInfo.GetItemFont();
 | |
| 
 | |
| 		  // the following code is used to be sure that the font used for symbols is the correct font
 | |
| 		  // based on whether the font for non-symbol text is fixed or proportional.  Each steprtb has
 | |
| 		  // a font for the non-symbol AND the symbol text, and these must be the correct association, i.e.
 | |
| 		  // for fixed fonts, the symbol font is 'VESymbFix', for proportional fonts, the symbol font is 
 | |
| 		  // 'Arial Unicode MS'.  The underlying flexgrid stores the fonts, and if the table font was
 | |
| 		  // reset for some reason (for example from the drop-down font selection in the user interface),
 | |
| 		  // this code 'cleans' up if there is a mismatch.
 | |
| 		  if (StepRTB.MyFontFamily != null)
 | |
| 		  {
 | |
| 			  FontFamily ff = StepRTB.MyFontFamily;
 | |
| 				if (StepRTB.MySymbolFontName != "FreeMono")  // FreeMono is now used for the edit screen only.  VESymbFix and Consolas are used for printing
 | |
| 				  str = _ReplaceVESymbFix.Replace(str, "$1" + StepRTB.MySymbolFontName + "$3");
 | |
|                 if (StepRTB.MySymbolFontName != Volian.Base.Library.vlnFont.ProportionalSymbolFont) // C2017-036 get best available proportional font for symbols
 | |
| 				  str = _ReplaceArialUnicodeMS.Replace(str, "$1" + StepRTB.MySymbolFontName + "$3");
 | |
| 			  str = _ReplaceTextFont.Replace(str, "$1" + ff.Name + "$4");
 | |
| 		  }
 | |
| 		  else
 | |
| 		  {
 | |
| 			  FontFamily ff = vefont.WindowsFont.FontFamily;
 | |
| 			  if (FontIsFixed(vefont.WindowsFont))
 | |
| 					str = _ReplaceArialUnicodeMS.Replace(str, "$1" + "FreeMono" + "$3");  // FreeMono is now used for the edit screen only.  VESymbFix and Consolas are used for printing
 | |
| 			  else
 | |
|                   str = _ReplaceVESymbFix.Replace(str, "$1" + Volian.Base.Library.vlnFont.ProportionalSymbolFont + "$3"); // C2017-036 get best available proportional font for symbols 
 | |
| 			  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.
 | |
| 		  Visible = false;
 | |
| 		  if (Parent is GridItem)
 | |
| 		  {
 | |
| 				try
 | |
| 				{
 | |
| 					System.Drawing.Image img = this.CreateImage();
 | |
| 					using (Graphics gr = (Parent as GridItem).CreateGraphics())
 | |
| 					{
 | |
| 						gr.DrawImage(img, Left, Top);
 | |
| 					}
 | |
| 				}
 | |
| 				catch (Exception ex)
 | |
| 				{
 | |
| 					_MyLog.WarnFormat("Table Content Corrupted");
 | |
| 				}
 | |
| 		  }
 | |
| 		  Clear();
 | |
| 		  MergedRanges.Clear();
 | |
| 		  _ReadingXml = true;
 | |
| 		  //Console.WriteLine("LoadGrid - Before ReadXML");
 | |
| 		  ReadXml(str);
 | |
| 		  //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;
 | |
| 			ProfileTimer.Pop(profileDepth);
 | |
| 	  }
 | |
| 
 | |
| 	  private void ReadXml(string str)
 | |
| 	  {
 | |
| 	      // Get the height/width adjusted for the DPI.  Depending on if the DPI setting for the current user's
 | |
| 		  // monitor is different than the DPI setting saved in the grid record, table height/width of rows/columns
 | |
| 		  // will be incorrect, i.e. lots of extra white space.  The reason behind this is that the height/width 
 | |
| 		  // of table cells are stored as dots (from the monitor) in the underlying component one flexgrid.
 | |
| 			try
 | |
| 			{
 | |
| 				str = AdjustHeightAndWidthForDPI(str);
 | |
| 				using (StringReader sr = new StringReader(str))
 | |
| 				{
 | |
| 					ReadXml(sr);
 | |
| 					this.BorderStyle = C1.Win.C1FlexGrid.Util.BaseControls.BorderStyleEnum.None;
 | |
| 					sr.Close();
 | |
| 				}
 | |
| 			}
 | |
| 			catch
 | |
| 			{
 | |
| 				;
 | |
| 			}
 | |
| 	  }
 | |
| 
 | |
| 	  private string AdjustHeightAndWidthForDPI(string str)
 | |
| 	  {
 | |
| 		  // create a graphics to get the DPI and then compare it to the DPI that is stored in the grid.
 | |
| 		  // if they are the same, we don't need to do anything.
 | |
| 		  int DPIscreen = 0;
 | |
| 		  using (Graphics gr = this.CreateGraphics())
 | |
| 		  {
 | |
| 			  DPIscreen = (int)gr.DpiX;
 | |
| 		  }
 | |
| 		  XmlDocument xd = new XmlDocument();
 | |
| 		  xd.LoadXml(str);
 | |
| 		  XmlNode xn = xd.SelectSingleNode("//DPI");
 | |
| 		  if (xn != null && xn.InnerText != DPIscreen.ToString())
 | |
| 		  {
 | |
| 			  int DPIgrid = int.Parse(xn.InnerText);
 | |
| 			  xn.InnerText = DPIscreen.ToString();
 | |
| 			  // adjust heights and widths based on the difference in DPIs between that what was saved
 | |
| 			  // in the database(grid) and the current DPI from the screen. Without doing this the 
 | |
| 			  // heights/widths will be 'off', i.e. lots of white space.
 | |
| 			  XmlNodeList xnl = xd.SelectNodes("//Height");
 | |
| 			  foreach (XmlNode xni in xnl)
 | |
| 			  {
 | |
| 				  int measurement = int.Parse(xni.InnerText);
 | |
| 				  if (measurement != -1)
 | |
| 					  xni.InnerText = ((measurement * DPIscreen) / DPIgrid).ToString();
 | |
| 			  }
 | |
| 			  xnl = xd.SelectNodes("//Width");
 | |
| 			  foreach (XmlNode xni in xnl)
 | |
| 			  {
 | |
| 				  int measurement = int.Parse(xni.InnerText);
 | |
| 				  if (measurement != -1)
 | |
| 					  xni.InnerText = ((measurement * DPIscreen) / DPIgrid).ToString();
 | |
| 			  }
 | |
| 			  xnl = xd.SelectNodes("//DefaultSize");
 | |
| 			  foreach (XmlNode xni in xnl)
 | |
| 			  {
 | |
| 				  int measurement = int.Parse(xni.InnerText);
 | |
| 				  if (measurement != -1)
 | |
| 					  xni.InnerText = ((measurement * DPIscreen) / DPIgrid).ToString();
 | |
| 			  }
 | |
| 			  str = xd.OuterXml;
 | |
| 		  }
 | |
| 		  return str;
 | |
| 	  }
 | |
| 		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.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 nW = _tableCellEditor.Width; // Width
 | |
| 			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();
 | |
| 				}
 | |
| 			}
 | |
| 			if (_tableCellEditor is StepRTB && (_tableCellEditor as StepRTB).ImageWidth > 0)
 | |
| 			{
 | |
| 				Width = Cols[0].Width = (_tableCellEditor as StepRTB).ImageWidth;
 | |
| 			}
 | |
| 		}
 | |
| 		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.Control && !e.Shift && !e.Alt)
 | |
| 					{
 | |
| 						if (MyDVI != null && UserInfo.CanEdit(MyUserInfo,MyDVI))
 | |
| 							OnEnterKeyPressed(sender, e);
 | |
| 						else
 | |
| 						{
 | |
| 							// if a Reviewer, then do a <Ctrl><DownArrow>.  Don't allow changes to a table
 | |
| 							if (IsRoTable) Select(Rows.Count - 1, 0);
 | |
| 							_tableCellEditor.StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlDown : E_ArrowKeys.Down);
 | |
| 							e.Handled = true;
 | |
| 						}
 | |
| 					}
 | |
| 					break;
 | |
| 			}
 | |
| 		}
 | |
| 		//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
 | |
| 			// convert \'99 to \u8482? this is for the trade mark symbol.  For some reason RTF is automatically
 | |
| 			//  converting the unicode \u8482? to \'99, but once this is done, PROMS StepRTB (edit windows) do not show it
 | |
| 			// Also convert \~ to a hard spece. Again RTF is automatically converting \u160? to \~ but will then convert
 | |
| 			// the \~ to a regular space!
 | |
| 			string rtfText = RtfTools.RTFConvertedSymbolsToUnicode(this.GetDataDisplay(e.Row, e.Col));//.Replace(@"\~", @"\u160?").Replace(@"\'99", @"\u8482?");
 | |
| 			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;
 | |
| 			MyBorders.CheckAndFixBorderArraySize(this.Rows.Count, this.Cols.Count, GridLinePattern.Single); // C2018-031 check the cell border arrays
 | |
| 			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;
 | |
| 					}
 | |
| 				// If one column and one row, then go into edit mode.
 | |
| 				if (cr.r1 == cr.r2 && cr.c1 == cr.c2)
 | |
| 					SendKeys.Send("{F2}"); // Toggle Edit Mode with F2
 | |
| 			}
 | |
| 		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
 | |
| 			if(!IsRoTable )
 | |
| 				_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();
 | |
| 			GC.Collect(GC.GetGeneration(this));  // there is a memory leak in Regex this fixes it. (called in StepRTB.cs FindLinks)
 | |
| 		}
 | |
| 
 | |
| 		// 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();
 | |
| 				}
 | |
| 				// B2017-197 move the Select inside if (hasNonMergedRow) 
 | |
| 				//           was getting a selection out of range error when spliting rows that contained mergered rows
 | |
| 				//           only need to do this if we inserted rows
 | |
| 				// 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;													// KBR: is this wrong, i.e. should it be like ColIsInMergeRange
 | |
| 				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(r, col);
 | |
| 					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)
 | |
| 				RemoveColumns(this.Selection.r1, this.Selection.c1, 1+this.Selection.c2-this.Selection.c1);
 | |
| 			else
 | |
| 				Select(saveCR);
 | |
| 		}
 | |
| 
 | |
| 		public void RemoveSelectedRow()
 | |
| 		{
 | |
| 			string msg = "";
 | |
| 			string title = "";
 | |
| 			CellRange saveCR = Selection;
 | |
| 			this.SelectionMode = SelectionModeEnum.RowRange;
 | |
| 			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.RemoveRows(this.Selection.r1, this.Selection.c1, 1 + this.Selection.r2 - this.Selection.r1);
 | |
| 			else
 | |
| 				Select(saveCR);
 | |
| 		}
 | |
| 
 | |
| 	  private void RemoveRows(int strow, int stcol, int cnt)
 | |
| 	  {
 | |
| 		  bool mergedRow = false;
 | |
| 		  for (int i = 0; i < cnt; i++)
 | |
| 		  {
 | |
| 			  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;
 | |
| 				  }
 | |
| 				  cl++;
 | |
| 			  }
 | |
| 			  this.Rows.Remove(strow);
 | |
| 			  this.AdjustMergedRows(strow, false, true);
 | |
| 			  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++)
 | |
| 		  {
 | |
| 			  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.Cols.Remove(stcol);
 | |
| 			  this.AdjustMergedColumns(stcol, false, true);
 | |
| 			  mergedCol = false;
 | |
| 		  }
 | |
| 		  MyBorders.DeleteColumns(stcol, cnt);
 | |
| 		  this.AdjustGridControlSize();
 | |
| 	  }
 | |
| 		#endregion //Grid Add and Remove Row / Column
 | |
| 
 | |
| 		#region Copy/Paste
 | |
| 
 | |
| 		public void CopyRow()
 | |
| 		{
 | |
| 			_tableCellEditor.Hide(); // B2017-200 force save of changes from active edit session
 | |
| 			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()
 | |
| 		{
 | |
| 			_tableCellEditor.Hide(); // B2017-200 force save of changes from active edit session
 | |
| 			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()
 | |
| 		{
 | |
| 			_tableCellEditor.Hide(); // B2017-200 force save of changes from active edit session
 | |
| 			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 static List<string> ROTableUpdate(object sender, ROFstInfoROTableUpdateEventArgs args)
 | |
| 		{
 | |
| 			string xml = null;
 | |
| 			string srchtxt = null;
 | |
| 			Content content = (Content)sender;
 | |
| 			bool isdirty = false;
 | |
| 			using (VlnFlexGrid myGrid = new VlnFlexGrid(content.ContentItems[0]))
 | |
| 			{
 | |
| 				using (StringReader sr = new StringReader(args.OldGridXml))
 | |
| 				{
 | |
| 					myGrid.ReadXml(sr);
 | |
| 					sr.Close();
 | |
| 				}
 | |
| 				string roid = content.ContentRoUsages[0].ROID; //myGrid.ROID;
 | |
| 				int rodbid = content.ContentRoUsages[0].RODbID; //myGrid.RODbId;
 | |
| 				myGrid.Visible = false;
 | |
| 				myGrid.ConvertTableROToGrid(args.ROText, rodbid, roid);
 | |
| 				myGrid.FixTableCellsHeightWidth();
 | |
| 				myGrid.AdjustGridControlSize();
 | |
| 				myGrid.Visible = true;
 | |
| 				using (StringWriter sw = new StringWriter())
 | |
| 				{
 | |
| 					myGrid.WriteXml(sw);
 | |
| 					xml = sw.GetStringBuilder().ToString();
 | |
| 					sw.Close();
 | |
| 				}
 | |
| 				srchtxt = myGrid.GetSearchableText();
 | |
| 				isdirty = myGrid.IsGridChanged(args.OldGridXml, xml, false);
 | |
| 			}
 | |
| 			List<string> retlist = new List<string>();
 | |
| 			retlist.Add(srchtxt);
 | |
| 			if(isdirty)
 | |
| 				retlist.Add(xml);
 | |
| 			else
 | |
| 				retlist.Add(args.OldGridXml);
 | |
| 			return retlist;
 | |
| 		}
 | |
| 	  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(@"\u9586?", "\\");
 | |
| 		  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;
 | |
| 			if (maxCol == 0) maxCol = dicCols.Count;
 | |
| 			// 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
 | |
| 							{
 | |
| 								// take a peek at the start of the next piece of table text to parse
 | |
| 								// if it starts with a space, return, newline, or EndOfFile char, 
 | |
| 								// then flag to merge the columns up to
 | |
| 								// this point with the same columns in the next row
 | |
| 								if (idx < txtbuff.Length - 1 && " \r\n\x02".IndexOf(txtbuff[idx + 1]) > 0)
 | |
| 								{
 | |
| 									int nextCol = (curCol + 1 > this.Cols.Count) ? curCol : curCol + 1;
 | |
| 									if (!tci[curRow, nextCol].ColEnd)
 | |
| 										tci[curRow, nextCol].MergeRowBellow = true;
 | |
| 									//for (int c = nextCol; c >= 0; c--)
 | |
| 									//    if (!tci[curRow, c].ColEnd)
 | |
| 									//        tci[curRow, c].MergeRowBellow = true;
 | |
| 								}
 | |
| 								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 && curCol > 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]==null)? " ": 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>
 | |
| 	public 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)
 | |
| 		{
 | |
| 			ItemInfo pinfo = MyItemInfo.MyProcedure as ItemInfo;
 | |
| 			DocVersionInfo dvi = (pinfo == null) ? null : pinfo.ActiveParent as DocVersionInfo;
 | |
| 			_initializingEdit = true;
 | |
| 			ReadOnly = IsRoTable || !UserInfo.CanEdit(MyUserInfo, dvi); // reviewer cannot make changes to a table
 | |
| 			// 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)
 | |
| 			{
 | |
| 				if(_pendingKey == '\\')
 | |
| 					SendKeys.Send("\\"); // B2016-162 Send a backslash which will be converted to "\u9586?"
 | |
| 				else
 | |
| 					Text = _pendingKey.ToString();
 | |
| 			}
 | |
| 			else if (_owner[row, col] != null)
 | |
| 			{
 | |
| 				string tmp = _owner[row, col].ToString();
 | |
| 				// convert \'99 to \u8482? this is for the trade mark symbol.  For some reason RTF is automatically
 | |
| 				//  converting the unicode \u8482? to \'99, but once this is done, PROMS StepRTB (edit windows) do not show it
 | |
| 				// Also convert \~ to a hard spece. Again RTF is automatically converting \u160? to \~ but will then convert
 | |
| 				// the \~ to a regular space!
 | |
| 				if (tmp.StartsWith(@"{\rtf"))
 | |
| 					Rtf = RtfTools.RTFConvertedSymbolsToUnicode(tmp);//.Replace(@"\~", @"\u160?").Replace(@"\'99", @"\u8482?");
 | |
| 				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 -1) //B2017066 check against count -1 to avoid index out of range error
 | |
| 							_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; }
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| }
 |