private void MergeInsertedTables() {
int i=0, j=0;
float [] lNewWidths = null;
int [] lDummyWidths = new int[columns]; // to keep track in how many new cols this one will be split
float[][] lDummyColumnWidths = new float[columns][]; // bugfix Tony Copping
int [] lDummyHeights = new int[rows.Count]; // to keep track in how many new rows this one will be split
ArrayList newRows = null;
bool isTable=false;
int lTotalRows = 0, lTotalColumns = 0;
int lNewMaxRows = 0, lNewMaxColumns = 0;
Table lDummyTable = null;
// first we'll add new columns when needed
// check one column at a time, find maximum needed nr of cols
// Search internal tables and find one with max columns
for (j=0; j < columns; j++) {
lNewMaxColumns = 1; // value to hold in how many columns the current one will be split
float [] tmpWidths = null;
for (i=0; i < rows.Count; i++) {
if (((Row) rows[i]).GetCell(j) is Table) {
isTable=true;
lDummyTable = ((Table) ((Row) rows[i]).GetCell(j));
if ( tmpWidths == null) {
tmpWidths = lDummyTable.widths;
lNewMaxColumns=tmpWidths.Length;
}
else {
int cols = lDummyTable.Dimension.width;
float [] tmpWidthsN = new float[ cols * tmpWidths.Length];
float tpW=0, btW=0, totW=0;
int tpI=0, btI=0, totI=0;
tpW+=tmpWidths[0];
btW+=lDummyTable.widths[0];
while ( tpI<tmpWidths.Length && btI<cols) {
if ( btW>tpW) {
tmpWidthsN[totI] = tpW-totW;
tpI++;
if (tpI<tmpWidths.Length) {
tpW+=tmpWidths[tpI];
}
}
else {
tmpWidthsN[totI] = btW-totW;
btI++;
if (Math.Abs(btW - tpW) < 0.0001) {
tpI++;
if (tpI<tmpWidths.Length) {
tpW+=tmpWidths[tpI];
}
}
if (btI<cols) {
btW+=lDummyTable.widths[btI];
}
}
totW+=tmpWidthsN[totI];
totI++;
}
tmpWidths = new float[totI];
Array.Copy(tmpWidthsN, 0, tmpWidths, 0, totI);
lNewMaxColumns=totI;
}
}
}
lDummyColumnWidths[j] = tmpWidths;
lTotalColumns += lNewMaxColumns;
lDummyWidths [j] = lNewMaxColumns;
}
// next we'll add new rows when needed
for (i=0; i < rows.Count; i++) {
lNewMaxRows = 1; // holds value in how many rows the current one will be split
for (j=0; j < columns; j++) {
if (((Row) rows[i]).GetCell(j) is Table ) {
isTable=true;
lDummyTable = (Table) ((Row) rows[i]).GetCell(j);
if ( lDummyTable.Dimension.height > lNewMaxRows ) {
lNewMaxRows = lDummyTable.Dimension.height;
}
}
}
lTotalRows += lNewMaxRows;
lDummyHeights [i] = lNewMaxRows;
}
if ( (lTotalColumns != columns) || (lTotalRows != rows.Count) || isTable) // NO ADJUSTMENT
{
// ** WIDTH
// set correct width for new columns
// divide width over new nr of columns
// Take new max columns of internal table and work out widths for each col
lNewWidths = new float [lTotalColumns];
int lDummy = 0;
for (int tel=0; tel < widths.Length;tel++) {
if ( lDummyWidths[tel] != 1) {
// divide
for (int tel2 = 0; tel2 < lDummyWidths[tel]; tel2++) {
lNewWidths[lDummy] = widths[tel] * lDummyColumnWidths[tel][tel2] / 100f; // bugfix Tony Copping
lDummy++;
}
}
else {
lNewWidths[lDummy] = widths[tel];
lDummy++;
}
}
// ** FILL OUR NEW TABLE
// generate new table
// set new widths
// copy old values
newRows = new ArrayList(lTotalRows);
for (i = 0; i < lTotalRows; i++) {
newRows.Add(new Row(lTotalColumns));
}
int lDummyRow = 0, lDummyColumn = 0; // to remember where we are in the new, larger table
Object lDummyElement = null;
for (i=0; i < rows.Count; i++) {
lDummyColumn = 0;
lNewMaxRows = 1;
for (j=0; j < columns; j++) {
if (((Row) rows[i]).GetCell(j) is Table ) // copy values from embedded table
{
lDummyTable = (Table) ((Row) rows[i]).GetCell(j);
// Work out where columns in table table correspond to columns in current table
int[] colMap = new int[lDummyTable.widths.Length+1];
int cb=0, ct=0;
for ( ; cb<lDummyTable.widths.Length;cb++) {
colMap[cb] = lDummyColumn+ct;
float wb;
wb = lDummyTable.widths[cb];
float wt=0;
while ( ct<lDummyWidths[j]) {
wt+=lDummyColumnWidths[j][ct++];
if (Math.Abs(wb - wt) < 0.0001) break;
}
}
colMap[cb] = lDummyColumn+ct;
// need to change this to work out how many cols to span
for (int k=0; k < lDummyTable.Dimension.height; k++) {
for (int l=0; l < lDummyTable.Dimension.width; l++) {
lDummyElement = lDummyTable.GetElement(k,l);
if (lDummyElement != null) {
int col=lDummyColumn+l;
if (lDummyElement is Cell) {
Cell lDummyC = (Cell)lDummyElement;
// Find col to add cell in and set col span
col = colMap[l];
int ot = colMap[l+lDummyC.Colspan];
lDummyC.Colspan = ot-col;
}
((Row) newRows[k + lDummyRow]).AddElement(lDummyElement,col); // use addElement to set reserved status ok in row
}
}
}
}
else // copy others values
{
Object aElement = GetElement(i,j);
if (aElement is Cell) {
// adjust spans for cell
((Cell) aElement).Rowspan = ((Cell) ((Row) rows[i]).GetCell(j)).Rowspan + lDummyHeights[i] - 1;
((Cell) aElement).Colspan = ((Cell) ((Row) rows[i]).GetCell(j)).Colspan + lDummyWidths[j] - 1;
// most likely this cell covers a larger area because of the row/cols splits : define not-to-be-filled cells
PlaceCell(newRows,((Cell) aElement), new System.Drawing.Point(lDummyRow,lDummyColumn));
}
}
lDummyColumn += lDummyWidths[j];
}
lDummyRow += lDummyHeights[i];
}
// Set our new matrix
columns = lTotalColumns;
rows = newRows;
this.widths = lNewWidths;
}
}