X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftabular.C;h=0dc9287192a0eeb709d7b78e355105843d0ed0b3;hb=8cb2e519b3975cc643f2c93706137cf2e6a4f4d8;hp=eae3289e051f270d697b6c1474f1325e76ce8ddd;hpb=0ee6cee81b55ccf3b2d91c43804d8a4474beaf89;p=lyx.git diff --git a/src/tabular.C b/src/tabular.C index eae3289e05..0dc9287192 100644 --- a/src/tabular.C +++ b/src/tabular.C @@ -3,20 +3,22 @@ * * LyX, The Document Processor * - * Copyright 2000 The LyX Team. + * Copyright 2000 The LyX Team. + * + * @author: Jürgen Vigna * * ====================================================== */ #include -#include -#include - #ifdef __GNUG__ #pragma implementation #endif +#include +#include + #include "tabular.h" #include "debug.h" #include "vspace.h" @@ -44,50 +46,17 @@ static int const WIDTH_OF_LINE = 5; LyXTabular::cellstruct::cellstruct() { - cellno = 0; //should be initilaized correctly later. + cellno = 0; width_of_cell = 0; multicolumn = LyXTabular::CELL_NORMAL; alignment = LYX_ALIGN_CENTER; + valignment = LYX_VALIGN_TOP; top_line = true; bottom_line = false; + left_line = true; + right_line = false; + usebox = BOX_NONE; rotate = false; - linebreaks = false; - inset = 0; -} - - -LyXTabular::cellstruct::~cellstruct() -{ - delete inset; -} - - -LyXTabular::cellstruct::cellstruct(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; - rotate = cs.rotate; - linebreaks = cs.linebreaks; - inset = 0; -} - - -LyXTabular::cellstruct & -LyXTabular::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; - rotate = cs.rotate; - linebreaks = cs.linebreaks; - return *this; } @@ -106,6 +75,7 @@ LyXTabular::columnstruct::columnstruct() left_line = true; right_line = false; alignment = LYX_ALIGN_CENTER; + valignment = LYX_VALIGN_TOP; width_of_column = 0; } @@ -122,22 +92,17 @@ LyXTabular::LyXTabular(InsetTabular * inset, LyXTabular const & lt) { owner_ = inset; Init(lt.rows_, lt.columns_); - +#ifdef WITH_WARNINGS +#warning Jürgen, can you make it the other way round. So that copy assignment depends on the copy constructor and not the other way. (Lgb) +#endif operator=(lt); } -LyXTabular::LyXTabular(InsetTabular * inset, LyXLex & lex) +LyXTabular::LyXTabular(Buffer const * buf, InsetTabular * inset, LyXLex & lex) { owner_ = inset; - Read(lex); -} - - -LyXTabular::~LyXTabular() -{ - delete[] rowofcell; - delete[] columnofcell; + Read(buf, lex); } @@ -170,17 +135,12 @@ LyXTabular & LyXTabular::operator=(LyXTabular const & lt) LyXTabular * LyXTabular::Clone(InsetTabular * inset) { LyXTabular * result = new LyXTabular(inset, *this); - /// // don't know if this is good but I need to Clone also // the text-insets here, this is for the Undo-facility! - /// - int i,j; - for(i=0; i < rows_; ++i) { - for(j=0; j < columns_; ++j) { - delete result->cell_info[i][j].inset; - result->cell_info[i][j].inset=new InsetText(*cell_info[i][j].inset, - inset->BufferOwner()); - result->cell_info[i][j].inset->setOwner(inset); + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < columns_; ++j) { + result->cell_info[i][j].inset = cell_info[i][j].inset; + result->cell_info[i][j].inset.setOwner(inset); } } return result; @@ -190,204 +150,159 @@ LyXTabular * LyXTabular::Clone(InsetTabular * inset) /* activates all lines and sets all widths to 0 */ void LyXTabular::Init(int rows_arg, int columns_arg) { - int i, j; - int cellno = 0; - rows_ = rows_arg; columns_ = columns_arg; - row_info = vector(rows_, rowstruct()); - column_info = vector(columns_, columnstruct()); - cell_info = vector > - (rows_, vector(columns_, cellstruct())); - - // Jürgen, use iterators. - for (i = 0; i < rows_; ++i) { - for (j = 0; j < columns_; ++j) { - cell_info[i][j].inset = new InsetText(owner_->BufferOwner()); - cell_info[i][j].inset->setOwner(owner_); - cell_info[i][j].inset->SetDrawLockedFrame(true); + row_info = row_vector(rows_, rowstruct()); + column_info = column_vector(columns_, columnstruct()); + cell_info = cell_vvector(rows_, cell_vector(columns_, cellstruct())); + + int cellno = 0; + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < columns_; ++j) { + cell_info[i][j].inset.setOwner(owner_); + cell_info[i][j].inset.SetDrawFrame(0, InsetText::LOCKED); cell_info[i][j].cellno = cellno++; } + cell_info[i].back().right_line = true; } - row_info[i-1].bottom_line = true; - row_info[0].bottom_line = true; + row_info.back().bottom_line = true; + row_info.front().bottom_line = true; - for (i = 0; i < columns_; ++i) { + for (int i = 0; i < columns_; ++i) { calculate_width_of_column(i); } - column_info[columns_-1].right_line = true; + column_info.back().right_line = true; calculate_width_of_tabular(); - rowofcell = 0; - columnofcell = 0; + rowofcell = vector(); + columnofcell = vector(); set_row_column_number_info(); is_long_tabular = false; - rotate = 0; - endhead = -1; - endfirsthead = -1; - endfoot = -1; - endlastfoot = -1; + rotate = false; + endhead = 0; + endfirsthead = 0; + endfoot = 0; + endlastfoot = 0; } -void LyXTabular::AppendRow(int /* cell */) +void LyXTabular::AppendRow(int cell) { -#if 0 + ++rows_; + int row = row_of_cell(cell); - rowstruct * row_info2 = new rowstruct[rows_ + 1]; - cellstruct ** cell_info2 = new cellstruct * [rows_ + 1]; - int i; - for (i = 0; i <= row; ++i) { - cell_info2[i] = cell_info[i]; - row_info2[i] = row_info[i]; + row_vector::iterator rit = row_info.begin() + row; + row_info.insert(rit, rowstruct()); + // now set the values of the row before + row_info[row] = row_info[row+1]; + +#if 0 + cell_vvector::iterator cit = cell_info.begin() + row; + cell_info.insert(cit, vector(columns_, cellstruct())); +#else + cell_vvector c_info = cell_vvector(rows_, cell_vector(columns_, + cellstruct())); + + for (int i = 0; i <= row; ++i) { + for (int j = 0; j < columns_; ++j) { + c_info[i][j] = cell_info[i][j]; + } } - for (i = rows_ - 1; i >= row; --i) { - cell_info2[i + 1] = cell_info[i]; - row_info2[i + 1] = row_info[i]; + for (int i = row + 1; i < rows_; ++i) { + for (int j = 0; j < columns_; ++j) { + c_info[i][j] = cell_info[i-1][j]; + } } - row_info2[row + 1].top_line = row_info[i].top_line; - cell_info2[row + 1] = new cellstruct[columns_](owner_->BufferOwner()); - for (i = 0; i < columns_; ++i) { - cell_info2[row + 1][i].width_of_cell = 0; - cell_info2[row + 1][i] = cell_info2[row][i]; + cell_info = c_info; + ++row; + for (int j = 0; j < columns_; ++j) { + cell_info[row][j].inset.clear(); } - - delete[] cell_info; - cell_info = cell_info2; - delete[] row_info; - row_info = row_info2; - - ++rows_; - - Reinit(); #endif + Reinit(); } void LyXTabular::DeleteRow(int row) { - row_info.erase(row_info.begin() + row); //&row_info[row]); - cell_info.erase(cell_info.begin() + row); //&cell_info[row]); - --rows_; - Reinit(); + // Why make it so hard? (Lgb) + //if (!(rows_ - 1)) + //return; + if (rows_ == 1) return; // Not allowed to delete last row + + row_info.erase(row_info.begin() + row); //&row_info[row]); + cell_info.erase(cell_info.begin() + row); //&cell_info[row]); + --rows_; + Reinit(); } -void LyXTabular::AppendColumn(int /*cell*/) +void LyXTabular::AppendColumn(int cell) { -#if 0 - int j; - columnstruct * column_info2 = new columnstruct[columns_ + 1]; - int column = right_column_of_cell(cell); + ++columns_; + + cell_vvector c_info = cell_vvector(rows_, cell_vector(columns_, + cellstruct())); + int const column = column_of_cell(cell); + column_vector::iterator cit = column_info.begin() + column + 1; + column_info.insert(cit, columnstruct()); + // set the column values of the column before + column_info[column+1] = column_info[column]; - 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]; - } - - 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](owner_->BufferOwner()); - for (j = 0; j <= column; ++j) { - cell_info[i][j] = tmp[j]; + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j <= column; ++j) { + c_info[i][j] = cell_info[i][j]; } - for (j = column; j < columns_; ++j) { - cell_info[i][j + 1] = tmp[j]; + for (int j = column + 1; j < columns_; ++j) { + c_info[i][j] = cell_info[i][j - 1]; } // care about multicolumns - if (cell_info[i][column + 1].multicolumn - == LyXTabular::CELL_BEGIN_OF_MULTICOLUMN){ - cell_info[i][column + 1].multicolumn = - LyXTabular::CELL_PART_OF_MULTICOLUMN; + if (cell_info[i][column + 1].multicolumn == CELL_BEGIN_OF_MULTICOLUMN) { + cell_info[i][column + 1].multicolumn = CELL_PART_OF_MULTICOLUMN; } - if (column + 1 == columns_ - || cell_info[i][column + 2].multicolumn - != LyXTabular::CELL_PART_OF_MULTICOLUMN){ - cell_info[i][column + 1].multicolumn = - LyXTabular::CELL_NORMAL; + if ((column + 1) == columns_ || + cell_info[i][column + 2].multicolumn != CELL_PART_OF_MULTICOLUMN) { + cell_info[i][column + 1].multicolumn = LyXTabular::CELL_NORMAL; } - delete[] tmp; } - - ++columns_; - Reinit(); -#endif -} - - -void LyXTabular::DeleteColumn(int /*cell*/) -{ -#if 0 - int column1 = column_of_cell(cell); - int column2 = right_column_of_cell(cell); - - if (column1 == 0 && column2 == columns_ - 1) - return; - - for (int column = column1; column <= column2; ++column) { - delete_column(column1); + cell_info = c_info; + //++column; + for (int i = 0; i < rows_; ++i) { + //cell_info[i][column].inset.clear(); + cell_info[i][column + 1].inset.clear(); } Reinit(); -#endif } -void LyXTabular::delete_column(int /*column*/) +void LyXTabular::DeleteColumn(int column) { -#if 0 - int i, j; - columnstruct * column_info2 = new columnstruct[columns_-1]; - - 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]; - } - - 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](owner_->BufferOwner()); - 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]; - } - delete[] tmp; + // Similar to DeleteRow + //if (!(columns_ - 1)) + //return; + if (columns_ == 1) return; // Not allowed to delete last column + + column_info.erase(column_info.begin() + column); + for (int i = 0; i < rows_; ++i) { + cell_info[i].erase(cell_info[i].begin() + column); } - --columns_; Reinit(); -#endif } void LyXTabular::Reinit() { - int j; - - int i = 0; - - // Jürgen, use iterators. - for (; i < rows_; ++i) { - for (j = 0; j < columns_; ++j) { + for (int i = 0; i < rows_; ++i) { + for (int j = 0; j < columns_; ++j) { cell_info[i][j].width_of_cell = 0; + cell_info[i][j].inset.setOwner(owner_); } } - for (i = 0; i < columns_; ++i) { + for (int i = 0; i < columns_; ++i) { calculate_width_of_column(i); } calculate_width_of_tabular(); @@ -396,14 +311,11 @@ void LyXTabular::Reinit() } -void LyXTabular::set_row_column_number_info() +void LyXTabular::set_row_column_number_info(bool oldformat) { - int c = 0; - int column = 0; numberofcells = -1; - int row = 0; - for (; row < rows_; ++row) { - for (column = 0; columnSetAutoBreakRows( + // now set the right line of multicolumns right for oldformat read + if (oldformat && + cell_info[row][column].multicolumn==CELL_BEGIN_OF_MULTICOLUMN) + { + int cn=cells_in_multicolumn(cell_info[row][column].cellno); + cell_info[row][column].right_line = + cell_info[row][column+cn-1].right_line; + } + cell_info[row][column].inset.SetAutoBreakRows( !GetPWidth(GetCellNumber(row, column)).empty()); } } @@ -452,7 +370,7 @@ int LyXTabular::GetNumberOfCells() const int LyXTabular::NumberOfCellsInRow(int cell) const { - int row = row_of_cell(cell); + int const row = row_of_cell(cell); int result = 0; for (int i = 0; i < columns_; ++i) { if (cell_info[row][i].multicolumn != LyXTabular::CELL_PART_OF_MULTICOLUMN) @@ -462,56 +380,43 @@ int LyXTabular::NumberOfCellsInRow(int cell) const } -int LyXTabular::AppendCellAfterCell(int append_cell, int question_cell) -{ - return (right_column_of_cell(append_cell) == - right_column_of_cell(question_cell)); -} - - -int LyXTabular::DeleteCellIfColumnIsDeleted(int cell, int delete_column_cell) -{ - if (column_of_cell(delete_column_cell) == 0 && - right_column_of_cell(delete_column_cell) == columns_ - 1) - return 0; - else - return - (column_of_cell(cell) >= column_of_cell(delete_column_cell) && - column_of_cell(cell) <= right_column_of_cell(delete_column_cell)); -} - - /* returns 1 if there is a topline, returns 0 if not */ -bool LyXTabular::TopLine(int cell) const +bool LyXTabular::TopLine(int cell, bool onlycolumn) const { - int row = row_of_cell(cell); + int const row = row_of_cell(cell); - if (IsMultiColumn(cell)) + if (!onlycolumn && IsMultiColumn(cell)) return cellinfo_of_cell(cell)->top_line; return row_info[row].top_line; } -bool LyXTabular::BottomLine(int cell) const +bool LyXTabular::BottomLine(int cell, bool onlycolumn) const { - //no bottom line underneath non-existent cells if you please - if(cell >= numberofcells) + // no bottom line underneath non-existent cells if you please + // Isn't that a programming error? Is so this should + // be an Assert instead. (Lgb) + if (cell >= numberofcells) return false; - if (IsMultiColumn(cell)) + if (!onlycolumn && IsMultiColumn(cell)) return cellinfo_of_cell(cell)->bottom_line; return row_info[row_of_cell(cell)].bottom_line; } -bool LyXTabular::LeftLine(int cell) const +bool LyXTabular::LeftLine(int cell, bool onlycolumn) const { + if (!onlycolumn && IsMultiColumn(cell)) + return cellinfo_of_cell(cell)->left_line; return column_info[column_of_cell(cell)].left_line; } -bool LyXTabular::RightLine(int cell) const +bool LyXTabular::RightLine(int cell, bool onlycolumn) const { + if (!onlycolumn && IsMultiColumn(cell)) + return cellinfo_of_cell(cell)->right_line; return column_info[right_column_of_cell(cell)].right_line; } @@ -561,14 +466,13 @@ bool LyXTabular::IsLastRow(int cell) const int LyXTabular::GetAdditionalHeight(int cell) const { - int row = row_of_cell(cell); + int const row = row_of_cell(cell); if (!row) return 0; - - int top = 1; // bool top = true; ?? - int bottom = 1; // bool bottom = true; ?? - int column; - for (column = 0; column < columns_ - 1 && bottom; ++column) { + bool top = true; + bool bottom = true; + + for (int column = 0; column < columns_ - 1 && bottom; ++column) { switch (cell_info[row - 1][column].multicolumn) { case LyXTabular::CELL_BEGIN_OF_MULTICOLUMN: bottom = cell_info[row - 1][column].bottom_line; @@ -577,7 +481,7 @@ int LyXTabular::GetAdditionalHeight(int cell) const bottom = row_info[row - 1].bottom_line; } } - for (column = 0; column < columns_ - 1 && top; ++column) { + for (int column = 0; column < columns_ - 1 && top; ++column) { switch (cell_info[row][column].multicolumn){ case LyXTabular::CELL_BEGIN_OF_MULTICOLUMN: top = cell_info[row][column].top_line; @@ -596,7 +500,7 @@ int LyXTabular::GetAdditionalWidth(int cell) const { // internally already set in SetWidthOfCell // used to get it back in text.C - int col = right_column_of_cell(cell); + int const col = right_column_of_cell(cell); if (col < columns_ - 1 && column_info[col].right_line && column_info[col+1].left_line) return WIDTH_OF_LINE; @@ -608,11 +512,10 @@ int LyXTabular::GetAdditionalWidth(int cell) const // returns the maximum over all rows int LyXTabular::GetWidthOfColumn(int cell) const { - int column1 = column_of_cell(cell); - int column2 = right_column_of_cell(cell); + int const column1 = column_of_cell(cell); + int const column2 = right_column_of_cell(cell); int result = 0; - int i = column1; - for (; i <= column2; ++i) { + for (int i = column1; i <= column2; ++i) { result += column_info[i].width_of_column; } return result; @@ -631,22 +534,23 @@ bool LyXTabular::SetWidthOfMulticolCell(int cell, int new_width) if (!IsMultiColumn(cell)) return false; - int row = row_of_cell(cell); - int column1 = column_of_cell(cell); - int column2 = right_column_of_cell(cell); + int const row = row_of_cell(cell); + int const column1 = column_of_cell(cell); + int const column2 = right_column_of_cell(cell); // first set columns to 0 so we can calculate the right width - int i = column1; - for (; i <= column2; ++i) { + for (int i = column1; i <= column2; ++i) { cell_info[row][i].width_of_cell = 0; } // set the width to MAX_WIDTH until width > 0 int width = (new_width + 2 * WIDTH_OF_LINE); - for (i = column1; (i < column2) && (width > 0); ++i) { + + int i = column1; + for (; i < column2 && width > column_info[i].width_of_column; ++i) { cell_info[row][i].width_of_cell = column_info[i].width_of_column; width -= column_info[i].width_of_column; } - if (i == column2) { + if (width > 0) { cell_info[row][i].width_of_cell = width; } return true; @@ -655,15 +559,15 @@ bool LyXTabular::SetWidthOfMulticolCell(int cell, int new_width) void LyXTabular::recalculateMulticolCells(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 const row = row_of_cell(cell); + int const column1 = column_of_cell(cell); + int const column2 = right_column_of_cell(cell); // first set columns to 0 so we can calculate the right width 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)); @@ -674,12 +578,14 @@ void LyXTabular::recalculateMulticolCells(int cell, int new_width) /* returns 1 if a complete update is necessary, otherwise 0 */ bool LyXTabular::SetWidthOfCell(int cell, int new_width) { - int row = row_of_cell(cell); - int column1 = column_of_cell(cell); - int tmp = 0; + int const row = row_of_cell(cell); + int const column1 = column_of_cell(cell); + bool tmp = false; int width = 0; - if (IsMultiColumn(cell)) { + if (GetWidthOfCell(cell) == (new_width+2*WIDTH_OF_LINE)) + return false; + if (IsMultiColumn(cell, true)) { tmp = SetWidthOfMulticolCell(cell, new_width); } else { width = (new_width + 2*WIDTH_OF_LINE); @@ -690,14 +596,14 @@ bool LyXTabular::SetWidthOfCell(int cell, int new_width) tmp = calculate_width_of_column_NMC(column1); } if (tmp) { - int i; - for(i = 0; ialignment = align; + if (!onlycolumn) + cellinfo_of_cell(cell)->alignment = align; + return true; +} + + +bool LyXTabular::SetVAlignment(int cell, VAlignment align, bool onlycolumn) +{ + if (!IsMultiColumn(cell) || onlycolumn) + column_info[column_of_cell(cell)].valignment = align; + if (!onlycolumn) + cellinfo_of_cell(cell)->valignment = align; return true; } -bool LyXTabular::SetPWidth(int cell, string const & width) +bool LyXTabular::SetColumnPWidth(int cell, string const & width) { bool flag = !width.empty(); + int const j = column_of_cell(cell); + + column_info[j].p_width = width; + if (flag) // do this only if there is a width + SetAlignment(cell, LYX_ALIGN_LEFT); + for (int i = 0; i < rows_; ++i) { + int c = GetCellNumber(i, j); + flag = !GetPWidth(c).empty(); // because of multicolumns! + GetCellInset(c)->SetAutoBreakRows(flag); + } + return true; +} + +bool LyXTabular::SetMColumnPWidth(int cell, string const & width) +{ + bool const flag = !width.empty(); + + cellinfo_of_cell(cell)->p_width = width; if (IsMultiColumn(cell)) { - cellinfo_of_cell(cell)->p_width = width; GetCellInset(cell)->SetAutoBreakRows(flag); - } else { - int j = column_of_cell(cell); - int c; - column_info[j].p_width = width; - if (flag) // do this only if there is a width - SetAlignment(cell, LYX_ALIGN_LEFT); - for(int i=0; i < rows_; ++i) { - c = GetCellNumber(i, j); - flag = !GetPWidth(c).empty(); // because of multicolumns! - GetCellInset(c)->SetAutoBreakRows(flag); - } + return true; } - return true; + return false; } -bool LyXTabular::SetAlignSpecial(int cell, string const & special, int what) +bool LyXTabular::SetAlignSpecial(int cell, string const & special, + LyXTabular::Feature what) { if (what == SET_SPECIAL_MULTI) cellinfo_of_cell(cell)->align_special = special; @@ -758,11 +683,11 @@ bool LyXTabular::SetAllLines(int cell, bool line) } -bool LyXTabular::SetTopLine(int cell, bool line) +bool LyXTabular::SetTopLine(int cell, bool line, bool onlycolumn) { - int row = row_of_cell(cell); + int const row = row_of_cell(cell); - if (!IsMultiColumn(cell)) + if (onlycolumn || !IsMultiColumn(cell)) row_info[row].top_line = line; else cellinfo_of_cell(cell)->top_line = line; @@ -770,9 +695,9 @@ bool LyXTabular::SetTopLine(int cell, bool line) } -bool LyXTabular::SetBottomLine(int cell, bool line) +bool LyXTabular::SetBottomLine(int cell, bool line, bool onlycolumn) { - if (!IsMultiColumn(cell)) + if (onlycolumn || !IsMultiColumn(cell)) row_info[row_of_cell(cell)].bottom_line = line; else cellinfo_of_cell(cell)->bottom_line = line; @@ -780,30 +705,46 @@ bool LyXTabular::SetBottomLine(int cell, bool line) } -bool LyXTabular::SetLeftLine(int cell, bool line) +bool LyXTabular::SetLeftLine(int cell, bool line, bool onlycolumn) { - column_info[column_of_cell(cell)].left_line = line; + if (onlycolumn || !IsMultiColumn(cell)) + column_info[column_of_cell(cell)].left_line = line; + else + cellinfo_of_cell(cell)->left_line = line; return true; } -bool LyXTabular::SetRightLine(int cell, bool line) +bool LyXTabular::SetRightLine(int cell, bool line, bool onlycolumn) { - column_info[right_column_of_cell(cell)].right_line = line; + if (onlycolumn || !IsMultiColumn(cell)) + column_info[right_column_of_cell(cell)].right_line = line; + else + cellinfo_of_cell(cell)->right_line = line; return true; } -char LyXTabular::GetAlignment(int cell) const +LyXAlignment LyXTabular::GetAlignment(int cell, bool onlycolumn) const { - if (IsMultiColumn(cell)) + if (!onlycolumn && IsMultiColumn(cell)) return cellinfo_of_cell(cell)->alignment; else return column_info[column_of_cell(cell)].alignment; } -string LyXTabular::GetPWidth(int cell) const +LyXTabular::VAlignment +LyXTabular::GetVAlignment(int cell, bool onlycolumn) const +{ + if (!onlycolumn && IsMultiColumn(cell)) + return cellinfo_of_cell(cell)->valignment; + else + return column_info[column_of_cell(cell)].valignment; +} + + +string const LyXTabular::GetPWidth(int cell) const { if (IsMultiColumn(cell)) return cellinfo_of_cell(cell)->p_width; @@ -811,7 +752,21 @@ string LyXTabular::GetPWidth(int cell) const } -string LyXTabular::GetAlignSpecial(int cell, int what) const +string const LyXTabular::GetColumnPWidth(int cell) const +{ + return column_info[column_of_cell(cell)].p_width; +} + + +string const LyXTabular::GetMColumnPWidth(int cell) const +{ + if (IsMultiColumn(cell)) + return cellinfo_of_cell(cell)->p_width; + return string(); +} + + +string const LyXTabular::GetAlignSpecial(int cell, int what) const { if (what == SET_SPECIAL_MULTI) return cellinfo_of_cell(cell)->align_special; @@ -821,20 +776,17 @@ string LyXTabular::GetAlignSpecial(int cell, int what) const int LyXTabular::GetWidthOfCell(int cell) const { - int row = row_of_cell(cell); - int column1 = column_of_cell(cell); - int column2 = right_column_of_cell(cell); + int const row = row_of_cell(cell); + int const column1 = column_of_cell(cell); + int const column2 = right_column_of_cell(cell); int result = 0; - int i = column1; - for (; i <= column2; ++i) { + for (int i = column1; i <= column2; ++i) { result += cell_info[row][i].width_of_cell; } - -// result += GetAdditionalWidth(cell); - return result; } + int LyXTabular::GetBeginningOfTextInCell(int cell) const { int x = 0; @@ -859,7 +811,7 @@ int LyXTabular::GetBeginningOfTextInCell(int cell) const bool LyXTabular::IsFirstCellInRow(int cell) const { - return (column_of_cell(cell) == 0); + return column_of_cell(cell) == 0; } @@ -886,7 +838,7 @@ int LyXTabular::GetLastCellInRow(int row) const bool LyXTabular::calculate_width_of_column(int column) { - int old_column_width = column_info[column].width_of_column; + int const old_column_width = column_info[column].width_of_column; int maximum = 0; for (int i = 0; i < rows_; ++i) { @@ -897,12 +849,16 @@ bool LyXTabular::calculate_width_of_column(int column) } +// +// calculate the with of the column without regarding REAL MultiColumn +// cells. This means MultiColumn-cells spanning more than 1 column. +// bool LyXTabular::calculate_width_of_column_NMC(int column) { - int old_column_width = column_info[column].width_of_column; + int const old_column_width = column_info[column].width_of_column; int max = 0; for (int i = 0; i < rows_; ++i) { - if (!IsMultiColumn(GetCellNumber(i, column)) && + if (!IsMultiColumn(GetCellNumber(i, column), true) && (cell_info[i][column].width_of_cell > max)) { max = cell_info[i][column].width_of_cell; } @@ -924,7 +880,7 @@ void LyXTabular::calculate_width_of_tabular() int LyXTabular::row_of_cell(int cell) const { if (cell >= numberofcells) - return rows_-1; + return rows_ - 1; else if (cell < 0) return 0; return rowofcell[cell]; @@ -934,7 +890,7 @@ int LyXTabular::row_of_cell(int cell) const int LyXTabular::column_of_cell(int cell) const { if (cell >= numberofcells) - return columns_-1; + return columns_ - 1; else if (cell < 0) return 0; return columnofcell[cell]; @@ -943,243 +899,446 @@ int LyXTabular::column_of_cell(int cell) const int LyXTabular::right_column_of_cell(int cell) const { - int row = row_of_cell(cell); + int const row = row_of_cell(cell); int column = column_of_cell(cell); while (column < (columns_ - 1) && - cell_info[row][column+1].multicolumn == LyXTabular::CELL_PART_OF_MULTICOLUMN) + cell_info[row][column + 1].multicolumn == LyXTabular::CELL_PART_OF_MULTICOLUMN) ++column; return column; } -void LyXTabular::Write(ostream & os) const +// Perfect case for a template... (Lgb) +#if 1 +template +string const write_attribute(string const & name, T const & t) +{ + string str = " " + name + "=\"" + tostr(t) + "\""; + return str; +} + +template <> +string const write_attribute(string const & name, bool const & b) +{ + return write_attribute(name, int(b)); +} + +#else + +string const write_attribute(string const & name, int value) +{ + string str = " " + name + "=\"" + tostr(value) + "\""; + return str; +} + + +string const write_attribute(string const & name, string const & value) +{ + string str = " " + name + "=\"" + value + "\""; + return str; +} + + +string const write_attribute(string const & name, bool value) +{ + string str = " " + name + "=\"" + tostr(static_cast(value)) + "\""; + return str; +} +#endif + + +template<> +inline +string const tostr(LyXAlignment const & num) +{ + switch(num) { + case LYX_ALIGN_NONE: + return "none"; + case LYX_ALIGN_BLOCK: + return "block"; + case LYX_ALIGN_LEFT: + return "left"; + case LYX_ALIGN_CENTER: + return "center"; + case LYX_ALIGN_RIGHT: + return "right"; + case LYX_ALIGN_LAYOUT: + return "layout"; + case LYX_ALIGN_SPECIAL: + return "special"; + } + return string(); +} + + +template<> +inline +string const tostr(LyXTabular::VAlignment const & num) +{ + switch(num) { + case LyXTabular::LYX_VALIGN_TOP: + return "top"; + case LyXTabular::LYX_VALIGN_CENTER: + return "center"; + case LyXTabular::LYX_VALIGN_BOTTOM: + return "bottom"; + } + return string(); +} + + +template<> +inline +string const tostr(LyXTabular::BoxType const & num) { - int i, j; + switch(num) { + case LyXTabular::BOX_NONE: + return "none"; + case LyXTabular::BOX_PARBOX: + return "parbox"; + case LyXTabular::BOX_MINIPAGE: + return "minipage"; + } + return string(); +} + +void LyXTabular::Write(Buffer const * buf, ostream & os) const +{ // header line - os << "" << endl; + os << "\n"; // global longtable options - os << "" << endl << endl; - for (i = 0; i < rows_; ++i) { - os << "" << endl; - for (j = 0; j < columns_; ++j) { + os << "\n"; + for (int j = 0; j < columns_; ++j) { + os << "\n"; + } + for (int i = 0; i < rows_; ++i) { + os << "\n"; + for (int j = 0; j < columns_; ++j) { +#if 0 if (!i) { - os << "" << endl; + os << "\n"; } else { - os << "" << endl; + os << "\n"; } - os << "" << endl; +#endif + os << "\n"; os << "\\begin_inset "; - cell_info[i][j].inset->Write(os); - os << "\n\\end_inset " << endl; - os << "" << endl; - os << "" << endl; + cell_info[i][j].inset.Write(buf, os); + os << "\n\\end_inset \n" + << "\n"; +#if 0 + << "\n"; +#endif } - os << "" << endl; + os << "\n"; } - os << "" << endl; + os << "\n"; } -static -bool getTokenValue(string const str, const char * token, string & ret) -{ - int pos = str.find(token); - char ch = str[pos+strlen(token)]; +// I would have liked a fromstr template a lot better. (Lgb) - if ((pos < 0) || (ch != '=')) +static inline +bool string2type(string const str, LyXAlignment & num) +{ + if (str == "none") + num = LYX_ALIGN_NONE; + else if (str == "block") + num = LYX_ALIGN_BLOCK; + else if (str == "left") + num = LYX_ALIGN_LEFT; + else if (str == "center") + num = LYX_ALIGN_CENTER; + else if (str == "right") + num = LYX_ALIGN_RIGHT; + else return false; - ret.erase(); - pos += strlen(token)+1; - ch = str[pos]; - if ((ch != '"') && (ch != '\'')) { // only read till next space - ret += ch; - ch = ' '; - } - while((pos < int(str.length()-1)) && (str[++pos] != ch)) - ret += str[pos]; - return true; } -static -bool getTokenValue(string const str, const char * token, int & num) +static inline +bool string2type(string const str, LyXTabular::VAlignment & num) { - string ret; - int pos = str.find(token); - char ch = str[pos+strlen(token)]; + if (str == "top") + num = LyXTabular::LYX_VALIGN_TOP; + else if (str == "center") + num = LyXTabular::LYX_VALIGN_CENTER; + else if (str == "bottom") + num = LyXTabular::LYX_VALIGN_BOTTOM; + else + return false; + return true; +} - if ((pos < 0) || (ch != '=')) + +static inline +bool string2type(string const str, LyXTabular::BoxType & num) +{ + if (str == "none") + num = LyXTabular::BOX_NONE; + else if (str == "parbox") + num = LyXTabular::BOX_PARBOX; + else if (str == "minipage") + num = LyXTabular::BOX_MINIPAGE; + else return false; - ret.erase(); - pos += strlen(token)+1; - ch = str[pos]; - if ((ch != '"') && (ch != '\'')) { // only read till next space - if (!isdigit(ch)) - return false; - ret += ch; - } - ++pos; - while((pos < int(str.length()-1)) && isdigit(str[pos])) - ret += str[pos++]; + return true; +} - num = strToInt(ret); + +static inline +bool string2type(string const str, bool & num) +{ + if (str == "true") + num = true; + else if (str == "false") + num = false; + else + return false; return true; } static -bool getTokenValue(string const str, const char * token, bool & flag) +bool getTokenValue(string const & str, const char * token, string & ret) { - string ret; - int pos = str.find(token); - char ch = str[pos+strlen(token)]; + size_t token_length = strlen(token); + string::size_type pos = str.find(token); - if ((pos < 0) || (ch != '=')) + if (pos == string::npos || pos+token_length+1 >= str.length() + || str[pos+token_length] != '=') return false; ret.erase(); - pos += strlen(token)+1; - ch = str[pos]; + pos += token_length + 1; + char ch = str[pos]; if ((ch != '"') && (ch != '\'')) { // only read till next space - if (!isdigit(ch)) - return false; ret += ch; + ch = ' '; } - ++pos; - while((pos < int(str.length()-1)) && isdigit(str[pos])) - ret += str[pos++]; + while((pos < str.length() - 1) && (str[++pos] != ch)) + ret += str[pos]; - flag = strToInt(ret); return true; } -void l_getline(istream & is, string & str) +static +bool getTokenValue(string const & str, const char * token, int & num) { - getline(is, str); - while(str.empty()) - getline(is, str); + string tmp; + if (!getTokenValue(str, token, tmp)) + return false; + num = strToInt(tmp); + return true; } -void LyXTabular::Read(LyXLex & lex) +static +bool getTokenValue(string const & str, const char * token, LyXAlignment & num) { - string line; - istream & is = lex.getStream(); + string tmp; + if (!getTokenValue(str, token, tmp)) + return false; + return string2type(tmp, num); +} - l_getline(is, line); - if (!prefixIs(line, " got" << + if (!prefixIs(line, " got" << line << ")" << endl; return; } - (void)getTokenValue(line, "islongtable", is_long_tabular); - (void)getTokenValue(line, "endhead", endhead); - (void)getTokenValue(line, "endfirsthead", endfirsthead); - (void)getTokenValue(line, "endfoot", endfoot); - (void)getTokenValue(line, "endlastfoot", endlastfoot); - int i, j; - for(i = 0; i < rows_; ++i) { + getTokenValue(line, "rotate", rotate); + getTokenValue(line, "islongtable", is_long_tabular); + getTokenValue(line, "endhead", endhead); + getTokenValue(line, "endfirsthead", endfirsthead); + getTokenValue(line, "endfoot", endfoot); + getTokenValue(line, "endlastfoot", endlastfoot); + + for (int j = 0; j < columns_; ++j) { + l_getline(is,line); + if (!prefixIs(line," got" << + line << ")" << endl; + return; + } + getTokenValue(line, "alignment", column_info[j].alignment); + getTokenValue(line, "valignment", column_info[j].valignment); + getTokenValue(line, "leftline", column_info[j].left_line); + getTokenValue(line, "rightline", column_info[j].right_line); + getTokenValue(line, "width", column_info[j].p_width); + getTokenValue(line, "special", column_info[j].align_special); + } + + for (int i = 0; i < rows_; ++i) { l_getline(is, line); - if (!prefixIs(line, " got" << + if (!prefixIs(line, " got" << line << ")" << endl; return; } - (void)getTokenValue(line, "topline", row_info[i].top_line); - (void)getTokenValue(line, "bottomline", row_info[i].bottom_line); - (void)getTokenValue(line, "newpage", row_info[i].newpage); - for (j = 0; j < columns_; ++j) { - l_getline(is,line); - if (!prefixIs(line," got" << - line << ")" << endl; - return; - } - if (!i) { - (void)getTokenValue(line, "alignment", column_info[j].alignment); - (void)getTokenValue(line, "leftline", column_info[j].left_line); - (void)getTokenValue(line, "rightline", column_info[j].right_line); - (void)getTokenValue(line, "width", column_info[j].p_width); - (void)getTokenValue(line, "special", column_info[j].align_special); - } + getTokenValue(line, "topline", row_info[i].top_line); + getTokenValue(line, "bottomline", row_info[i].bottom_line); + getTokenValue(line, "newpage", row_info[i].newpage); + for (int j = 0; j < columns_; ++j) { l_getline(is, line); - if (!prefixIs(line, " got" << + if (!prefixIs(line, " got" << line << ")" << endl; return; } - (void)getTokenValue(line, "multicolumn", cell_info[i][j].multicolumn); - (void)getTokenValue(line, "alignment", cell_info[i][j].alignment); - (void)getTokenValue(line, "topline", cell_info[i][j].top_line); - (void)getTokenValue(line, "bottomline", cell_info[i][j].bottom_line); - (void)getTokenValue(line, "rotate", cell_info[i][j].rotate); - (void)getTokenValue(line, "linebreaks", cell_info[i][j].linebreaks); - (void)getTokenValue(line, "width", cell_info[i][j].p_width); - (void)getTokenValue(line, "special", cell_info[i][j].align_special); + getTokenValue(line, "multicolumn", cell_info[i][j].multicolumn); + getTokenValue(line, "alignment", cell_info[i][j].alignment); + getTokenValue(line, "valignment", cell_info[i][j].valignment); + getTokenValue(line, "topline", cell_info[i][j].top_line); + getTokenValue(line, "bottomline", cell_info[i][j].bottom_line); + getTokenValue(line, "leftline", cell_info[i][j].left_line); + getTokenValue(line, "rightline", cell_info[i][j].right_line); + getTokenValue(line, "rotate", cell_info[i][j].rotate); + getTokenValue(line, "usebox", cell_info[i][j].usebox); + getTokenValue(line, "width", cell_info[i][j].p_width); + getTokenValue(line, "special", cell_info[i][j].align_special); l_getline(is, line); if (prefixIs(line, "\\begin_inset")) { - cell_info[i][j].inset->Read(lex); + cell_info[i][j].inset.Read(buf, lex); l_getline(is, line); } - if (line != "") { - lyxerr << "Wrong tabular format (expected got" << - line << ")" << endl; - return; - } - l_getline(is, line); - if (line != "") { - lyxerr << "Wrong tabular format (expected got" << + if (line != "") { + lyxerr << "Wrong tabular format (expected got" << line << ")" << endl; return; } } l_getline(is, line); - if (line != "") { - lyxerr << "Wrong tabular format (expected got" << + if (line != "") { + lyxerr << "Wrong tabular format (expected got" << line << ")" << endl; return; } } - while (line != "") { + while (line != "") { l_getline(is, line); } set_row_column_number_info(); @@ -1189,7 +1348,8 @@ void LyXTabular::Read(LyXLex & lex) void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) { int version; - int i, j; + int i; + int j; int rows_arg = 0; int columns_arg = 0; int is_long_tabular_arg = false; @@ -1201,12 +1361,11 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) int e = 0; int f = 0; int g = 0; - int h = 0; istream & is = lex.getStream(); string s(fl); if (s.length() > 8) - version = atoi(s.c_str() + 8); + version = lyx::atoi(s.substr(8, string::npos)); else version = 1; @@ -1248,12 +1407,12 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) cont_row_info = vector(rows_arg); SetLongTabular(is_long_tabular_arg); SetRotateTabular(rotate_arg); - endhead = a; - endfirsthead = b; - endfoot = c; - endlastfoot = d; + endhead = a + 1; + endfirsthead = b + 1; + endfoot = c + 1; + endlastfoot = d + 1; for (i = 0; i < rows_; ++i) { - a = b = c = d = e = f = g = h = 0; + a = b = c = d = e = f = g = 0; is >> a >> b >> c >> d; row_info[i].top_line = a; row_info[i].bottom_line = b; @@ -1264,12 +1423,22 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) string s1; string s2; is >> a >> b >> c; +#if 1 char ch; // skip '"' is >> ch; +#else + // ignore is buggy but we will use it later (Lgb) + is.ignore(); // skip '"' +#endif getline(is, s1, '"'); +#if 1 is >> ch; // skip '"' +#else + // ignore is buggy but we will use it later (Lgb) + is.ignore(); // skip '"' +#endif getline(is, s2, '"'); - column_info[i].alignment = static_cast(a); + column_info[i].alignment = static_cast(a); column_info[i].left_line = b; column_info[i].right_line = c; column_info[i].p_width = s1; @@ -1280,50 +1449,69 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) string s1; string s2; is >> a >> b >> c >> d >> e >> f >> g; +#if 1 char ch; is >> ch; // skip '"' +#else + // ignore is buggy but we will use it later (Lgb) + is.ignore(); // skip '"' +#endif getline(is, s1, '"'); +#if 1 is >> ch; // skip '"' +#else + // ignore is buggy but we will use it later (Lgb) + is.ignore(); // skip '"' +#endif getline(is, s2, '"'); cell_info[i][j].multicolumn = static_cast(a); - cell_info[i][j].alignment = static_cast(b); + cell_info[i][j].alignment = static_cast(b); cell_info[i][j].top_line = static_cast(c); cell_info[i][j].bottom_line = static_cast(d); + cell_info[i][j].left_line = column_info[j].left_line; + cell_info[i][j].right_line = column_info[j].right_line; cell_info[i][j].rotate = static_cast(f); - cell_info[i][j].linebreaks = static_cast(g); + cell_info[i][j].usebox = static_cast(g); cell_info[i][j].align_special = s1; cell_info[i][j].p_width = s2; } } } - set_row_column_number_info(); + set_row_column_number_info(true); LyXParagraph * par = new LyXParagraph; LyXParagraph * return_par = 0; +#ifndef NEW_INSETS LyXParagraph::footnote_flag footnoteflag = LyXParagraph::NO_FOOTNOTE; LyXParagraph::footnote_kind footnotekind = LyXParagraph::FOOTNOTE; - string token, tmptok; +#endif + string tmptok; int pos = 0; char depth = 0; - LyXFont font(LyXFont::ALL_SANE); + LyXFont font(LyXFont::ALL_INHERIT); + font.setLanguage(owner_->BufferOwner()->GetLanguage()); while (lex.IsOK()) { lex.nextToken(); - token = lex.GetString(); + string const token = lex.GetString(); if (token.empty()) continue; - if ((token == "\\layout") || (token == "\\end_float") || - (token == "\\end_deeper")) - { + if (token == "\\layout" + || token == "\\end_float" + || token == "\\end_deeper") { lex.pushToken(token); break; } if (owner_->BufferOwner()->parseSingleLyXformat2Token(lex, par, return_par, token, pos, - depth, font, + depth, font +#ifndef NEW_INSETS + , footnoteflag, - footnotekind)) + footnotekind +#endif + )) { // the_end read lex.pushToken(token); @@ -1339,16 +1527,21 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) } // now we have the par we should fill the insets with this! int cell = 0; - InsetText *inset = GetCellInset(cell); + InsetText * inset = GetCellInset(cell); int row; - for(int i=0; i < par->Last(); ++i) { +#ifndef NEW_INSETS + for (int i = 0; i < par->Last(); ++i) { +#else + for (int i = 0; i < par->size(); ++i) { +#endif if (par->IsNewline(i)) { ++cell; if (cell > GetNumberOfCells()) { lyxerr << "Some error in reading old table format occured!" << endl << "Terminating when reading cell[" << cell << "]!" << endl; + delete par; return; } row = row_of_cell(cell); @@ -1362,229 +1555,62 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) } inset = GetCellInset(cell); row = row_of_cell(cell); - if (!cell_info[row_of_cell(cell)][column_of_cell(cell)].linebreaks) + if (!cell_info[row_of_cell(cell)][column_of_cell(cell)].usebox) { // insert a space instead par->Erase(i); par->InsertChar(i, ' '); } } - par->CopyIntoMinibuffer(i); + par->CopyIntoMinibuffer(*owner_->BufferOwner(), i); +#ifndef NEW_INSETS inset->par->InsertFromMinibuffer(inset->par->Last()); - } - Reinit(); -} - - -char const * LyXTabular::GetDocBookAlign(int cell, bool isColumn) const -{ - int i = isColumn ? cell : column_of_cell(cell); - - //if (isColumn) - //i = cell; - //else - //i = column_of_cell(cell); - if (!isColumn && IsMultiColumn(cell)) { - if (!cellinfo_of_cell(cell)->align_special.empty()) { - return cellinfo_of_cell(cell)->align_special.c_str(); - } else { - switch (GetAlignment(cell)) { - case LYX_ALIGN_LEFT: - return "left"; - case LYX_ALIGN_RIGHT: - return "right"; - default: - return "center"; - } - } - } else { - if (!column_info[i].align_special.empty()) { - return column_info[i].align_special.c_str(); - } -#ifdef IGNORE_THIS_FOR_NOW - else if (!column_info[i].p_width.empty()) { - file += "p{"; - file += column_info[i].p_width; - file += '}'; - } -#endif - else { - switch (column_info[i].alignment) { - case LYX_ALIGN_LEFT: - return "left"; - case LYX_ALIGN_RIGHT: - return "right"; - default: - return "center"; - } - } - } -} - - -// cell <0 will tex the preamble -// returns the number of printed newlines -int LyXTabular::DocBookEndOfCell(ostream & os, int cell, int & depth) const -{ - int i; - int ret = 0; - //int tmp; // tmp2; // unused - int nvcell; // fcell; // unused - if (IsLastCell(cell)) { - os << newlineAndDepth(--depth) - << "" - << newlineAndDepth(--depth) - << "" - << newlineAndDepth(--depth) - << "" - << newlineAndDepth(--depth); - if (is_long_tabular) - os << ""; - else - os << "" - << newlineAndDepth(--depth); - ret += 4; - } else { - nvcell = cell + 1; - if (cell < 0) { - // preamble - if (is_long_tabular) - os << "" - << newlineAndDepth(++depth); - ++ret; - for (i = 0; i < columns_; ++i) { - os << "" - << newlineAndDepth(depth); - ++ret; -#ifdef NOT_HANDLED_YET_AS_I_DONT_KNOW_HOW - if (column_info[i].left_line) - os << '|'; +#else + inset->par->InsertFromMinibuffer(inset->par->size()); #endif - } - os << "" - << newlineAndDepth(++depth) - << "" - << newlineAndDepth(++depth) - << "" - << newlineAndDepth(++depth); - ret += 3; - } else { - if (IsLastCellInRow(cell)) { - os << newlineAndDepth(--depth) - << "" - << newlineAndDepth(--depth) - << "" - << newlineAndDepth(depth) - << "" - << newlineAndDepth(++depth) - << "" - << newlineAndDepth(++depth); - ret += 4; - } else { - os << newlineAndDepth(--depth) - << "" - << newlineAndDepth(depth) - << "" - << newlineAndDepth(++depth); - ret += 3; - } - } } - return ret; + delete par; + Reinit(); } -bool LyXTabular::IsMultiColumn(int cell) const +bool LyXTabular::IsMultiColumn(int cell, bool real) const { - return (cellinfo_of_cell(cell)->multicolumn != LyXTabular::CELL_NORMAL); + return ((!real || (column_of_cell(cell) != right_column_of_cell(cell))) && + (cellinfo_of_cell(cell)->multicolumn != LyXTabular::CELL_NORMAL)); } LyXTabular::cellstruct * LyXTabular::cellinfo_of_cell(int cell) const { - int row = row_of_cell(cell); - int column = column_of_cell(cell); + int const row = row_of_cell(cell); + int const column = column_of_cell(cell); return &cell_info[row][column]; } - + void LyXTabular::SetMultiColumn(int cell, int number) { - int new_width = cellinfo_of_cell(cell)->width_of_cell; - - cellinfo_of_cell(cell)->multicolumn = LyXTabular::CELL_BEGIN_OF_MULTICOLUMN; + cellinfo_of_cell(cell)->multicolumn = CELL_BEGIN_OF_MULTICOLUMN; cellinfo_of_cell(cell)->alignment = column_info[column_of_cell(cell)].alignment; cellinfo_of_cell(cell)->top_line = row_info[row_of_cell(cell)].top_line; cellinfo_of_cell(cell)->bottom_line = row_info[row_of_cell(cell)].bottom_line; for (number--; number > 0; --number) { - cellinfo_of_cell(cell+number)->multicolumn = - LyXTabular::CELL_PART_OF_MULTICOLUMN; - new_width += cellinfo_of_cell(cell+number)->width_of_cell; + cellinfo_of_cell(cell+number)->multicolumn = CELL_PART_OF_MULTICOLUMN; } set_row_column_number_info(); - SetWidthOfCell(cell, new_width); } int LyXTabular::cells_in_multicolumn(int cell) const { - int row = row_of_cell(cell); + int const row = row_of_cell(cell); int column = column_of_cell(cell); int result = 1; ++column; - while (column < columns_ && cell_info[row][column].multicolumn - == LyXTabular::CELL_PART_OF_MULTICOLUMN){ + while ((column < columns_) && + cell_info[row][column].multicolumn == CELL_PART_OF_MULTICOLUMN) + { ++result; ++column; } @@ -1594,20 +1620,18 @@ int LyXTabular::cells_in_multicolumn(int cell) const int LyXTabular::UnsetMultiColumn(int cell) { - int row = row_of_cell(cell); + int const row = row_of_cell(cell); int column = column_of_cell(cell); int result = 0; - if (cell_info[row][column].multicolumn - == LyXTabular::CELL_BEGIN_OF_MULTICOLUMN){ - cell_info[row][column].multicolumn = LyXTabular::CELL_NORMAL; + if (cell_info[row][column].multicolumn == CELL_BEGIN_OF_MULTICOLUMN) { + cell_info[row][column].multicolumn = CELL_NORMAL; ++column; - while (column < columns_ && - cell_info[row][column].multicolumn - == LyXTabular::CELL_PART_OF_MULTICOLUMN){ - cell_info[row][column].multicolumn = - LyXTabular::CELL_NORMAL; + while ((column < columns_) && + (cell_info[row][column].multicolumn ==CELL_PART_OF_MULTICOLUMN)) + { + cell_info[row][column].multicolumn = CELL_NORMAL; ++column; ++result; } @@ -1617,7 +1641,7 @@ int LyXTabular::UnsetMultiColumn(int cell) } -void LyXTabular::SetLongTabular(int what) +void LyXTabular::SetLongTabular(bool what) { is_long_tabular = what; } @@ -1629,9 +1653,9 @@ bool LyXTabular::IsLongTabular() const } -void LyXTabular::SetRotateTabular(int what) +void LyXTabular::SetRotateTabular(bool flag) { - rotate = what; + rotate = flag; } @@ -1641,9 +1665,9 @@ bool LyXTabular::GetRotateTabular() const } -void LyXTabular::SetRotateCell(int cell, int what) +void LyXTabular::SetRotateCell(int cell, bool flag) { - cellinfo_of_cell(cell)->rotate = what; + cellinfo_of_cell(cell)->rotate = flag; } @@ -1669,7 +1693,7 @@ bool LyXTabular::NeedRotating() const bool LyXTabular::IsLastCell(int cell) const { - if ((cell+1) < GetNumberOfCells()) + if ((cell + 1) < GetNumberOfCells()) return false; return true; } @@ -1685,12 +1709,32 @@ int LyXTabular::GetCellAbove(int cell) const int LyXTabular::GetCellBelow(int cell) const { - if (row_of_cell(cell)+1 < rows_) + if (row_of_cell(cell) + 1 < rows_) return cell_info[row_of_cell(cell)+1][column_of_cell(cell)].cellno; return cell; } +int LyXTabular::GetLastCellAbove(int cell) const +{ + if (row_of_cell(cell) <= 0) + return cell; + if (!IsMultiColumn(cell)) + return GetCellAbove(cell); + return cell_info[row_of_cell(cell) - 1][right_column_of_cell(cell)].cellno; +} + + +int LyXTabular::GetLastCellBelow(int cell) const +{ + if (row_of_cell(cell) + 1 >= rows_) + return cell; + if (!IsMultiColumn(cell)) + return GetCellBelow(cell); + return cell_info[row_of_cell(cell) + 1][right_column_of_cell(cell)].cellno; +} + + int LyXTabular::GetCellNumber(int row, int column) const { if (column >= columns_) @@ -1706,85 +1750,94 @@ int LyXTabular::GetCellNumber(int row, int column) const } -void LyXTabular::SetLinebreaks(int cell, bool what) +void LyXTabular::SetUsebox(int cell, BoxType type) { - cellinfo_of_cell(cell)->linebreaks = what; + cellinfo_of_cell(cell)->usebox = type; } -bool LyXTabular::GetLinebreaks(int cell) const +LyXTabular::BoxType LyXTabular::GetUsebox(int cell) const { if (column_info[column_of_cell(cell)].p_width.empty() && !(IsMultiColumn(cell) && !cellinfo_of_cell(cell)->p_width.empty())) - return false; - return cellinfo_of_cell(cell)->linebreaks; + return BOX_NONE; + if (cellinfo_of_cell(cell)->usebox > 1) + return cellinfo_of_cell(cell)->usebox; + return UseParbox(cell); } void LyXTabular::SetLTHead(int cell, bool first) { - int row = row_of_cell(cell); + int const row = row_of_cell(cell); + int const val = (row + 1) * (column_of_cell(cell) ? 1 : -1); if (first) { - if (row == endfirsthead) - endfirsthead = -1; + if (endfirsthead == val) + endfirsthead = 0; else - endfirsthead = row; + endfirsthead = val; } else { - if (row == endhead) - endhead = -1; + if (endhead == val) + endhead = 0; else - endhead = row; + endhead = val; } } -bool LyXTabular::GetRowOfLTHead(int cell) const +bool LyXTabular::GetRowOfLTHead(int cell, int & row) const { - if ((endhead+1) > rows_) + row = endhead; + if (abs(endhead) > rows_) return false; - return (row_of_cell(cell) == endhead); + return (row_of_cell(cell) == abs(endhead) - 1); } -bool LyXTabular::GetRowOfLTFirstHead(int cell) const +bool LyXTabular::GetRowOfLTFirstHead(int cell, int & row) const { - if ((endfirsthead+1) > rows_) + row = endfirsthead; + if (abs(endfirsthead) > rows_) return false; - return (row_of_cell(cell) == endfirsthead); + return (row_of_cell(cell) == abs(endfirsthead) - 1); } void LyXTabular::SetLTFoot(int cell, bool last) { - int row = row_of_cell(cell); + int const row = row_of_cell(cell); + int const val = (row + 1) * (column_of_cell(cell) ? 1 : -1); if (last) { - if (row == endlastfoot) - endlastfoot = -1; + if (endlastfoot == val) + endlastfoot = 0; else - endlastfoot = row; + endlastfoot = val; } else { - if (row == endfoot) - endfoot = -1; + if (endfoot == val) + endfoot = 0; else - endfoot = row; + endfoot = val; } } -bool LyXTabular::GetRowOfLTFoot(int cell) const +bool LyXTabular::GetRowOfLTFoot(int cell, int & row) const { - if ((endfoot+1) > rows_) + row = endfoot; + if ((endfoot + 1) > rows_) return false; - return (row_of_cell(cell) == endfoot); + return (row_of_cell(cell) == abs(endfoot) - 1); } -bool LyXTabular::GetRowOfLTLastFoot(int cell) const + +bool LyXTabular::GetRowOfLTLastFoot(int cell, int & row) const { - if ((endlastfoot+1) > rows_) + row = endlastfoot; + if (abs(endlastfoot) > rows_) return false; - return (row_of_cell(cell) == endlastfoot); + return (row_of_cell(cell) == (abs(endlastfoot)-1)); } @@ -1800,19 +1853,21 @@ bool LyXTabular::GetLTNewPage(int cell) const } -void LyXTabular::SetAscentOfRow(int row, int height) +bool LyXTabular::SetAscentOfRow(int row, int height) { - if (row >= rows_) - return; + if ((row >= rows_) || (row_info[row].ascent_of_row == height)) + return false; row_info[row].ascent_of_row = height; + return true; } -void LyXTabular::SetDescentOfRow(int row, int height) +bool LyXTabular::SetDescentOfRow(int row, int height) { - if (row >= rows_) - return; + if ((row >= rows_) || (row_info[row].descent_of_row == height)) + return false; row_info[row].descent_of_row = height; + return true; } @@ -1836,7 +1891,7 @@ int LyXTabular::GetHeightOfTabular() const { int height = 0; - for(int row = 0; row < rows_; ++row) + for (int row = 0; row < rows_; ++row) height += GetAscentOfRow(row) + GetDescentOfRow(row) + GetAdditionalHeight(GetCellNumber(row, 0)); return height; @@ -1847,25 +1902,27 @@ bool LyXTabular::IsPartOfMultiColumn(int row, int column) const { if ((row >= rows_) || (column >= columns_)) return false; - return (cell_info[row][column].multicolumn==CELL_PART_OF_MULTICOLUMN); + return (cell_info[row][column].multicolumn == CELL_PART_OF_MULTICOLUMN); } int LyXTabular::TeXTopHLine(ostream & os, int row) const { - int fcell = GetFirstCellInRow(row); - int n = NumberOfCellsInRow(fcell) + fcell; - int tmp=0; - int i; + if ((row < 0) || (row >= rows_)) + return 0; + + int const fcell = GetFirstCellInRow(row); + int const n = NumberOfCellsInRow(fcell) + fcell; + int tmp = 0; - for (i = fcell; i < n; ++i) { + for (int i = fcell; i < n; ++i) { if (TopLine(i)) ++tmp; } if (tmp == (n - fcell)){ os << "\\hline "; - } else { - for (i = fcell; i < n; ++i) { + } else if (tmp) { + for (int i = fcell; i < n; ++i) { if (TopLine(i)) { os << "\\cline{" << column_of_cell(i) + 1 @@ -1874,30 +1931,31 @@ int LyXTabular::TeXTopHLine(ostream & os, int row) const << "} "; } } + } else { + return 0; } - if (tmp) { - os << endl; - return 1; - } - return 0; + os << "\n"; + return 1; } int LyXTabular::TeXBottomHLine(ostream & os, int row) const { - int fcell = GetFirstCellInRow(row); - int n = NumberOfCellsInRow(fcell) + fcell; + if ((row < 0) || (row >= rows_)) + return 0; + + int const fcell = GetFirstCellInRow(row); + int const n = NumberOfCellsInRow(fcell) + fcell; int tmp = 0; - int i; - for (i = fcell; i < n; ++i) { + for (int i = fcell; i < n; ++i) { if (BottomLine(i)) ++tmp; } if (tmp == (n-fcell)){ os << "\\hline"; - } else { - for (i = fcell; i < n; ++i) { + } else if (tmp) { + for (int i = fcell; i < n; ++i) { if (BottomLine(i)) { os << "\\cline{" << column_of_cell(i) + 1 @@ -1906,12 +1964,11 @@ int LyXTabular::TeXBottomHLine(ostream & os, int row) const << "} "; } } + } else { + return 0; } - if (tmp) { - os << endl; - return 1; - } - return 0; + os << "\n"; + return 1; } @@ -1920,18 +1977,29 @@ int LyXTabular::TeXCellPreamble(ostream & os, int cell) const int ret = 0; if (GetRotateCell(cell)) { - os << "\\begin{sideways}" << endl; + os << "\\begin{sideways}\n"; ++ret; } if (IsMultiColumn(cell)) { os << "\\multicolumn{" << cells_in_multicolumn(cell) << "}{"; - if (!cellinfo_of_cell(cell+1)->align_special.empty()) { - os << cellinfo_of_cell(cell+1)->align_special << "}{"; + if (!cellinfo_of_cell(cell)->align_special.empty()) { + os << cellinfo_of_cell(cell)->align_special << "}{"; } else { if (LeftLine(cell)) os << '|'; if (!GetPWidth(cell).empty()) { - os << "p{" << GetPWidth(cell) << '}'; + switch (GetVAlignment(cell)) { + case LYX_VALIGN_TOP: + os << "p"; + break; + case LYX_VALIGN_CENTER: + os << "m"; + break; + case LYX_VALIGN_BOTTOM: + os << "b"; + break; + } + os << "{" << GetPWidth(cell) << '}'; } else { switch (GetAlignment(cell)) { case LYX_ALIGN_LEFT: @@ -1953,8 +2021,35 @@ int LyXTabular::TeXCellPreamble(ostream & os, int cell) const os << "}{"; } } - if (GetLinebreaks(cell)) { - os << "\\parbox[t]{" << GetPWidth(cell) << "}{\\smallskip{}"; + if (GetUsebox(cell) == BOX_PARBOX) { + os << "\\parbox["; + switch (GetVAlignment(cell)) { + case LYX_VALIGN_TOP: + os << "t"; + break; + case LYX_VALIGN_CENTER: + os << "c"; + break; + case LYX_VALIGN_BOTTOM: + os << "b"; + break; + } + os << "]{" << GetPWidth(cell) << "}{"; + } else if (GetUsebox(cell) == BOX_MINIPAGE) { + os << "\\begin{minipage}["; + switch (GetVAlignment(cell)) { + case LYX_VALIGN_TOP: + os << "t"; + break; + case LYX_VALIGN_CENTER: + os << "m"; + break; + case LYX_VALIGN_BOTTOM: + os << "b"; + break; + } + os << "]{" << GetPWidth(cell) << "}\n"; + ++ret; } return ret; } @@ -1965,23 +2060,27 @@ int LyXTabular::TeXCellPostamble(ostream & os, int cell) const int ret = 0; // usual cells - if (GetLinebreaks(cell)) - os << "\\smallskip{}}"; + if (GetUsebox(cell) == BOX_PARBOX) + os << "}"; + else if (GetUsebox(cell) == BOX_MINIPAGE) { + os << "%\n\\end{minipage}"; + ret += 2; + } if (IsMultiColumn(cell)){ os << '}'; } if (GetRotateCell(cell)) { - os << endl << "\\end{sideways}"; + os << "%\n\\end{sideways}"; ++ret; } return ret; } -int LyXTabular::Latex(ostream & os, bool fragile, bool fp) const +int LyXTabular::Latex(Buffer const * buf, + ostream & os, bool fragile, bool fp) const { int ret = 0; - int i,j; int cell = 0; //+--------------------------------------------------------------------- @@ -1989,20 +2088,31 @@ int LyXTabular::Latex(ostream & os, bool fragile, bool fp) const //+--------------------------------------------------------------------- if (rotate) { - os << "\\begin{sideways}" << endl; + os << "\\begin{sideways}\n"; ++ret; } if (is_long_tabular) os << "\\begin{longtable}{"; else os << "\\begin{tabular}{"; - for (i = 0; i < columns_; ++i) { + for (int i = 0; i < columns_; ++i) { if (column_info[i].left_line) os << '|'; if (!column_info[i].align_special.empty()) { os << column_info[i].align_special; } else if (!column_info[i].p_width.empty()) { - os << "p{" + switch (column_info[i].valignment) { + case LYX_VALIGN_TOP: + os << "p"; + break; + case LYX_VALIGN_CENTER: + os << "m"; + break; + case LYX_VALIGN_BOTTOM: + os << "b"; + break; + } + os << "{" << column_info[i].p_width << '}'; } else { @@ -2021,46 +2131,85 @@ int LyXTabular::Latex(ostream & os, bool fragile, bool fp) const if (column_info[i].right_line) os << '|'; } - os << "}" << endl; + os << "}\n"; ++ret; //+--------------------------------------------------------------------- //+ the single row and columns (cells) + //+--------------------------------------------------------------------- - for(i=0; i < rows_; ++i) { + for (int i = 0; i < rows_; ++i) { ret += TeXTopHLine(os, i); - for(j=0; j < columns_; ++j) { + int bret = ret; + if (IsLongTabular()) { + if ((endhead < 0) && (i == (abs(endhead)-1))) { + os << "\\endhead\n"; + ++ret; + } + if ((endfirsthead < 0) && (i == (abs(endfirsthead)-1))) { + os << "\\endfirsthead\n"; + ++ret; + } + if ((endfoot < 0) && (i == (abs(endfoot)-1))) { + os << "\\endfoot\n"; + ++ret; + } + if ((endlastfoot < 0) && (i == (abs(endlastfoot)-1))) { + os << "\\endlastfoot\n"; + ++ret; + } + } + if (ret > bret) { + ret += TeXBottomHLine(os, i-1); + ret += TeXTopHLine(os, i); + } + for (int j = 0; j < columns_; ++j) { if (IsPartOfMultiColumn(i,j)) continue; ret += TeXCellPreamble(os, cell); - ret += GetCellInset(cell)->Latex(os, fragile, fp); + InsetText * inset = GetCellInset(cell); + + bool rtl = inset->par->isRightToLeftPar(buf->params) && +#ifndef NEW_INSETS + inset->par->Last() > 0 && GetPWidth(cell).empty(); +#else + inset->par->size() > 0 && GetPWidth(cell).empty(); +#endif + if (rtl) + os << "\\R{"; + ret += inset->Latex(buf, os, fragile, fp); + if (rtl) + os << "}"; + ret += TeXCellPostamble(os, cell); if (!IsLastCellInRow(cell)) { // not last cell in row - os << "&" << endl; + os << "&\n"; ++ret; } ++cell; } - os << "\\\\" << endl; + os << "\\\\\n"; ret += TeXBottomHLine(os, i); + bret = ret; if (IsLongTabular()) { - if (i == endhead) { + if ((endhead > 0) && (i == (endhead - 1))) { os << "\\endhead\n"; ++ret; } - if (i == endfirsthead) { + if ((endfirsthead > 0) && (i == (endfirsthead - 1))) { os << "\\endfirsthead\n"; ++ret; } - if (i == endfoot) { + if ((endfoot > 0) && (i == (endfoot - 1))) { os << "\\endfoot\n"; ++ret; } - if (i == endlastfoot) { + if ((endlastfoot > 0) && (i == (endlastfoot - 1))) { os << "\\endlastfoot\n"; ++ret; } +// if (ret > bret) +// ret += TeXBottomHLine(os, i); if (row_info[i].newpage) { os << "\\newpage\n"; ++ret; @@ -2085,17 +2234,349 @@ int LyXTabular::Latex(ostream & os, bool fragile, bool fp) const } +int LyXTabular::DocBook(Buffer const * buf, ostream & os) const +{ + int ret = 0; + + //+--------------------------------------------------------------------- + //+ first the opening preamble + + //+--------------------------------------------------------------------- + + os << "\n"; + + for (int i = 0; i < columns_; ++i) { + os << "\n"; + ++ret; + } + + //+--------------------------------------------------------------------- + //+ the single row and columns (cells) + + //+--------------------------------------------------------------------- + + int cell = 0; + os << "\n"; + for (int i = 0; i < rows_; ++i) { + os << "\n"; + for (int j = 0; j < columns_; ++j) { + if (IsPartOfMultiColumn(i, j)) + continue; + + os << ""; + ret += GetCellInset(cell)->DocBook(buf, os); + os << ""; + ++cell; + } + os << "\n"; + } + os << "\n"; + //+--------------------------------------------------------------------- + //+ the closing of the tabular + + //+--------------------------------------------------------------------- + + os << ""; + ++ret; + + return ret; +} + + +static +inline +void print_n_chars(ostream & os, unsigned char ch, int n) +{ + os << string(n, ch); +} + + +int LyXTabular::AsciiTopHLine(ostream & os, int row, + vector const & clen) const +{ + int const fcell = GetFirstCellInRow(row); + int const n = NumberOfCellsInRow(fcell) + fcell; + int tmp = 0; + + for (int i = fcell; i < n; ++i) { + if (TopLine(i)) { + ++tmp; + break; + } + } + if (!tmp) + return 0; + + unsigned char ch; + for (int i = fcell; i < n; ++i) { + if (TopLine(i)) { + if (LeftLine(i)) + os << "+-"; + else + os << "--"; + ch = '-'; + } else { + os << " "; + ch = ' '; + } + int column = column_of_cell(i); + int len = clen[column]; + while(IsPartOfMultiColumn(row, ++column)) + len += clen[column] + 4; + print_n_chars(os, ch, len); + if (TopLine(i)) { + if (RightLine(i)) + os << "-+"; + else + os << "--"; + } else { + os << " "; + } + } + os << endl; + return 1; +} + + +int LyXTabular::AsciiBottomHLine(ostream & os, int row, + vector const & clen) const +{ + int const fcell = GetFirstCellInRow(row); + int const n = NumberOfCellsInRow(fcell) + fcell; + int tmp = 0; + + for (int i = fcell; i < n; ++i) { + if (BottomLine(i)) { + ++tmp; + break; + } + } + if (!tmp) + return 0; + + unsigned char ch; + for (int i = fcell; i < n; ++i) { + if (BottomLine(i)) { + if (LeftLine(i)) + os << "+-"; + else + os << "--"; + ch = '-'; + } else { + os << " "; + ch = ' '; + } + int column = column_of_cell(i); + int len = clen[column]; + while(IsPartOfMultiColumn(row, ++column)) + len += clen[column] + 4; + print_n_chars(os, ch, len); + if (BottomLine(i)) { + if (RightLine(i)) + os << "-+"; + else + os << "--"; + } else { + os << " "; + } + } + os << endl; + return 1; +} + + +int LyXTabular::AsciiPrintCell(Buffer const * buf, ostream & os, + int cell, int row, int column, + vector const & clen) const +{ + ostringstream sstr; + int ret = GetCellInset(cell)->Ascii(buf, sstr, 0); + + if (LeftLine(cell)) + os << "| "; + else + os << " "; + + unsigned int len1 = sstr.str().length(); + unsigned int len2 = clen[column]; + while(IsPartOfMultiColumn(row, ++column)) + len2 += clen[column] + 4; + len2 -= len1; + + switch (GetAlignment(cell)) { + default: + case LYX_ALIGN_LEFT: + len1 = 0; + break; + case LYX_ALIGN_RIGHT: + len1 = len2; + len2 = 0; + break; + case LYX_ALIGN_CENTER: + len1 = len2 / 2; + len2 -= len1; + break; + } + + for (unsigned int i = 0; i < len1; ++i) + os << " "; + os << sstr.str(); + for (unsigned int i = 0; i < len2; ++i) + os << " "; + if (RightLine(cell)) + os << " |"; + else + os << " "; + + return ret; +} + + +int LyXTabular::Ascii(Buffer const * buf, ostream & os) const +{ + int ret = 0; + + //+--------------------------------------------------------------------- + //+ first calculate the width of the single columns + + //+--------------------------------------------------------------------- + vector clen(columns_); + + // first all non (real) multicolumn cells! + for (int j = 0; j < columns_; ++j) { + clen[j] = 0; + for (int i = 0; i < rows_; ++i) { + int cell = GetCellNumber(i, j); + if (IsMultiColumn(cell, true)) + continue; + ostringstream sstr; + GetCellInset(cell)->Ascii(buf, sstr, 0); + if (clen[j] < sstr.str().length()) + clen[j] = sstr.str().length(); + } + } + // then all (real) multicolumn cells! + for (int j = 0; j < columns_; ++j) { + for (int i = 0; i < rows_; ++i) { + int cell = GetCellNumber(i, j); + if (!IsMultiColumn(cell, true) || IsPartOfMultiColumn(i, j)) + continue; + ostringstream sstr; + GetCellInset(cell)->Ascii(buf, sstr, 0); + int len = int(sstr.str().length()); + int const n = cells_in_multicolumn(cell); + for (int k = j; (len > 0) && (k < (j + n - 1)); ++k) + len -= clen[k]; + if (len > int(clen[j + n - 1])) + clen[j + n - 1] = len; + } + } + int cell = 0; + for (int i = 0; i < rows_; ++i) { + AsciiTopHLine(os, i, clen); + for (int j = 0; j < columns_; ++j) { + if (IsPartOfMultiColumn(i,j)) + continue; + ret += AsciiPrintCell(buf, os, cell, i, j, clen); + ++cell; + } + os << endl; + AsciiBottomHLine(os, i, clen); + } + return ret; +} + + InsetText * LyXTabular::GetCellInset(int cell) const { - return cell_info[row_of_cell(cell)][column_of_cell(cell)].inset; + return & cell_info[row_of_cell(cell)][column_of_cell(cell)].inset; } + +InsetText * LyXTabular::GetCellInset(int row, int column) const +{ + return GetCellInset(GetCellNumber(row, column)); +} + + void LyXTabular::Validate(LaTeXFeatures & features) const { if (IsLongTabular()) features.longtable = true; if (NeedRotating()) features.rotating = true; - for(int cell = 0; cell < numberofcells; ++cell) + for (int cell = 0; cell < numberofcells; ++cell) { + if (GetVAlignment(cell) != LYX_VALIGN_TOP) + features.array = true; GetCellInset(cell)->Validate(features); + } } + + +#ifndef NEW_INSETS +LyXTabular::BoxType LyXTabular::UseParbox(int cell) const +{ + LyXParagraph * par = GetCellInset(cell)->par; + + for (; par; par = par->next_) { + for (int i = 0; i < par->Last(); ++i) { + if (par->GetChar(i) == LyXParagraph::META_NEWLINE) + return BOX_PARBOX; + } + } + return BOX_NONE; +} +#else +LyXTabular::BoxType LyXTabular::UseParbox(int cell) const +{ + LyXParagraph * par = GetCellInset(cell)->par; + + for (; par; par = par->next()) { + for (int i = 0; i < par->size(); ++i) { + if (par->GetChar(i) == LyXParagraph::META_NEWLINE) + return BOX_PARBOX; + } + } + return BOX_NONE; +} +#endif