]> git.lyx.org Git - lyx.git/blobdiff - src/table.C
Baruch's graphic-inset patch.
[lyx.git] / src / table.C
index a00a4e5d32c921851e19d14bde935eac1a4afe41..e9972a7e7bbc56f5053f885508dcf54246c3b549 100644 (file)
  * 
  *           LyX, The Document Processor
  *      
- *       Copyright (C) 1995 Matthias Ettrich
- *        Copyright (C) 1995-1998 The LyX Team.
+ *       Copyright 1995 Matthias Ettrich
+ *        Copyright 1995-2000 The LyX Team.
  *
  * ====================================================== 
  */
 
 #include <config.h>
 
+#include <algorithm>
 #include <cstdlib>
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
 #include "table.h"
+#include "debug.h"
 #include "vspace.h"
 #include "layout.h"
 #include "support/lstrings.h"
+#include "support/lyxmanip.h"
+#include "support/LAssert.h"
+#include "lyx_gui_misc.h"
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
+using std::ostream;
+using std::istream;
+using std::getline;
+using std::max;
+using std::endl;
+
+static int const WIDTH_OF_LINE = 5;
+
+/// Define a few methods for the inner structs
+
+LyXTable::cellstruct::cellstruct() 
+{
+       cellno = 0; //should be initilaized correctly later.
+       width_of_cell = 0;
+       multicolumn = LyXTable::CELL_NORMAL;
+       alignment = LYX_ALIGN_CENTER;
+       top_line = true;
+       bottom_line = false;
+       has_cont_row = false;
+       rotate = false;
+       linebreaks = false;
+}
+
+LyXTable::cellstruct::~cellstruct() 
+{
+}
+
+LyXTable::cellstruct & 
+  LyXTable::cellstruct::operator=(cellstruct const & cs)
+{
+       cellno = cs.cellno;
+       width_of_cell = cs.width_of_cell;
+       multicolumn = cs.multicolumn;
+       alignment = cs.alignment;
+       top_line = cs.top_line;
+       bottom_line = cs.bottom_line;
+       has_cont_row = cs.has_cont_row;
+       rotate = cs.rotate;
+       linebreaks = cs.linebreaks;
+       return *this;
+}
+
+LyXTable::rowstruct::rowstruct() 
+{
+       top_line = true;
+       bottom_line = false;
+       is_cont_row = false;
+       ascent_of_row = 0;
+       descent_of_row = 0;
+       newpage = false;
+}
+
+// Nothing to do, but gcc 2.7.2.3 wants one... (JMarc)
+LyXTable::rowstruct::~rowstruct() 
+{
+}
 
-extern void addNewlineAndDepth(string &file, int const depth); // Jug 990923
+LyXTable::rowstruct & 
+  LyXTable::rowstruct::operator=(rowstruct const & rs)
+{
+       top_line = rs.top_line;
+       bottom_line = rs.bottom_line;
+       is_cont_row = rs.is_cont_row;
+       ascent_of_row = rs.ascent_of_row;
+       descent_of_row = rs.descent_of_row;
+       newpage = rs.newpage;
+       return *this;
+}
 
-#define WIDTH_OF_LINE 5
+LyXTable::columnstruct::columnstruct() 
+{
+        left_line = true;
+        right_line = false;
+        alignment = LYX_ALIGN_CENTER;
+        width_of_column = 0;
+}
+
+LyXTable::columnstruct::~columnstruct() 
+{
+}
+
+LyXTable::columnstruct & 
+  LyXTable::columnstruct::operator=(columnstruct const & cs)
+{
+        left_line = cs.left_line;
+        right_line = cs.right_line;
+        alignment = cs.alignment;
+        width_of_column = cs.width_of_column;
+       p_width = cs.p_width;
+       align_special = cs.align_special;
+       return *this;
+}
 
 /* konstruktor */
 LyXTable::LyXTable(int rows_arg, int columns_arg)
 {
-       Init(rows_arg, columns_arg);
+    Init(rows_arg, columns_arg);
 }
 
 
-LyXTable::LyXTable(LyXLex &lex)
+LyXTable::LyXTable(LyXTable const & lt)
 {
-       FILE *file = lex.getFile();
-       Read(file);
+    Init(lt.rows, lt.columns);
+    
+    operator=(lt);
 }
 
+LyXTable::LyXTable(LyXLex & lex)
+{
+    istream & is = lex.getStream();
+    Read(is);
+}
 
