using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using FastReport.Design;
using FastReport.Utils;
using FastReport.Engine;
using FastReport.Preview;
using FastReport.Design.PageDesigners.Page;
using FastReport.Data;
using FastReport.Controls;
using System.Linq;
using System.Runtime.CompilerServices;
namespace FastReport.Table
{
partial class TableObject
{
#region Fields
private ExpandingTag expandingTag;
private TableCell dragCell;
private SelectedObjectCollection itemsBeforeMDown;
private bool isResizing;
#endregion
#region Public Methods
///
public override void Draw(FRPaintEventArgs e)
{
base.Draw(e);
if (dragCell != null)
dragCell.DrawDragAcceptFrame(e, Color.Silver);
DrawDesign(e);
}
///
public override void HandleKeyDown(Control sender, KeyEventArgs e)
{
base.HandleKeyDown(sender, e);
if (IsSelected && IsDesigning)
foreach (KeyValuePair shorcut in Config.Shortcuts)
{
if (shorcut.Value == e.KeyData)
{
switch (shorcut.Key)
{
case "Editing,Cut":
Clipboard.CutCells(GetSelectionRect());
CreateUniqueNames();
Report.Designer.SetModified(null, "Change");
break;
case "Editing,Copy":
Clipboard.CopyCells(GetSelectionRect());
Report.Designer.SetModified(null, "Change");
break;
case "Editing,Paste":
Clipboard.PasteCells((Report.Designer.SelectedObjects[0] as TableCell).Address);
CreateUniqueNames();
Report.Designer.SelectedObjects.Clear();
Report.Designer.SelectedObjects.Add(this);
Report.Designer.SetModified(null, "Change");
break;
}
}
}
}
///
public override void HandleDragOver(FRMouseEventArgs e)
{
dragCell = null;
if (!(e.DragSource is TextObject))
return;
for (int y = 0; y < Rows.Count; y++)
{
for (int x = 0; x < Columns.Count; x++)
{
TableCell cell = this[x, y];
if (!IsInsideSpan(cell) && cell.PointInObject(new PointF(e.x, e.y)))
{
dragCell = cell;
e.handled = true;
break;
}
}
}
}
///
public override void HandleMouseDown(FRMouseEventArgs e)
{
base.HandleMouseDown(e);
HandleMouseHover(e);
if (IsSelected)
{
if (new RectangleF(AbsRight + 1, AbsBottom + 1, 16, 16).Contains(new PointF(e.x, e.y)))
{
e.handled = true;
e.mode = WorkspaceMode2.Size;
if (itemsBeforeMDown == null)
itemsBeforeMDown = new SelectedObjectCollection();
Report.Designer.SelectedObjects.CopyTo(itemsBeforeMDown);
Report.Designer.SelectedObjects.Clear();
foreach (ComponentBase line in ChildObjects)
{
if (line is TableColumn)
Report.Designer.SelectedObjects.Add(line);
}
e.activeObject = this.Rows[0].ChildObjects[0] as TableCell;
isResizing = true;
e.cursor = Cursors.PanSW;
}
expandingTag.OnClick(e);
}
}
///
public override void HandleMouseUp(FRMouseEventArgs e)
{
base.HandleMouseUp(e);
if (itemsBeforeMDown != null && itemsBeforeMDown.Count != 0)
{
Report.Designer.SelectedObjects.Clear();
foreach (ComponentBase item in itemsBeforeMDown)
{
if (AllObjects.Contains(item))
Report.Designer.SelectedObjects.Add(item);
}
if (Report.Designer.SelectedObjects.Count == 0)
Report.Designer.SelectedObjects.Add(this);
itemsBeforeMDown.Clear();
}
isResizing = false;
}
///
public override void HandleMouseMove(FRMouseEventArgs e)
{
base.HandleMouseMove(e);
if (IsSelected)
{
if (new RectangleF(AbsRight + 2, AbsBottom + 3, 16, 16).Contains(new PointF(e.x, e.y)))
{
e.cursor = Cursors.PanSE;
e.handled = true;
}
expandingTag.OnMove(e);
}
if (!(e.mode == WorkspaceMode2.Size && e.activeObject == this.Rows[0].ChildObjects[0] as TableCell && isResizing))
return;
float longestHeigh = (Rows.ToArray().ToList().Last() as TableRow).ChildObjects.ToArray().ToList().Max((x => (x as TableCell).Height));
float longestWidth = (Rows.ToArray().ToList().Last() as TableRow).ChildObjects.ToArray().ToList().Max((x => (x as TableCell).Width));
bool wasChanged = false;
if (e.y > AbsBottom + 19)
{
TableRow row = new TableRow();
Rows.Insert(Rows.Count, row);
CreateUniqueNames();
wasChanged = true;
}
else if (e.y < AbsBottom - longestHeigh && Rows.Count > 1)
{
wasChanged = true;
Rows.RemoveAt(Rows.Count - 1);
}
if (e.x > AbsRight + longestWidth)
{
TableColumn column = new TableColumn();
Columns.Insert(Columns.Count, column);
CreateUniqueNames();
wasChanged = true;
}
else if (e.x < AbsRight - longestWidth && Columns.Count > 1)
{
wasChanged = true;
Columns.RemoveAt(Columns.Count - 1);
}
if (wasChanged)
{
Report.Designer.SelectedObjects.Clear();
foreach (ComponentBase line in ChildObjects)
{
if (line is TableColumn)
Report.Designer.SelectedObjects.Add(line);
}
}
}
///
public override void HandleDragDrop(FRMouseEventArgs e)
{
dragCell.Text = (e.DragSource as TextObject).Text;
dragCell = null;
}
internal override ContextMenuBase GetColumnContextMenu(TableColumn column)
{
return new TableColumnMenu(Report.Designer);
}
internal override ContextMenuBase GetRowContextMenu(TableRow row)
{
return new TableRowMenu(Report.Designer);
}
internal override ContextMenuBase GetCellContextMenu(TableCell cell)
{
return new TableCellMenu(Report.Designer);
}
internal override SmartTagBase GetCellSmartTag(TableCell cell)
{
return new TextObjectSmartTag(cell);
}
internal override void HandleCellDoubleClick(TableCell cell)
{
if (!cell.HasRestriction(Restrictions.DontEdit) && cell.InvokeEditor())
Report.Designer.SetModified(this, "Change");
}
#endregion
#region private methods
partial void InitTag()
{
expandingTag = new ExpandingTag(this);
}
private void DrawDesign(FRPaintEventArgs e)
{
if (IsDesigning && IsSelected)
{
e.Graphics.DrawImage(Report.Designer.GetImage(152), (int)(AbsRight * e.ScaleX + 2), (int)(AbsBottom * e.ScaleY + 3));
expandingTag.Draw(e);
}
}
#endregion
///
/// Represent expanding tags for add a new row/column.
///
partial class ExpandingTag
{
internal enum TriggeredRegion
{
None,
NewColumn,
NewRow,
ActiveNewColumn,
ActiveNewRow
}
private TableObject table;
internal TriggeredRegion region;
private TriggeredRegion prevRegion;
internal int section;
public void OnClick(FRMouseEventArgs e)
{
if (region == TriggeredRegion.ActiveNewColumn)
{
TableColumn column = new TableColumn();
table.Columns.Insert(section + 1, column);
table.CreateUniqueNames();
table.Report.Designer.SelectedObjects.Clear();
table.Report.Designer.SelectedObjects.Add(column);
prevRegion = region;
region = TriggeredRegion.None;
e.handled = true;
e.activeObject = column;
table.Report.Designer.SetModified(null, "Change");
}
else if (region == TriggeredRegion.ActiveNewRow)
{
TableRow row = new TableRow();
table.Rows.Insert(section + 1, row);
table.CreateUniqueNames();
table.Report.Designer.SelectedObjects.Clear();
table.Report.Designer.SelectedObjects.Add(row);
prevRegion = region;
region = TriggeredRegion.None;
e.handled = true;
e.activeObject = row;
table.FixParentHeight();
table.Report.Designer.SetModified(null, "Change");
}
}
public void OnMove(FRMouseEventArgs e)
{
if (table.IsSelected)
{
if (table.Parent is ReportComponentBase parent && (parent.AbsBottom < e.y || parent.AbsRight < e.x))
{
if (region != TriggeredRegion.None)
prevRegion = region;
region = TriggeredRegion.None;
}
else if (table.AbsTop > e.y && table.AbsTop - 16 < e.y)
{
for (int i = 0; i < table.ColumnCount; i++)
{
if (Math.Abs(table.Columns[i].AbsRight - e.x) < 16)
{
prevRegion = region;
if (Math.Abs(table.Columns[i].AbsRight - e.x) < 8)
{
region = TriggeredRegion.ActiveNewColumn;
e.cursor = Cursors.Default;
}
else
region = TriggeredRegion.NewColumn;
section = i;
e.handled = true;
break;
}
else
{
if (region != TriggeredRegion.None)
prevRegion = region;
region = TriggeredRegion.None;
}
}
}
else if (table.AbsLeft > e.x && table.AbsLeft - 16 < e.x)
{
for (int i = 0; i < table.RowCount; i++)
{
if (Math.Abs(table.Rows[i].AbsBottom - e.y) < 16)
{
if (Math.Abs(table.Rows[i].AbsBottom - e.y) < 8)
{
region = TriggeredRegion.ActiveNewRow;
e.cursor = Cursors.Default;
}
else
region = TriggeredRegion.NewRow;
section = i;
e.handled = true;
break;
}
else
{
if (region != TriggeredRegion.None)
prevRegion = region;
region = TriggeredRegion.None;
}
}
}
else
{
prevRegion = region;
region = TriggeredRegion.None;
}
if (region != prevRegion)
(table.Report.Designer.ActiveReportTab.ActivePageDesigner as ReportPageDesigner).Workspace.Refresh();
}
}
///
/// Draw expanding tag.
///
///
public void Draw(FRPaintEventArgs e)
{
if (table.IsDesigning && table.IsSelected)
{
if (region == TriggeredRegion.NewColumn || region == TriggeredRegion.ActiveNewColumn)
{
using (Pen pen = new Pen(region == TriggeredRegion.ActiveNewColumn ? Color.CornflowerBlue : Color.LightGray))
{
using (SolidBrush brush = new SolidBrush(Color.White))
{
float right = table.Columns[section].AbsRight;
RectangleF rect = new RectangleF(
(float)Math.Round((right - 8) * e.ScaleX),
(float)Math.Round((table.AbsTop - 16) * e.ScaleY),
(float)Math.Ceiling(16 * e.ScaleX),
(float)Math.Ceiling(16 * e.ScaleY)
);
e.Graphics.FillAndDrawEllipse(pen, brush, rect);
e.Graphics.FillRectangle(brush, (right - 2) * e.ScaleX, (table.AbsTop - 2) * e.ScaleY, 4 * e.ScaleX, (table.Height + 2) * e.ScaleY);
e.Graphics.DrawLine(pen, (right - 2) * e.ScaleX, (table.AbsTop) * e.ScaleY, (right - 2) * e.ScaleX, (table.AbsBottom + 1) * e.ScaleY);
e.Graphics.DrawLine(pen, (right + 2) * e.ScaleX, (table.AbsTop) * e.ScaleY, (right + 2) * e.ScaleX, (table.AbsBottom + 1) * e.ScaleY);
pen.Width = 2 * e.ScaleY;
e.Graphics.DrawLine(pen, rect.Left + 2 * e.ScaleX, (rect.Top + rect.Bottom) / 2, rect.Right - 2 * e.ScaleX, (rect.Top + rect.Bottom) / 2);
e.Graphics.DrawLine(pen, (rect.Right + rect.Left) / 2, rect.Top + 2 * e.ScaleY, (rect.Right + rect.Left) / 2, rect.Bottom - 2 * e.ScaleY);
}
}
}
else if (region == TriggeredRegion.NewRow || region == TriggeredRegion.ActiveNewRow)
{
using (Pen pen = new Pen(region == TriggeredRegion.ActiveNewRow ? Color.CornflowerBlue : Color.LightGray))
{
using (SolidBrush brush = new SolidBrush(Color.White))
{
float bottom = table.Rows[section].AbsBottom;
RectangleF rect = new RectangleF(
(float)Math.Round((table.AbsLeft - 16) * e.ScaleX),
(float)Math.Round((bottom - 8) * e.ScaleY),
(float)Math.Ceiling(16 * e.ScaleX),
(float)Math.Ceiling(16 * e.ScaleY)
);
e.Graphics.FillAndDrawEllipse(pen, brush, rect);
e.Graphics.FillRectangle(brush, (table.AbsLeft - 2) * e.ScaleX, (bottom - 2) * e.ScaleY, (table.Width + 2) * e.ScaleX, 4 * e.ScaleY);
e.Graphics.DrawLine(pen, (table.AbsLeft) * e.ScaleX, (bottom - 2) * e.ScaleY, (table.AbsRight + 1) * e.ScaleX, (bottom - 2) * e.ScaleY);
e.Graphics.DrawLine(pen, (table.AbsLeft) * e.ScaleX, (bottom + 2) * e.ScaleY, (table.AbsRight + 1) * e.ScaleX, (bottom + 2) * e.ScaleY);
pen.Width = 2 * e.ScaleY;
e.Graphics.DrawLine(pen, rect.Left + 2 * e.ScaleX, (rect.Top + rect.Bottom) / 2, rect.Right - 2 * e.ScaleX, (rect.Top + rect.Bottom) / 2);
e.Graphics.DrawLine(pen, (rect.Right + rect.Left) / 2, rect.Top + 2 * e.ScaleY, (rect.Right + rect.Left) / 2, rect.Bottom - 2 * e.ScaleY);
}
}
}
}
}
public ExpandingTag(TableObject table)
{
this.table = table;
}
}
}
}