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; } } } }