#include "buffer.h"
#include "bufferparams.h"
+#include "BufferView.h"
+#include "cursor.h"
#include "debug.h"
#include "LaTeXFeatures.h"
#include "lyxlex.h"
#include "outputparams.h"
#include "paragraph.h"
+#include "paragraph_funcs.h"
#include "insets/insettabular.h"
LyXTabular::LyXTabular(BufferParams const & bp, row_type rows_arg,
- col_type columns_arg)
+ col_type columns_arg)
{
init(bp, rows_arg, columns_arg);
}
// activates all lines and sets all widths to 0
void LyXTabular::init(BufferParams const & bp, row_type rows_arg,
- col_type columns_arg)
+ col_type columns_arg)
{
rows_ = rows_arg;
columns_ = columns_arg;
}
//++column;
for (row_type i = 0; i < rows_; ++i) {
- cell_info[i][column + 1].inset->clear(false);
+ cell_info[i][column + 1].inset->clear();
if (bp.tracking_changes)
cell_info[i][column + 1].inset->markNew(true);
}
// 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))
+ if (columns_ < 2 || column > (columns_ - 2))
return;
- for(row_type row = 0; row < rows_; ++row) {
+ for (row_type 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
void LyXTabular::setAlignment(idx_type cell, LyXAlignment align,
- bool onlycolumn)
+ bool onlycolumn)
{
if (!isMultiColumn(cell) || onlycolumn)
column_info[column_of_cell(cell)].alignment = align;
void LyXTabular::setVAlignment(idx_type cell, VAlignment align,
- bool onlycolumn)
+ bool onlycolumn)
{
if (!isMultiColumn(cell) || onlycolumn)
column_info[column_of_cell(cell)].valignment = align;
}
-void LyXTabular::setColumnPWidth(idx_type cell, LyXLength const & width)
+namespace {
+
+/**
+ * Allow line and paragraph breaks for fixed width cells or disallow them,
+ * merge cell paragraphs and reset layout to standard for variable width
+ * cells.
+ */
+void toggleFixedWidth(LCursor & cur, InsetText * inset, bool fixedWidth)
+{
+ inset->setAutoBreakRows(fixedWidth);
+ if (fixedWidth)
+ return;
+
+ // merge all paragraphs to one
+ BufferParams const & bp =
+ inset->getText(0)->bv_owner->buffer()->params();
+ while (inset->paragraphs().size() > 1)
+ mergeParagraph(bp, inset->paragraphs(), 0);
+
+ // reset layout
+ cur.push(*inset);
+ // undo information has already been recorded
+ inset->getText(0)->setLayout(0, cur.lastpit() + 1,
+ bp.getLyXTextClass().defaultLayoutName());
+ cur.pop();
+}
+
+}
+
+
+void LyXTabular::setColumnPWidth(LCursor & cur, idx_type cell,
+ LyXLength const & width)
{
col_type const j = column_of_cell(cell);
for (row_type i = 0; i < rows_; ++i) {
idx_type const cell = getCellNumber(i, j);
// because of multicolumns
- getCellInset(cell)->setAutoBreakRows(!getPWidth(cell).zero());
+ toggleFixedWidth(cur, getCellInset(cell).get(),
+ !getPWidth(cell).zero());
}
+ // cur paragraph can become invalid after paragraphs were merged
+ if (cur.pit() > cur.lastpit())
+ cur.pit() = cur.lastpit();
+ // cur position can become invalid after newlines were removed
+ if (cur.pos() > cur.lastpos())
+ cur.pos() = cur.lastpos();
}
-bool LyXTabular::setMColumnPWidth(idx_type cell, LyXLength const & width)
+bool LyXTabular::setMColumnPWidth(LCursor & cur, idx_type cell,
+ LyXLength const & width)
{
if (!isMultiColumn(cell))
return false;
cellinfo_of_cell(cell).p_width = width;
- getCellInset(cell)->setAutoBreakRows(!width.zero());
+ toggleFixedWidth(cur, getCellInset(cell).get(), !width.zero());
+ // cur paragraph can become invalid after paragraphs were merged
+ if (cur.pit() > cur.lastpit())
+ cur.pit() = cur.lastpit();
+ // cur position can become invalid after newlines were removed
+ if (cur.pos() > cur.lastpos())
+ cur.pos() = cur.lastpos();
return true;
}
void LyXTabular::setMultiColumn(Buffer * buffer, idx_type cell,
- idx_type number)
+ idx_type number)
{
cellstruct & cs = cellinfo_of_cell(cell);
cs.multicolumn = CELL_BEGIN_OF_MULTICOLUMN;
cs.alignment = column_info[column_of_cell(cell)].alignment;
cs.top_line = row_info[row_of_cell(cell)].top_line;
cs.bottom_line = row_info[row_of_cell(cell)].bottom_line;
+ cs.left_line = column_info[column_of_cell(cell)].left_line;
cs.right_line = column_info[column_of_cell(cell+number-1)].right_line;
for (idx_type i = 1; i < number; ++i) {
cellstruct & cs1 = cellinfo_of_cell(cell + i);
cs1.multicolumn = CELL_PART_OF_MULTICOLUMN;
cs.inset->appendParagraphs(buffer, cs1.inset->paragraphs());
- cs1.inset->clear(false);
+ cs1.inset->clear();
}
set_row_column_number_info();
}
LyXTabular::idx_type LyXTabular::getCellNumber(row_type row,
- col_type column) const
+ col_type column) const
{
BOOST_ASSERT(column != npos && column < columns_ &&
- row != npos && row < rows_);
+ row != npos && row < rows_);
return cell_info[row][column].cellno;
}
// This are functions used for the longtable support
///
void LyXTabular::setLTHead(row_type row, bool flag, ltType const & hd,
- bool first)
+ bool first)
{
if (first) {
endfirsthead = hd;
void LyXTabular::setLTFoot(row_type row, bool flag, ltType const & fd,
- bool last)
+ bool last)
{
if (last) {
endlastfoot = fd;
shared_ptr<InsetText> LyXTabular::getCellInset(row_type row,
- col_type column) const
+ col_type column) const
{
return cell_info[row][column].inset;
}
}
-void LyXTabular::getLabelList(Buffer const & buffer,
- std::vector<string> & list) const
-{
- for (row_type i = 0; i < rows_; ++i)
- for (col_type j = 0; j < columns_; ++j)
- getCellInset(i, j)->getLabelList(buffer, list);
-}
-
-
LyXTabular::BoxType LyXTabular::useParbox(idx_type cell) const
{
ParagraphList const & parlist = getCellInset(cell)->paragraphs();