X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftabular.C;h=519813af97d027e70e8f2a7fbc2a7b85fdc184d2;hb=1b0cfa4381f8efa0f724bfc661c108d73242d1d6;hp=80dfcbcfc04b589055a05c8d9f9abcaded7356a8;hpb=9987ffaee8932c18807af7f6ce076eb57f0a54cf;p=lyx.git diff --git a/src/tabular.C b/src/tabular.C index 80dfcbcfc0..519813af97 100644 --- a/src/tabular.C +++ b/src/tabular.C @@ -1,13 +1,13 @@ /* This file is part of - * ====================================================== - * + * ====================================================== + * * LyX, The Document Processor - * - * Copyright 2000-2001 The LyX Team. + * + * Copyright 2000-2002 The LyX Team. * * @author: Jürgen Vigna * - * ====================================================== + * ====================================================== */ #include @@ -25,7 +25,7 @@ #include "layout.h" #include "buffer.h" #include "BufferView.h" -#include "Painter.h" +#include "frontends/Painter.h" #include "LaTeXFeatures.h" #include "insets/insettabular.h" #include "insets/insettext.h" @@ -35,10 +35,12 @@ #include "frontends/Alert.h" #include "gettext.h" #include "tabular_funcs.h" +#include "lyxlex.h" #include #include +using std::abs; using std::ostream; using std::istream; using std::getline; @@ -58,7 +60,8 @@ namespace { /// Define a few methods for the inner structs -LyXTabular::cellstruct::cellstruct() +LyXTabular::cellstruct::cellstruct(BufferParams const & bg) + : inset(bg) { cellno = 0; width_of_cell = 0; @@ -74,7 +77,7 @@ LyXTabular::cellstruct::cellstruct() } -LyXTabular::rowstruct::rowstruct() +LyXTabular::rowstruct::rowstruct() { top_line = true; bottom_line = false; @@ -88,7 +91,7 @@ LyXTabular::rowstruct::rowstruct() } -LyXTabular::columnstruct::columnstruct() +LyXTabular::columnstruct::columnstruct() { left_line = true; right_line = false; @@ -107,20 +110,22 @@ LyXTabular::lttype::lttype() /* konstruktor */ -LyXTabular::LyXTabular(InsetTabular * inset, int rows_arg, int columns_arg) +LyXTabular::LyXTabular(BufferParams const & bp, + InsetTabular * inset, int rows_arg, int columns_arg) { owner_ = inset; cur_cell = -1; - Init(rows_arg, columns_arg); + Init(bp, rows_arg, columns_arg); } -LyXTabular::LyXTabular(InsetTabular * inset, LyXTabular const & lt, - bool same_id) +LyXTabular::LyXTabular(BufferParams const & bp, + InsetTabular * inset, LyXTabular const & lt, + bool same_id) { owner_ = inset; cur_cell = -1; - Init(lt.rows_, lt.columns_, <); + Init(bp, lt.rows_, lt.columns_, <); // we really should change again to have InsetText as a pointer // and allocate it then we would not have to do this stuff all // double! @@ -174,9 +179,10 @@ LyXTabular & LyXTabular::operator=(LyXTabular const & lt) } -LyXTabular * LyXTabular::clone(InsetTabular * inset, bool same_id) +LyXTabular * LyXTabular::clone(BufferParams const & bp, + InsetTabular * inset, bool same_id) { - LyXTabular * result = new LyXTabular(inset, *this, same_id); + LyXTabular * result = new LyXTabular(bp, inset, *this, same_id); #if 0 // don't know if this is good but I need to Clone also // the text-insets here, this is for the Undo-facility! @@ -191,14 +197,15 @@ LyXTabular * LyXTabular::clone(InsetTabular * inset, bool same_id) } -/* activates all lines and sets all widths to 0 */ -void LyXTabular::Init(int rows_arg, int columns_arg, LyXTabular const * lt) +/* activates all lines and sets all widths to 0 */ +void LyXTabular::Init(BufferParams const & bp, + int rows_arg, int columns_arg, LyXTabular const * lt) { rows_ = rows_arg; columns_ = columns_arg; row_info = row_vector(rows_, rowstruct()); column_info = column_vector(columns_, columnstruct()); - cell_info = cell_vvector(rows_, cell_vector(columns_, cellstruct())); + cell_info = cell_vvector(rows_, cell_vector(columns_, cellstruct(bp))); if (lt) { operator=(*lt); @@ -221,7 +228,7 @@ void LyXTabular::Init(int rows_arg, int columns_arg, LyXTabular const * lt) calculate_width_of_column(i); } column_info.back().right_line = true; - + calculate_width_of_tabular(); rowofcell = vector(); @@ -232,23 +239,23 @@ void LyXTabular::Init(int rows_arg, int columns_arg, LyXTabular const * lt) } -void LyXTabular::AppendRow(int cell) +void LyXTabular::AppendRow(BufferParams const & bp, int cell) { ++rows_; - + int row = row_of_cell(cell); 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]; + row_info[row] = row_info[row + 1]; #if 0 cell_vvector::iterator cit = cell_info.begin() + row; - cell_info.insert(cit, vector(columns_, cellstruct())); + cell_info.insert(cit, vector(columns_, cellstruct(bp))); #else cell_vvector c_info = cell_vvector(rows_, cell_vector(columns_, - cellstruct())); + cellstruct(bp))); for (int i = 0; i <= row; ++i) { for (int j = 0; j < columns_; ++j) { @@ -273,7 +280,7 @@ void LyXTabular::AppendRow(int cell) void LyXTabular::DeleteRow(int row) { 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_; @@ -281,17 +288,17 @@ void LyXTabular::DeleteRow(int row) } -void LyXTabular::AppendColumn(int cell) +void LyXTabular::AppendColumn(BufferParams const & bp, int cell) { ++columns_; - + cell_vvector c_info = cell_vvector(rows_, cell_vector(columns_, - cellstruct())); + cellstruct(bp))); 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]; + column_info[column + 1] = column_info[column]; for (int i = 0; i < rows_; ++i) { for (int j = 0; j <= column; ++j) { @@ -301,11 +308,13 @@ void LyXTabular::AppendColumn(int cell) c_info[i][j] = cell_info[i][j - 1]; } // care about multicolumns - if (c_info[i][column + 1].multicolumn==CELL_BEGIN_OF_MULTICOLUMN) { + if (c_info[i][column + 1].multicolumn==CELL_BEGIN_OF_MULTICOLUMN) + { c_info[i][column + 1].multicolumn = CELL_PART_OF_MULTICOLUMN; } - if ((column + 1) == columns_ || - c_info[i][column + 2].multicolumn != CELL_PART_OF_MULTICOLUMN) { + if ((column + 2) >= columns_ || + c_info[i][column + 2].multicolumn != CELL_PART_OF_MULTICOLUMN) + { c_info[i][column + 1].multicolumn = LyXTabular::CELL_NORMAL; } } @@ -325,7 +334,7 @@ void LyXTabular::DeleteColumn(int column) //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); @@ -351,7 +360,7 @@ void LyXTabular::Reinit(bool reset_widths) } } } - + for (int i = 0; i < columns_; ++i) { calculate_width_of_column(i); } @@ -430,11 +439,11 @@ int LyXTabular::NumberOfCellsInRow(int cell) const } -/* returns 1 if there is a topline, returns 0 if not */ +/* returns 1 if there is a topline, returns 0 if not */ bool LyXTabular::TopLine(int cell, bool onlycolumn) const { int const row = row_of_cell(cell); - + if (!onlycolumn && IsMultiColumn(cell)) return cellinfo_of_cell(cell)->top_line; return row_info[row].top_line; @@ -457,11 +466,13 @@ bool LyXTabular::BottomLine(int cell, bool onlycolumn) const bool LyXTabular::LeftLine(int cell, bool onlycolumn) const { - if (!onlycolumn && IsMultiColumn(cell)) { + if (!onlycolumn && IsMultiColumn(cell) && + (IsFirstCellInRow(cell) || IsMultiColumn(cell-1))) + { #ifdef SPECIAL_COLUM_HANDLING if (cellinfo_of_cell(cell)->align_special.empty()) return cellinfo_of_cell(cell)->left_line; - return prefixIs(frontStrip(cellinfo_of_cell(cell)->align_special), "|"); + return prefixIs(ltrim(cellinfo_of_cell(cell)->align_special), "|"); #else return cellinfo_of_cell(cell)->left_line; #endif @@ -469,7 +480,7 @@ bool LyXTabular::LeftLine(int cell, bool onlycolumn) const #ifdef SPECIAL_COLUM_HANDLING if (column_info[column_of_cell(cell)].align_special.empty()) return column_info[column_of_cell(cell)].left_line; - return prefixIs(frontStrip(column_info[column_of_cell(cell)].align_special), "|"); + return prefixIs(ltrim(column_info[column_of_cell(cell)].align_special), "|"); #else return column_info[column_of_cell(cell)].left_line; #endif @@ -478,11 +489,13 @@ bool LyXTabular::LeftLine(int cell, bool onlycolumn) const bool LyXTabular::RightLine(int cell, bool onlycolumn) const { - if (!onlycolumn && IsMultiColumn(cell)) { + if (!onlycolumn && IsMultiColumn(cell) && + (IsLastCellInRow(cell) || IsMultiColumn(cell+1))) + { #ifdef SPECIAL_COLUM_HANDLING if (cellinfo_of_cell(cell)->align_special.empty()) return cellinfo_of_cell(cell)->right_line; - return suffixIs(strip(cellinfo_of_cell(cell)->align_special), "|"); + return suffixIs(rtrim(cellinfo_of_cell(cell)->align_special), "|"); #else return cellinfo_of_cell(cell)->right_line; #endif @@ -490,7 +503,7 @@ bool LyXTabular::RightLine(int cell, bool onlycolumn) const #ifdef SPECIAL_COLUM_HANDLING if (column_info[column_of_cell(cell)].align_special.empty()) return column_info[right_column_of_cell(cell)].right_line; - return suffixIs(strip(column_info[column_of_cell(cell)].align_special), "|"); + return suffixIs(rtrim(column_info[column_of_cell(cell)].align_special), "|"); #else return column_info[right_column_of_cell(cell)].right_line; #endif @@ -527,7 +540,7 @@ bool LyXTabular::LeftAlreadyDrawed(int cell) const if (GetAdditionalWidth(cell_info[row][column].cellno)) return false; #ifdef SPECIAL_COLUM_HANDLING - return column_info[column].right_line; + return RightLine(cell_info[row][column].cellno); #else return RightLine(cell_info[row][column].cellno, true); #endif @@ -550,7 +563,7 @@ int LyXTabular::GetAdditionalHeight(int row) const bool top = true; bool bottom = true; - for (int column = 0; column < columns_ - 1 && bottom; ++column) { + for (int column = 0; column < columns_ && bottom; ++column) { switch (cell_info[row - 1][column].multicolumn) { case LyXTabular::CELL_BEGIN_OF_MULTICOLUMN: bottom = cell_info[row - 1][column].bottom_line; @@ -559,8 +572,8 @@ int LyXTabular::GetAdditionalHeight(int row) const bottom = row_info[row - 1].bottom_line; } } - for (int column = 0; column < columns_ - 1 && top; ++column) { - switch (cell_info[row][column].multicolumn){ + for (int column = 0; column < columns_ && top; ++column) { + switch (cell_info[row][column].multicolumn) { case LyXTabular::CELL_BEGIN_OF_MULTICOLUMN: top = cell_info[row][column].top_line; break; @@ -580,8 +593,8 @@ int LyXTabular::GetAdditionalWidth(int cell) const // used to get it back in text.C int const col = right_column_of_cell(cell); int const row = row_of_cell(cell); - if (col < columns_ - 1 && RightLine(cell, true) && - LeftLine(cell_info[row][col+1].cellno, true)) // column_info[col+1].left_line) + if (col < columns_ - 1 && RightLine(cell) && + LeftLine(cell_info[row][col+1].cellno)) // column_info[col+1].left_line) { return WIDTH_OF_LINE; } else { @@ -590,7 +603,7 @@ int LyXTabular::GetAdditionalWidth(int cell) const } -// returns the maximum over all rows +// returns the maximum over all rows int LyXTabular::GetWidthOfColumn(int cell) const { int const column1 = column_of_cell(cell); @@ -609,15 +622,16 @@ int LyXTabular::GetWidthOfTabular() const } -/* returns 1 if a complete update is necessary, otherwise 0 */ +/* returns 1 if a complete update is necessary, otherwise 0 */ bool LyXTabular::SetWidthOfMulticolCell(int cell, int new_width) { if (!IsMultiColumn(cell)) return false; - + int const row = row_of_cell(cell); int const column1 = column_of_cell(cell); int const column2 = right_column_of_cell(cell); + int const old_val = cell_info[row][column2].width_of_cell; // first set columns to 0 so we can calculate the right width for (int i = column1; i <= column2; ++i) { @@ -625,7 +639,6 @@ bool LyXTabular::SetWidthOfMulticolCell(int cell, int new_width) } // set the width to MAX_WIDTH until width > 0 int width = (new_width + 2 * WIDTH_OF_LINE); - 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; @@ -634,29 +647,42 @@ bool LyXTabular::SetWidthOfMulticolCell(int cell, int new_width) if (width > 0) { cell_info[row][i].width_of_cell = width; } + if (old_val != cell_info[row][column2].width_of_cell) { + // in this case we have to recalculate all multicolumn cells which + // have this column as one of theirs but not as last one + calculate_width_of_column_NMC(i); + recalculateMulticolumnsOfColumn(i); + calculate_width_of_column(i); + } return true; } -void LyXTabular::recalculateMulticolCells(int cell, int new_width) +void LyXTabular::recalculateMulticolumnsOfColumn(int column) { - 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) - ; - if (i < numberofcells) - recalculateMulticolCells(i, GetWidthOfCell(i) - (2 * WIDTH_OF_LINE)); - SetWidthOfMulticolCell(cell, new_width); + // the last column does not have to be recalculated because all + // multicolumns will have here there last multicolumn cell which + // always will have the whole rest of the width of the cell. + if (column > (columns_ - 2)) + return; + for(int row = 0; row < rows_; ++row) { + int mc = cell_info[row][column].multicolumn; + int nmc = cell_info[row][column+1].multicolumn; + // we only have to update multicolumns which do not have this + // column as their last column! + if (mc == CELL_BEGIN_OF_MULTICOLUMN || + ((mc == CELL_PART_OF_MULTICOLUMN) && + (nmc == CELL_PART_OF_MULTICOLUMN))) + { + int const cellno = cell_info[row][column].cellno; + SetWidthOfMulticolCell(cellno, + GetWidthOfCell(cellno)-(2 * WIDTH_OF_LINE)); + } + } } -/* returns 1 if a complete update is necessary, otherwise 0 */ +/* returns 1 if a complete update is necessary, otherwise 0 */ bool LyXTabular::SetWidthOfCell(int cell, int new_width) { int const row = row_of_cell(cell); @@ -686,16 +712,11 @@ bool LyXTabular::SetWidthOfCell(int cell, int new_width) width = (new_width + 2*WIDTH_OF_LINE + add_width); cell_info[row][column1].width_of_cell = width; tmp = calculate_width_of_column_NMC(column1); + if (tmp) + recalculateMulticolumnsOfColumn(column1); } if (tmp) { - int i = 0; - for (; ialign_special = special; @@ -882,8 +904,8 @@ int LyXTabular::GetWidthOfCell(int cell) const int LyXTabular::GetBeginningOfTextInCell(int cell) const { int x = 0; - - switch (GetAlignment(cell)){ + + switch (GetAlignment(cell)) { case LYX_ALIGN_CENTER: x += (GetWidthOfColumn(cell) - GetWidthOfCell(cell)) / 2; break; @@ -891,10 +913,10 @@ int LyXTabular::GetBeginningOfTextInCell(int cell) const x += GetWidthOfColumn(cell) - GetWidthOfCell(cell); // + GetAdditionalWidth(cell); break; - default: /* LYX_ALIGN_LEFT: nothing :-) */ + default: /* LYX_ALIGN_LEFT: nothing :-) */ break; } - + // the LaTeX Way :-( x += WIDTH_OF_LINE; return x; @@ -932,7 +954,7 @@ bool LyXTabular::calculate_width_of_column(int column) { int const old_column_width = column_info[column].width_of_column; int maximum = 0; - + for (int i = 0; i < rows_; ++i) { maximum = max(cell_info[i][column].width_of_cell, maximum); } @@ -942,16 +964,21 @@ 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. +// Calculate the columns regarding ONLY the normal cells and if this +// column is inside a multicolumn cell then use it only if its the last +// column of this multicolumn cell as this gives an added with to the +// column, all the rest should be adapted! // bool LyXTabular::calculate_width_of_column_NMC(int 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), true) && - (cell_info[i][column].width_of_cell > max)) { + int cell = GetCellNumber(i, column); + bool ismulti = IsMultiColumn(cell, true); + if ((!ismulti || (column == right_column_of_cell(cell))) && + (cell_info[i][column].width_of_cell > max)) + { max = cell_info[i][column].width_of_cell; } } @@ -1010,50 +1037,50 @@ void LyXTabular::Write(Buffer const * buf, ostream & os) const << ">\n"; // global longtable options 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) { os << "\n"; @@ -1076,7 +1103,7 @@ void LyXTabular::Read(Buffer const * buf, LyXLex & lex) l_getline(is, line); if (!prefixIs(line, "params, lex, line); return; } @@ -1102,7 +1129,7 @@ void LyXTabular::setHeaderFooterRows(int hr, int fhr, int fr, int lfr) row_info[--fhr].endfirsthead = true; row_info[fhr].endhead = false; } - } else if (row_info[fhr-1].endhead) { + } else if (row_info[fhr - 1].endhead) { endfirsthead.empty = true; } else { while((fhr > 0) && !row_info[--fhr].endhead) { @@ -1122,7 +1149,7 @@ void LyXTabular::setHeaderFooterRows(int hr, int fhr, int fr, int lfr) row_info[fr].endfoot = true; row_info[fr].endfirsthead = false; } - } else if (!row_info[fr-1].endhead && !row_info[fr-1].endfirsthead) { + } else if (!row_info[fr - 1].endhead && !row_info[fr - 1].endfirsthead) { while((fr > 0) && !row_info[--fr].endhead && !row_info[fr].endfirsthead) { @@ -1132,25 +1159,27 @@ void LyXTabular::setHeaderFooterRows(int hr, int fhr, int fr, int lfr) } // set lastfooter info if (lfr && (lfr < rows_)) { - if (row_info[lfr].endhead && row_info[lfr-1].endhead) { + if (row_info[lfr].endhead && row_info[lfr - 1].endhead) { while((lfr > 0) && !row_info[--lfr].endhead) { row_info[lfr].endlastfoot = true; row_info[lfr].endhead = false; } } else if (row_info[lfr].endfirsthead && - row_info[lfr-1].endfirsthead) + row_info[lfr - 1].endfirsthead) { while((lfr > 0) && !row_info[--lfr].endfirsthead) { row_info[lfr].endlastfoot = true; row_info[lfr].endfirsthead = false; } - } else if (row_info[lfr].endfoot && row_info[lfr-1].endfoot) { + } else if (row_info[lfr].endfoot + && row_info[lfr - 1].endfoot) { while((lfr > 0) && !row_info[--lfr].endfoot) { row_info[lfr].endlastfoot = true; row_info[lfr].endfoot = false; } - } else if (!row_info[fr-1].endhead && !row_info[fr-1].endfirsthead && - !row_info[fr-1].endfoot) + } else if (!row_info[fr - 1].endhead + && !row_info[fr - 1].endfirsthead && + !row_info[fr - 1].endfoot) { while((lfr > 0) && !row_info[--lfr].endhead && !row_info[lfr].endfirsthead && @@ -1165,7 +1194,7 @@ void LyXTabular::setHeaderFooterRows(int hr, int fhr, int fr, int lfr) } void LyXTabular::ReadNew(Buffer const * buf, istream & is, - LyXLex & lex, string const & l, int const version) + LyXLex & lex, string const & l, int const version) { string line(l); int rows_arg; @@ -1174,7 +1203,7 @@ void LyXTabular::ReadNew(Buffer const * buf, istream & is, int columns_arg; if (!getTokenValue(line, "columns", columns_arg)) return; - Init(rows_arg, columns_arg); + Init(buf->params, rows_arg, columns_arg); l_getline(is, line); if (!prefixIs(line, " got" << @@ -1286,7 +1315,8 @@ void LyXTabular::ReadNew(Buffer const * buf, istream & is, } -void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) +void LyXTabular::OldFormatRead(BufferParams const & bp, + LyXLex & lex, string const & fl) { int version; int i; @@ -1302,7 +1332,7 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) int e = 0; int f = 0; int g = 0; - + istream & is = lex.getStream(); string s(fl); if (s.length() > 8) @@ -1324,7 +1354,7 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) >> rotate_arg >> a >> b >> c >> d; } else is >> rows_arg >> columns_arg; - Init(rows_arg, columns_arg); + Init(bp, rows_arg, columns_arg); cont_row_info = vector(rows_arg); SetLongTabular(is_long_tabular_arg); SetRotateTabular(rotate_arg); @@ -1344,7 +1374,7 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) } else { is >> rows_arg >> columns_arg >> is_long_tabular_arg >> rotate_arg >> a >> b >> c >> d; - Init(rows_arg, columns_arg); + Init(bp, rows_arg, columns_arg); cont_row_info = vector(rows_arg); SetLongTabular(is_long_tabular_arg); SetRotateTabular(rotate_arg); @@ -1367,7 +1397,7 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) #else // ignore is buggy but we will use it later (Lgb) is.ignore(); // skip '"' -#endif +#endif getline(is, s1, '"'); #if 1 is >> ch; // skip '"' @@ -1420,6 +1450,8 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) Paragraph * par = new Paragraph; Paragraph * return_par = 0; + par->layout(bp.getLyXTextClass().defaultLayout()); + string tmptok; int pos = 0; Paragraph::depth_type depth = 0; @@ -1432,14 +1464,11 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl) if (token.empty()) continue; if (token == "\\layout" - || token == "\\end_float" - || token == "\\end_deeper") { + || token == "\\end_float" // this should not exist anymore + || token == "\\end_inset" // as it is substituted by this + || token == "\\end_deeper") + { lex.pushToken(token); -#ifndef NO_COMPABILITY - // Here we need to insert the inset_ert_contents into the last - // cell of the tabular. - owner_->bufferOwner()->insertErtContents(par, pos, font); -#endif break; } if (owner_->bufferOwner()->parseSingleLyXformat2Token(lex, par, @@ -1514,15 +1543,25 @@ LyXTabular::cellstruct * LyXTabular::cellinfo_of_cell(int cell) const } -void LyXTabular::SetMultiColumn(int cell, int number) +void LyXTabular::SetMultiColumn(Buffer const * buffer, int cell, int number) { 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; + cellinfo_of_cell(cell)->right_line = column_info[column_of_cell(cell+number-1)].right_line; +#if 1 + for (int i = 1; i < number; ++i) { + cellinfo_of_cell(cell+i)->multicolumn = CELL_PART_OF_MULTICOLUMN; + cellinfo_of_cell(cell)->inset.appendParagraphs(buffer->params, + cellinfo_of_cell(cell+i)->inset.paragraph()); + cellinfo_of_cell(cell+i)->inset.clear(); + } +#else for (number--; number > 0; --number) { cellinfo_of_cell(cell+number)->multicolumn = CELL_PART_OF_MULTICOLUMN; } +#endif set_row_column_number_info(); } @@ -1547,9 +1586,9 @@ int LyXTabular::UnsetMultiColumn(int cell) { int const row = row_of_cell(cell); int column = column_of_cell(cell); - + int result = 0; - + if (cell_info[row][column].multicolumn == CELL_BEGIN_OF_MULTICOLUMN) { cell_info[row][column].multicolumn = CELL_NORMAL; ++column; @@ -1882,7 +1921,7 @@ int LyXTabular::TeXTopHLine(ostream & os, int row) const if (TopLine(i)) ++tmp; } - if (tmp == (n - fcell)){ + if (tmp == (n - fcell)) { os << "\\hline "; } else if (tmp) { for (int i = fcell; i < n; ++i) { @@ -1915,7 +1954,7 @@ int LyXTabular::TeXBottomHLine(ostream & os, int row) const if (BottomLine(i)) ++tmp; } - if (tmp == (n-fcell)){ + if (tmp == (n - fcell)) { os << "\\hline"; } else if (tmp) { for (int i = fcell; i < n; ++i) { @@ -1949,7 +1988,7 @@ int LyXTabular::TeXCellPreamble(ostream & os, int cell) const os << cellinfo_of_cell(cell)->align_special << "}{"; } else { if (LeftLine(cell) && - (IsFirstCellInRow(cell) || + (IsFirstCellInRow(cell) || (!IsMultiColumn(cell-1) && !LeftLine(cell, true) && !RightLine(cell-1, true)))) { @@ -2034,7 +2073,7 @@ int LyXTabular::TeXCellPostamble(ostream & os, int cell) const os << "%\n\\end{minipage}"; ret += 2; } - if (IsMultiColumn(cell)){ + if (IsMultiColumn(cell)) { os << '}'; } if (GetRotateCell(cell)) { @@ -2046,7 +2085,7 @@ int LyXTabular::TeXCellPostamble(ostream & os, int cell) const int LyXTabular::TeXLongtableHeaderFooter(ostream & os, Buffer const * buf, - bool fragile, bool fp) const + bool fragile, bool fp) const { if (!is_long_tabular) return 0; @@ -2146,7 +2185,7 @@ bool LyXTabular::isValidRow(int const row) const int LyXTabular::TeXRow(ostream & os, int const i, Buffer const * buf, - bool fragile, bool fp) const + bool fragile, bool fp) const { int ret = 0; int cell = GetCellNumber(i, 0); @@ -2159,7 +2198,7 @@ int LyXTabular::TeXRow(ostream & os, int const i, Buffer const * buf, InsetText * inset = GetCellInset(cell); bool rtl = inset->paragraph()->isRightToLeftPar(buf->params) && - inset->paragraph()->size() > 0 && GetPWidth(cell).zero(); + !inset->paragraph()->empty() && GetPWidth(cell).zero(); if (rtl) os << "\\R{"; @@ -2174,7 +2213,7 @@ int LyXTabular::TeXRow(ostream & os, int const i, Buffer const * buf, } ++cell; } - os << "\\\\\n"; + os << "\\tabularnewline\n"; ++ret; ret += TeXBottomHLine(os, i); return ret; @@ -2201,10 +2240,22 @@ int LyXTabular::latex(Buffer const * buf, for (int i = 0; i < columns_; ++i) { if (!column_info[i].align_special.empty()) { os << column_info[i].align_special; - } else { + } else { if (column_info[i].left_line) os << '|'; if (!column_info[i].p_width.zero()) { + switch (column_info[i].alignment) { + case LYX_ALIGN_LEFT: + os << ">{\\raggedright}"; + break; + case LYX_ALIGN_RIGHT: + os << ">{\\raggedleft}"; + break; + case LYX_ALIGN_CENTER: + os << ">{\\centering}"; + break; + } + switch (column_info[i].valignment) { case LYX_VALIGN_TOP: os << "p"; @@ -2240,7 +2291,7 @@ int LyXTabular::latex(Buffer const * buf, ++ret; ret += TeXLongtableHeaderFooter(os, buf, fragile, fp); - + //+--------------------------------------------------------------------- //+ the single row and columns (cells) + //+--------------------------------------------------------------------- @@ -2276,7 +2327,7 @@ int LyXTabular::docbookRow(Buffer const * buf, ostream & os, int row) const { int ret = 0; int cell = GetFirstCellInRow(row); - + os << "\n"; for (int j = 0; j < columns_; ++j) { if (IsPartOfMultiColumn(row, j)) @@ -2314,16 +2365,17 @@ int LyXTabular::docbookRow(Buffer const * buf, ostream & os, int row) const } os << ">"; - ret += GetCellInset(cell)->docbook(buf, os); + ret += GetCellInset(cell)->docbook(buf, os, true); os << "\n"; ++cell; } os << "\n"; return ret; -} +} -int LyXTabular::docBook(Buffer const * buf, ostream & os) const +int LyXTabular::docbook(Buffer const * buf, ostream & os, + bool /*mixcont*/) const { int ret = 0; @@ -2333,7 +2385,7 @@ int LyXTabular::docBook(Buffer const * buf, ostream & os) const os << "\n"; - + for (int i = 0; i < columns_; ++i) { os << "\n"; - if( endfirsthead.row ) { - docbookRow( buf, os, endfirsthead.row - 1); - } - if( endhead.row && endhead.row != endfirsthead.row) { - docbookRow(buf, os, endhead.row - 1); + // output header info + if (haveLTHead() || haveLTFirstHead()) { + os << "\n"; + ++ret; + for (int i = 0; i < rows_; ++i) { + if (row_info[i].endhead || row_info[i].endfirsthead) { + ret += docbookRow(buf, os, i); } - os << "\n"; } - - // Footer - if( endfoot.row || endlastfoot.row ) { - os << "\n"; - if( endfoot.row ) { - docbookRow( buf, os, endfoot.row - 1); - } - if( endlastfoot.row && endlastfoot.row != endfoot.row) { - docbookRow( buf, os, endlastfoot.row - 1); + os << "\n"; + ++ret; + } + // output footer info + if (haveLTFoot() || haveLTLastFoot()) { + os << "\n"; + ++ret; + for (int i = 0; i < rows_; ++i) { + if (row_info[i].endfoot || row_info[i].endlastfoot) { + ret += docbookRow(buf, os, i); } - os << "\n"; } + os << "\n"; + ++ret; } -#endif + //+--------------------------------------------------------------------- //+ the single row and columns (cells) + //+--------------------------------------------------------------------- os << "\n"; + ++ret; for (int i = 0; i < rows_; ++i) { - if(!IsLongTabular() || ( - !row_info[i].endhead && !row_info[i].endfirsthead && - !row_info[i].endfoot && !row_info[i].endlastfoot)) { - docbookRow( buf, os, i); + if (isValidRow(i)) { + ret += docbookRow(buf, os, i); } } os << "\n"; + ++ret; //+--------------------------------------------------------------------- //+ the closing of the tabular + //+--------------------------------------------------------------------- @@ -2411,7 +2459,7 @@ int LyXTabular::docBook(Buffer const * buf, ostream & os) const // ASCII export function and helpers //-- int LyXTabular::asciiTopHLine(ostream & os, int row, - vector const & clen) const + vector const & clen) const { int const fcell = GetFirstCellInRow(row); int const n = NumberOfCellsInRow(fcell) + fcell; @@ -2458,7 +2506,7 @@ int LyXTabular::asciiTopHLine(ostream & os, int row, int LyXTabular::asciiBottomHLine(ostream & os, int row, - vector const & clen) const + vector const & clen) const { int const fcell = GetFirstCellInRow(row); int const n = NumberOfCellsInRow(fcell) + fcell; @@ -2505,9 +2553,9 @@ int LyXTabular::asciiBottomHLine(ostream & os, int row, int LyXTabular::asciiPrintCell(Buffer const * buf, ostream & os, - int cell, int row, int column, - vector const & clen, - bool onlydata) const + int cell, int row, int column, + vector const & clen, + bool onlydata) const { ostringstream sstr; int ret = GetCellInset(cell)->ascii(buf, sstr, 0); @@ -2516,7 +2564,7 @@ int LyXTabular::asciiPrintCell(Buffer const * buf, ostream & os, os << sstr.str(); return ret; } - + if (LeftLine(cell)) os << "| "; else @@ -2645,26 +2693,69 @@ InsetText * LyXTabular::GetCellInset(int row, int column) const } +int LyXTabular::GetCellFromInset(Inset const * inset, int maybe_cell) const +{ + // is this inset part of the tabular? + if (!inset || inset->owner() != owner_) { + lyxerr[Debug::INSETTEXT] + << "this is not a cell of the tabular!" << endl; + return -1; + } + + const int save_cur_cell = cur_cell; + int cell = cur_cell; + if (GetCellInset(cell) != inset) { + cell = maybe_cell; + if (cell == -1 || GetCellInset(cell) != inset) { + cell = -1; + } + } + + if (cell == -1) { + for (cell = GetNumberOfCells(); cell >= 0; --cell) { + if (GetCellInset(cell) == inset) + break; + } + lyxerr[Debug::INSETTEXT] + << "LyXTabular::GetCellFromInset: " + << "cell=" << cell + << ", cur_cell=" << save_cur_cell + << ", maybe_cell=" << maybe_cell + << endl; + // We should have found a cell at this point + if (cell == -1) { + lyxerr << "LyXTabular::GetCellFromInset: " + << "Cell not found!" << endl; + } + } + + return cell; +} + + void LyXTabular::Validate(LaTeXFeatures & features) const { + features.require("NeedTabularnewline"); if (IsLongTabular()) features.require("longtable"); if (NeedRotating()) features.require("rotating"); - for (int cell = 0; !features.isRequired("array") && (cell < numberofcells); ++cell) { - if (GetVAlignment(cell) != LYX_VALIGN_TOP) + for (int cell = 0; cell < numberofcells; ++cell) { + if ( (GetVAlignment(cell) != LYX_VALIGN_TOP) || + ( !(GetPWidth(cell).zero())&&!(IsMultiColumn(cell)) ) + ) features.require("array"); GetCellInset(cell)->validate(features); } } -std::vector const LyXTabular::getLabelList() const +vector const LyXTabular::getLabelList() const { - std::vector label_list; + vector label_list; for (int i = 0; i < rows_; ++i) for (int j = 0; j < columns_; ++j) { - std::vector const l = + vector const l = GetCellInset(i, j)->getLabelList(); label_list.insert(label_list.end(), l.begin(), l.end()); @@ -2672,7 +2763,7 @@ std::vector const LyXTabular::getLabelList() const return label_list; } - + LyXTabular::BoxType LyXTabular::UseParbox(int cell) const { Paragraph * par = GetCellInset(cell)->paragraph();