123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755 |
- using System;
- using System.ComponentModel;
- using System.Windows.Forms;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using FastReport.Table;
- using FastReport.Data;
- using FastReport.Utils;
- using FastReport.Forms;
- namespace FastReport.Matrix
- {
- internal enum MatrixElement
- {
- None,
- Column,
- Row,
- Cell
- }
- partial class MatrixObject
- {
- #region Fields
- internal TableCell selectedCell;
- private bool dragSelectedCell;
- internal DragInfo dragInfo;
- #endregion
- #region Properties
- /// <summary>
- /// This property is not relevant to this class.
- /// </summary>
- [Browsable(false)]
- public override int ColumnCount
- {
- get { return base.ColumnCount; }
- set { base.ColumnCount = value; }
- }
- /// <summary>
- /// This property is not relevant to this class.
- /// </summary>
- [Browsable(false)]
- public override int RowCount
- {
- get { return base.RowCount; }
- set { base.RowCount = value; }
- }
- /// <summary>
- /// This property is not relevant to this class.
- /// </summary>
- [Browsable(false)]
- public new int FixedRows
- {
- get { return base.FixedRows; }
- set { base.FixedRows = value; }
- }
- /// <summary>
- /// This property is not relevant to this class.
- /// </summary>
- [Browsable(false)]
- public new int FixedColumns
- {
- get { return base.FixedColumns; }
- set { base.FixedColumns = value; }
- }
- /// <summary>
- /// This property is not relevant to this class.
- /// </summary>
- [Browsable(false)]
- public new bool CanBreak
- {
- get { return base.CanBreak; }
- set { base.CanBreak = value; }
- }
- /// <summary>
- /// This property is not relevant to this class.
- /// </summary>
- [Browsable(false)]
- public new bool GrowToBottom
- {
- get { return base.GrowToBottom; }
- set { base.GrowToBottom = value; }
- }
- private bool DragCellMode
- {
- get { return selectedCell != null && dragSelectedCell; }
- }
- #endregion
- #region Private Methods
- internal void RefreshTemplate(bool reset)
- {
- Helper.UpdateDescriptors();
- for (int x = 0; x < Helper.BodyWidth; x++)
- {
- for (int y = 0; y < Helper.BodyHeight; y++)
- {
- TableCell cell = this[x + FixedColumns, y + FixedRows];
- if (reset)
- cell.Text = "";
- else
- cell.SetFlags(Flags.CanEdit, false);
- }
- }
- MatrixElement element;
- MatrixDescriptor descriptor;
- bool isTotal;
- for (int x = 0; x < ColumnCount; x++)
- {
- for (int y = 0; y < RowCount; y++)
- {
- TableCell cell = this[x, y];
- GetMatrixElement(cell, out element, out descriptor, out isTotal);
- bool enableSmartTag = descriptor != null && !isTotal;
- cell.SetFlags(Flags.HasSmartTag, enableSmartTag);
- }
- }
- }
- internal void DrawSelectedCellFrame(FRPaintEventArgs e, TableCell cell)
- {
- Pen p = e.Cache.GetPen(Color.Black, 3, System.Drawing.Drawing2D.DashStyle.Solid);
- e.Graphics.DrawRectangle(p, cell.AbsLeft * e.ScaleX, cell.AbsTop * e.ScaleY,
- cell.Width * e.ScaleX, cell.Height * e.ScaleY);
- }
- internal void DrawDragIndicator(FRPaintEventArgs e)
- {
- dragInfo.targetCell.DrawDragAcceptFrame(e, Color.Red);
- if (dragInfo.indicator.Width > 0 || dragInfo.indicator.Height > 0)
- {
- IGraphics g = e.Graphics;
- int left = (int)Math.Round((dragInfo.indicator.Left + AbsLeft) * e.ScaleX);
- int top = (int)Math.Round((dragInfo.indicator.Top + AbsTop) * e.ScaleY);
- int right = (int)Math.Round(dragInfo.indicator.Width * e.ScaleX) + left;
- int bottom = (int)Math.Round(dragInfo.indicator.Height * e.ScaleY) + top;
- Pen p = e.Cache.GetPen(Color.Red, 1, DashStyle.Solid);
- g.DrawLine(p, left, top, right, bottom);
- p = Pens.Red;
- Brush b = Brushes.Red;
- if (dragInfo.indicator.Width == 0)
- {
- Point[] poly = new Point[] {
- new Point(left, top),
- new Point(left - 4, top - 4),
- new Point(left + 4, top - 4),
- new Point(left, top) };
- g.FillPolygon(b, poly);
- g.DrawPolygon(p, poly);
- poly = new Point[] {
- new Point(left, bottom),
- new Point(left - 4, bottom + 4),
- new Point(left + 4, bottom + 4),
- new Point(left, bottom) };
- g.FillPolygon(b, poly);
- g.DrawPolygon(p, poly);
- }
- else
- {
- Point[] poly = new Point[] {
- new Point(left, top),
- new Point(left - 4, top - 4),
- new Point(left - 4, top + 4),
- new Point(left, top) };
- g.FillPolygon(b, poly);
- g.DrawPolygon(p, poly);
- poly = new Point[] {
- new Point(right, top),
- new Point(right + 4, top - 4),
- new Point(right + 4, top + 4),
- new Point(right, top) };
- g.FillPolygon(b, poly);
- g.DrawPolygon(p, poly);
- }
- }
- }
- private void GetMatrixElement(TableCell cell, out MatrixElement element, out MatrixDescriptor descriptor,
- out bool isTotal)
- {
- element = MatrixElement.None;
- descriptor = null;
- isTotal = false;
- bool noColumns = Data.Columns.Count == 0;
- bool noRows = Data.Rows.Count == 0;
- bool noCells = Data.Cells.Count == 0;
- // create temporary descriptors
- if (noColumns)
- Data.Columns.Add(new MatrixHeaderDescriptor("", false));
- if (noRows)
- Data.Rows.Add(new MatrixHeaderDescriptor("", false));
- if (noCells)
- Data.Cells.Add(new MatrixCellDescriptor());
- Helper.UpdateDescriptors();
- foreach (MatrixHeaderDescriptor descr in Data.Columns)
- {
- if (descr.TemplateCell == cell || descr.TemplateTotalCell == cell)
- {
- element = MatrixElement.Column;
- if (!noColumns)
- descriptor = descr;
- isTotal = descr.TemplateTotalCell == cell;
- }
- }
- foreach (MatrixHeaderDescriptor descr in Data.Rows)
- {
- if (descr.TemplateCell == cell || descr.TemplateTotalCell == cell)
- {
- element = MatrixElement.Row;
- if (!noRows)
- descriptor = descr;
- isTotal = descr.TemplateTotalCell == cell;
- }
- }
- foreach (MatrixCellDescriptor descr in Data.Cells)
- {
- if (descr.TemplateCell == cell)
- {
- element = MatrixElement.Cell;
- if (!noCells)
- descriptor = descr;
- }
- }
- if (cell.Address.X >= FixedColumns && cell.Address.Y >= FixedRows)
- element = MatrixElement.Cell;
- if (noColumns)
- Data.Columns.Clear();
- if (noRows)
- Data.Rows.Clear();
- if (noCells)
- Data.Cells.Clear();
- }
- #endregion
- #region Protected Methods
- /// <inheritdoc/>
- protected override SelectionPoint[] GetSelectionPoints()
- {
- if (AutoSize)
- return new SelectionPoint[] { new SelectionPoint(AbsLeft, AbsTop, SizingPoint.LeftTop) };
- return base.GetSelectionPoints();
- }
- #endregion
- #region Public Methods
- /// <inheritdoc/>
- public override void Draw(FRPaintEventArgs e)
- {
- if (IsDesigning && AutoSize)
- {
- AutoSize = true;
- CalcHeight();
- }
- base.Draw(e);
- if (selectedCell != null)
- DrawSelectedCellFrame(e, selectedCell);
- if (dragInfo.target != MatrixElement.None)
- DrawDragIndicator(e);
- if (!IsResultMatrix)
- RefreshTemplate(false);
- }
- /// <inheritdoc/>
- public override void SelectionChanged()
- {
- base.SelectionChanged();
- this.selectedCell = null;
- dragInfo.source = MatrixElement.None;
- dragInfo.sourceDescriptor = null;
- if (!IsSelected || Report.Designer.SelectedObjects.Count != 1)
- return;
- TableCell selectedCell = Report.Designer.SelectedObjects[0] as TableCell;
- if (selectedCell == null)
- return;
- bool isTotal;
- GetMatrixElement(selectedCell, out dragInfo.source, out dragInfo.sourceDescriptor, out isTotal);
- if (dragInfo.sourceDescriptor == null || isTotal)
- {
- dragInfo.source = MatrixElement.None;
- dragInfo.sourceDescriptor = null;
- }
- else
- this.selectedCell = selectedCell;
- }
- /// <inheritdoc/>
- public override void HandleMouseDown(FRMouseEventArgs e)
- {
- if (DragCellMode)
- {
- e.handled = true;
- e.mode = WorkspaceMode2.Custom;
- e.activeObject = this;
- }
- else
- base.HandleMouseDown(e);
- }
- /// <inheritdoc/>
- public override void HandleMouseMove(FRMouseEventArgs e)
- {
- if (DragCellMode && e.button == MouseButtons.Left)
- {
- e.DragSource = selectedCell;
- HandleDragOver(e);
- }
- else
- {
- base.HandleMouseMove(e);
- if (AutoSize && (MouseMode == MouseMode.ResizeColumn || MouseMode == MouseMode.ResizeRow))
- {
- MouseMode = MouseMode.None;
- e.handled = false;
- e.mode = WorkspaceMode2.None;
- e.cursor = Cursors.Default;
- }
- if (selectedCell != null && e.button == MouseButtons.None)
- {
- PointF point = new PointF(e.x, e.y);
- RectangleF innerRect = selectedCell.AbsBounds;
- RectangleF outerRect = innerRect;
- innerRect.Inflate(-3, -3);
- outerRect.Inflate(3, 3);
- dragSelectedCell = outerRect.Contains(point) && !innerRect.Contains(point);
- if (dragSelectedCell)
- {
- e.handled = true;
- e.cursor = Cursors.SizeAll;
- }
- }
- }
- }
- /// <inheritdoc/>
- public override void HandleMouseUp(FRMouseEventArgs e)
- {
- if (DragCellMode)
- {
- HandleDragDrop(e);
- Report.Designer.SetModified(this, "Change");
- selectedCell = null;
- dragSelectedCell = false;
- }
- else
- base.HandleMouseUp(e);
- }
- /// <inheritdoc/>
- public override void HandleDragOver(FRMouseEventArgs e)
- {
- // matrix that is defined in the base report cannot be configured such way.
- if (IsAncestor)
- return;
- dragInfo.target = MatrixElement.None;
- dragInfo.indicator = Rectangle.Empty;
- if (!(e.DragSource is TextObject))
- return;
- bool noColumns = Data.Columns.Count == 0;
- bool noRows = Data.Rows.Count == 0;
- bool noCells = Data.Cells.Count == 0;
- // create temporary descriptors
- if (noColumns)
- Data.Columns.Add(new MatrixHeaderDescriptor("", false));
- if (noRows)
- Data.Rows.Add(new MatrixHeaderDescriptor("", false));
- if (noCells)
- Data.Cells.Add(new MatrixCellDescriptor());
- Helper.UpdateDescriptors();
- PointF point = new PointF(e.x, e.y);
- // determine the location where to insert a new item: column, row or cell
- foreach (MatrixHeaderDescriptor descr in Data.Columns)
- {
- TableCell cell = descr.TemplateCell;
- if (cell != e.DragSource && cell.PointInObject(point))
- {
- dragInfo.target = MatrixElement.Column;
- dragInfo.targetIndex = Data.Columns.IndexOf(descr) + 1;
- dragInfo.targetCell = cell;
- float top = cell.Bottom;
- float width = cell.Width;
- if (noColumns || point.Y < cell.AbsTop + cell.Height / 2)
- {
- if (descr.TemplateTotalCell != null)
- width += descr.TemplateTotalCell.Width;
- top = cell.Top;
- dragInfo.targetIndex--;
- }
- dragInfo.indicator = new RectangleF(cell.Left, top, noColumns ? 0 : width, 0);
- e.dragMessage = Res.Get("ComponentsMisc,Matrix,NewColumn");
- }
- }
- foreach (MatrixHeaderDescriptor descr in Data.Rows)
- {
- TableCell cell = descr.TemplateCell;
- if (cell != e.DragSource && cell.PointInObject(point))
- {
- dragInfo.target = MatrixElement.Row;
- dragInfo.targetIndex = Data.Rows.IndexOf(descr) + 1;
- dragInfo.targetCell = cell;
- float left = cell.Right;
- float height = cell.Height;
- if (noRows || point.X < cell.AbsLeft + cell.Width / 2)
- {
- if (descr.TemplateTotalCell != null)
- height += descr.TemplateTotalCell.Height;
- left = cell.Left;
- dragInfo.targetIndex--;
- }
- dragInfo.indicator = new RectangleF(left, cell.Top, 0, noRows ? 0 : height);
- e.dragMessage = Res.Get("ComponentsMisc,Matrix,NewRow");
- }
- }
- foreach (MatrixCellDescriptor descr in Data.Cells)
- {
- TableCell cell = descr.TemplateCell;
- if (cell != e.DragSource && cell.PointInObject(point))
- {
- dragInfo.target = MatrixElement.Cell;
- dragInfo.targetCell = cell;
- bool preferLeftRight = Math.Min(point.X - cell.AbsLeft, cell.AbsRight - point.X) < 10;
- if (Data.Cells.Count < 2 || CellsSideBySide)
- {
- dragInfo.targetIndex = Data.Cells.IndexOf(descr) + 1;
- dragInfo.cellsSideBySide = true;
- float left = cell.Right;
- if (point.X < cell.AbsLeft + cell.Width / 2)
- {
- left = cell.Left;
- dragInfo.targetIndex--;
- }
- dragInfo.indicator = new RectangleF(left, cell.Top, 0, cell.Height);
- }
- if ((Data.Cells.Count < 2 && !preferLeftRight) || (Data.Cells.Count >= 2 && !CellsSideBySide))
- {
- dragInfo.targetIndex = Data.Cells.IndexOf(descr) + 1;
- dragInfo.cellsSideBySide = false;
- float top = cell.Bottom;
- if (point.Y < cell.AbsTop + cell.Height / 2)
- {
- top = cell.Top;
- dragInfo.targetIndex--;
- }
- dragInfo.indicator = new RectangleF(cell.Left, top, cell.Width, 0);
- }
- if (noCells)
- {
- dragInfo.targetIndex = 0;
- dragInfo.indicator = RectangleF.Empty;
- }
- e.dragMessage = Res.Get("ComponentsMisc,Matrix,NewCell");
- }
- }
- if (noColumns)
- Data.Columns.Clear();
- if (noRows)
- Data.Rows.Clear();
- if (noCells)
- Data.Cells.Clear();
- e.handled = PointInObject(point);
- }
- /// <inheritdoc/>
- public override void HandleDragDrop(FRMouseEventArgs e)
- {
- if (dragInfo.target != MatrixElement.None)
- {
- string draggedText = (e.DragSource as TextObject).Text;
- MatrixDescriptor sourceDescr = dragInfo.sourceDescriptor;
- MatrixDescriptor targetDescr = null;
- // insert new item.
- switch (dragInfo.target)
- {
- case MatrixElement.Column:
- targetDescr = new MatrixHeaderDescriptor(draggedText);
- if (sourceDescr != null)
- targetDescr.Assign(sourceDescr);
- if (dragInfo.source == MatrixElement.Cell)
- targetDescr.TemplateCell = null;
- Data.Columns.Insert(dragInfo.targetIndex, targetDescr as MatrixHeaderDescriptor);
- break;
- case MatrixElement.Row:
- targetDescr = new MatrixHeaderDescriptor(draggedText);
- if (sourceDescr != null)
- targetDescr.Assign(sourceDescr);
- if (dragInfo.source == MatrixElement.Cell)
- targetDescr.TemplateCell = null;
- Data.Rows.Insert(dragInfo.targetIndex, targetDescr as MatrixHeaderDescriptor);
- break;
- case MatrixElement.Cell:
- targetDescr = new MatrixCellDescriptor(draggedText);
- if (sourceDescr != null)
- targetDescr.Assign(sourceDescr);
- if (dragInfo.source != MatrixElement.Cell)
- targetDescr.TemplateCell = null;
- CellsSideBySide = dragInfo.cellsSideBySide;
- Data.Cells.Insert(dragInfo.targetIndex, targetDescr as MatrixCellDescriptor);
- break;
- }
- // remove source item
- switch (dragInfo.source)
- {
- case MatrixElement.Column:
- Data.Columns.Remove(sourceDescr as MatrixHeaderDescriptor);
- break;
- case MatrixElement.Row:
- Data.Rows.Remove(sourceDescr as MatrixHeaderDescriptor);
- break;
- case MatrixElement.Cell:
- Data.Cells.Remove(sourceDescr as MatrixCellDescriptor);
- break;
- }
- if (DataSource == null)
- {
- if (draggedText.StartsWith("[") && draggedText.EndsWith("]"))
- draggedText = draggedText.Substring(1, draggedText.Length - 2);
- DataSource = DataHelper.GetDataSource(Report.Dictionary, draggedText);
- }
- Helper.BuildTemplate();
- if (targetDescr != null)
- {
- Report.Designer.SelectedObjects.Clear();
- Report.Designer.SelectedObjects.Add(targetDescr.TemplateCell);
- }
- }
- dragInfo.target = MatrixElement.None;
- dragInfo.source = MatrixElement.None;
- }
- /// <inheritdoc/>
- public override void OnBeforeInsert(int flags)
- {
- BuildTemplate();
- }
- /// <inheritdoc/>
- public override ContextMenuBase GetContextMenu()
- {
- return new MatrixObjectMenu(Report.Designer);
- }
- internal override ContextMenuBase GetCellContextMenu(TableCell cell)
- {
- if (Report.Designer.SelectedObjects.Count == 1)
- {
- MatrixElement element;
- MatrixDescriptor descriptor;
- bool isTotal;
- GetMatrixElement(cell, out element, out descriptor, out isTotal);
- switch (element)
- {
- case MatrixElement.Column:
- case MatrixElement.Row:
- if (isTotal)
- return new MatrixTotalMenu(this, element, descriptor);
- else if (descriptor != null)
- return new MatrixHeaderMenu(this, element, descriptor);
- break;
- case MatrixElement.Cell:
- if (descriptor != null)
- return new MatrixCellMenu(this, element, descriptor);
- break;
- }
- }
- return new MatrixCellMenuBase(this, MatrixElement.None, null);
- }
- internal override SmartTagBase GetCellSmartTag(TableCell cell)
- {
- MatrixElement element;
- MatrixDescriptor descriptor;
- bool isTotal;
- GetMatrixElement(cell, out element, out descriptor, out isTotal);
- if (descriptor != null && !isTotal)
- return new MatrixCellSmartTag(this, descriptor);
- return null;
- }
- internal override void HandleCellDoubleClick(TableCell cell)
- {
- MatrixElement element;
- MatrixDescriptor descriptor;
- bool isTotal;
- GetMatrixElement(cell, out element, out descriptor, out isTotal);
- if (descriptor != null && !isTotal)
- {
- using (ExpressionEditorForm form = new ExpressionEditorForm(Report))
- {
- form.ExpressionText = descriptor.Expression;
- if (form.ShowDialog() == DialogResult.OK)
- {
- descriptor.Expression = form.ExpressionText;
- BuildTemplate();
- Report.Designer.SetModified(cell, "Change");
- }
- }
- }
- else
- {
- if (cell.HasFlag(Flags.CanEdit) && !cell.HasRestriction(Restrictions.DontEdit) && cell.InvokeEditor())
- Report.Designer.SetModified(cell, "Change");
- }
- }
- /// <inheritdoc/>
- public override void HandleKeyDown(Control sender, KeyEventArgs e)
- {
- bool myKey = false;
- SelectedObjectCollection selection = Report.Designer.SelectedObjects;
- if (!IsSelected || !(selection[0] is TableCell))
- return;
- TableCell cell = selection[0] as TableCell;
- MatrixElement element;
- MatrixDescriptor descriptor;
- bool isTotal;
- GetMatrixElement(cell, out element, out descriptor, out isTotal);
- switch (e.KeyCode)
- {
- case Keys.Delete:
- if (element != MatrixElement.None)
- {
- if (descriptor != null && !IsAncestor)
- {
- if (isTotal)
- (descriptor as MatrixHeaderDescriptor).Totals = false;
- else
- {
- switch (element)
- {
- case MatrixElement.Column:
- Data.Columns.Remove(descriptor as MatrixHeaderDescriptor);
- break;
- case MatrixElement.Row:
- Data.Rows.Remove(descriptor as MatrixHeaderDescriptor);
- break;
- case MatrixElement.Cell:
- Data.Cells.Remove(descriptor as MatrixCellDescriptor);
- break;
- }
- }
- }
- myKey = true;
- }
- break;
- case Keys.Enter:
- if (descriptor != null && !isTotal)
- {
- HandleCellDoubleClick(cell);
- myKey = true;
- }
- break;
- }
- if (myKey)
- {
- e.Handled = true;
- BuildTemplate();
- Report.Designer.SetModified(this, "Change");
- }
- else
- base.HandleKeyDown(sender, e);
- }
- #endregion
- private void InitDesign()
- {
- dragInfo = new DragInfo();
- }
- internal class DragInfo
- {
- public MatrixElement source;
- public MatrixElement target;
- public MatrixDescriptor sourceDescriptor;
- public int targetIndex;
- public RectangleF indicator;
- public bool cellsSideBySide;
- public TableCell targetCell;
- }
- }
- }
|