using System;
using System.Drawing;
using System.Windows.Forms;
using FastReport.Data;
using FastReport.Table;
using FastReport.Utils;
namespace FastReport.AdvMatrix
{
public partial class AdvMatrixObject
{
#region Fields
internal DragInfo dragInfo = new DragInfo();
#endregion
#region Properties
private bool DragCellMode
{
get { return dragInfo.SelectedCell != null && dragInfo.DragSelectedCell; }
}
#endregion
#region Private Methods
#endregion
#region Public Methods
///
public override void SelectionChanged()
{
base.SelectionChanged();
dragInfo.SelectedCell = null;
dragInfo.Source = MatrixElement.None;
if (!IsSelected || Report.Designer.SelectedObjects.Count != 1)
return;
TableCell cell = Report.Designer.SelectedObjects[0] as TableCell;
if (cell == null)
return;
MatrixElement el = cell.GetMatrixElement();
if (el == MatrixElement.Column || el == MatrixElement.Row)
{
dragInfo.SelectedCell = cell;
dragInfo.Source = el;
}
}
///
public override void HandleMouseDown(FRMouseEventArgs e)
{
if (DragCellMode)
{
e.handled = true;
e.mode = WorkspaceMode2.Custom;
e.activeObject = this;
}
else
base.HandleMouseDown(e);
}
///
public override void HandleMouseMove(FRMouseEventArgs e)
{
if (DragCellMode && e.button == MouseButtons.Left)
{
HandleDragOver(e);
}
else
{
base.HandleMouseMove(e);
if (dragInfo.SelectedCell != null && e.button == MouseButtons.None)
{
PointF point = new PointF(e.x, e.y);
RectangleF innerRect = dragInfo.SelectedCell.AbsBounds;
RectangleF outerRect = innerRect;
innerRect.Inflate(-3, -3);
outerRect.Inflate(3, 3);
dragInfo.DragSelectedCell = outerRect.Contains(point) && !innerRect.Contains(point);
if (dragInfo.DragSelectedCell)
{
e.DragSource = dragInfo.SelectedCell;
e.handled = true;
e.cursor = Cursors.SizeAll;
}
}
}
}
///
public override void HandleMouseUp(FRMouseEventArgs e)
{
if (DragCellMode)
{
HandleDragDrop(e);
Report.Designer.SetModified(this, "Change");
Report.Designer.SelectedObjects.Clear();
Report.Designer.SelectedObjects.Add(dragInfo.SelectedCell);
dragInfo.DragSelectedCell = false;
}
else
base.HandleMouseUp(e);
}
///
public override void HandleDragOver(FRMouseEventArgs e)
{
// matrix that is defined in the base report cannot be configured this way
if (IsAncestor)
return;
dragInfo.Target = MatrixElement.None;
dragInfo.TargetCell = null;
dragInfo.Indicator = Rectangle.Empty;
if (!(e.DragSource is TextObject))
return;
PointF point = new PointF(e.x, e.y);
for (int x = 0; x < Columns.Count; x++)
{
for (int y = 0; y < Rows.Count; y++)
{
TableCell cell = this[x, y];
if (cell != e.DragSource && cell.PointInObject(point))
{
MatrixElement el = cell.GetMatrixElement();
if (el == MatrixElement.Column)
{
dragInfo.SetHeaderTargetInfo(cell, point);
e.dragMessage = Res.Get("ComponentsMisc,Matrix,NewColumn");
}
else if (el == MatrixElement.Row)
{
dragInfo.SetHeaderTargetInfo(cell, point);
e.dragMessage = Res.Get("ComponentsMisc,Matrix,NewRow");
}
else if (el == MatrixElement.Cell && dragInfo.Source == MatrixElement.None)
{
dragInfo.SetCellTargetInfo(cell, point);
e.dragMessage = Res.Get("ComponentsMisc,Matrix,NewCell");
}
else if (dragInfo.Source == MatrixElement.None)
{
dragInfo.Target = el;
dragInfo.TargetCell = cell;
}
e.handled = true;
return;
}
}
}
e.handled = PointInObject(point);
}
///
public override void HandleDragDrop(FRMouseEventArgs e)
{
if (e.DragSource == null)
return;
TextObject draggedText = e.DragSource as TextObject;
if (dragInfo.Target == MatrixElement.Column || dragInfo.Target == MatrixElement.Row)
{
HeaderDescriptor sourceDescr = dragInfo.SelectedCell != null ? dragInfo.SelectedCell.GetHeaderDescriptor() : null;
HeaderDescriptor targetDescr = dragInfo.TargetCell.GetHeaderDescriptor();
HeaderDescriptor newItem = sourceDescr;
HeaderInsertPosition position = dragInfo.InsertPosition;
if (sourceDescr == null)
{
// we're inserting a new item from the Data window
newItem = new HeaderDescriptor();
newItem.Expression = draggedText.Text;
}
else
{
// we're reordering header items
// Whole descriptor tree can be inserted before or after target item, or as a child if there is no children in the target.
// Also target should not be a child of source. In other cases insert selected descriptor only
bool canDragItemTree = !targetDescr.HasParent(sourceDescr) &&
position != HeaderInsertPosition.Parent &&
(position != HeaderInsertPosition.Child || targetDescr.Items.Count == 0);
// Delete source descriptor from its current position.
if (canDragItemTree)
sourceDescr.DeleteTree();
else
sourceDescr.DeleteThis();
// item from another header: copy template items to fill in the cell area properly
if (dragInfo.Source != dragInfo.Target)
{
newItem.TemplateColumn = targetDescr.TemplateColumn;
newItem.TemplateRow = targetDescr.TemplateRow;
}
}
switch (position)
{
case HeaderInsertPosition.After:
targetDescr.InsertAfter(newItem);
break;
case HeaderInsertPosition.Before:
targetDescr.InsertBefore(newItem);
break;
case HeaderInsertPosition.Parent:
targetDescr.InsertParent(newItem);
break;
case HeaderInsertPosition.Child:
targetDescr.InsertChild(newItem);
break;
case HeaderInsertPosition.Inside:
targetDescr.InsertAfter(newItem);
targetDescr.DeleteThis();
break;
}
BuildTemplate();
FixParentHeight();
e.dragTarget = newItem.TemplateCell;
dragInfo.SelectedCell = newItem.TemplateCell;
if (sourceDescr == null)
newItem.TemplateCell.Format = draggedText.Format;
}
else if (dragInfo.Target == MatrixElement.Cell)
{
TableCell cell = dragInfo.TargetCell;
switch (dragInfo.Position)
{
case DragPosition.Right:
cell.InsertAfter(draggedText);
break;
case DragPosition.Left:
cell.InsertBefore(draggedText);
break;
case DragPosition.Top:
cell.InsertAbove(draggedText);
break;
case DragPosition.Bottom:
cell.InsertBelow(draggedText);
break;
case DragPosition.Inside:
cell.InsertInside(draggedText);
break;
}
FixParentHeight();
}
else if (dragInfo.Target == MatrixElement.Corner)
{
dragInfo.TargetCell.Text = draggedText.Text;
}
if (DataSource == null)
{
string text = draggedText.Text;
if (text.StartsWith("[") && text.EndsWith("]"))
text = text.Substring(1, text.Length - 2);
DataSource = DataHelper.GetDataSource(Report.Dictionary, text);
}
dragInfo.Target = MatrixElement.None;
dragInfo.TargetCell = null;
dragInfo.Source = MatrixElement.None;
}
#endregion
}
}