internal TableCellData CellData(int col) { while (col >= cells.Count) { cells.Add(new TableCellData()); } TableCellData cellData = cells[col]; cellData.Table = Parent as TableBase; cellData.Address = new Point(col, Index); return(cellData); }
public TableCell this[int col] { get { TableCellData cellData = CellData(col); TableCell cell = cellData.Cell; cell.SetParent(this); cell.SetValue(cellData.Value); return(cell); } set { TableCellData cellData = CellData(col); cellData.AttachCell(value); } }
internal List <Rectangle> GetSpanList() { if (spanList == null) { spanList = new List <Rectangle>(); for (int y = 0; y < Rows.Count; y++) { for (int x = 0; x < Columns.Count; x++) { TableCellData cell = GetCellData(x, y); if (cell.ColSpan > 1 || cell.RowSpan > 1) { spanList.Add(new Rectangle(x, y, cell.ColSpan, cell.RowSpan)); } } } } return(spanList); }
internal void CorrectSpansOnRowChange(int rowIndex, int correct) { if (lockCorrectSpans || (correct == 1 && rowIndex >= Rows.Count)) { return; } for (int y = 0; y < rowIndex; y++) { for (int x = 0; x < Columns.Count; x++) { TableCellData cell = GetCellData(x, y); if (rowIndex < y + cell.RowSpan) { cell.RowSpan += correct; } } } ResetSpanList(); }
private void AdjustSpannedCellWidth(TableCellData cell) { if (!AdjustSpannedCellsWidth) { return; } // check that spanned cell has enough width float columnsWidth = 0; for (int i = 0; i < cell.ColSpan; i++) { columnsWidth += Columns[cell.Address.X + i].Width; } // if cell is bigger than sum of column width, increase the last column width float cellWidth = cell.CalcWidth(); if (columnsWidth < cellWidth) { Columns[cell.Address.X + cell.ColSpan - 1].Width += cellWidth - columnsWidth; } }
internal void CorrectSpansOnColumnChange(int columnIndex, int correct) { if (lockCorrectSpans || (correct == 1 && columnIndex >= Columns.Count)) { return; } for (int y = 0; y < Rows.Count; y++) { for (int x = 0; x < columnIndex; x++) { TableCellData cell = GetCellData(x, y); if (columnIndex < x + cell.ColSpan) { cell.ColSpan += correct; } } // correct cells Rows[y].CorrectCellsOnColumnChange(columnIndex, correct); } ResetSpanList(); }
private void CopyCells(int originalColumnIndex, int originalRowIndex, int resultColumnIndex, int resultRowIndex) { TableCell cell = sourceTable[originalColumnIndex, originalRowIndex]; TableCellData cellTo = resultTable.GetCellData(resultColumnIndex, resultRowIndex); sourceTable.PrintingCell = cellTo; bool needData = true; if (AutoSpans) { if (rowsPriority) { // We are printing columns inside a row. Check if we need to finish the column cell. if (columnSpans.Count > 0) { SpanData spanData = columnSpans[0]; // check if we are printing the last column of the cell's span. From now, we will not accept // the first column. if (originalColumnIndex == spanData.originalCellOrigin.X + spanData.originalCell.ColSpan - 1) { spanData.finishFlag = true; } if ((spanData.finishFlag && originalColumnIndex == spanData.originalCellOrigin.X) || (originalColumnIndex < spanData.originalCellOrigin.X || originalColumnIndex > spanData.originalCellOrigin.X + spanData.originalCell.ColSpan - 1)) { columnSpans.Clear(); } else { spanData.resultCell.ColSpan++; needData = false; } } // add the column cell if it has ColSpan > 1 if (cell.ColSpan > 1 && columnSpans.Count == 0) { SpanData spanData = new SpanData(); columnSpans.Add(spanData); spanData.originalCell = cell; spanData.resultCell = cellTo; spanData.originalCellOrigin = new Point(originalColumnIndex, originalRowIndex); spanData.resultCellOrigin = new Point(resultColumnIndex, resultRowIndex); } // now check the row cells. Do this once for each row. if (printingColumnIndex == 0) { for (int i = 0; i < rowSpans.Count; i++) { SpanData spanData = rowSpans[i]; // check if we are printing the last row of the cell's span. From now, we will not accept // the first row. if (originalRowIndex == spanData.originalCellOrigin.Y + spanData.originalCell.RowSpan - 1) { spanData.finishFlag = true; } if ((spanData.finishFlag && originalRowIndex == spanData.originalCellOrigin.Y) || (originalRowIndex < spanData.originalCellOrigin.Y || originalRowIndex > spanData.originalCellOrigin.Y + spanData.originalCell.RowSpan - 1)) { rowSpans.RemoveAt(i); i--; } else { spanData.resultCell.RowSpan++; } } } // check if we should skip current cell because it is inside a span for (int i = 0; i < rowSpans.Count; i++) { SpanData spanData = rowSpans[i]; if (resultColumnIndex >= spanData.resultCellOrigin.X && resultColumnIndex <= spanData.resultCellOrigin.X + spanData.resultCell.ColSpan - 1 && resultRowIndex >= spanData.resultCellOrigin.Y && resultRowIndex <= spanData.resultCellOrigin.Y + spanData.resultCell.RowSpan) { needData = false; break; } } // add the row cell if it has RowSpan > 1 and not added yet if (cell.RowSpan > 1 && needData) { SpanData spanData = new SpanData(); rowSpans.Add(spanData); spanData.originalCell = cell; spanData.resultCell = cellTo; spanData.originalCellOrigin = new Point(originalColumnIndex, originalRowIndex); spanData.resultCellOrigin = new Point(resultColumnIndex, resultRowIndex); } } else { // We are printing rows inside a column. Check if we need to finish the row cell. if (rowSpans.Count > 0) { SpanData spanData = rowSpans[0]; // check if we are printing the last row of the cell's span. From now, we will not accept // the first row. if (originalRowIndex == spanData.originalCellOrigin.Y + spanData.originalCell.RowSpan - 1) { spanData.finishFlag = true; } if ((spanData.finishFlag && originalRowIndex == spanData.originalCellOrigin.Y) || (originalRowIndex < spanData.originalCellOrigin.Y || originalRowIndex > spanData.originalCellOrigin.Y + spanData.originalCell.RowSpan - 1)) { rowSpans.Clear(); } else { spanData.resultCell.RowSpan++; needData = false; } } // add the row cell if it has RowSpan > 1 if (cell.RowSpan > 1 && rowSpans.Count == 0) { SpanData spanData = new SpanData(); rowSpans.Add(spanData); spanData.originalCell = cell; spanData.resultCell = cellTo; spanData.originalCellOrigin = new Point(originalColumnIndex, originalRowIndex); spanData.resultCellOrigin = new Point(resultColumnIndex, resultRowIndex); } // now check the column cells. Do this once for each column. if (printingRowIndex == 0) { for (int i = 0; i < columnSpans.Count; i++) { SpanData spanData = columnSpans[i]; // check if we are printing the last column of the cell's span. From now, we will not accept // the first column. if (originalColumnIndex == spanData.originalCellOrigin.X + spanData.originalCell.ColSpan - 1) { spanData.finishFlag = true; } if ((spanData.finishFlag && originalColumnIndex == spanData.originalCellOrigin.X) || (originalColumnIndex < spanData.originalCellOrigin.X || originalColumnIndex > spanData.originalCellOrigin.X + spanData.originalCell.ColSpan - 1)) { columnSpans.RemoveAt(i); i--; } else { spanData.resultCell.ColSpan++; } } } // check if we should skip current cell because it is inside a span for (int i = 0; i < columnSpans.Count; i++) { SpanData spanData = columnSpans[i]; if (resultColumnIndex >= spanData.resultCellOrigin.X && resultColumnIndex <= spanData.resultCellOrigin.X + spanData.resultCell.ColSpan - 1 && resultRowIndex >= spanData.resultCellOrigin.Y && resultRowIndex <= spanData.resultCellOrigin.Y + spanData.resultCell.RowSpan) { needData = false; break; } } // add the column cell if it has ColSpan > 1 and not added yet if (cell.ColSpan > 1 && needData) { SpanData spanData = new SpanData(); columnSpans.Add(spanData); spanData.originalCell = cell; spanData.resultCell = cellTo; spanData.originalCellOrigin = new Point(originalColumnIndex, originalRowIndex); spanData.resultCellOrigin = new Point(resultColumnIndex, resultRowIndex); } } } else { cellTo.ColSpan = cell.ColSpan; cellTo.RowSpan = cell.RowSpan; } if (needData) { cell.SaveState(); cell.GetData(); cellTo.RunTimeAssign(cell, true); cell.RestoreState(); } }
/// <summary> /// Assigns another <see cref="TableCellData"/> instance. /// </summary> /// <param name="source">The table cell data that used as a source.</param> /// <remarks>This method is called when we copy cells or clone columns/rows in a designer.</remarks> public void Assign(TableCellData source) { AttachCell(source.Cell); }
/// <inheritdoc/> public int GetChildOrder(Base child) { TableCellData cellData = FindCellData(child as TableCell); return(cellData == null ? 0 : cells.IndexOf(cellData)); }
private float GeneratePage(int startColumn, int startRow, int columnsFit, int rowsFit, RectangleF bounds, List <Rectangle> spans) { // break spans foreach (Rectangle span in spans) { TableCellData spannedCell = GetCellData(span.Left, span.Top); TableCellData newSpannedCell = null; if (span.Left < startColumn && span.Right > startColumn) { if ((RepeatHeaders || RepeatRowHeaders) && span.Left < FixedColumns) { spannedCell.ColSpan = Math.Min(span.Right, startColumn + columnsFit) - startColumn + FixedColumns; } else { newSpannedCell = GetCellData(startColumn, span.Top); newSpannedCell.RunTimeAssign(spannedCell.Cell, true); newSpannedCell.ColSpan = Math.Min(span.Right, startColumn + columnsFit) - startColumn; newSpannedCell.RowSpan = spannedCell.RowSpan; AdjustSpannedCellWidth(newSpannedCell); } } if (span.Left < startColumn + columnsFit && span.Right > startColumn + columnsFit) { spannedCell.ColSpan = startColumn + columnsFit - span.Left; AdjustSpannedCellWidth(spannedCell); } if (span.Top < startRow && span.Bottom > startRow) { if ((RepeatHeaders || RepeatColumnHeaders) && span.Top < FixedRows) { spannedCell.RowSpan = Math.Min(span.Bottom, startRow + rowsFit) - startRow + FixedRows; } } if (span.Top < startRow + rowsFit && span.Bottom > startRow + rowsFit) { spannedCell.RowSpan = startRow + rowsFit - span.Top; newSpannedCell = GetCellData(span.Left, startRow + rowsFit); newSpannedCell.RunTimeAssign(spannedCell.Cell, true); newSpannedCell.ColSpan = spannedCell.ColSpan; newSpannedCell.RowSpan = span.Bottom - (startRow + rowsFit); // break the cell text TableCell cell = spannedCell.Cell; using (TextObject tempObject = new TextObject()) { if (!cell.Break(tempObject)) { cell.Text = ""; } if (cell.CanBreak) { newSpannedCell.Text = tempObject.Text; } } // fix the row height float textHeight = newSpannedCell.Cell.CalcHeight(); float rowsHeight = 0; for (int i = 0; i < newSpannedCell.RowSpan; i++) { rowsHeight += Rows[i + startRow + rowsFit].Height; } if (rowsHeight < textHeight) { // fix the last row's height Rows[startRow + rowsFit + newSpannedCell.RowSpan - 1].Height += textHeight - rowsHeight; } } } // set visible columns ColumnsToSerialize.Clear(); if (RepeatHeaders || RepeatRowHeaders) { for (int i = 0; i < FixedColumns; i++) { if (Columns[i].Visible) { ColumnsToSerialize.Add(Columns[i]); } } if (startColumn < FixedColumns) { columnsFit -= FixedColumns - startColumn; startColumn = FixedColumns; } } // calc visible columns and last X coordinate of table for unlimited page width float tableEndX = Columns[0].Width; for (int i = startColumn; i < startColumn + columnsFit; i++) { if (Columns[i].Visible) { ColumnsToSerialize.Add(Columns[i]); tableEndX += Columns[i].Width; } } // set visible rows RowsToSerialize.Clear(); if (RepeatHeaders || RepeatColumnHeaders) { for (int i = 0; i < FixedRows; i++) { if (Rows[i].Visible) { RowsToSerialize.Add(Rows[i]); } } if (startRow < FixedRows) { rowsFit -= FixedRows - startRow; startRow = FixedRows; } } // calc visible rows and last Y coordinate of table for unlimited page height float tableEndY = Rows[0].Top; for (int i = startRow; i < startRow + rowsFit; i++) { if (Rows[i].Visible) { RowsToSerialize.Add(Rows[i]); tableEndY += Rows[i].Height; } } // include row header if (startRow != 0 && (RepeatHeaders || RepeatColumnHeaders)) { for (int i = 0; i < FixedRows; i++) { tableEndY += Rows[i].Height; } } // generate unlimited page if (Report.Engine.UnlimitedHeight || Report.Engine.UnlimitedWidth) { ReportPage page = Report.PreparedPages.GetPage(Report.Engine.CurPage); if (Report.Engine.UnlimitedHeight) { bounds.Height = tableEndY; } if (Report.Engine.UnlimitedWidth) { bounds.Width = tableEndX; } Report.PreparedPages.ModifyPage(Report.Engine.CurPage, page); } DataBand band = new DataBand(); band.Bounds = bounds; band.Objects.Add(this); Report.Engine.AddToPreparedPages(band); return(GetRowsHeight(startRow, rowsFit)); }
private void ProcessDuplicates(TableCell cell, int startX, int startY, List <Rectangle> list) { string cellAlias = cell.Alias; TableCellData cellData = cell.CellData; string cellText = cell.Text; CellDuplicates cellDuplicates = cell.CellDuplicates; Func <int, int> func = (row) => { int span = 0; for (int x = startX; x < ColumnCount; x++) { TableCell c = this[x, row]; if (IsInsideSpan(c, list)) { break; } if (c.Alias == cellAlias) { if (c.Text == cellText) { span++; } else { break; } } else { break; } } return(span); }; int colSpan = func(startY); int rowSpan = 1; for (int y = startY + 1; y < RowCount; y++) { int span = func(y); if (span < cellData.ColSpan) { break; } rowSpan++; } if (cellDuplicates == CellDuplicates.Clear) { for (int x = 0; x < colSpan; x++) { for (int y = 0; y < rowSpan; y++) { if (!(x == 0 && y == 0)) { GetCellData(x + startX, y + startY).Text = ""; } } } } else if (cellDuplicates == CellDuplicates.Merge || (cellDuplicates == CellDuplicates.MergeNonEmpty && !String.IsNullOrEmpty(cellText))) { cellData.ColSpan = colSpan; cellData.RowSpan = rowSpan; } list.Add(new Rectangle(startX, startY, colSpan, rowSpan)); }
/// <inheritdoc/> public override float CalcHeight() { if (ColumnCount * RowCount > 1000) { Config.ReportSettings.OnProgress(Report, Res.Get("ComponentsMisc,Table,CalcBounds"), 0, 0); } // calc width CalcWidth(); // first pass, calc non-spanned cells for (int y = 0; y < Rows.Count; y++) { TableRow row = Rows[y]; if (!row.AutoSize) { continue; } float rowHeight = IsDesigning ? 16 : -1; // calc the max row height for (int x = 0; x < Columns.Count; x++) { TableCellData cell = GetCellData(x, y); if (cell.RowSpan == 1) { float cellHeight = cell.CalcHeight(cell.Width); if (cellHeight > rowHeight) { rowHeight = cellHeight; } } } // update row height if (rowHeight != -1) { row.Height = rowHeight; } } // second pass, calc spanned cells for (int y = 0; y < Rows.Count; y++) { for (int x = 0; x < Columns.Count; x++) { TableCellData cell = GetCellData(x, y); if (cell.RowSpan > 1) { float cellHeight = cell.CalcHeight(cell.Width); // check that spanned rows have enough height float rowsHeight = 0; for (int i = 0; i < cell.RowSpan; i++) { if (y + i < Rows.Count) { rowsHeight += Rows[y + i].Height; } else { // Error, we don't have row, rowSpan has incorrect cell.RowSpan--; } } // if cell is bigger than sum of row heights, increase the last row height if (y + cell.RowSpan - 1 < Rows.Count) { TableRow lastRow = Rows[y + cell.RowSpan - 1]; if (rowsHeight < cellHeight && lastRow.AutoSize) { lastRow.Height += cellHeight - rowsHeight; } } } } } // finally, calculate the table height float height = 0; for (int i = 0; i < Rows.Count; i++) { height += Rows[i].Visible ? Rows[i].Height : 0; } return(height); }
/// <summary> /// Calculates and returns the table width, in pixels. /// </summary> public float CalcWidth() { // first pass, calc non-spanned cells for (int x = 0; x < Columns.Count; x++) { TableColumn column = Columns[x]; if (!column.AutoSize) { continue; } float columnWidth = IsDesigning ? 16 : -1; // calc the max column width for (int y = 0; y < Rows.Count; y++) { TableCellData cell = GetCellData(x, y); if (cell.ColSpan == 1) { float cellWidth = cell.CalcWidth(); if (cellWidth > columnWidth) { columnWidth = cellWidth; } } } // update column width if (columnWidth != -1) { column.Width = columnWidth; } } // second pass, calc spanned cells for (int x = 0; x < Columns.Count; x++) { Columns[x].MinimumBreakWidth = 0; for (int y = 0; y < Rows.Count; y++) { TableCellData cell = GetCellData(x, y); if (cell.ColSpan > 1) { float cellWidth = cell.CalcWidth(); if (AdjustSpannedCellsWidth && cellWidth > Columns[x].MinimumBreakWidth) { Columns[x].MinimumBreakWidth = cellWidth; } // check that spanned columns have enough width float columnsWidth = 0; for (int i = 0; i < cell.ColSpan; i++) { columnsWidth += Columns[x + i].Width; } // if cell is bigger than sum of column width, increase the last column width TableColumn lastColumn = Columns[x + cell.ColSpan - 1]; if (columnsWidth < cellWidth && lastColumn.AutoSize) { lastColumn.Width += cellWidth - columnsWidth; } } } } // finally, calculate the table width float width = 0; for (int i = 0; i < Columns.Count; i++) { width += Columns[i].Width; } lockColumnRowChange = true; Width = width; lockColumnRowChange = false; return(width); }
private float GeneratePage(int startColumn, int startRow, int columnsFit, int rowsFit, RectangleF bounds, List <Rectangle> spans) { // break spans foreach (Rectangle span in spans) { TableCellData spannedCell = GetCellData(span.Left, span.Top); TableCellData newSpannedCell = null; if (span.Left < startColumn && span.Right > startColumn) { if (RepeatHeaders && span.Left < FixedColumns) { spannedCell.ColSpan = Math.Min(span.Right, startColumn + columnsFit) - startColumn + FixedColumns; } else { newSpannedCell = GetCellData(startColumn, span.Top); newSpannedCell.RunTimeAssign(spannedCell.Cell, true); newSpannedCell.ColSpan = Math.Min(span.Right, startColumn + columnsFit) - startColumn; newSpannedCell.RowSpan = spannedCell.RowSpan; } } if (span.Left < startColumn + columnsFit && span.Right > startColumn + columnsFit) { spannedCell.ColSpan = startColumn + columnsFit - span.Left; } if (span.Top < startRow && span.Bottom > startRow) { if (RepeatHeaders && span.Top < FixedRows) { spannedCell.RowSpan = Math.Min(span.Bottom, startRow + rowsFit) - startRow + FixedRows; } } if (span.Top < startRow + rowsFit && span.Bottom > startRow + rowsFit) { spannedCell.RowSpan = startRow + rowsFit - span.Top; newSpannedCell = GetCellData(span.Left, startRow + rowsFit); newSpannedCell.RunTimeAssign(spannedCell.Cell, true); newSpannedCell.ColSpan = spannedCell.ColSpan; newSpannedCell.RowSpan = span.Bottom - (startRow + rowsFit); // break the cell text TableCell cell = spannedCell.Cell; using (TextObject tempObject = new TextObject()) { if (!cell.Break(tempObject)) { cell.Text = ""; } if (cell.CanBreak) { newSpannedCell.Text = tempObject.Text; } } // fix the row height float textHeight = newSpannedCell.Cell.CalcHeight(); float rowsHeight = 0; for (int i = 0; i < newSpannedCell.RowSpan; i++) { rowsHeight += Rows[i + startRow + rowsFit].Height; } if (rowsHeight < textHeight) { // fix the last row's height Rows[startRow + rowsFit + newSpannedCell.RowSpan - 1].Height += textHeight - rowsHeight; } } } // set visible columns for (int i = 0; i < Columns.Count; i++) { if (!RepeatHeaders || i >= FixedColumns) { Columns[i].Visible = i >= startColumn && i < startColumn + columnsFit; } } // set visible rows for (int i = 0; i < Rows.Count; i++) { if (!RepeatHeaders || i >= FixedRows) { Rows[i].Visible = i >= startRow && i < startRow + rowsFit; } } DataBand band = new DataBand(); band.Bounds = bounds; band.Objects.Add(this); Report.Engine.AddToPreparedPages(band); return(GetRowsHeight(startRow, rowsFit)); }