-LyXTable::~LyXTable() {
-       int i;
-       delete[] rowofcell;
-       delete[] columnofcell;
-       delete[] column_info;
-        delete[] row_info;
-       for (i = 0; i<rows; i++) {
-               delete[] cell_info[i]; // verify that this shoudn't be freed with delete
-       }
-       delete[] cell_info;
+
+LyXTable::~LyXTable()
+{
+    delete[] rowofcell;
+    delete[] columnofcell;
+    delete[] column_info;
+    delete[] row_info;
+    for (int i = 0; i < rows; ++i) {
+       delete[] cell_info[i];
+    }
+    delete[] cell_info;
 }
 
 
+LyXTable & LyXTable::operator=(LyXTable const & lt)
+{
+    // If this and lt is not of the same size we have a serious bug
+    // So then it is ok to throw an exception, or for now
+    // call abort()
+    Assert(rows == lt.rows && columns == lt.columns);
+
+    int row = 0, column = 0;
+    
+    for (row = 0; row < rows; ++row) {
+        for (column = 0; column < columns; ++column) {
+            cell_info[row][column] = lt.cell_info[row][column];
+        }
+    }
+    
+    for (row = 0; row < rows; ++row) {
+        row_info[row] = lt.row_info[row];
+    }
+    
+    for (column = 0; column < columns; ++column) {
+       column_info[column] = lt.column_info[column];
+    }
+
+    SetLongTable(lt.is_long_table);
+    rotate = lt.rotate;
+    Reinit();
+    
+    return *this;
+}
+
 LyXTable * LyXTable::Clone()
 {
-    LyXTable *result = new LyXTable(rows, columns);
-    int row, column;;
+    LyXTable * result = new LyXTable(rows, columns);
+    int row, column;
 
-    for (row = 0; row<rows; row++){
-        for (column = 0; column<columns;column++){
+    for (row = 0; row < rows; ++row) {
+        for (column = 0; column < columns; ++column) {
             result->cell_info[row][column] = cell_info[row][column];
         }
     }
 
-    for (row = 0; row<rows; row++){
+    for (row = 0; row < rows; ++row) {
         result->row_info[row] = row_info[row];
     }
 
-    for (column = 0; column<columns; column++){
+    for (column = 0; column < columns; ++column) {
         result->column_info[column].left_line = column_info[column].left_line;
         result->column_info[column].right_line = column_info[column].right_line;
         result->column_info[column].alignment = column_info[column].alignment;
@@ -85,42 +217,24 @@ LyXTable * LyXTable::Clone()
 /* activates all lines and sets all widths to 0 */ 
 void LyXTable::Init(int rows_arg, int columns_arg)
 {
-    int i, j, cellno;
+    int i, j;
     rows = rows_arg;
     columns = columns_arg;
     column_info = new columnstruct[columns];
     row_info = new rowstruct[rows];
     cell_info = new cellstruct*[rows];
 
-    cellno = 0;
-    for (i = 0; i<rows;i++) {
+    int cellno = 0;
+    for (i = 0; i < rows; ++i) {
         cell_info[i] = new cellstruct[columns];
-        row_info[i].top_line = true;
-        row_info[i].bottom_line = false;
-        row_info[i].is_cont_row = false;
-        row_info[i].newpage = false;
-        for (j = 0; j<columns; j++) {
+        for (j = 0; j < columns; ++j) {
             cell_info[i][j].cellno = cellno++;
-            cell_info[i][j].width_of_cell = 0;
-            cell_info[i][j].multicolumn = LyXTable::CELL_NORMAL;
-            cell_info[i][j].alignment = LYX_ALIGN_CENTER;
-            cell_info[i][j].top_line = row_info[i].top_line;
-            cell_info[i][j].bottom_line = row_info[i].bottom_line;
-            cell_info[i][j].has_cont_row = false;
-            cell_info[i][j].rotate = false;
-            cell_info[i][j].linebreaks = false;
         }
     }
     row_info[i-1].bottom_line = true;
     row_info[0].bottom_line = true;
 
-    for (i = 0; i<columns;i++) {
-        column_info[i].left_line = true;
-        column_info[i].right_line = false;
-        column_info[i].alignment = LYX_ALIGN_CENTER;
-        // set width_of_column to zero before it is used in
-        // calculate_width_of_column() (thornley)
-        column_info[i].width_of_column = 0;
+    for (i = 0; i < columns; ++i) {
         calculate_width_of_column(i);
     }
     column_info[i-1].right_line = true;
@@ -142,26 +256,26 @@ void LyXTable::Init(int rows_arg, int columns_arg)
 void LyXTable::AppendRow(int cell)
 {
     int row = row_of_cell(cell);
-    rowstruct *row_info2 = new rowstruct[rows+1];
-    cellstruct** cell_info2 = new cellstruct*[rows+1];
+    rowstruct * row_info2 = new rowstruct[rows + 1];
+    cellstruct ** cell_info2 = new cellstruct * [rows + 1];
     int i;
 
-    for (i = 0; i <= row; i++) {
+    for (i = 0; i <= row; ++i) {
         cell_info2[i] = cell_info[i];
         row_info2[i] = row_info[i];
     }
-    for (i = rows-1; i >= row; i--) {
-        cell_info2[i+1] = cell_info[i];
-        row_info2[i+1] = row_info[i];
+    for (i = rows - 1; i >= row; --i) {
+        cell_info2[i + 1] = cell_info[i];
+        row_info2[i + 1] = row_info[i];
     }
-    for (i = row;row_info[i].is_cont_row;i--);
-    if (((row+1)>= rows) || !row_info[row+1].is_cont_row)
-        row_info2[row+1].is_cont_row = false;
-    row_info2[row+1].top_line = row_info[i].top_line;
-    cell_info2[row+1] = new cellstruct[columns];
-    for (i = 0; i<columns; i++) {
-        cell_info2[row+1][i].width_of_cell = 0;
-        cell_info2[row+1][i] = cell_info2[row][i];
+    for (i = row; row_info[i].is_cont_row; --i);
+    if (((row + 1) >= rows) || !row_info[row + 1].is_cont_row)
+        row_info2[row + 1].is_cont_row = false;
+    row_info2[row + 1].top_line = row_info[i].top_line;
+    cell_info2[row + 1] = new cellstruct[columns];
+    for (i = 0; i < columns; ++i) {
+        cell_info2[row + 1][i].width_of_cell = 0;
+        cell_info2[row + 1][i] = cell_info2[row][i];
     }
    
     delete[] cell_info;
@@ -169,7 +283,7 @@ void LyXTable::AppendRow(int cell)
     delete[] row_info;
     row_info = row_info2;
    
-    rows++;
+    ++rows;
    
     Reinit();
 }
@@ -180,29 +294,28 @@ void LyXTable::DeleteRow(int cell)
        int row = row_of_cell(cell);
         while(!row_info[row].is_cont_row && RowHasContRow(cell))
             DeleteRow(cell_info[row+1][0].cellno);
-        rowstruct *row_info2 = new rowstruct[rows-1];
-       cellstruct** cell_info2 = new cellstruct*[rows-1];
-       int i;
+        rowstruct * row_info2 = new rowstruct[rows - 1];
+       cellstruct ** cell_info2 = new cellstruct * [rows - 1];
 
        delete[] cell_info[row];
-       for (i = 0; i < row; i++) {
+       int i = 0;
+       for (; i < row; ++i) {
                cell_info2[i] = cell_info[i];
                 row_info2[i] = row_info[i];
        }
         if (row_info[i].is_cont_row)
-            row_info2[i-1].bottom_line = row_info[i].bottom_line;
-       for (i = row; i < rows - 1; i++) {
-               cell_info2[i] = cell_info[i+1];
-                row_info2[i] = row_info[i+1];
+            row_info2[i - 1].bottom_line = row_info[i].bottom_line;
+       for (i = row; i < rows - 1; ++i) {
+               cell_info2[i] = cell_info[i + 1];
+                row_info2[i] = row_info[i + 1];
        }
-   
 
        delete[] cell_info;
        cell_info = cell_info2;
         delete[] row_info;
         row_info = row_info2;
    
-       rows--;
+       --rows;
 
        Reinit();
 }
@@ -210,63 +323,64 @@ void LyXTable::DeleteRow(int cell)
 
 void LyXTable::AppendColumn(int cell)
 {
-    int i, j;
-    columnstruct *column_info2 = new columnstruct[columns+1];
+    int j;
+    columnstruct * column_info2 = new columnstruct[columns + 1];
     int column = right_column_of_cell(cell);
-   
-    for (i = 0; i<= column; i++){
+
+    int i = 0;
+    for (; i <= column; ++i) {
         column_info2[i] = column_info[i];
     }
-    for (i = columns-1; i>= column; i--){
-        column_info2[i+1] = column_info[i];
+    for (i = columns - 1; i >= column; --i) {
+        column_info2[i + 1] = column_info[i];
     }
     
     delete[] column_info;
     column_info = column_info2;
     
-    for (i = 0; i<rows;i++){
-        cellstruct* tmp = cell_info[i];
-        cell_info[i] = new cellstruct[columns+1];
-        for (j = 0; j<= column; j++){
+    for (i = 0; i < rows; ++i) {
+        cellstruct * tmp = cell_info[i];
+        cell_info[i] = new cellstruct[columns + 1];
+        for (j = 0; j <= column; ++j) {
             cell_info[i][j] = tmp[j];
         }
-        for (j = column; j<columns; j++){
-            cell_info[i][j+1] = tmp[j];
+        for (j = column; j < columns; ++j) {
+            cell_info[i][j + 1] = tmp[j];
         }
         // care about multicolumns
-        if (cell_info[i][column+1].multicolumn
+        if (cell_info[i][column + 1].multicolumn
             == LyXTable::CELL_BEGIN_OF_MULTICOLUMN){
-            cell_info[i][column+1].multicolumn = 
+            cell_info[i][column + 1].multicolumn = 
                 LyXTable::CELL_PART_OF_MULTICOLUMN;
         }
         if (column + 1 == columns
-            || cell_info[i][column+2].multicolumn
+            || cell_info[i][column + 2].multicolumn
             != LyXTable::CELL_PART_OF_MULTICOLUMN){
-            cell_info[i][column+1].multicolumn = 
+            cell_info[i][column + 1].multicolumn = 
                 LyXTable::CELL_NORMAL;
         }
-        
         delete[] tmp;
     }
     
-    columns++;
+    ++columns;
     Reinit();
 }
 
 
 void LyXTable::Reinit()
 {   
-       int i, j;
+       int j;
 
-       for (i = 0; i<rows;i++) {
-               for (j = 0; j<columns; j++) {
+       int i = 0;
+       for (; i < rows; ++i) {
+               for (j = 0; j < columns; ++j) {
                        cell_info[i][j].width_of_cell = 0;
-                        if ((i+1 < rows) && !row_info[i+1].is_cont_row)
+                        if ((i + 1 < rows) && !row_info[i+1].is_cont_row)
                             cell_info[i][j].has_cont_row = false;
                }
        }
   
-       for (i = 0; i<columns;i++) {
+       for (i = 0; i < columns; ++i) {
                calculate_width_of_column(i);
        }
        calculate_width_of_table();
@@ -277,11 +391,11 @@ void LyXTable::Reinit()
 
 void LyXTable::set_row_column_number_info()
 {
-       int row = 0;
        int c = 0;
        int column = 0;
        numberofcells = -1;
-       for (row = 0; row<rows; ++row) {
+       int row = 0;
+       for (; row < rows; ++row) {
                for (column = 0; column<columns; ++column) {
                        if (cell_info[row][column].multicolumn
                            != LyXTable::CELL_PART_OF_MULTICOLUMN)
@@ -293,25 +407,23 @@ void LyXTable::set_row_column_number_info()
        row = 0;
        column = 0;
 
-       if (rowofcell)
-               delete [] rowofcell;
+       delete [] rowofcell;
        rowofcell = new int[numberofcells];
-       if (columnofcell)
-               delete [] columnofcell;
+       delete [] columnofcell;
        columnofcell = new int[numberofcells];
   
        while (c < numberofcells && row < rows && column < columns) {
                rowofcell[c] = row;
                columnofcell[c] = column;
-               c++;
-               do{
-                       column++;
+               ++c;
+               do {
+                       ++column;
                } while (column < columns &&
                         cell_info[row][column].multicolumn
                         == LyXTable::CELL_PART_OF_MULTICOLUMN);
-               if (column == columns){
+               if (column == columns) {
                        column = 0;
-                       row++;
+                       ++row;
                }
        }
 }
@@ -321,12 +433,11 @@ void LyXTable::DeleteColumn(int cell)
 {
        int column1 = column_of_cell(cell);
        int column2 = right_column_of_cell(cell);
-       int column;
    
        if (column1 == 0 && column2 == columns - 1)
                return;
    
-       for (column = column1; column <= column2;column++){
+       for (int column = column1; column <= column2; ++column) {
                delete_column(column1);
        }
        Reinit();
@@ -342,11 +453,10 @@ int LyXTable::GetNumberOfCells()
 int LyXTable::NumberOfCellsInRow(int cell)
 {
        int row = row_of_cell(cell);
-       int i = 0;
        int result = 0;
-       for (i = 0; i<columns; i++){
+       for (int i = 0; i < columns; ++i) {
                if (cell_info[row][i].multicolumn != LyXTable::CELL_PART_OF_MULTICOLUMN)
-                       result++;
+                       ++result;
        }
        return result;
 }
@@ -405,6 +515,7 @@ bool LyXTable::LeftLine(int cell)
        return column_info[column_of_cell(cell)].left_line;
 }
 
+
 bool LyXTable::RightLine(int cell)
 {
        return column_info[right_column_of_cell(cell)].right_line;
@@ -421,7 +532,7 @@ bool LyXTable::TopAlreadyDrawed(int cell)
                while (column
                       && cell_info[row-1][column].multicolumn
                       == LyXTable::CELL_PART_OF_MULTICOLUMN)
-                       column--;
+                       --column;
                if (cell_info[row-1][column].multicolumn
                    == LyXTable::CELL_NORMAL)
                        return row_info[row-1].bottom_line;
@@ -434,38 +545,39 @@ bool LyXTable::TopAlreadyDrawed(int cell)
 
 bool LyXTable::VeryLastRow(int cell)
 {
-       return (row_of_cell(cell) == rows-1);
+       return (row_of_cell(cell) == rows - 1);
 }
 
 
 int LyXTable::AdditionalHeight(int cell)
 {
        int row = row_of_cell(cell);
-       int top = 1;
-       int bottom = 1;
+       if (!row) return 0;
+       
+       int top = 1; // bool top = true; ??
+       int bottom = 1; // bool bottom = true; ??
        int column;
-       if (row){
-               for (column = 0;column < columns-1 && bottom;column++){
-                       switch (cell_info[row-1][column].multicolumn){
-                       case LyXTable::CELL_BEGIN_OF_MULTICOLUMN:
-                               bottom = cell_info[row-1][column].bottom_line;
-                               break;
-                       case LyXTable::CELL_NORMAL:
-                               bottom = row_info[row-1].bottom_line;
-                       }
+
+       for (column = 0; column < columns - 1 && bottom; ++column) {
+               switch (cell_info[row - 1][column].multicolumn) {
+               case LyXTable::CELL_BEGIN_OF_MULTICOLUMN:
+                       bottom = cell_info[row - 1][column].bottom_line;
+                       break;
+               case LyXTable::CELL_NORMAL:
+                       bottom = row_info[row - 1].bottom_line;
                }
-               for (column = 0;column < columns-1 && top;column++){
-                       switch (cell_info[row][column].multicolumn){
-                       case LyXTable::CELL_BEGIN_OF_MULTICOLUMN:
-                               top = cell_info[row][column].top_line;
-                               break;
-                       case LyXTable::CELL_NORMAL:
-                               top = row_info[row].top_line;
-                       }
+       }
+       for (column = 0; column < columns - 1 && top; ++column) {
+               switch (cell_info[row][column].multicolumn){
+               case LyXTable::CELL_BEGIN_OF_MULTICOLUMN:
+                       top = cell_info[row][column].top_line;
+                       break;
+               case LyXTable::CELL_NORMAL:
+                       top = row_info[row].top_line;
                }
-               if (top && bottom)
-                       return WIDTH_OF_LINE;
        }
+       if (top && bottom)
+               return WIDTH_OF_LINE;
        return 0;
 }
 
@@ -488,9 +600,9 @@ int LyXTable::WidthOfColumn(int cell)
 {
        int column1 = column_of_cell(cell);
        int column2 = right_column_of_cell(cell);
-       int i;
        int result = 0;
-       for (i = column1; i<= column2;i++){
+       int i = column1;
+       for (; i <= column2; ++i) {
                result += column_info[i].width_of_column;
        }
        return result;
@@ -511,16 +623,15 @@ bool LyXTable::SetWidthOfMulticolCell(int cell, int new_width)
     int row = row_of_cell(cell);
     int column1 = column_of_cell(cell);
     int column2 = right_column_of_cell(cell);
-    int i;
-    int width = 0;
 
     // first set columns to 0 so we can calculate the right width
-    for (i = column1; i<= column2;i++) {
+    int i = column1;
+    for (; i <= column2; ++i) {
         cell_info[row][i].width_of_cell = 0;
     }
     // set the width to MAX_WIDTH until width > 0
-    width = (new_width + 2*WIDTH_OF_LINE);
-    for (i = column1; (i<column2) && (width > 0);i++){
+    int width = (new_width + 2 * WIDTH_OF_LINE);
+    for (i = column1; (i < column2) && (width > 0); ++i) {
         cell_info[row][i].width_of_cell = column_info[i].width_of_column;
         width -= column_info[i].width_of_column;
     }
@@ -530,24 +641,25 @@ bool LyXTable::SetWidthOfMulticolCell(int cell, int new_width)
     return true;
 }
 
+
 void LyXTable::recalculateMulticolCells(int cell, int new_width)
 {
-    int
-        row = row_of_cell(cell),
-        column1 = column_of_cell(cell),
-        column2 = right_column_of_cell(cell),
-        i;
+       int row = row_of_cell(cell);
+       int column1 = column_of_cell(cell);
+        int column2 = right_column_of_cell(cell);
 
     // first set columns to 0 so we can calculate the right width
-    for (i = column1; i<= column2;++i)
+        int i = column1;
+    for (; i <= column2; ++i)
         cell_info[row][i].width_of_cell = 0;
-    for(i = cell+1;(i<numberofcells) && (!IsMultiColumn(i));++i)
+    for(i = cell + 1; (i < numberofcells) && (!IsMultiColumn(i)); ++i)
         ;
     if (i < numberofcells)
-        recalculateMulticolCells(i, GetWidthOfCell(i)-(2*WIDTH_OF_LINE));
+        recalculateMulticolCells(i, GetWidthOfCell(i) - (2 * WIDTH_OF_LINE));
     SetWidthOfMulticolCell(cell, new_width);
 }
 
+
 /* returns 1 if a complete update is necessary, otherwise 0 */ 
 bool LyXTable::SetWidthOfCell(int cell, int new_width)
 {
@@ -696,9 +808,9 @@ int LyXTable::GetWidthOfCell(int cell)
        int row = row_of_cell(cell);
        int column1 = column_of_cell(cell);
        int column2 = right_column_of_cell(cell);
-       int i;
        int result = 0;
-       for (i = column1; i<= column2;i++){
+       int i = column1;
+       for (; i <= column2; ++i) {
                result += cell_info[row][i].width_of_cell;
        }
   
@@ -736,30 +848,27 @@ bool LyXTable::IsFirstCell(int cell)
 
 bool LyXTable::IsLastCell(int cell)
 {
-       return (right_column_of_cell(cell) == (columns-1));
+       return (right_column_of_cell(cell) == (columns - 1));
 }
 
 
 bool LyXTable::calculate_width_of_column(int column)
 {
-       int i, max;
        int old_column_width = column_info[column].width_of_column;
-       max = 0;
-       for (i = 0; i<rows; i++) {
-               if (cell_info[i][column].width_of_cell > max) {
-                       max = cell_info[i][column].width_of_cell;
-               }
+       int maximum = 0;
+
+       for (int i = 0; i < rows; ++i) {
+               maximum = max(cell_info[i][column].width_of_cell, maximum);
        }
-       column_info[column].width_of_column = max;
+       column_info[column].width_of_column = maximum;
        return (column_info[column].width_of_column != old_column_width);
 }
 
 bool LyXTable::calculate_width_of_column_NMC(int column)
 {
-    int i, max;
     int old_column_width = column_info[column].width_of_column;
-    max = 0;
-    for (i = 0; i<rows; ++i) {
+    int max = 0;
+    for (int i = 0; i < rows; ++i) {
         if (!IsMultiColumn(GetCellNumber(column, i)) &&
             (cell_info[i][column].width_of_cell > max)) {
             max = cell_info[i][column].width_of_cell;
@@ -778,7 +887,7 @@ void LyXTable::calculate_width_of_table()
 }
 
 
-int LyXTable::row_of_cell(int cell) 
+int LyXTable::row_of_cell(int cell) const
 {
     if (cell >= numberofcells)
         return rows-1;
@@ -788,7 +897,7 @@ int LyXTable::row_of_cell(int cell)
 }
 
 
-int LyXTable::column_of_cell(int cell)
+int LyXTable::column_of_cell(int cell) const
 {
     if (cell >= numberofcells)
         return columns-1;
@@ -804,34 +913,35 @@ int LyXTable::right_column_of_cell(int cell)
        int column = column_of_cell(cell);
        while (column < columns - 1 &&
               cell_info[row][column+1].multicolumn == LyXTable::CELL_PART_OF_MULTICOLUMN)
-               column++;
+               ++column;
        return column;
 }
 
 
-void LyXTable::Write(ostream & os)
+void LyXTable::Write(ostream & os, bool old_format)
 {
-    int i, j;
-    os << "multicol5\n"
-       << rows << " " << columns << " " << is_long_table << " "
-       << rotate << " " << endhead << " " << endfirsthead << " "
-       << endfoot << " " << endlastfoot << "\n";
-    for (i = 0; i < rows; ++i) {
+    if (old_format) {
+       int i, j;
+       os << "multicol5\n"
+          << rows << " " << columns << " " << is_long_table << " "
+          << rotate << " " << endhead << " " << endfirsthead << " "
+          << endfoot << " " << endlastfoot << "\n";
+       for (i = 0; i < rows; ++i) {
            os << row_info[i].top_line << " "
               << row_info[i].bottom_line << " "
               << row_info[i].is_cont_row << " "
               << row_info[i].newpage << "\n";
-    }
-    for (i = 0; i < columns; ++i) {
+       }
+       for (i = 0; i < columns; ++i) {
            os << column_info[i].alignment << " "
               << column_info[i].left_line << " "
               << column_info[i].right_line << " \""
               << VSpace(column_info[i].p_width).asLyXCommand() << "\" \""
               << column_info[i].align_special << "\"\n";
-    }
+       }
 
-    for (i = 0; i < rows; ++i) {
-        for (j = 0; j < columns; ++j) {
+       for (i = 0; i < rows; ++i) {
+           for (j = 0; j < columns; ++j) {
                os << cell_info[i][j].multicolumn << " "
                   << cell_info[i][j].alignment << " "
                   << cell_info[i][j].top_line << " "
@@ -841,127 +951,128 @@ void LyXTable::Write(ostream & os)
                   << cell_info[i][j].linebreaks << " \""
                   << cell_info[i][j].align_special << "\" \""
                   << cell_info[i][j].p_width << "\"\n";
-        }
+           }
+       }
+    } else {
+       lyxerr << "New format type not yet implemented!!!\n" << endl;
     }
 }
 
 
-void LyXTable::Read(FILE * file)
+void LyXTable::Read(istream & is)
 {
-    int version;
-    int i, j;
-    int rows_arg = 0;
-    int columns_arg = 0;
-    int is_long_table_arg = false;
-    int rotate_arg = false;
-    string s;
-    int a = 0;
-    int b = 0;
-    int c = 0;
-    int d = 0;
-    int e = 0;
-    int f = 0;
-    int g = 0;
-    int h = 0;
-    char vtmp[100], stmp[100], atmp[100];
-
-    fscanf(file, "%s\n", vtmp);
-    s = vtmp;
-    if (s.length() > 8)
-        version = atoi(s.c_str() + 8);
-    else
-        version = 1;
-#ifdef WITH_WARNINGS
-#warning Insert a error message window here that this format is not supported anymore
-#endif
-    if (version < 5) {
-       fprintf(stderr, "Tabular format < 5 is not supported anymore\n"
-               "Get an older version of LyX (< 1.1.x) for conversion!\n");
-       return;
-    }
-    a = b = c = d = -1;
-    fgets(vtmp, sizeof(vtmp), file);
-    sscanf(vtmp, "%d %d %d %d %d %d %d %d\n", &rows_arg, &columns_arg,
-          &is_long_table_arg, &rotate_arg, &a, &b, &c, &d);
-    Init(rows_arg, columns_arg);
-    SetLongTable(is_long_table_arg);
-    SetRotateTable(rotate_arg);
-    endhead = a;
-    endfirsthead = b;
-    endfoot = c;
-    endlastfoot = d;
-    for (i = 0; i<rows; i++){
-        a = b = c = d = e = f = g = h = 0;
-        fgets(vtmp, sizeof(vtmp), file);
-        sscanf(vtmp, "%d %d %d %d\n",
-               &a, &b, &c, &d);
-        row_info[i].top_line = a;
-        row_info[i].bottom_line = b;
-        row_info[i].is_cont_row = c;
-        row_info[i].newpage = d;
-    }
-    for (i = 0; i<columns; i++){
-        *stmp = 0;
-        *atmp = 0;
-        fgets(vtmp, sizeof(vtmp), file);
-        sscanf(vtmp, "%d %d %d %s %s", &a, &b, &c, stmp, atmp);
-        column_info[i].alignment = static_cast<char>(a);
-        column_info[i].left_line = b;
-        column_info[i].right_line = c;
-        if (*stmp == '"') { /* strip quotes if they exists */
-            *stmp = 0;
-            *atmp = 0;
-            // there are quotes so I have to reread the string correctly
-            // this is only because the old format did not have "
-            // this means also that atmp is ONLY set here!!!
-            if (stmp[1] == '"')
-                sscanf(vtmp, "%*d %*d %*d %*s \"%[^\"]\"", atmp);
-            else // otherwise after the first empty "" read is aborded
-                sscanf(vtmp, "%*d %*d %*d \"%[^\"]\" \"%[^\"]\"", stmp, atmp);
-            column_info[i].p_width = stmp;
-            column_info[i].align_special = atmp;
-        } else if (*stmp)
-            column_info[i].p_width = stmp;
-    }
-    for (i = 0; i < rows; ++i) {
-       for (j = 0; j < columns; ++j) {
-           *stmp = 0;
-           *atmp = 0;
-           a = b = c = d = e = f = g = 0;
-           fgets(vtmp, sizeof(vtmp), file);
-           sscanf(vtmp, "%d %d %d %d %d %d %d %s %s\n",
-                  &a, &b, &c, &d, &e, &f, &g, stmp, atmp);
-           cell_info[i][j].multicolumn = static_cast<char>(a);
-           cell_info[i][j].alignment = static_cast<char>(b);
-           cell_info[i][j].top_line = static_cast<char>(c);
-           cell_info[i][j].bottom_line = static_cast<char>(d);
-           cell_info[i][j].has_cont_row = static_cast<bool>(e);
-           cell_info[i][j].rotate = static_cast<bool>(f);
-           cell_info[i][j].linebreaks = static_cast<bool>(g);
-           // this is only to see if I have an empty string first
-           // this clause should be always TRUE!!!
-           if (*stmp == '"') {
-               *stmp = 0;
-               *atmp = 0;
-               if (stmp[1] == '"')
-                   sscanf(vtmp, "%*d %*d %*d %*d %*d %*d %*d %*s \"%[^\"]\"",
-                          atmp);
-               else // otherwise after the first empty "" read is aborded
-                   sscanf(vtmp, "%*d %*d %*d %*d %*d %*d %*d \"%[^\"]\" \"%[^\"]\"",
-                          stmp, atmp);
-               cell_info[i][j].align_special = stmp;
-               cell_info[i][j].p_width = atmp;
-           } else if (*stmp)
-               cell_info[i][j].align_special = stmp;
+       int version;
+       int i, j;
+       int rows_arg = 0;
+       int columns_arg = 0;
+       int is_long_table_arg = false;
+       int rotate_arg = false;
+       int a = -1;
+       int b = -1;
+       int c = -1;
+       int d = -1;
+       int e = 0;
+       int f = 0;
+       int g = 0;
+       int h = 0;
+       
+       string s;
+       while(!s.length())
+           getline(is, s);
+       if (s.length() > 8)
+               version = atoi(s.c_str() + 8);
+       else
+               version = 1;
+       if (version < 5) {
+               lyxerr << "Tabular format < 5 is not supported anymore\n"
+                       "Get an older version of LyX (< 1.1.x) for conversion!"
+                      << endl;
+               WriteAlert(_("Warning:"),
+                          _("Tabular format < 5 is not supported anymore\n"),
+                          _("Get an older version of LyX (< 1.1.x) for conversion!"));
+               if (version > 2) {
+                       is >> rows_arg >> columns_arg >> is_long_table_arg
+                          >> rotate_arg >> a >> b >> c >> d;
+               } else
+                       is >> rows_arg >> columns_arg;
+               Init(rows_arg, columns_arg);
+               SetLongTable(is_long_table_arg);
+               SetRotateTable(rotate_arg);
+               string tmp;
+               for (i = 0; i < rows; ++i) {
+                       getline(is, tmp);
+               }
+               for (i = 0; i < columns; ++i) {
+                       getline(is, tmp);
+               }
+               for (i = 0; i < rows; ++i) {
+                       for (j = 0; j < columns; ++j) {
+                               getline(is, tmp);
+                       }
+               }
+               set_row_column_number_info();
+               return;
        }
-    }
-    set_row_column_number_info();
+       is >> rows_arg >> columns_arg >> is_long_table_arg
+          >> rotate_arg >> a >> b >> c >> d;
+       Init(rows_arg, columns_arg);
+       SetLongTable(is_long_table_arg);
+       SetRotateTable(rotate_arg);
+       endhead = a;
+       endfirsthead = b;
+       endfoot = c;
+       endlastfoot = d;
+       for (i = 0; i < rows; ++i) {
+               a = b = c = d = e = f = g = h = 0;
+               is >> a >> b >> c >> d;
+               row_info[i].top_line = a;
+               row_info[i].bottom_line = b;
+               row_info[i].is_cont_row = c;
+               row_info[i].newpage = d;
+       }
+       for (i = 0; i < columns; ++i) {
+               string s1;
+               string s2;
+               is >> a >> b >> c;
+               char ch; // skip '"'
+               is >> ch;
+               getline(is, s1, '"');
+               is >> ch; // skip '"'
+               getline(is, s2, '"');
+               column_info[i].alignment = static_cast<char>(a);
+               column_info[i].left_line = b;
+               column_info[i].right_line = c;
+               column_info[i].p_width = s1;
+               column_info[i].align_special = s2;
+       }
+       for (i = 0; i < rows; ++i) {
+               for (j = 0; j < columns; ++j) {
+                       string s1;
+                       string s2;
+                       is >> a >> b >> c >> d >> e >> f >> g;
+                       char ch;
+                       is >> ch; // skip '"'
+                       getline(is, s1, '"');
+                       is >> ch; // skip '"'
+                       getline(is, s2, '"');
+                       cell_info[i][j].multicolumn = static_cast<char>(a);
+                       cell_info[i][j].alignment = static_cast<char>(b);
+                       cell_info[i][j].top_line = static_cast<char>(c);
+                       cell_info[i][j].bottom_line = static_cast<char>(d);
+                       cell_info[i][j].has_cont_row = static_cast<bool>(e);
+                       cell_info[i][j].rotate = static_cast<bool>(f);
+                       cell_info[i][j].linebreaks = static_cast<bool>(g);
+                       cell_info[i][j].align_special = s1;
+                       cell_info[i][j].p_width = s2;
+               }
+       }
+       set_row_column_number_info();
 }
 
 
 // cell <0 will tex the preamble
 // returns the number of printed newlines
-int LyXTable::TexEndOfCell(string & file, int cell)
+int LyXTable::TexEndOfCell(ostream & os, int cell)
 {
     int i;
     int ret = 0;
@@ -970,144 +1081,143 @@ int LyXTable::TexEndOfCell(string & file, int cell)
     if (ShouldBeVeryLastCell(cell)) {
         // the very end at the very beginning
         if (Linebreaks(cell))
-            file += "\\smallskip{}}";
+               os << "\\smallskip{}}";
         if (IsMultiColumn(cell))
-            file += '}';
+               os << '}';
         if (RotateCell(cell)) {
-            file += "\n\\end{sideways}";
-            ret++;
+               os << "\n\\end{sideways}";
+            ++ret;
         }
-        file += "\\\\\n";
-        ret++;
+        os << "\\\\\n";
+        ++ret;
     
         tmp = 0;
         fcell = cell; 
-        while (!IsFirstCell(fcell))fcell--;
-        for (i = 0; i < NumberOfCellsInRow(fcell); i++){
-            if (BottomLine(fcell+i))
-                tmp++;
+        while (!IsFirstCell(fcell)) --fcell;
+        for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
+            if (BottomLine(fcell + i))
+                ++tmp;
         }
-        if (tmp == NumberOfCellsInRow(fcell)){
-            file += "\\hline ";
+        if (tmp == NumberOfCellsInRow(fcell)) {
+               os << "\\hline ";
         } else {
             tmp = 0;
-            for (i = 0; i < NumberOfCellsInRow(fcell); i++){
-                if (BottomLine(fcell+i)){
-                   file += "\\cline{";
-                   file += tostr(column_of_cell(fcell+i)+1);
-                   file += '-';
-                   file += tostr(right_column_of_cell(fcell+i)+1);
-                   file += "} ";
+            for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
+                if (BottomLine(fcell + i)) {
+                       os << "\\cline{"
+                          << column_of_cell(fcell + i) + 1
+                          << '-'
+                          << right_column_of_cell(fcell + i) + 1
+                          << "} ";
                     tmp = 1;
                 }
             }
         }
         if (tmp){
-            file += '\n';
-            ret++;
+               os << '\n';
+            ++ret;
         }
         if (is_long_table)
-            file += "\\end{longtable}";
+               os << "\\end{longtable}";
         else
-            file += "\\end{tabular}";
+               os << "\\end{tabular}";
         if (rotate) {
-            file += "\n\\end{sideways}";
-            ret++;
+               os << "\n\\end{sideways}";
+            ++ret;
         }
     } else {
-        nvcell = NextVirtualCell(cell+1);
+        nvcell = NextVirtualCell(cell + 1);
         if (cell < 0){
             // preamble
             if (rotate) {
-                file += "\\begin{sideways}\n";
-                ret++;
+                   os << "\\begin{sideways}\n";
+                ++ret;
             }
             if (is_long_table)
-                file += "\\begin{longtable}{";
+                   os << "\\begin{longtable}{";
             else
-                file += "\\begin{tabular}{";
-            for (i = 0; i<columns;i++){
+                   os << "\\begin{tabular}{";
+            for (i = 0; i < columns; ++i) {
                 if (column_info[i].left_line)
-                   file += '|';
+                       os << '|';
                 if (!column_info[i].align_special.empty()) {
-                    file += column_info[i].align_special.c_str();
+                       os << column_info[i].align_special;
                 } else if (!column_info[i].p_width.empty()) {
-                    file += "p{";
-                    file += column_info[i].p_width;
-                    file += '}';
+                       os << "p{"
+                          << column_info[i].p_width
+                          << '}';
                 } else {
                     switch (column_info[i].alignment) {
                       case LYX_ALIGN_LEFT:
-                          file += 'l';
+                             os << 'l';
                           break;
                       case LYX_ALIGN_RIGHT:
-                          file += 'r';
+                             os << 'r';
                           break;
                       default:
-                          file += 'c';
+                             os << 'c';
                           break;
                     }
                 }
                 if (column_info[i].right_line)
-                    file += '|';
+                       os << '|';
             }
-            file += "}\n";
-            ret++;
+            os << "}\n";
+            ++ret;
             tmp = 0;
-            if (GetNumberOfCells()){
+            if (GetNumberOfCells()) {
                 fcell = 0;
-                for (i = 0; i < NumberOfCellsInRow(fcell); i++){
-                    if (TopLine(fcell+i))
-                        tmp++;
+                for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
+                    if (TopLine(fcell + i))
+                        ++tmp;
                 }
                 if (tmp == NumberOfCellsInRow(fcell)){
-                    file += "\\hline ";
+                       os << "\\hline ";
                 } else {
                     tmp = 0;
-                    for (i = 0; i < NumberOfCellsInRow(fcell); i++){
-                        if (TopLine(fcell+i)){
-                           file += "\\cline{";
-                           file += tostr(column_of_cell(fcell+i)+1);
-                           file += '-';
-                           file += tostr(right_column_of_cell(fcell+i)+1);
-                           file += "} ";
-                            tmp = 1;
+                    for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
+                        if (TopLine(fcell + i)) {
+                               os << "\\cline{"
+                                  << column_of_cell(fcell + i) + 1
+                                  << '-'
+                                  << right_column_of_cell(fcell + i) + 1
+                                  << "} ";
+                               tmp = 1;
                         }
                     }
                 }
                 if (tmp){
-                    file += '\n';
-                    ret++;
+                       os << '\n';
+                    ++ret;
                 }
             }
             if (RotateCell(0)) {
-                file += "\\begin{sideways}\n";
-                ret++;
+                   os << "\\begin{sideways}\n";
+                ++ret;
             }
         } else {
             // usual cells
             if (Linebreaks(cell))
-                file += "\\smallskip{}}";
+                   os << "\\smallskip{}}";
             if (IsMultiColumn(cell)){
-                file += '}';
+                   os << '}';
             }
             if (RotateCell(cell)) {
-                file += "\n\\end{sideways}";
-                ret++;
+                   os << "\n\\end{sideways}";
+                ++ret;
             }
             if (IsLastCell(cell)) {
                 int row = row_of_cell(cell);
                 string hline1, hline2;
                 bool print_hline = true;
-                bool pr_top_hline, flag1, flag2;
-                flag1 = IsLongTable() &&
+                bool flag1 = IsLongTable() &&
                     ((row == endhead) || (row == endfirsthead) ||
                      (row == endfoot) || (row == endlastfoot));
-                row++;
-                flag2 = IsLongTable() &&
+                ++row;
+                bool flag2 = IsLongTable() &&
                     ((row <= endhead) || (row <= endfirsthead) ||
                      (row <= endfoot) || (row <= endlastfoot));
-                row--;
+                --row;
                 // print the bottom hline only if (otherwise it is doubled):
                 // - is no LongTable
                 // - there IS a first-header
@@ -1115,81 +1225,81 @@ int LyXTable::TexEndOfCell(string & file, int cell)
                 //   & this row is no special header/footer
                 // - the next row is a special header/footer
                 //   & this row is a special header/footer
-                pr_top_hline = (flag1 && flag2) || (!flag1 && !flag2) ||
+                bool pr_top_hline = (flag1 && flag2) || (!flag1 && !flag2) ||
                     (endfirsthead == endhead);
-                file += "\\\\\n";
-                ret++;
+                os << "\\\\\n";
+                ++ret;
                 tmp = 0;
                 fcell = cell;
                 while (!IsFirstCell(fcell))
-                    fcell--;
-                for (i = 0; i < NumberOfCellsInRow(cell); i++){
-                    if (BottomLine(fcell+i))
-                        tmp++;
+                    --fcell;
+                for (i = 0; i < NumberOfCellsInRow(cell); ++i) {
+                    if (BottomLine(fcell + i))
+                        ++tmp;
                 }
                 if (tmp == NumberOfCellsInRow(cell)){
-                    file += "\\hline ";
+                       os << "\\hline ";
                     hline1 = "\\hline ";
                 } else {
                     tmp = 0;
-                    for (i = 0; i < NumberOfCellsInRow(fcell); i++){
-                        if (BottomLine(fcell+i)){
-                            file += "\\cline{";
-                            file += tostr(column_of_cell(fcell+i)+1);
-                            file += '-';
-                            file += tostr(right_column_of_cell(fcell+i)+1);
-                            file += "} ";
+                    for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
+                        if (BottomLine(fcell + i)){
+                               os << "\\cline{"
+                                  << column_of_cell(fcell + i) + 1
+                                  << '-'
+                                  << right_column_of_cell(fcell + i) + 1
+                                  << "} ";
                             hline1 += "\\cline{";
-                            hline1 += tostr(column_of_cell(fcell+i)+1);
+                            hline1 += tostr(column_of_cell(fcell + i) + 1);
                             hline1 += '-';
-                            hline1 += tostr(right_column_of_cell(fcell+i)+1);
+                            hline1 += tostr(right_column_of_cell(fcell + i) + 1);
                             hline1 += "} ";
                             tmp = 1;
                         }
                     }
                 }
                 if (tmp){
-                    file += '\n';
-                    ret++;
+                       os << '\n';
+                    ++ret;
                 }
                 if (IsLongTable() && (row == endfoot)) {
-                    file += "\\endfoot\n";
-                    ret++;
+                       os << "\\endfoot\n";
+                    ++ret;
                     print_hline = false; // no double line below footer
                 }
                 if (IsLongTable() && (row == endlastfoot)) {
-                    file += "\\endlastfoot\n";
-                    ret++;
+                       os << "\\endlastfoot\n";
+                    ++ret;
                     print_hline = false; // no double line below footer
                 }
                 if (IsLongTable() && row_info[row].newpage) {
-                    file += "\\newpage\n";
-                    ret++;
+                       os << "\\newpage\n";
+                    ++ret;
                     print_hline = false; // no line below a \\newpage-command
                 }
                 tmp = 0;
-                if (nvcell < numberofcells && (cell < GetNumberOfCells()-1) &&
-                    !ShouldBeVeryLastCell(cell)) {
+                if (nvcell < numberofcells
+                   && (cell < GetNumberOfCells() - 1)
+                    && !ShouldBeVeryLastCell(cell)) {
                     fcell = nvcell;
-                    for (i = 0; i < NumberOfCellsInRow(fcell); i++){
-                        if (TopLine(fcell+i))
-                            tmp++;
+                    for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
+                        if (TopLine(fcell + i))
+                            ++tmp;
                     }
-                    if (tmp == NumberOfCellsInRow(fcell)){
+                    if (tmp == NumberOfCellsInRow(fcell)) {
                         if (print_hline)
-                            file += "\\hline ";
+                               os << "\\hline ";
                         hline2 = "\\hline ";
-                    }
-                    else {
+                    } else {
                         tmp = 0;
-                        for (i = 0; i < NumberOfCellsInRow(fcell); i++){
-                            if (TopLine(fcell+i)){
+                        for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
+                            if (TopLine(fcell + i)) {
                                 if (print_hline) {
-                                   file += "\\cline{";
-                                   file += tostr(column_of_cell(fcell+i)+1);
-                                   file += '-';
-                                   file += tostr(right_column_of_cell(fcell+i)+1);
-                                   file += "} ";
+                                       os << "\\cline{"
+                                          << column_of_cell(fcell + i) + 1
+                                          << '-'
+                                          << right_column_of_cell(fcell + i) + 1
+                                          << "} ";
                                }
                                 hline2 += "\\cline{";
                                 hline2 += tostr(column_of_cell(fcell+i)+1);
@@ -1201,8 +1311,8 @@ int LyXTable::TexEndOfCell(string & file, int cell)
                         }
                     }
                     if (tmp && print_hline){
-                        file += '\n';
-                        ret++;
+                           os << '\n';
+                        ++ret;
                     }
                 }
                 // the order here is important as if one defines two
@@ -1212,96 +1322,96 @@ int LyXTable::TexEndOfCell(string & file, int cell)
                 // lastfooter is NOT displayed!!!
                 bool sflag2 = (row == endhead) || (row == endfirsthead) ||
                     (row == endfoot) || (row == endlastfoot);
-                row--;
+                --row;
 //                sflag2 = IsLongTable() && (row >= 0) &&
 //                    (sflag2 || (row == endhead) || (row == endfirsthead));
                 row += 2;
                 bool sflag1 = IsLongTable() && (row != endhead) &&
                     (row != endfirsthead) &&
                     ((row == endfoot) || (row == endlastfoot));
-                row--;
+                --row;
                 if (IsLongTable() && (row == endhead)) {
-                   file += "\\endhead\n";
-                    ret++;
+                       os << "\\endhead\n";
+                    ++ret;
                 }
                 if (IsLongTable() && (row == endfirsthead)) {
-                    file += "\\endfirsthead\n";
-                    ret++;
+                       os << "\\endfirsthead\n";
+                    ++ret;
                 }
                 if (sflag1) { // add the \hline for next foot row
                     if (!hline1.empty()) {
-                        file += hline1 + '\n';
-                        ret++;
+                           os << hline1 + '\n';
+                        ++ret;
                     }
                 }
                 // add the \hline for the first row
                 if (pr_top_hline && sflag2) {
                     if (!hline2.empty()) {
-                        file += hline2 + '\n';
-                        ret++;
+                           os << hline2 + '\n';
+                        ++ret;
                     }
                 }
                 if (nvcell < numberofcells && RotateCell(nvcell)) {
-                    file += "\\begin{sideways}\n";
-                    ret++;
+                       os << "\\begin{sideways}\n";
+                    ++ret;
                 }
             } else {
-                file += "&\n";
-                ret++;
+                   os << "&\n";
+                ++ret;
                 if (nvcell < numberofcells && RotateCell(nvcell)) {
-                    file += "\\begin{sideways}\n";
-                    ret++;
+                       os << "\\begin{sideways}\n";
+                    ++ret;
                 }
             }
         }
         if (nvcell < numberofcells && IsMultiColumn(nvcell)) {
-            file += "\\multicolumn{";
-           file += tostr(cells_in_multicolumn(nvcell));
-           file += "}{";
-            if (!cellinfo_of_cell(cell+1)->align_special.empty()) {
-                file += cellinfo_of_cell(cell+1)->align_special;
-                file += "}{";
+               os << "\\multicolumn{"
+                  << cells_in_multicolumn(nvcell)
+                  << "}{";
+            if (!cellinfo_of_cell(nvcell)->align_special.empty()) {
+                   os << cellinfo_of_cell(nvcell)->align_special
+                      << "}{";
             } else {
                 if (LeftLine(nvcell))
-                    file += '|';
+                       os << '|';
                 if (!GetPWidth(nvcell).empty()) {
-                    file += "p{";
-                    file += GetPWidth(nvcell);
-                    file += '}';
+                       os << "p{"
+                          << GetPWidth(nvcell)
+                          << '}';
                 } else {
                     switch (GetAlignment(nvcell)) {
-                      case LYX_ALIGN_LEFT: file += 'l'; break;
-                      case LYX_ALIGN_RIGHT: file += 'r'; break;
-                      default:  file += 'c'; break;
+                   case LYX_ALIGN_LEFT: os << 'l'; break;
+                   case LYX_ALIGN_RIGHT: os << 'r'; break;
+                   default:  os << 'c'; break;
                     }
                 }
                 if (RightLine(nvcell))
-                    file += '|';
+                       os << '|';
                 //if (column_of_cell(cell+2)!= 0 && LeftLine(cell+2))
-                if (((nvcell+1) < numberofcells) &&
+                if (((nvcell + 1) < numberofcells) &&
                     (NextVirtualCell(nvcell+1) < numberofcells) &&
                     (column_of_cell(NextVirtualCell(nvcell+1))!= 0) &&
                     LeftLine(NextVirtualCell(nvcell+1)))
-                    file += '|';
-                file += "}{";
+                       os << '|';
+               
+               os << "}{";
             }
         }
         if (nvcell < numberofcells && Linebreaks(nvcell)) {
-//            !column_info[column_of_cell(nvcell)].p_width.empty()) {
-            file += "\\parbox{";
-           file += GetPWidth(nvcell);
-           file += "}{\\smallskip{}";
+               os << "\\parbox[t]{"
+                  << GetPWidth(nvcell)
+                  << "}{\\smallskip{}";
        }
     }
     return ret;
 }
 
 
+#if 0
 // cell <0 will tex the preamble
 // returns the number of printed newlines
 int LyXTable::RoffEndOfCell(ostream & os, int cell)
 {
-    int i, j;
     int ret = 0;
 
     if (cell == GetNumberOfCells() - 1){
@@ -1311,19 +1421,19 @@ int LyXTable::RoffEndOfCell(ostream & os, int cell)
             ++ret;
         }
         os << "\n";
-        ret++;
+        ++ret;
         if (row_info[row_of_cell(cell)].bottom_line) {
                os << "_\n";
             ++ret;
         }
         os << ".TE\n.pl 1c";
     } else {  
-        if (cell < 0){
+        if (cell < 0) {
             int fcell = 0;
             // preamble
             os << "\n.pl 500c\n.TS\n";
-            for (j = 0; j<rows; ++j) {
-                for (i = 0; i<columns; ++i, ++fcell) {
+            for (int j = 0; j < rows; ++j) {
+                for (int i = 0; i < columns; ++i, ++fcell) {
                     if (column_info[i].left_line)
                            os << " | ";
                     if (cell_info[j][i].multicolumn == CELL_PART_OF_MULTICOLUMN)
@@ -1390,6 +1500,7 @@ int LyXTable::RoffEndOfCell(ostream & os, int cell)
     }
     return ret;
 }
+#endif
 
 
 char const *LyXTable::getDocBookAlign(int cell, bool isColumn)
@@ -1436,121 +1547,122 @@ char const *LyXTable::getDocBookAlign(int cell, bool isColumn)
     }
 }
 
+
 // cell <0 will tex the preamble
 // returns the number of printed newlines
-int LyXTable::DocBookEndOfCell(string & file, int cell, int &depth)
+int LyXTable::DocBookEndOfCell(ostream & os, int cell, int & depth)
 {
     int i;
     int ret = 0;
     //int tmp; // tmp2; // unused
     int nvcell; // fcell; // unused
     if (ShouldBeVeryLastCell(cell)) {
-       addNewlineAndDepth(file,--depth);
-        file += "</ENTRY>";
-       addNewlineAndDepth(file,--depth);
-        file += "</ROW>";
-       addNewlineAndDepth(file,--depth);
-        file += "</TBODY>";
-       addNewlineAndDepth(file,--depth);
+           os << newlineAndDepth(--depth)
+              << "</ENTRY>"
+              << newlineAndDepth(--depth)
+              << "</ROW>"
+              << newlineAndDepth(--depth)
+              << "</TBODY>"
+              << newlineAndDepth(--depth);
         if (is_long_table)
-            file += "</TGROUP>";
+               os << "</TGROUP>";
         else
-            file += "</TGROUP>";
-       addNewlineAndDepth(file,--depth);
+               os << "</TGROUP>"
+                  << newlineAndDepth(--depth);
         ret += 4;
     } else {
-        nvcell = NextVirtualCell(cell+1);
+        nvcell = NextVirtualCell(cell + 1);
         if (cell < 0) {
             // preamble
             if (is_long_table)
-                file += "<TGROUP ";
+                   os << "<TGROUP ";
             else
-                file += "<TGROUP ";
-            file += "COLS='";
-            file += tostr(columns);
-            file += "' COLSEP='1' ROWSEP='1'>";
-           addNewlineAndDepth(file,++depth);
-            ret++;
+                   os << "<TGROUP ";
+            os << "COLS='"
+              << columns
+              << "' COLSEP='1' ROWSEP='1'>"
+              << newlineAndDepth(++depth);
+            ++ret;
             for (i = 0; i < columns; ++i) {
-                file += "<COLSPEC ALIGN='";
-               file += getDocBookAlign(i, true);
-               file += "' COLNAME='col";
-                file += tostr(i+1);
-                file += "' COLNUM='";
-                file += tostr(i+1);
-               file += "' COLSEP='";
+                   os << "<COLSPEC ALIGN='"
+                      << getDocBookAlign(i, true)
+                      << "' COLNAME='col"
+                      << i + 1
+                      << "' COLNUM='"
+                      << i + 1
+                      << "' COLSEP='";
                if (i == (columns-1)) {
-                    file += '1';
+                      os << '1';
                } else {
                    if (column_info[i].right_line ||
                        column_info[i+1].left_line)
-                       file += '1';
+                          os << '1';
                    else
-                       file += '0';
+                          os << '0';
                }
-               file += "'>";
-               addNewlineAndDepth(file, depth);
-                ret++;
+               os << "'>"
+                 << newlineAndDepth(depth);
+                ++ret;
 #ifdef NOT_HANDLED_YET_AS_I_DONT_KNOW_HOW
                 if (column_info[i].left_line)
-                    file += '|';
+                       os << '|';
 #endif
             }
-            file += "<TBODY>";
-           addNewlineAndDepth(file,++depth);
-            file += "<ROW>";
-           addNewlineAndDepth(file,++depth);
-            file += "<ENTRY ALIGN='";
-            file += getDocBookAlign(0);
-           file += "'";
+            os << "<TBODY>"
+              << newlineAndDepth(++depth)
+              << "<ROW>"
+              << newlineAndDepth(++depth)
+              << "<ENTRY ALIGN='"
+              << getDocBookAlign(0)
+              << "'";
            if (IsMultiColumn(0)) {
-               file += " NAMEST='col1' NAMEEND='col";
-               file += tostr(cells_in_multicolumn(0));
-               file += "'";
+                  os << " NAMEST='col1' NAMEEND='col"
+                     << cells_in_multicolumn(0)
+                     << "'";
            }
-            file += ">";
-           addNewlineAndDepth(file,++depth);
+          os << ">"
+             << newlineAndDepth(++depth);
             ret += 3;
         } else {
             if (IsLastCell(cell)) {
-               addNewlineAndDepth(file,--depth);
-                file += "</ENTRY>";
-               addNewlineAndDepth(file,--depth);
-                file += "</ROW>";
-               addNewlineAndDepth(file, depth);
-               file += "<ROW>";
-               addNewlineAndDepth(file,++depth);
-                file += "<ENTRY ALIGN='";
-                file += getDocBookAlign(cell+1);
-                file += "' VALIGN='middle'";
-               if (IsMultiColumn(cell+1)) {
-                   file += " NAMEST='col";
-                   file += tostr(column_of_cell(cell+1) + 1);
-                   file += "' NAMEEND='col";
-                   file += tostr(column_of_cell(cell+1) +
-                       cells_in_multicolumn(cell+1));
-                   file += "'";
+                   os << newlineAndDepth(--depth)
+                      << "</ENTRY>"
+                      << newlineAndDepth(--depth)
+                      << "</ROW>"
+                      << newlineAndDepth(depth)
+                      << "<ROW>"
+                      << newlineAndDepth(++depth)
+                      << "<ENTRY ALIGN='"
+                      << getDocBookAlign(cell + 1)
+                      << "' VALIGN='middle'";
+               if (IsMultiColumn(cell + 1)) {
+                      os << " NAMEST='col"
+                         << column_of_cell(cell+1) + 1
+                         << "' NAMEEND='col"
+                         << column_of_cell(cell + 1) +
+                              cells_in_multicolumn(cell + 1)
+                         << "'";
                }
-               file += ">";
-               addNewlineAndDepth(file,++depth);
+               os << ">"
+                 << newlineAndDepth(++depth);
                 ret += 4;
             } else {
-               addNewlineAndDepth(file,--depth);
-                file += "</ENTRY>";
-               addNewlineAndDepth(file, depth);
-                file += "<ENTRY ALIGN='";
-                file += getDocBookAlign(cell+1);
-                file += "' VALIGN='middle'";
-               if (IsMultiColumn(cell+1)) {
-                   file += " NAMEST='col";
-                   file += tostr(column_of_cell(cell+1) + 1);
-                   file += "' NAMEEND='col";
-                   file += tostr(column_of_cell(cell+1) +
-                       cells_in_multicolumn(cell+1));
-                   file += "'";
+                   os << newlineAndDepth(--depth)
+                      << "</ENTRY>"
+                      << newlineAndDepth(depth)
+                      << "<ENTRY ALIGN='"
+                      << getDocBookAlign(cell + 1)
+                      << "' VALIGN='middle'";
+               if (IsMultiColumn(cell + 1)) {
+                      os << " NAMEST='col"
+                         << column_of_cell(cell+1) + 1
+                         << "' NAMEEND='col"
+                         << column_of_cell(cell+1) +
+                              cells_in_multicolumn(cell+1)
+                         << "'";
                }
-               file += ">";
-               addNewlineAndDepth(file,++depth);
+               os << ">"
+                 << newlineAndDepth(++depth);
                 ret += 3;
             }
         }
@@ -1584,7 +1696,7 @@ void LyXTable::SetMultiColumn(int cell, int number)
     cellinfo_of_cell(fvcell)->alignment = column_info[column_of_cell(fvcell)].alignment;
     cellinfo_of_cell(fvcell)->top_line = row_info[row_of_cell(fvcell)].top_line;
     cellinfo_of_cell(fvcell)->bottom_line = row_info[row_of_cell(fvcell)].bottom_line;
-    for (number--;number>0;number--){
+    for (number--; number > 0; --number) {
         cellinfo_of_cell(fvcell+number)->multicolumn = 
             LyXTable::CELL_PART_OF_MULTICOLUMN;
         new_width += cellinfo_of_cell(fvcell+number)->width_of_cell;
@@ -1599,11 +1711,11 @@ int LyXTable::cells_in_multicolumn(int cell)
     int row = row_of_cell(cell);
     int column = column_of_cell(cell);
     int result = 1;
-    column++;
+    ++column;
     while (column < columns && cell_info[row][column].multicolumn
            == LyXTable::CELL_PART_OF_MULTICOLUMN){
-        result++;
-        column++;
+        ++result;
+        ++column;
     }
     return result;
 }
@@ -1620,14 +1732,14 @@ int  LyXTable::UnsetMultiColumn(int cell)
     if (cell_info[row][column].multicolumn
         == LyXTable::CELL_BEGIN_OF_MULTICOLUMN){
         cell_info[row][column].multicolumn = LyXTable::CELL_NORMAL;
-        column++;
+        ++column;
         while (column < columns &&
                cell_info[row][column].multicolumn
                == LyXTable::CELL_PART_OF_MULTICOLUMN){
             cell_info[row][column].multicolumn = 
                 LyXTable::CELL_NORMAL;
-            column++;
-            result++;
+            ++column;
+            ++result;
         }
     }
     set_row_column_number_info();
@@ -1638,39 +1750,41 @@ int  LyXTable::UnsetMultiColumn(int cell)
 void LyXTable::delete_column(int column)
 {
     int i, j;
-    columnstruct *column_info2 = new columnstruct[columns-1];
+    columnstruct * column_info2 = new columnstruct[columns-1];
    
-    for (i = 0; i<column; i++){
+    for (i = 0; i < column; ++i) {
         column_info2[i] = column_info[i];
     }
-    for (i = column; i<columns-1; i++){
-        column_info2[i] = column_info[i+1];
+    for (i = column; i < columns - 1; ++i) {
+        column_info2[i] = column_info[i + 1];
     }
    
     delete[] column_info;
     column_info = column_info2;
 
-    for (i = 0; i<rows;i++){
-        cellstruct* tmp = cell_info[i];
-        cell_info[i] = new cellstruct[columns-1];
-        for (j = 0; j<column; j++){
+    for (i = 0; i < rows; ++i) {
+        cellstruct * tmp = cell_info[i];
+        cell_info[i] = new cellstruct[columns - 1];
+        for (j = 0; j < column; ++j) {
             cell_info[i][j] = tmp[j];
         }
-        for (j = column; j<columns-1; j++){
-            cell_info[i][j] = tmp[j+1];
+        for (j = column; j < columns - 1; ++j) {
+            cell_info[i][j] = tmp[j + 1];
         }
         delete[] tmp;
     }
 
-    columns--;
+    --columns;
     Reinit();
 }
 
+
 void LyXTable::SetLongTable(int what)
 {
     is_long_table = what;
 }
 
+
 bool LyXTable::IsLongTable()
 {
     return is_long_table;
@@ -1700,8 +1814,8 @@ bool LyXTable::NeedRotating()
 {
     if (rotate)
         return true;
-    for (int i = 0; i<rows;i++){
-        for (int j = 0;j<columns;j++){
+    for (int i = 0; i < rows; ++i) {
+        for (int j = 0; j < columns; ++j) {
             if (cell_info[i][j].rotate)
                 return true;
         }
@@ -1752,7 +1866,7 @@ int LyXTable::FirstVirtualCell(int cell)
         return cell;
     int row = row_of_cell(cell);
     int column = column_of_cell(cell);
-    for(;(row>0) && IsContRow(cell_info[row][column].cellno); row--)
+    for(; (row > 0) && IsContRow(cell_info[row][column].cellno); --row)
         ;
     return cell_info[row][column].cellno;
 }
@@ -1781,7 +1895,7 @@ bool LyXTable::ShouldBeVeryLastCell(int cell)
     if (!IsContRow(fcell))
         return false;
     while((fcell < GetNumberOfCells() - 1) && IsContRow(fcell))
-        fcell++;
+        ++fcell;
     if (fcell < GetNumberOfCells() - 1)
         return false;
     return true;
@@ -1791,10 +1905,10 @@ bool LyXTable::ShouldBeVeryLastRow(int cell)
 {
     if (CellHasContRow(cell)>= 0)
         return false;
-    int row = row_of_cell(cell)+1;
+    int row = row_of_cell(cell) + 1;
     int column = column_of_cell(cell);
     while((row < rows) && IsContRow(cell_info[row][column].cellno))
-        row++;
+        ++row;
     if (row < rows)
         return false; // found another valid row
     // I do not have any valid row after the actual
@@ -1912,3 +2026,55 @@ bool LyXTable::LTNewPage(int cell)
 {
     return row_info[row_of_cell(cell)].newpage;
 }
+
+void LyXTable::SetAscentOfRow(int row, int height)
+{
+    if (row >= rows)
+        return;
+    row_info[row].ascent_of_row = height;
+}
+
+void LyXTable::SetDescentOfRow(int row, int height)
+{
+    if (row >= rows)
+        return;
+    row_info[row].descent_of_row = height;
+}
+
+int LyXTable::AscentOfRow(int row)
+{
+    if (row >= rows)
+        return 0;
+    return row_info[row].ascent_of_row;
+}
+
+int LyXTable::DescentOfRow(int row)
+{
+    if (row >= rows)
+        return 0;
+    return row_info[row].descent_of_row;
+}
+
+int LyXTable::HeightOfTable()
+{
+    int
+        height,
+        row;
+
+    for(row=0,height=0;(row<rows); ++row)
+        height += AscentOfRow(row) + DescentOfRow(row) +
+           AdditionalHeight(GetCellNumber(0,row));
+    return height;
+}
+
+bool LyXTable::IsPartOfMultiColumn(int row, int column)
+{
+    if ((row >= rows) || (column >= columns))
+        return false;
+    return (cell_info[row][column].multicolumn==CELL_PART_OF_MULTICOLUMN);
+}
+
+int LyXTable::Latex(ostream &)
+{
+    return 0;
+}