/// <summary> /// Imprime um item tabular para o elemento da tabela. /// </summary> /// <typeparam name="R">O tipo dos objectos que constituem as linhas do item tabular.</typeparam> /// <typeparam name="L">O tipo dos objectos que constituem as células do item tabular.</typeparam> /// <param name="cellElementName">O nome do elemento da célula.</param> /// <param name="element">O elemento da tabela que irá conter as linhas.</param> /// <param name="columnsNumber">O número de colunas esperado.</param> /// <param name="tabularItem">O item tabular.</param> /// <param name="mergingRegions">O conjunto de regiões de células fundidas.</param> /// <param name="attributessSetter">A função responsável pela adição de atributos.</param> /// <param name="elementsSetter">A função responsável pelo processamento de elementos.</param> private void PrintTabularItem <R, L>( string cellElementName, XmlElement element, int columnsNumber, IGeneralTabularItem <R> tabularItem, NonIntersectingMergingRegionsSet <int, MergingRegion <int> > mergingRegions, Action <int, AttributeSetter> attributessSetter, Action <int, int, object, ElementSetter> elementsSetter) where R : IGeneralTabularRow <L> where L : IGeneralTabularCell { var attributeSetter = new AttributeSetter(); var validatedCellElementSetter = new ValidatedCellElementSetter(); var linesNumber = tabularItem.LastRowNumber + 1; var linePointer = 0; foreach (var tabularLine in tabularItem) { var currentLine = tabularLine.RowNumber; for (; linePointer < currentLine; ++linePointer) { var rowElement = element.OwnerDocument.CreateElement("tr"); attributeSetter.CurrentElement = rowElement; attributessSetter.Invoke( linePointer, attributeSetter); this.AppendEmptyCells( cellElementName, rowElement, linePointer, columnsNumber, linesNumber, columnsNumber, validatedCellElementSetter, mergingRegions, elementsSetter); element.AppendChild(rowElement); } var lineElement = element.OwnerDocument.CreateElement("tr"); attributeSetter.CurrentElement = lineElement; attributessSetter.Invoke( linePointer, attributeSetter); var currentCellNumber = 0; foreach (var tabularCell in tabularLine) { if (currentCellNumber <= tabularCell.ColumnNumber) { var emptyCellsCount = tabularCell.ColumnNumber - currentCellNumber; this.AppendEmptyCells( cellElementName, lineElement, linePointer, emptyCellsCount, linesNumber, columnsNumber, validatedCellElementSetter, mergingRegions, elementsSetter); var mergingRegion = mergingRegions.GetMergingRegionForCell( tabularCell.ColumnNumber, currentLine); if (mergingRegion == null) { var tableCellElement = lineElement.OwnerDocument.CreateElement(cellElementName); validatedCellElementSetter.CurrentElement = tableCellElement; lineElement.AppendChild(tableCellElement); elementsSetter.Invoke( currentLine, tabularCell.ColumnNumber, tabularCell.GetCellValue <object>(), validatedCellElementSetter); lineElement.AppendChild(tableCellElement); currentCellNumber = tabularCell.ColumnNumber + 1; } else if (mergingRegion.TopLeftX == tabularCell.ColumnNumber) { var colDifference = mergingRegion.BottomRightX - mergingRegion.TopLeftX; if (mergingRegion.TopLeftY == currentLine) { var tableCellElement = lineElement.OwnerDocument.CreateElement(cellElementName); validatedCellElementSetter.CurrentElement = tableCellElement; lineElement.AppendChild(tableCellElement); elementsSetter.Invoke( currentLine, tabularCell.ColumnNumber, tabularCell.GetCellValue <object>(), validatedCellElementSetter); if (colDifference > 0) { var colSpan = Math.Min( colDifference + 1, columnsNumber - tabularCell.ColumnNumber); if (colSpan > 1) { tableCellElement.SetAttribute("colspan", colSpan.ToString()); } } var rowDifference = mergingRegion.BottomRightY - mergingRegion.TopLeftY; if (rowDifference > 0) { var rowSpan = Math.Min( rowDifference + 1, linesNumber - currentLine); if (rowSpan > 1) { tableCellElement.SetAttribute("rowspan", rowSpan.ToString()); } } } currentCellNumber = tabularCell.ColumnNumber + colDifference + 1; } } } var finalEmptyCellsCount = columnsNumber - currentCellNumber; this.AppendEmptyCells( cellElementName, lineElement, linePointer, finalEmptyCellsCount, linesNumber, columnsNumber, validatedCellElementSetter, mergingRegions, elementsSetter); element.AppendChild(lineElement); ++linePointer; } // Inserção das restantes linhas vazias for (; linePointer < linesNumber; ++linePointer) { var rowElement = element.OwnerDocument.CreateElement("th"); attributeSetter.CurrentElement = rowElement; this.headerRowAttributesSetter.Invoke( linePointer, attributeSetter); this.AppendEmptyCells( cellElementName, rowElement, linePointer, columnsNumber, linesNumber, columnsNumber, validatedCellElementSetter, mergingRegions, elementsSetter); } }
/// <summary> /// Adenda células do vazias a uma linha do cabeçalho. /// </summary> /// <param name="cellElementName">O nome da célula.</param> /// <param name="lineElement">A linha à qual serão adicionadas células vazias.</param> /// <param name="currentLine">O número da linha de inserção.</param> /// <param name="count">O número de elementos a inserir.</param> /// <param name="linesNumber">O número de linhas na tabela.</param> /// <param name="columnsNumber">O número de colunas.</param> /// <param name="elementSetter">O objecto responsável pela alteração do elemento.</param> /// <param name="mergingRegions">As regiões de fusão de células.</param> /// <param name="elementsSetter">A função responsável pelo processamento dos elementos.</param> private void AppendEmptyCells( string cellElementName, XmlElement lineElement, int currentLine, int count, int linesNumber, int columnsNumber, ValidatedCellElementSetter elementSetter, NonIntersectingMergingRegionsSet <int, MergingRegion <int> > mergingRegions, Action <int, int, object, ElementSetter> elementsSetter) { for (int i = 0; i < count; ++i) { var mergingRegion = mergingRegions.GetMergingRegionForCell( i, currentLine); if (mergingRegion == null) { var tableCellElement = lineElement.OwnerDocument.CreateElement(cellElementName); elementSetter.CurrentElement = tableCellElement; lineElement.AppendChild(tableCellElement); elementsSetter.Invoke( currentLine, i, null, elementSetter); lineElement.AppendChild(tableCellElement); } else if (mergingRegion.TopLeftX == i) { var colDifference = mergingRegion.BottomRightX - mergingRegion.TopLeftY; if (mergingRegion.TopLeftY == currentLine) { var tableCellElement = lineElement.OwnerDocument.CreateElement(cellElementName); elementSetter.CurrentElement = tableCellElement; lineElement.AppendChild(tableCellElement); elementsSetter.Invoke( currentLine, i, null, elementSetter); if (colDifference > 0) { var colSpan = Math.Min( colDifference + 1, columnsNumber - i); if (colSpan > 1) { tableCellElement.SetAttribute("colspan", colSpan.ToString()); } } var rowDifference = mergingRegion.BottomRightY - mergingRegion.TopLeftY; if (rowDifference > 0) { var rowSpan = Math.Min( rowDifference + 1, linesNumber - currentLine); if (rowSpan > 1) { tableCellElement.SetAttribute("rowspan", rowSpan.ToString()); } } } i += colDifference; } } }