1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 2000 The LyX Team.
8 * ======================================================
17 #pragma implementation
24 #include "support/lstrings.h"
25 #include "support/lyxmanip.h"
26 #include "lyx_gui_misc.h"
27 #include "insets/insettext.h"
36 static int const WIDTH_OF_LINE = 5;
38 /// Define a few methods for the inner structs
40 LyXTabular::cellstruct::cellstruct()
42 cellno = 0; //should be initilaized correctly later.
44 multicolumn = LyXTabular::CELL_NORMAL;
45 alignment = LYX_ALIGN_CENTER;
53 LyXTabular::cellstruct::~cellstruct()
58 LyXTabular::cellstruct &
59 LyXTabular::cellstruct::operator=(cellstruct const & cs)
62 width_of_cell = cs.width_of_cell;
63 multicolumn = cs.multicolumn;
64 alignment = cs.alignment;
65 top_line = cs.top_line;
66 bottom_line = cs.bottom_line;
68 linebreaks = cs.linebreaks;
72 LyXTabular::rowstruct::rowstruct()
81 // Nothing to do, but gcc 2.7.2.3 wants one... (JMarc)
82 LyXTabular::rowstruct::~rowstruct()
86 LyXTabular::rowstruct &
87 LyXTabular::rowstruct::operator=(rowstruct const & rs)
89 top_line = rs.top_line;
90 bottom_line = rs.bottom_line;
91 ascent_of_row = rs.ascent_of_row;
92 descent_of_row = rs.descent_of_row;
97 LyXTabular::columnstruct::columnstruct()
101 alignment = LYX_ALIGN_CENTER;
105 LyXTabular::columnstruct::~columnstruct()
109 LyXTabular::columnstruct &
110 LyXTabular::columnstruct::operator=(columnstruct const & cs)
112 left_line = cs.left_line;
113 right_line = cs.right_line;
114 alignment = cs.alignment;
115 width_of_column = cs.width_of_column;
116 p_width = cs.p_width;
117 align_special = cs.align_special;
122 LyXTabular::LyXTabular(int rows_arg, int columns_arg, Buffer *buf)
125 Init(buf, rows_arg, columns_arg);
129 LyXTabular::LyXTabular(LyXTabular const & lt, Buffer * buf)
132 Init(buf, lt.rows_, lt.columns_);
137 LyXTabular::LyXTabular(LyXLex & lex, Buffer *buf)
144 LyXTabular::~LyXTabular()
147 delete[] columnofcell;
148 // delete[] column_info;
149 // delete[] row_info;
150 // for (int i = 0; i < rows_; ++i) {
151 // delete[] cell_info[i];
153 // delete[] cell_info;
157 LyXTabular & LyXTabular::operator=(LyXTabular const & lt)
159 // If this and lt is not of the same size we have a serious bug
160 // So then it is ok to throw an exception, or for now
162 Assert(rows_ == lt.rows_ && columns_ == lt.columns_);
164 int row = 0, column = 0;
166 for (row = 0; row < rows_; ++row) {
167 for (column = 0; column < columns_; ++column) {
168 cell_info[row][column] = lt.cell_info[row][column];
172 for (row = 0; row < rows_; ++row) {
173 row_info[row] = lt.row_info[row];
176 for (column = 0; column < columns_; ++column) {
177 column_info[column] = lt.column_info[column];
180 SetLongTabular(lt.is_long_tabular);
187 LyXTabular * LyXTabular::Clone(Buffer * buf)
189 LyXTabular * result = new LyXTabular(rows_, columns_, buf);
192 for (row = 0; row < rows_; ++row) {
193 for (column = 0; column < columns_; ++column) {
194 result->cell_info[row][column] = cell_info[row][column];
198 for (row = 0; row < rows_; ++row) {
199 result->row_info[row] = row_info[row];
202 for (column = 0; column < columns_; ++column) {
203 result->column_info[column].left_line = column_info[column].left_line;
204 result->column_info[column].right_line = column_info[column].right_line;
205 result->column_info[column].alignment = column_info[column].alignment;
206 result->column_info[column].p_width = column_info[column].p_width;
207 result->column_info[column].align_special = column_info[column].align_special;
210 result->SetLongTabular(is_long_tabular);
211 result->rotate = rotate;
217 /* activates all lines and sets all widths to 0 */
218 void LyXTabular::Init(Buffer * buf, int rows_arg, int columns_arg)
224 columns_ = columns_arg;
225 row_info = vector<rowstruct>(rows_, rowstruct());
226 column_info = vector<columnstruct>(columns_, columnstruct());
227 cell_info = vector<vector<cellstruct> >
228 (rows_, vector<cellstruct>(columns_, cellstruct()));
230 for (i = 0; i < rows_; ++i) {
231 for (j = 0; j < columns_; ++j) {
232 cell_info[i][j].inset = new InsetText(buf);
233 cell_info[i][j].cellno = cellno++;
236 row_info[i-1].bottom_line = true;
237 row_info[0].bottom_line = true;
239 for (i = 0; i < columns_; ++i) {
240 calculate_width_of_column(i);
242 column_info[columns_-1].right_line = true;
244 calculate_width_of_tabular();
248 set_row_column_number_info();
249 is_long_tabular = false;
258 void LyXTabular::AppendRow(int /* cell */)
261 int row = row_of_cell(cell);
262 rowstruct * row_info2 = new rowstruct[rows_ + 1];
263 cellstruct ** cell_info2 = new cellstruct * [rows_ + 1];
266 for (i = 0; i <= row; ++i) {
267 cell_info2[i] = cell_info[i];
268 row_info2[i] = row_info[i];
270 for (i = rows_ - 1; i >= row; --i) {
271 cell_info2[i + 1] = cell_info[i];
272 row_info2[i + 1] = row_info[i];
274 row_info2[row + 1].top_line = row_info[i].top_line;
275 cell_info2[row + 1] = new cellstruct[columns_](buffer);
276 for (i = 0; i < columns_; ++i) {
277 cell_info2[row + 1][i].width_of_cell = 0;
278 cell_info2[row + 1][i] = cell_info2[row][i];
282 cell_info = cell_info2;
284 row_info = row_info2;
293 void LyXTabular::DeleteRow(int /*cell*/)
296 int row = row_of_cell(cell);
297 rowstruct * row_info2 = new rowstruct[rows_ - 1];
298 cellstruct ** cell_info2 = new cellstruct * [rows_ - 1];
300 delete[] cell_info[row];
302 for (; i < row; ++i) {
303 cell_info2[i] = cell_info[i];
304 row_info2[i] = row_info[i];
306 for (i = row; i < rows_ - 1; ++i) {
307 cell_info2[i] = cell_info[i + 1];
308 row_info2[i] = row_info[i + 1];
312 cell_info = cell_info2;
314 row_info = row_info2;
323 void LyXTabular::AppendColumn(int /*cell*/)
327 columnstruct * column_info2 = new columnstruct[columns_ + 1];
328 int column = right_column_of_cell(cell);
331 for (; i <= column; ++i) {
332 column_info2[i] = column_info[i];
334 for (i = columns_ - 1; i >= column; --i) {
335 column_info2[i + 1] = column_info[i];
338 delete[] column_info;
339 column_info = column_info2;
341 for (i = 0; i < rows_; ++i) {
342 cellstruct * tmp = cell_info[i];
343 cell_info[i] = new cellstruct[columns_ + 1](buffer);
344 for (j = 0; j <= column; ++j) {
345 cell_info[i][j] = tmp[j];
347 for (j = column; j < columns_; ++j) {
348 cell_info[i][j + 1] = tmp[j];
350 // care about multicolumns
351 if (cell_info[i][column + 1].multicolumn
352 == LyXTabular::CELL_BEGIN_OF_MULTICOLUMN){
353 cell_info[i][column + 1].multicolumn =
354 LyXTabular::CELL_PART_OF_MULTICOLUMN;
356 if (column + 1 == columns_
357 || cell_info[i][column + 2].multicolumn
358 != LyXTabular::CELL_PART_OF_MULTICOLUMN){
359 cell_info[i][column + 1].multicolumn =
360 LyXTabular::CELL_NORMAL;
371 void LyXTabular::DeleteColumn(int /*cell*/)
374 int column1 = column_of_cell(cell);
375 int column2 = right_column_of_cell(cell);
377 if (column1 == 0 && column2 == columns_ - 1)
380 for (int column = column1; column <= column2; ++column) {
381 delete_column(column1);
388 void LyXTabular::delete_column(int /*column*/)
392 columnstruct * column_info2 = new columnstruct[columns_-1];
394 for (i = 0; i < column; ++i) {
395 column_info2[i] = column_info[i];
397 for (i = column; i < columns_ - 1; ++i) {
398 column_info2[i] = column_info[i + 1];
401 delete[] column_info;
402 column_info = column_info2;
404 for (i = 0; i < rows_; ++i) {
405 cellstruct * tmp = cell_info[i];
406 cell_info[i] = new cellstruct[columns_ - 1](buffer);
407 for (j = 0; j < column; ++j) {
408 cell_info[i][j] = tmp[j];
410 for (j = column; j < columns_ - 1; ++j) {
411 cell_info[i][j] = tmp[j + 1];
422 void LyXTabular::Reinit()
427 for (; i < rows_; ++i) {
428 for (j = 0; j < columns_; ++j) {
429 cell_info[i][j].width_of_cell = 0;
433 for (i = 0; i < columns_; ++i) {
434 calculate_width_of_column(i);
436 calculate_width_of_tabular();
438 set_row_column_number_info();
442 void LyXTabular::set_row_column_number_info()
448 for (; row < rows_; ++row) {
449 for (column = 0; column<columns_; ++column) {
450 if (cell_info[row][column].multicolumn
451 != LyXTabular::CELL_PART_OF_MULTICOLUMN)
453 cell_info[row][column].cellno = numberofcells;
456 ++numberofcells; // because this is one more than as we start from 0
461 rowofcell = new int[numberofcells];
462 delete [] columnofcell;
463 columnofcell = new int[numberofcells];
465 while (c < numberofcells && row < rows_ && column < columns_) {
467 columnofcell[c] = column;
471 } while (column < columns_ &&
472 cell_info[row][column].multicolumn
473 == LyXTabular::CELL_PART_OF_MULTICOLUMN);
474 if (column == columns_) {
481 int LyXTabular::GetNumberOfCells() const
483 return numberofcells;
487 int LyXTabular::NumberOfCellsInRow(int cell) const
489 int row = row_of_cell(cell);
491 for (int i = 0; i < columns_; ++i) {
492 if (cell_info[row][i].multicolumn != LyXTabular::CELL_PART_OF_MULTICOLUMN)
499 int LyXTabular::AppendCellAfterCell(int append_cell, int question_cell)
501 return (right_column_of_cell(append_cell) ==
502 right_column_of_cell(question_cell));
506 int LyXTabular::DeleteCellIfColumnIsDeleted(int cell, int delete_column_cell)
508 if (column_of_cell(delete_column_cell) == 0 &&
509 right_column_of_cell(delete_column_cell) == columns_ - 1)
513 (column_of_cell(cell) >= column_of_cell(delete_column_cell) &&
514 column_of_cell(cell) <= right_column_of_cell(delete_column_cell));
518 /* returns 1 if there is a topline, returns 0 if not */
519 bool LyXTabular::TopLine(int cell) const
521 int row = row_of_cell(cell);
523 if (IsMultiColumn(cell))
524 return cellinfo_of_cell(cell)->top_line;
525 return row_info[row].top_line;
529 bool LyXTabular::BottomLine(int cell) const
531 //no bottom line underneath non-existent cells if you please
532 if(cell >= numberofcells)
535 if (IsMultiColumn(cell))
536 return cellinfo_of_cell(cell)->bottom_line;
537 return row_info[row_of_cell(cell)].bottom_line;
541 bool LyXTabular::LeftLine(int cell) const
543 return column_info[column_of_cell(cell)].left_line;
547 bool LyXTabular::RightLine(int cell) const
549 return column_info[right_column_of_cell(cell)].right_line;
553 bool LyXTabular::TopAlreadyDrawed(int cell) const
555 if (GetAdditionalHeight(cell))
557 int row = row_of_cell(cell);
559 int column = column_of_cell(cell);
562 && cell_info[row][column].multicolumn
563 == LyXTabular::CELL_PART_OF_MULTICOLUMN)
565 if (cell_info[row][column].multicolumn == LyXTabular::CELL_NORMAL)
566 return row_info[row].bottom_line;
568 return cell_info[row][column].bottom_line;
574 bool LyXTabular::LeftAlreadyDrawed(int cell) const
576 int column = column_of_cell(cell);
578 int row = row_of_cell(cell);
580 (cell_info[row][column].multicolumn ==
581 LyXTabular::CELL_PART_OF_MULTICOLUMN));
582 if (GetAdditionalWidth(cell_info[row][column].cellno))
584 return column_info[column].right_line;
590 bool LyXTabular::IsLastRow(int cell) const
592 return (row_of_cell(cell) == rows_ - 1);
596 int LyXTabular::GetAdditionalHeight(int cell) const
598 int row = row_of_cell(cell);
601 int top = 1; // bool top = true; ??
602 int bottom = 1; // bool bottom = true; ??
605 for (column = 0; column < columns_ - 1 && bottom; ++column) {
606 switch (cell_info[row - 1][column].multicolumn) {
607 case LyXTabular::CELL_BEGIN_OF_MULTICOLUMN:
608 bottom = cell_info[row - 1][column].bottom_line;
610 case LyXTabular::CELL_NORMAL:
611 bottom = row_info[row - 1].bottom_line;
614 for (column = 0; column < columns_ - 1 && top; ++column) {
615 switch (cell_info[row][column].multicolumn){
616 case LyXTabular::CELL_BEGIN_OF_MULTICOLUMN:
617 top = cell_info[row][column].top_line;
619 case LyXTabular::CELL_NORMAL:
620 top = row_info[row].top_line;
624 return WIDTH_OF_LINE;
629 int LyXTabular::GetAdditionalWidth(int cell) const
631 // internally already set in SetWidthOfCell
632 // used to get it back in text.C
633 int col = right_column_of_cell(cell);
634 if (col < columns_ - 1 && column_info[col].right_line &&
635 column_info[col+1].left_line)
636 return WIDTH_OF_LINE;
642 // returns the maximum over all rows
643 int LyXTabular::GetWidthOfColumn(int cell) const
645 int column1 = column_of_cell(cell);
646 int column2 = right_column_of_cell(cell);
649 for (; i <= column2; ++i) {
650 result += column_info[i].width_of_column;
656 int LyXTabular::GetWidthOfTabular() const
658 return width_of_tabular;
661 /* returns 1 if a complete update is necessary, otherwise 0 */
662 bool LyXTabular::SetWidthOfMulticolCell(int cell, int new_width)
664 if (!IsMultiColumn(cell))
667 int row = row_of_cell(cell);
668 int column1 = column_of_cell(cell);
669 int column2 = right_column_of_cell(cell);
671 // first set columns to 0 so we can calculate the right width
673 for (; i <= column2; ++i) {
674 cell_info[row][i].width_of_cell = 0;
676 // set the width to MAX_WIDTH until width > 0
677 int width = (new_width + 2 * WIDTH_OF_LINE);
678 for (i = column1; (i < column2) && (width > 0); ++i) {
679 cell_info[row][i].width_of_cell = column_info[i].width_of_column;
680 width -= column_info[i].width_of_column;
683 cell_info[row][i].width_of_cell = width;
689 void LyXTabular::recalculateMulticolCells(int cell, int new_width)
691 int row = row_of_cell(cell);
692 int column1 = column_of_cell(cell);
693 int column2 = right_column_of_cell(cell);
695 // first set columns to 0 so we can calculate the right width
697 for (; i <= column2; ++i)
698 cell_info[row][i].width_of_cell = 0;
699 for(i = cell + 1; (i < numberofcells) && (!IsMultiColumn(i)); ++i)
701 if (i < numberofcells)
702 recalculateMulticolCells(i, GetWidthOfCell(i) - (2 * WIDTH_OF_LINE));
703 SetWidthOfMulticolCell(cell, new_width);
707 /* returns 1 if a complete update is necessary, otherwise 0 */
708 bool LyXTabular::SetWidthOfCell(int cell, int new_width)
710 int row = row_of_cell(cell);
711 int column1 = column_of_cell(cell);
715 if (IsMultiColumn(cell)) {
716 tmp = SetWidthOfMulticolCell(cell, new_width);
718 width = (new_width + 2*WIDTH_OF_LINE);
719 cell_info[row][column1].width_of_cell = width;
720 if (column_info[column1].right_line && (column1 < columns_-1) &&
721 column_info[column1+1].left_line) // additional width
722 cell_info[row][column1].width_of_cell += WIDTH_OF_LINE;
723 tmp = calculate_width_of_column_NMC(column1);
727 for(i = 0; i<columns_;++i)
728 calculate_width_of_column_NMC(i);
729 for(i = 0; (i<numberofcells) && !IsMultiColumn(i); ++i)
732 recalculateMulticolCells(i, GetWidthOfCell(i)-(2*WIDTH_OF_LINE));
733 for(i = 0; i<columns_;++i)
734 calculate_width_of_column(i);
735 calculate_width_of_tabular();
742 bool LyXTabular::SetAlignment(int cell, char align)
744 if (!IsMultiColumn(cell))
745 column_info[column_of_cell(cell)].alignment = align;
746 cellinfo_of_cell(cell)->alignment = align;
750 bool LyXTabular::SetPWidth(int cell, string width)
752 if (IsMultiColumn(cell)) {
753 cellinfo_of_cell(cell)->p_width = width;
755 column_info[column_of_cell(cell)].p_width = width;
756 if (!width.empty()) // do this only if there is a width
757 SetAlignment(cell, LYX_ALIGN_LEFT);
762 bool LyXTabular::SetAlignSpecial(int cell, string special, int what)
764 if (what == SET_SPECIAL_MULTI)
765 cellinfo_of_cell(cell)->align_special = special;
767 column_info[column_of_cell(cell)].align_special = special;
771 bool LyXTabular::SetAllLines(int cell, bool line)
773 SetTopLine(cell, line);
774 SetBottomLine(cell, line);
775 SetRightLine(cell, line);
776 SetLeftLine(cell, line);
780 bool LyXTabular::SetTopLine(int cell, bool line)
782 int row = row_of_cell(cell);
784 if (!IsMultiColumn(cell))
785 row_info[row].top_line = line;
787 cellinfo_of_cell(cell)->top_line = line;
792 bool LyXTabular::SetBottomLine(int cell, bool line)
794 if (!IsMultiColumn(cell))
795 row_info[row_of_cell(cell)].bottom_line = line;
797 cellinfo_of_cell(cell)->bottom_line = line;
802 bool LyXTabular::SetLeftLine(int cell, bool line)
804 column_info[column_of_cell(cell)].left_line = line;
809 bool LyXTabular::SetRightLine(int cell, bool line)
811 column_info[right_column_of_cell(cell)].right_line = line;
816 char LyXTabular::GetAlignment(int cell) const
818 if (IsMultiColumn(cell))
819 return cellinfo_of_cell(cell)->alignment;
821 return column_info[column_of_cell(cell)].alignment;
824 string LyXTabular::GetPWidth(int cell) const
826 if (IsMultiColumn(cell))
827 return cellinfo_of_cell(cell)->p_width;
828 return column_info[column_of_cell(cell)].p_width;
831 string LyXTabular::GetAlignSpecial(int cell, int what) const
833 if (what == SET_SPECIAL_MULTI)
834 return cellinfo_of_cell(cell)->align_special;
835 return column_info[column_of_cell(cell)].align_special;
838 int LyXTabular::GetWidthOfCell(int cell) const
840 int row = row_of_cell(cell);
841 int column1 = column_of_cell(cell);
842 int column2 = right_column_of_cell(cell);
845 for (; i <= column2; ++i) {
846 result += cell_info[row][i].width_of_cell;
849 // result += GetAdditionalWidth(cell);
855 int LyXTabular::GetBeginningOfTextInCell(int cell) const
859 switch (GetAlignment(cell)){
860 case LYX_ALIGN_CENTER:
861 x += (GetWidthOfColumn(cell) - GetWidthOfCell(cell)) / 2;
863 case LYX_ALIGN_RIGHT:
864 x += GetWidthOfColumn(cell) - GetWidthOfCell(cell);
865 // + GetAdditionalWidth(cell);
867 default: /* LYX_ALIGN_LEFT: nothing :-) */
877 bool LyXTabular::IsFirstCellInRow(int cell) const
879 return (column_of_cell(cell) == 0);
882 bool LyXTabular::IsLastCellInRow(int cell) const
884 return (right_column_of_cell(cell) == (columns_ - 1));
888 bool LyXTabular::calculate_width_of_column(int column)
890 int old_column_width = column_info[column].width_of_column;
893 for (int i = 0; i < rows_; ++i) {
894 maximum = max(cell_info[i][column].width_of_cell, maximum);
896 column_info[column].width_of_column = maximum;
897 return (column_info[column].width_of_column != old_column_width);
900 bool LyXTabular::calculate_width_of_column_NMC(int column)
902 int old_column_width = column_info[column].width_of_column;
904 for (int i = 0; i < rows_; ++i) {
905 if (!IsMultiColumn(GetCellNumber(column, i)) &&
906 (cell_info[i][column].width_of_cell > max)) {
907 max = cell_info[i][column].width_of_cell;
910 column_info[column].width_of_column = max;
911 return (column_info[column].width_of_column != old_column_width);
914 void LyXTabular::calculate_width_of_tabular()
916 width_of_tabular = 0;
917 for (int i = 0; i < columns_; ++i) {
918 width_of_tabular += column_info[i].width_of_column;
923 int LyXTabular::row_of_cell(int cell) const
925 if (cell >= numberofcells)
929 return rowofcell[cell];
933 int LyXTabular::column_of_cell(int cell) const
935 if (cell >= numberofcells)
939 return columnofcell[cell];
943 int LyXTabular::right_column_of_cell(int cell) const
945 int row = row_of_cell(cell);
946 int column = column_of_cell(cell);
947 while (column < (columns_ - 1) &&
948 cell_info[row][column+1].multicolumn == LyXTabular::CELL_PART_OF_MULTICOLUMN)
954 void LyXTabular::Write(ostream & os) const
959 os << "<LyXTabular version=1 rows=" << rows_ << " columns=" << columns_ <<
961 // global longtable options
962 os << "<Features rotate=" << rotate <<
963 " islongtable=" << is_long_tabular <<
964 " endhead=" << endhead << " endfirsthead=" << endfirsthead <<
965 " endfoot=" << endfoot << " endlastfoot=" << endlastfoot <<
967 for (i = 0; i < rows_; ++i) {
968 os << "<Row topline=" << row_info[i].top_line <<
969 " bottomline=" << row_info[i].bottom_line <<
970 " newpage=" << row_info[i].newpage <<
972 for (j = 0; j < columns_; ++j) {
974 os << "<Column alignment=" << column_info[j].alignment <<
975 " leftline=" << column_info[j].left_line <<
976 " rightline=" << column_info[j].right_line <<
977 " width=\"" << VSpace(column_info[j].p_width).asLyXCommand() <<
978 "\" special=\"" << column_info[j].align_special <<
981 os << "<Column>" << endl;
983 os << "<Cell multicolumn=" << cell_info[i][j].multicolumn <<
984 " alignment=" << cell_info[i][j].alignment <<
985 " topline=" << cell_info[i][j].top_line <<
986 " bottomline=" << cell_info[i][j].bottom_line <<
987 " rotate=" << cell_info[i][j].rotate <<
988 " linebreaks=" << cell_info[i][j].linebreaks <<
989 " width=\"" << cell_info[i][j].p_width <<
990 "\" special=\"" << cell_info[i][j].align_special <<
992 os << "\\begin_inset ";
993 cell_info[i][j].inset->Write(os);
994 os << "\n\\end_inset " << endl;
995 os << "</Cell>" << endl;
996 os << "</Column>" << endl;
998 os << "</Row>" << endl;
1000 os << "</LyXTabular>" << endl;
1003 static bool getTokenValue(string const str, const char * token, string & ret)
1005 int pos = str.find(token);
1006 char ch = str[pos+strlen(token)];
1008 if ((pos < 0) || (ch != '='))
1011 pos += strlen(token)+1;
1013 if ((ch != '"') && (ch != '\'')) { // only read till next space
1017 while((pos < int(str.length()-1)) && (str[++pos] != ch))
1023 static bool getTokenValue(string const str, const char * token, int & num)
1026 int pos = str.find(token);
1027 char ch = str[pos+strlen(token)];
1029 if ((pos < 0) || (ch != '='))
1032 pos += strlen(token)+1;
1034 if ((ch != '"') && (ch != '\'')) { // only read till next space
1040 while((pos < int(str.length()-1)) && isdigit(str[pos]))
1043 num = strToInt(ret);
1047 static bool getTokenValue(string const str, const char * token, bool & flag)
1050 int pos = str.find(token);
1051 char ch = str[pos+strlen(token)];
1053 if ((pos < 0) || (ch != '='))
1056 pos += strlen(token)+1;
1058 if ((ch != '"') && (ch != '\'')) { // only read till next space
1064 while((pos < int(str.length()-1)) && isdigit(str[pos]))
1067 flag = strToInt(ret);
1071 void l_getline(istream & is, string & str)
1078 void LyXTabular::Read(LyXLex & lex)
1081 istream & is = lex.getStream();
1083 l_getline(is, line);
1084 if (!prefixIs(line, "<LyXTabular ")) {
1085 OldFormatRead(is, line);
1092 if (!getTokenValue(line, "version", version))
1094 if (!getTokenValue(line, "rows", rows_arg))
1096 if (!getTokenValue(line, "columns", columns_arg))
1098 Init(buffer, rows_arg, columns_arg);
1099 l_getline(is, line);
1100 if (!prefixIs(line, "<Features ")) {
1101 lyxerr << "Wrong tabular format (expected <Feture ...> got" <<
1102 line << ")" << endl;
1105 (void)getTokenValue(line, "islongtable", is_long_tabular);
1106 (void)getTokenValue(line, "endhead", endhead);
1107 (void)getTokenValue(line, "endfirsthead", endfirsthead);
1108 (void)getTokenValue(line, "endfoot", endfoot);
1109 (void)getTokenValue(line, "endlastfoot", endlastfoot);
1111 for(i = 0; i < rows_; ++i) {
1112 l_getline(is, line);
1113 if (!prefixIs(line, "<Row ")) {
1114 lyxerr << "Wrong tabular format (expected <Row ...> got" <<
1115 line << ")" << endl;
1118 (void)getTokenValue(line, "topline", row_info[i].top_line);
1119 (void)getTokenValue(line, "bottomline", row_info[i].bottom_line);
1120 (void)getTokenValue(line, "newpage", row_info[i].newpage);
1121 for (j = 0; j < columns_; ++j) {
1123 if (!prefixIs(line,"<Column")) {
1124 lyxerr << "Wrong tabular format (expected <Column ...> got" <<
1125 line << ")" << endl;
1129 (void)getTokenValue(line, "alignment", column_info[j].alignment);
1130 (void)getTokenValue(line, "leftline", column_info[j].left_line);
1131 (void)getTokenValue(line, "rightline", column_info[j].right_line);
1132 (void)getTokenValue(line, "width", column_info[j].p_width);
1133 (void)getTokenValue(line, "special", column_info[j].align_special);
1135 l_getline(is, line);
1136 if (!prefixIs(line, "<Cell")) {
1137 lyxerr << "Wrong tabular format (expected <Cell ...> got" <<
1138 line << ")" << endl;
1141 (void)getTokenValue(line, "multicolumn", cell_info[i][j].multicolumn);
1142 (void)getTokenValue(line, "alignment", cell_info[i][j].alignment);
1143 (void)getTokenValue(line, "topline", cell_info[i][j].top_line);
1144 (void)getTokenValue(line, "bottomline", cell_info[i][j].bottom_line);
1145 (void)getTokenValue(line, "rotate", cell_info[i][j].rotate);
1146 (void)getTokenValue(line, "linebreaks", cell_info[i][j].linebreaks);
1147 (void)getTokenValue(line, "width", cell_info[i][j].p_width);
1148 (void)getTokenValue(line, "special", cell_info[i][j].align_special);
1149 l_getline(is, line);
1150 if (prefixIs(line, "\\begin_inset")) {
1151 cell_info[i][j].inset->Read(lex);
1152 l_getline(is, line);
1154 if (line != "</Cell>") {
1155 lyxerr << "Wrong tabular format (expected </Cell> got" <<
1156 line << ")" << endl;
1159 l_getline(is, line);
1160 if (line != "</Column>") {
1161 lyxerr << "Wrong tabular format (expected </Column> got" <<
1162 line << ")" << endl;
1166 l_getline(is, line);
1167 if (line != "</Row>") {
1168 lyxerr << "Wrong tabular format (expected </Row> got" <<
1169 line << ")" << endl;
1173 while (line != "</LyXTabular>") {
1174 l_getline(is, line);
1176 set_row_column_number_info();
1179 void LyXTabular::OldFormatRead(istream & is, string fl)
1184 int columns_arg = 0;
1185 int is_long_tabular_arg = false;
1186 int rotate_arg = false;
1199 version = atoi(s.c_str() + 8);
1203 lyxerr << "Tabular format < 5 is not supported anymore\n"
1204 "Get an older version of LyX (< 1.1.x) for conversion!"
1206 WriteAlert(_("Warning:"),
1207 _("Tabular format < 5 is not supported anymore\n"),
1208 _("Get an older version of LyX (< 1.1.x) for conversion!"));
1210 is >> rows_arg >> columns_arg >> is_long_tabular_arg
1211 >> rotate_arg >> a >> b >> c >> d;
1213 is >> rows_arg >> columns_arg;
1214 Init(buffer, rows_arg, columns_arg);
1215 SetLongTabular(is_long_tabular_arg);
1216 SetRotateTabular(rotate_arg);
1218 for (i = 0; i < rows_; ++i) {
1221 for (i = 0; i < columns_; ++i) {
1224 for (i = 0; i < rows_; ++i) {
1225 for (j = 0; j < columns_; ++j) {
1229 set_row_column_number_info();
1232 is >> rows_arg >> columns_arg >> is_long_tabular_arg
1233 >> rotate_arg >> a >> b >> c >> d;
1234 Init(buffer, rows_arg, columns_arg);
1235 SetLongTabular(is_long_tabular_arg);
1236 SetRotateTabular(rotate_arg);
1241 for (i = 0; i < rows_; ++i) {
1242 a = b = c = d = e = f = g = h = 0;
1243 is >> a >> b >> c >> d;
1244 row_info[i].top_line = a;
1245 row_info[i].bottom_line = b;
1246 // row_info[i].is_cont_row = c;
1247 row_info[i].newpage = d;
1249 for (i = 0; i < columns_; ++i) {
1253 char ch; // skip '"'
1255 getline(is, s1, '"');
1256 is >> ch; // skip '"'
1257 getline(is, s2, '"');
1258 column_info[i].alignment = static_cast<char>(a);
1259 column_info[i].left_line = b;
1260 column_info[i].right_line = c;
1261 column_info[i].p_width = s1;
1262 column_info[i].align_special = s2;
1264 for (i = 0; i < rows_; ++i) {
1265 for (j = 0; j < columns_; ++j) {
1268 is >> a >> b >> c >> d >> e >> f >> g;
1270 is >> ch; // skip '"'
1271 getline(is, s1, '"');
1272 is >> ch; // skip '"'
1273 getline(is, s2, '"');
1274 cell_info[i][j].multicolumn = static_cast<char>(a);
1275 cell_info[i][j].alignment = static_cast<char>(b);
1276 cell_info[i][j].top_line = static_cast<char>(c);
1277 cell_info[i][j].bottom_line = static_cast<char>(d);
1278 // cell_info[i][j].has_cont_row = static_cast<bool>(e);
1279 cell_info[i][j].rotate = static_cast<bool>(f);
1280 cell_info[i][j].linebreaks = static_cast<bool>(g);
1281 cell_info[i][j].align_special = s1;
1282 cell_info[i][j].p_width = s2;
1285 set_row_column_number_info();
1289 // cell < 0 will tex the preamble
1290 // returns the number of printed newlines
1291 int LyXTabular::TexEndOfCell(ostream & os, int cell) const
1297 if (IsLastCell(cell)) {
1298 // the very end at the very beginning
1299 if (GetLinebreaks(cell))
1300 os << "\\smallskip{}}";
1301 if (IsMultiColumn(cell))
1303 if (GetRotateCell(cell)) {
1304 os << "\n\\end{sideways}";
1312 while (!IsFirstCellInRow(fcell)) --fcell;
1313 for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
1314 if (BottomLine(fcell + i))
1317 if (tmp == NumberOfCellsInRow(fcell)) {
1321 for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
1322 if (BottomLine(fcell + i)) {
1324 << column_of_cell(fcell + i) + 1
1326 << right_column_of_cell(fcell + i) + 1
1336 if (is_long_tabular)
1337 os << "\\end{longtable}";
1339 os << "\\end{tabular}";
1341 os << "\n\\end{sideways}";
1349 os << "\\begin{sideways}\n";
1352 if (is_long_tabular)
1353 os << "\\begin{longtable}{";
1355 os << "\\begin{tabular}{";
1356 for (i = 0; i < columns_; ++i) {
1357 if (column_info[i].left_line)
1359 if (!column_info[i].align_special.empty()) {
1360 os << column_info[i].align_special;
1361 } else if (!column_info[i].p_width.empty()) {
1363 << column_info[i].p_width
1366 switch (column_info[i].alignment) {
1367 case LYX_ALIGN_LEFT:
1370 case LYX_ALIGN_RIGHT:
1378 if (column_info[i].right_line)
1384 if (GetNumberOfCells()) {
1386 for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
1387 if (TopLine(fcell + i))
1390 if (tmp == NumberOfCellsInRow(fcell)){
1394 for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
1395 if (TopLine(fcell + i)) {
1397 << column_of_cell(fcell + i) + 1
1399 << right_column_of_cell(fcell + i) + 1
1410 if (GetRotateCell(0)) {
1411 os << "\\begin{sideways}\n";
1416 if (GetLinebreaks(cell))
1417 os << "\\smallskip{}}";
1418 if (IsMultiColumn(cell)){
1421 if (GetRotateCell(cell)) {
1422 os << "\n\\end{sideways}";
1425 if (IsLastCellInRow(cell)) {
1426 int row = row_of_cell(cell);
1427 string hline1, hline2;
1428 bool print_hline = true;
1429 bool flag1 = IsLongTabular() &&
1430 ((row == endhead) || (row == endfirsthead) ||
1431 (row == endfoot) || (row == endlastfoot));
1433 bool flag2 = IsLongTabular() &&
1434 ((row <= endhead) || (row <= endfirsthead) ||
1435 (row <= endfoot) || (row <= endlastfoot));
1437 // print the bottom hline only if (otherwise it is doubled):
1438 // - is no LongTabular
1439 // - there IS a first-header
1440 // - the next row is no special header/footer
1441 // & this row is no special header/footer
1442 // - the next row is a special header/footer
1443 // & this row is a special header/footer
1444 bool pr_top_hline = (flag1 && flag2) || (!flag1 && !flag2) ||
1445 (endfirsthead == endhead);
1450 while (!IsFirstCellInRow(fcell))
1452 for (i = 0; i < NumberOfCellsInRow(cell); ++i) {
1453 if (BottomLine(fcell + i))
1456 if (tmp == NumberOfCellsInRow(cell)){
1458 hline1 = "\\hline ";
1461 for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
1462 if (BottomLine(fcell + i)){
1464 << column_of_cell(fcell + i) + 1
1466 << right_column_of_cell(fcell + i) + 1
1468 hline1 += "\\cline{";
1469 hline1 += tostr(column_of_cell(fcell + i) + 1);
1471 hline1 += tostr(right_column_of_cell(fcell + i) + 1);
1481 if (IsLongTabular() && (row == endfoot)) {
1482 os << "\\endfoot\n";
1484 print_hline = false; // no double line below footer
1486 if (IsLongTabular() && (row == endlastfoot)) {
1487 os << "\\endlastfoot\n";
1489 print_hline = false; // no double line below footer
1491 if (IsLongTabular() && row_info[row].newpage) {
1492 os << "\\newpage\n";
1494 print_hline = false; // no line below a \\newpage-command
1497 if ((nvcell < numberofcells) &&
1498 (cell < GetNumberOfCells() - 1) && !IsLastCell(cell)) {
1500 for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
1501 if (TopLine(fcell + i))
1504 if (tmp == NumberOfCellsInRow(fcell)) {
1507 hline2 = "\\hline ";
1510 for (i = 0; i < NumberOfCellsInRow(fcell); ++i) {
1511 if (TopLine(fcell + i)) {
1514 << column_of_cell(fcell + i) + 1
1516 << right_column_of_cell(fcell + i) + 1
1519 hline2 += "\\cline{";
1520 hline2 += tostr(column_of_cell(fcell+i)+1);
1522 hline2 += tostr(right_column_of_cell(fcell+i)+1);
1528 if (tmp && print_hline){
1533 // the order here is important as if one defines two
1534 // or more things in one line only the first entry is
1535 // displayed the other are set to an empty-row. This
1536 // is important if I have a footer and want that the
1537 // lastfooter is NOT displayed!!!
1538 bool sflag2 = (row == endhead) || (row == endfirsthead) ||
1539 (row == endfoot) || (row == endlastfoot);
1542 bool sflag1 = IsLongTabular() && (row != endhead) &&
1543 (row != endfirsthead) &&
1544 ((row == endfoot) || (row == endlastfoot));
1546 if (IsLongTabular() && (row == endhead)) {
1547 os << "\\endhead\n";
1550 if (IsLongTabular() && (row == endfirsthead)) {
1551 os << "\\endfirsthead\n";
1554 if (sflag1) { // add the \hline for next foot row
1555 if (!hline1.empty()) {
1556 os << hline1 + '\n';
1560 // add the \hline for the first row
1561 if (pr_top_hline && sflag2) {
1562 if (!hline2.empty()) {
1563 os << hline2 + '\n';
1567 if (nvcell < numberofcells && GetRotateCell(nvcell)) {
1568 os << "\\begin{sideways}\n";
1574 if (nvcell < numberofcells && GetRotateCell(nvcell)) {
1575 os << "\\begin{sideways}\n";
1580 if (nvcell < numberofcells && IsMultiColumn(nvcell)) {
1581 os << "\\multicolumn{"
1582 << cells_in_multicolumn(nvcell)
1584 if (!cellinfo_of_cell(cell+1)->align_special.empty()) {
1585 os << cellinfo_of_cell(cell+1)->align_special
1588 if (LeftLine(nvcell))
1590 if (!GetPWidth(nvcell).empty()) {
1592 << GetPWidth(nvcell)
1595 switch (GetAlignment(nvcell)) {
1596 case LYX_ALIGN_LEFT: os << 'l'; break;
1597 case LYX_ALIGN_RIGHT: os << 'r'; break;
1598 default: os << 'c'; break;
1601 if (RightLine(nvcell))
1603 //if (column_of_cell(cell+2)!= 0 && LeftLine(cell+2))
1604 if (((nvcell + 1) < numberofcells) &&
1605 ((nvcell+1) < numberofcells) &&
1606 (column_of_cell(nvcell+1)!= 0) &&
1613 if (nvcell < numberofcells && GetLinebreaks(nvcell)) {
1614 os << "\\parbox[t]{"
1615 << GetPWidth(nvcell)
1616 << "}{\\smallskip{}";
1624 // cell <0 will tex the preamble
1625 // returns the number of printed newlines
1626 int LyXTabular::RoffEndOfCell(ostream & os, int cell)
1630 if (cell == GetNumberOfCells() - 1){
1631 // the very end at the very beginning
1632 // if (CellHasContRow(cell) >= 0) {
1638 if (row_info[row_of_cell(cell)].bottom_line) {
1642 os << ".TE\n.pl 1c";
1647 os << "\n.pl 500c\n.TS\n";
1648 for (int j = 0; j < rows_; ++j) {
1649 for (int i = 0; i < columns_; ++i, ++fcell) {
1650 if (column_info[i].left_line)
1652 if (cell_info[j][i].multicolumn == CELL_PART_OF_MULTICOLUMN)
1655 switch (column_info[i].alignment) {
1656 case LYX_ALIGN_LEFT:
1659 case LYX_ALIGN_RIGHT:
1667 if (!column_info[i].p_width.empty())
1668 os << "w(" << column_info[i].p_width << ")";
1669 if (column_info[i].right_line)
1672 if ((j + 1) < rows_) {
1679 if (row_info[0].top_line) {
1683 // if (CellHasContRow(0) >= 0) {
1689 // if (CellHasContRow(cell) >= 0) {
1693 if (right_column_of_cell(cell) == columns_ -1){
1696 int row = row_of_cell(cell);
1697 if (row_info[row++].bottom_line) {
1701 if ((row < rows_) && row_info[row].top_line) {
1707 // if ((cell < GetNumberOfCells() - 1) &&
1708 // (CellHasContRow(cell+1) >= 0)) {
1719 char const *LyXTabular::GetDocBookAlign(int cell, bool isColumn) const
1725 i = column_of_cell(cell);
1726 if (!isColumn && IsMultiColumn(cell)) {
1727 if (!cellinfo_of_cell(cell)->align_special.empty()) {
1728 return cellinfo_of_cell(cell)->align_special.c_str();
1730 switch (GetAlignment(cell)) {
1731 case LYX_ALIGN_LEFT:
1733 case LYX_ALIGN_RIGHT:
1740 if (!column_info[i].align_special.empty()) {
1741 return column_info[i].align_special.c_str();
1743 #ifdef IGNORE_THIS_FOR_NOW
1744 else if (!column_info[i].p_width.empty()) {
1746 file += column_info[i].p_width;
1751 switch (column_info[i].alignment) {
1752 case LYX_ALIGN_LEFT:
1754 case LYX_ALIGN_RIGHT:
1764 // cell <0 will tex the preamble
1765 // returns the number of printed newlines
1766 int LyXTabular::DocBookEndOfCell(ostream & os, int cell, int & depth) const
1770 //int tmp; // tmp2; //Â unused
1771 int nvcell; // fcell; //Â unused
1772 if (IsLastCell(cell)) {
1773 os << newlineAndDepth(--depth)
1775 << newlineAndDepth(--depth)
1777 << newlineAndDepth(--depth)
1779 << newlineAndDepth(--depth);
1780 if (is_long_tabular)
1784 << newlineAndDepth(--depth);
1790 if (is_long_tabular)
1796 << "' COLSEP='1' ROWSEP='1'>"
1797 << newlineAndDepth(++depth);
1799 for (i = 0; i < columns_; ++i) {
1800 os << "<COLSPEC ALIGN='"
1801 << GetDocBookAlign(i, true)
1807 if (i == (columns_-1)) {
1810 if (column_info[i].right_line ||
1811 column_info[i+1].left_line)
1817 << newlineAndDepth(depth);
1819 #ifdef NOT_HANDLED_YET_AS_I_DONT_KNOW_HOW
1820 if (column_info[i].left_line)
1825 << newlineAndDepth(++depth)
1827 << newlineAndDepth(++depth)
1829 << GetDocBookAlign(0)
1831 if (IsMultiColumn(0)) {
1832 os << " NAMEST='col1' NAMEEND='col"
1833 << cells_in_multicolumn(0)
1837 << newlineAndDepth(++depth);
1840 if (IsLastCellInRow(cell)) {
1841 os << newlineAndDepth(--depth)
1843 << newlineAndDepth(--depth)
1845 << newlineAndDepth(depth)
1847 << newlineAndDepth(++depth)
1849 << GetDocBookAlign(cell + 1)
1850 << "' VALIGN='middle'";
1851 if (IsMultiColumn(cell + 1)) {
1852 os << " NAMEST='col"
1853 << column_of_cell(cell+1) + 1
1855 << column_of_cell(cell + 1) +
1856 cells_in_multicolumn(cell + 1)
1860 << newlineAndDepth(++depth);
1863 os << newlineAndDepth(--depth)
1865 << newlineAndDepth(depth)
1867 << GetDocBookAlign(cell + 1)
1868 << "' VALIGN='middle'";
1869 if (IsMultiColumn(cell + 1)) {
1870 os << " NAMEST='col"
1871 << column_of_cell(cell+1) + 1
1873 << column_of_cell(cell+1) +
1874 cells_in_multicolumn(cell+1)
1878 << newlineAndDepth(++depth);
1887 bool LyXTabular::IsMultiColumn(int cell) const
1889 return (cellinfo_of_cell(cell)->multicolumn != LyXTabular::CELL_NORMAL);
1893 LyXTabular::cellstruct* LyXTabular::cellinfo_of_cell(int cell) const
1895 int row = row_of_cell(cell);
1896 int column = column_of_cell(cell);
1897 return &cell_info[row][column];
1901 void LyXTabular::SetMultiColumn(int cell, int number)
1903 int new_width = cellinfo_of_cell(cell)->width_of_cell;
1905 cellinfo_of_cell(cell)->multicolumn = LyXTabular::CELL_BEGIN_OF_MULTICOLUMN;
1906 cellinfo_of_cell(cell)->alignment = column_info[column_of_cell(cell)].alignment;
1907 cellinfo_of_cell(cell)->top_line = row_info[row_of_cell(cell)].top_line;
1908 cellinfo_of_cell(cell)->bottom_line = row_info[row_of_cell(cell)].bottom_line;
1909 for (number--; number > 0; --number) {
1910 cellinfo_of_cell(cell+number)->multicolumn =
1911 LyXTabular::CELL_PART_OF_MULTICOLUMN;
1912 new_width += cellinfo_of_cell(cell+number)->width_of_cell;
1914 set_row_column_number_info();
1915 SetWidthOfCell(cell, new_width);
1919 int LyXTabular::cells_in_multicolumn(int cell) const
1921 int row = row_of_cell(cell);
1922 int column = column_of_cell(cell);
1925 while (column < columns_ && cell_info[row][column].multicolumn
1926 == LyXTabular::CELL_PART_OF_MULTICOLUMN){
1934 int LyXTabular::UnsetMultiColumn(int cell)
1936 int row = row_of_cell(cell);
1937 int column = column_of_cell(cell);
1941 if (cell_info[row][column].multicolumn
1942 == LyXTabular::CELL_BEGIN_OF_MULTICOLUMN){
1943 cell_info[row][column].multicolumn = LyXTabular::CELL_NORMAL;
1945 while (column < columns_ &&
1946 cell_info[row][column].multicolumn
1947 == LyXTabular::CELL_PART_OF_MULTICOLUMN){
1948 cell_info[row][column].multicolumn =
1949 LyXTabular::CELL_NORMAL;
1954 set_row_column_number_info();
1959 void LyXTabular::SetLongTabular(int what)
1961 is_long_tabular = what;
1965 bool LyXTabular::IsLongTabular() const
1967 return is_long_tabular;
1970 void LyXTabular::SetRotateTabular(int what)
1975 bool LyXTabular::GetRotateTabular() const
1980 void LyXTabular::SetRotateCell(int cell, int what)
1982 cellinfo_of_cell(cell)->rotate = what;
1985 bool LyXTabular::GetRotateCell(int cell) const
1987 return cellinfo_of_cell(cell)->rotate;
1990 bool LyXTabular::NeedRotating() const
1994 for (int i = 0; i < rows_; ++i) {
1995 for (int j = 0; j < columns_; ++j) {
1996 if (cell_info[i][j].rotate)
2004 bool LyXTabular::IsLastCell(int cell) const
2006 if (cell < GetNumberOfCells())
2011 int LyXTabular::GetCellAbove(int cell) const
2013 if (row_of_cell(cell) > 0)
2014 return cell_info[row_of_cell(cell)-1][column_of_cell(cell)].cellno;
2018 int LyXTabular::GetCellNumber(int column, int row) const
2020 if (column >= columns_)
2021 column = columns_ - 1;
2022 else if (column < 0)
2029 return cell_info[row][column].cellno;
2032 void LyXTabular::SetLinebreaks(int cell, bool what)
2034 cellinfo_of_cell(cell)->linebreaks = what;
2037 bool LyXTabular::GetLinebreaks(int cell) const
2039 if (column_info[column_of_cell(cell)].p_width.empty() &&
2040 !(IsMultiColumn(cell) && !cellinfo_of_cell(cell)->p_width.empty()))
2042 return cellinfo_of_cell(cell)->linebreaks;
2045 void LyXTabular::SetLTHead(int cell, bool first)
2047 int row = row_of_cell(cell);
2050 if (row == endfirsthead)
2062 bool LyXTabular::GetRowOfLTHead(int cell) const
2064 if ((endhead+1) > rows_)
2066 return (row_of_cell(cell) == endhead);
2069 bool LyXTabular::GetRowOfLTFirstHead(int cell) const
2071 if ((endfirsthead+1) > rows_)
2073 return (row_of_cell(cell) == endfirsthead);
2076 void LyXTabular::SetLTFoot(int cell, bool last)
2078 int row = row_of_cell(cell);
2081 if (row == endlastfoot)
2093 bool LyXTabular::GetRowOfLTFoot(int cell) const
2095 if ((endfoot+1) > rows_)
2097 return (row_of_cell(cell) == endfoot);
2100 bool LyXTabular::GetRowOfLTLastFoot(int cell) const
2102 if ((endlastfoot+1) > rows_)
2104 return (row_of_cell(cell) == endlastfoot);
2107 void LyXTabular::SetLTNewPage(int cell, bool what)
2109 row_info[row_of_cell(cell)].newpage = what;
2112 bool LyXTabular::GetLTNewPage(int cell) const
2114 return row_info[row_of_cell(cell)].newpage;
2117 void LyXTabular::SetAscentOfRow(int row, int height)
2121 row_info[row].ascent_of_row = height;
2124 void LyXTabular::SetDescentOfRow(int row, int height)
2128 row_info[row].descent_of_row = height;
2131 int LyXTabular::GetAscentOfRow(int row) const
2135 return row_info[row].ascent_of_row;
2138 int LyXTabular::GetDescentOfRow(int row) const
2142 return row_info[row].descent_of_row;
2145 int LyXTabular::GetHeightOfTabular() const
2151 for(row=0,height=0;(row<rows_); ++row)
2152 height += GetAscentOfRow(row) + GetDescentOfRow(row) +
2153 GetAdditionalHeight(GetCellNumber(0,row));
2157 bool LyXTabular::IsPartOfMultiColumn(int row, int column) const
2159 if ((row >= rows_) || (column >= columns_))
2161 return (cell_info[row][column].multicolumn==CELL_PART_OF_MULTICOLUMN);
2164 int LyXTabular::Latex(ostream &) const
2169 InsetText * LyXTabular::GetCellInset(int cell) const
2171 return cell_info[row_of_cell(cell)][column_of_cell(cell)].inset;