fr.opensagres.xdocreport.itext.extension.ExtendedPdfPTable Maven / Gradle / Ivy
/**
* Copyright (C) 2011-2015 The XDocReport Team
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package fr.opensagres.xdocreport.itext.extension;
import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.Phrase;
import com.lowagie.text.Table;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPRow;
import com.lowagie.text.pdf.PdfPTable;
public class ExtendedPdfPTable
extends PdfPTable
implements IITextContainer
{
private IITextContainer container;
private boolean empty;
private PdfPCell wrapperCell;
private PdfPTable wrapperTable;
public ExtendedPdfPTable( int numColumns )
{
super( numColumns );
super.setSpacingBefore( 0f );
this.empty = true;
super.setLockedWidth( true );
super.setHorizontalAlignment( Element.ALIGN_LEFT );
}
public void addElement( Element element )
{
if ( element instanceof PdfPCell )
{
addCell( (PdfPCell) element );
}
}
public IITextContainer getITextContainer()
{
return container;
}
public void setITextContainer( IITextContainer container )
{
this.container = container;
}
public float getRowHeight( int idx )
{
return getRowHeight( idx, false );
}
/**
* Gets the height of a particular row.
*
* @param idx the row index (starts at 0)
* @param firsttime is this the first time the row heigh is calculated?
* @return the height of a particular row
* @since 3.0.0
*/
public float getRowHeight( int idx, boolean firsttime )
{
if ( totalWidth <= 0 || idx < 0 || idx >= rows.size() )
return 0;
PdfPRow row = (PdfPRow) rows.get( idx );
if ( row == null )
return 0;
if ( firsttime )
row.setWidths( absoluteWidths );
float height = row.getMaxHeights();
PdfPCell cell;
PdfPRow tmprow;
for ( int i = 0; i < relativeWidths.length; i++ )
{
if ( !rowSpanAbove( idx, i ) )
continue;
int rs = 1;
while ( rowSpanAbove( idx - rs, i ) )
{
rs++;
}
tmprow = (PdfPRow) rows.get( idx - rs );
cell = tmprow.getCells()[i];
float tmp = 0;
// AZERR patch : sometimes cell is null????
// LP : cell may be null if colspan/rowspan occurs
// create a dummy cell to avoid NullPointerException
if ( cell == null )
{
cell = new PdfPCell();
tmprow.getCells()[i] = cell;
}
if ( cell.getRowspan() == rs + 1 )
{
tmp = cell.getMaxHeight();
while ( rs > 0 )
{
tmp -= getRowHeight( idx - rs );
rs--;
}
}
if ( tmp > height )
height = tmp;
}
row.setMaxHeights( height );
return height;
}
/**
* Checks if there are rows above belonging to a rowspan.
*
* @param currRow the current row to check
* @param currCol the current column to check
* @return true if there's a cell above that belongs to a rowspan
* @since 2.1.6
*/
@SuppressWarnings( "all" )
boolean rowSpanAbove( int currRow, int currCol )
{
if ( ( currCol >= getNumberOfColumns() ) || ( currCol < 0 ) || ( currRow == 0 ) )
return false;
int row = currRow - 1;
PdfPRow aboveRow = (PdfPRow) rows.get( row );
if ( aboveRow == null )
return false;
PdfPCell aboveCell = (PdfPCell) aboveRow.getCells()[currCol];
while ( ( aboveCell == null ) && ( row > 0 ) )
{
aboveRow = (PdfPRow) rows.get( --row );
if ( aboveRow == null )
return false;
aboveCell = (PdfPCell) aboveRow.getCells()[currCol];
}
int distance = currRow - row;
if ( aboveCell == null )
{
int col = currCol - 1;
aboveCell = (PdfPCell) aboveRow.getCells()[col];
while ( ( aboveCell == null ) && ( row > 0 ) )
aboveCell = (PdfPCell) aboveRow.getCells()[--col];
return aboveCell != null && aboveCell.getRowspan() > distance;
}
if ( ( aboveCell.getRowspan() == 1 ) && ( distance > 1 ) )
{
int col = currCol - 1;
aboveRow = (PdfPRow) rows.get( row + 1 );
distance--;
aboveCell = (PdfPCell) aboveRow.getCells()[col];
while ( ( aboveCell == null ) && ( col > 0 ) )
aboveCell = (PdfPCell) aboveRow.getCells()[--col];
}
return aboveCell != null && aboveCell.getRowspan() > distance;
}
@Override
public void addCell( Image image )
{
this.empty = false;
super.addCell( image );
}
@Override
public void addCell( PdfPCell cell )
{
this.empty = false;
super.addCell( cell );
}
@Override
public void addCell( PdfPTable table )
{
this.empty = false;
super.addCell( table );
}
@Override
public void addCell( Phrase phrase )
{
this.empty = false;
super.addCell( phrase );
}
@Override
public void addCell( String text )
{
this.empty = false;
super.addCell( text );
}
public boolean isEmpty()
{
return empty;
}
/**
* Sets the padding of the contents in the cell (space between content and border).
*
* @param padding
*/
public void setPadding( float padding )
{
getWrapperCell().setPadding( padding );
}
/**
* Setter for property paddingLeft.
*
* @param paddingLeft New value of property paddingLeft.
*/
public void setPaddingLeft( float paddingLeft )
{
getWrapperCell().setPaddingLeft( paddingLeft );
}
/**
* Setter for property paddingRight.
*
* @param paddingRight New value of property paddingRight.
*/
public void setPaddingRight( float paddingRight )
{
getWrapperCell().setPaddingRight( paddingRight );
}
/**
* Setter for property paddingBottom.
*
* @param paddingBottom New value of property paddingBottom.
*/
public void setPaddingBottom( float paddingBottom )
{
getWrapperCell().setPaddingBottom( paddingBottom );
}
/**
* Setter for property paddingTop.
*
* @param paddingTop New value of property paddingTop.
*/
public void setPaddingTop( float paddingTop )
{
getWrapperCell().setPaddingTop( paddingTop );
}
private PdfPCell createCell()
{
PdfPCell cell = new PdfPCell();
cell.setBorder( Table.NO_BORDER );
cell.setPadding( 0.0f );
cell.setUseBorderPadding( true );
return cell;
}
private PdfPTable createTable( PdfPCell cell )
{
PdfPTable table = new PdfPTable( 1 );
table.setSpacingBefore( this.spacingBefore() );
table.setSpacingAfter( this.spacingAfter() );
table.setHorizontalAlignment( this.getHorizontalAlignment() );
table.setTotalWidth( cell.getPaddingLeft() + this.getTotalWidth() + cell.getPaddingRight() );
table.setLockedWidth( true );
table.setSplitLate( false );
table.addCell( cell );
return table;
}
private PdfPCell getWrapperCell()
{
if ( wrapperCell == null )
{
wrapperCell = createCell();
}
return wrapperCell;
}
public Element getElement()
{
if ( wrapperTable != null )
{
return wrapperTable;
}
else if ( wrapperCell != null )
{
wrapperCell.addElement( this );
wrapperTable = createTable( wrapperCell );
return wrapperTable;
}
return this;
}
}