#include "frontends/Painter.h"
#include "frontends/Selection.h"
-#include "support/lassert.h"
#include "support/convert.h"
#include "support/debug.h"
#include "support/docstream.h"
#include "support/FileName.h"
#include "support/gettext.h"
+#include "support/lassert.h"
#include "support/lstrings.h"
#include <boost/scoped_ptr.hpp>
/////////////////////////////////////////////////////////////////////
-Tabular::CellData::CellData(Buffer const & buf, Tabular const & table)
+Tabular::CellData::CellData(Buffer & buf)
: cellno(0),
width(0),
multicolumn(Tabular::CELL_NORMAL),
right_line(false),
usebox(BOX_NONE),
rotate(false),
- inset(new InsetTableCell(buf, this, &table))
+ inset(new InsetTableCell(buf))
{
inset->setBuffer(const_cast<Buffer &>(buf));
inset->paragraphs().back().setLayout(buf.params().documentClass().emptyLayout());
p_width(cs.p_width),
inset(dynamic_cast<InsetTableCell *>(cs.inset->clone()))
{
- inset->setCellData(this);
}
-
Tabular::CellData & Tabular::CellData::operator=(CellData cs)
{
swap(cs);
return *this;
}
-
void Tabular::CellData::swap(CellData & rhs)
{
std::swap(cellno, rhs.cellno);
{}
-Tabular::Tabular(Buffer const & buffer, row_type rows_arg, col_type columns_arg)
+Tabular::Tabular(Buffer & buffer, row_type rows_arg, col_type columns_arg)
{
init(buffer, rows_arg, columns_arg);
}
+void Tabular::setBuffer(Buffer & buffer)
+{
+ buffer_ = &buffer;
+ size_t row_count = row_info.size();
+ size_t column_count = column_info.size();
+ // set silly default lines
+ for (row_type i = 0; i < row_count; ++i)
+ for (col_type j = 0; j < column_count; ++j)
+ cell_info[i][j].inset->setBuffer(*buffer_);
+}
+
+
// activates all lines and sets all widths to 0
-void Tabular::init(Buffer const & buf, row_type rows_arg,
+void Tabular::init(Buffer & buf, row_type rows_arg,
col_type columns_arg)
{
buffer_ = &buf;
row_info = row_vector(rows_arg);
column_info = column_vector(columns_arg);
- cell_info = cell_vvector(rows_arg, cell_vector(columns_arg, CellData(buf, *this)));
+ cell_info = cell_vvector(rows_arg, cell_vector(columns_arg, CellData(buf)));
row_info.reserve(10);
column_info.reserve(10);
cell_info.reserve(100);
// set silly default lines
for (row_type i = 0; i < row_count; ++i)
for (col_type j = 0; j < column_count; ++j) {
+ cell_info[i][j].inset->setBuffer(*buffer_);
cell_info[i][j].top_line = true;
cell_info[i][j].left_line = true;
cell_info[i][j].bottom_line = i == 0 || i == row_count - 1;
for (row_type i = 0; i < nrows - 1; ++i)
swap(cell_info[i], old[i]);
- cell_info = cell_vvector(nrows, cell_vector(ncols, CellData(buffer(), *this)));
+ cell_info = cell_vvector(nrows, cell_vector(ncols, CellData(buffer())));
for (row_type i = 0; i <= row; ++i)
swap(cell_info[i], old[i]);
for (row_type r = 0; r < nrows; ++r) {
cell_info[r].insert(cell_info[r].begin() + c + 1,
- CellData(buffer(), *this));
+ CellData(buffer()));
if (cell_info[r][c].multicolumn == CELL_BEGIN_OF_MULTICOLUMN)
cell_info[r][c + 1].multicolumn = CELL_PART_OF_MULTICOLUMN;
else
continue;
rowofcell[i] = row;
columnofcell[i] = column;
+ setFixedWidth(row, column);
++i;
}
}
void toggleFixedWidth(Cursor & cur, InsetTableCell * inset, bool fixedWidth)
{
inset->setAutoBreakRows(fixedWidth);
+ inset->toggleFixedWidth(fixedWidth);
if (fixedWidth)
return;
}
+bool Tabular::setFixedWidth(row_type r, col_type c)
+{
+ if (!column_info[c].p_width.zero() ||
+ (cell_info[r][c].multicolumn != CELL_NORMAL &&
+ !cell_info[r][c].p_width.zero())) {
+ cell_info[r][c].inset->toggleFixedWidth(true);
+ return true;
+ }
+ return false;
+}
+
+
bool Tabular::setMColumnPWidth(Cursor & cur, idx_type cell,
Length const & width)
{
bool Tabular::columnLeftLine(col_type c) const
{
+ if (use_booktabs)
+ return false;
+
int nrows_left = 0;
int total = 0;
row_type const nrows = row_info.size();
++nrows_left;
}
}
- return nrows_left >= total / 2;
+ return 2 * nrows_left >= total;
}
bool Tabular::columnRightLine(col_type c) const
{
+ if (use_booktabs)
+ return false;
+
int nrows_right = 0;
int total = 0;
row_type const nrows = row_info.size();
++nrows_right;
}
}
- return nrows_right >= total / 2;
+ return 2 * nrows_right >= total;
}
if (cell >= numberofcells)
return column_info.size() - 1;
if (cell == npos)
- return 0;
+ return 0;
return columnofcell[cell];
}
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);
+ setFixedWidth(i,j);
getTokenValue(line, "special", cell_info[i][j].align_special);
l_getline(is, line);
if (prefixIs(line, "\\begin_inset")) {
+ cell_info[i][j].inset->setBuffer(*buffer_);
cell_info[i][j].inset->read(lex);
l_getline(is, line);
}
}
+// FIXME: Remove this routine because we cannot insert \parboxes when the user
+// adds line breaks, see bug 4886.
Tabular::BoxType Tabular::getUsebox(idx_type cell) const
{
- if (column_info[cellColumn(cell)].p_width.zero() &&
- !(isMultiColumn(cell) && !cellInfo(cell).p_width.zero()))
+ if ((!column_info[cellColumn(cell)].p_width.zero() && !isMultiColumn(cell)) ||
+ (isMultiColumn(cell) && !cellInfo(cell).p_width.zero()))
return BOX_NONE;
if (cellInfo(cell).usebox > 1)
return cellInfo(cell).usebox;
col_type const nextcol = c + columnSpan(cell);
bool colright = columnRightLine(c);
bool colleft = columnLeftLine(c);
- bool nextcolleft = nextcol < column_info.size() && colleft;
+ bool nextcolleft = nextcol < column_info.size() && columnLeftLine(nextcol);
bool nextcellleft = nextcol < column_info.size()
&& leftLine(cellIndex(r, nextcol));
bool coldouble = colright && nextcolleft;
bool celldouble = rightLine(cell) && nextcellleft;
- bool prevcellright = c > 0 && rightLine(cellIndex(r, c - 1));
ismulticol = isMultiColumn(cell)
|| (c == 0 && colleft != leftLine(cell))
|| ((colright || nextcolleft) && !rightLine(cell) && !nextcellleft)
|| (coldouble != celldouble);
if (ismulticol) {
os << "\\multicolumn{" << columnSpan(cell) << "}{";
- if (leftLine(cell) || prevcellright)
+ if (c ==0 && leftLine(cell))
os << '|';
if (!cellInfo(cell).align_special.empty()) {
os << cellInfo(cell).align_special;
os << "\\begin{tabular}{";
for (col_type i = 0; i < column_info.size(); ++i) {
- if (!use_booktabs && columnLeftLine(i))
+ if (columnLeftLine(i))
os << '|';
if (!column_info[i].align_special.empty()) {
os << column_info[i].align_special;
}
} // end if else !column_info[i].p_width
} // end if else !column_info[i].align_special
- if (!use_booktabs && columnRightLine(i))
+ if (columnRightLine(i))
os << '|';
}
os << "}\n";
{
CellData & cd = cell_info[row][column];
cd.inset = ins;
- // reset the InsetTableCell's pointers
- ins->setCellData(&cd);
- ins->setTabular(this);
-}
-
-
-Tabular::idx_type Tabular::cellFromInset(Inset const * inset) const
-{
- // is this inset part of the tabular?
- if (!inset) {
- lyxerr << "Error: this is not a cell of the tabular!" << endl;
- LASSERT(false, /**/);
- }
-
- for (idx_type cell = 0, n = numberofcells; cell < n; ++cell)
- if (cellInset(cell).get() == inset) {
- LYXERR(Debug::INSETTEXT, "Tabular::cellFromInset: "
- << "cell=" << cell);
- return cell;
- }
-
- // We should have found a cell at this point
- lyxerr << "Tabular::cellFromInset: Cell of inset "
- << inset << " not found!" << endl;
- LASSERT(false, /**/);
- // shut up compiler
- return 0;
}
//
/////////////////////////////////////////////////////////////////////
-InsetTableCell::InsetTableCell(Buffer const & buf,
- Tabular::CellData const * cell, Tabular const * table)
- : InsetText(buf), cell_data_(cell), table_(table)
+InsetTableCell::InsetTableCell(Buffer & buf)
+ : InsetText(buf), isFixedWidth(false)
{}
-bool InsetTableCell::forceEmptyLayout(idx_type) const
+bool InsetTableCell::forcePlainLayout(idx_type) const
{
- LASSERT(table_, /**/);
- LASSERT(cell_data_, /**/);
- return table_->getPWidth(cell_data_->cellno).zero();
+ return !isFixedWidth;
}
bool InsetTableCell::allowParagraphCustomization(idx_type) const
{
- LASSERT(table_, /**/);
- LASSERT(cell_data_, /**/);
- return !table_->getPWidth(cell_data_->cellno).zero();
+ return isFixedWidth;
}
bool InsetTableCell::getStatus(Cursor & cur, FuncRequest const & cmd,
bool enabled;
switch (cmd.action) {
case LFUN_LAYOUT:
- enabled = !forceEmptyLayout();
+ enabled = !forcePlainLayout();
break;
case LFUN_LAYOUT_PARAGRAPH:
enabled = allowParagraphCustomization();
default:
return InsetText::getStatus(cur, cmd, status);
}
- status.enabled(enabled);
+ status.setEnabled(enabled);
return true;
}
//
/////////////////////////////////////////////////////////////////////
-InsetTabular::InsetTabular(Buffer const & buf, row_type rows,
+InsetTabular::InsetTabular(Buffer & buf, row_type rows,
col_type columns)
: tabular(buf, max(rows, row_type(1)), max(columns, col_type(1))), scx_(0),
rowselect_(false), colselect_(false)
{
- setBuffer(const_cast<Buffer &>(buf)); // FIXME: remove later
+ setBuffer(buf); // FIXME: remove later
}
InsetTabular::InsetTabular(InsetTabular const & tab)
: Inset(tab), tabular(tab.tabular), scx_(0)
{
- setBuffer(const_cast<Buffer &>(tab.buffer())); // FIXME: remove later
}
}
case LFUN_PASTE:
- if (tabularStackDirty() && theClipboard().isInternal() ||
+ if (!tabularStackDirty()) {
+ cell(cur.idx())->dispatch(cur, cmd);
+ break;
+ }
+ if (theClipboard().isInternal() ||
!theClipboard().hasInternal() && theClipboard().hasLyXContents()) {
cur.recordUndoInset(INSERT_UNDO);
pasteClipboard(cur);
- break;
}
- cell(cur.idx())->dispatch(cur, cmd);
break;
case LFUN_FONT_EMPH:
case LFUN_FONT_FRAK:
case LFUN_FONT_TYPEWRITER:
case LFUN_FONT_SANS:
- case LFUN_FONT_FREE_APPLY:
- case LFUN_FONT_FREE_UPDATE:
+ case LFUN_TEXTSTYLE_APPLY:
+ case LFUN_TEXTSTYLE_UPDATE:
case LFUN_FONT_SIZE:
case LFUN_FONT_UNDERLINE:
case LFUN_LANGUAGE:
return true;
case Tabular::MULTICOLUMN:
- status.enabled(sel_row_start == sel_row_end);
+ status.setEnabled(sel_row_start == sel_row_end);
status.setOnOff(tabular.isMultiColumn(cur.idx()));
break;
case Tabular::SET_ALL_LINES:
case Tabular::UNSET_ALL_LINES:
case Tabular::SET_BORDER_LINES:
- status.enabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
+ status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
break;
case Tabular::TOGGLE_LINE_TOP:
- status.enabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
+ status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
status.setOnOff(tabular.topLine(cur.idx()));
break;
case Tabular::TOGGLE_LINE_BOTTOM:
- status.enabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
+ status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
status.setOnOff(tabular.bottomLine(cur.idx()));
break;
case Tabular::TOGGLE_LINE_LEFT:
- status.enabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
+ status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
status.setOnOff(tabular.leftLine(cur.idx()));
break;
case Tabular::TOGGLE_LINE_RIGHT:
- status.enabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
+ status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
status.setOnOff(tabular.rightLine(cur.idx()));
break;
break;
case Tabular::ALIGN_BLOCK:
- status.enabled(!tabular.getPWidth(cur.idx()).zero());
+ status.setEnabled(!tabular.getPWidth(cur.idx()).zero());
status.setOnOff(tabular.getAlignment(cur.idx(), flag) == LYX_ALIGN_BLOCK);
break;
break;
case Tabular::TOGGLE_LTCAPTION:
- status.enabled(sel_row_start == sel_row_end);
+ status.setEnabled(sel_row_start == sel_row_end);
status.setOnOff(tabular.ltCaption(sel_row_start));
break;
default:
status.clear();
- status.enabled(false);
+ status.setEnabled(false);
break;
}
return true;
// These are only enabled inside tabular
case LFUN_CELL_BACKWARD:
case LFUN_CELL_FORWARD:
- status.enabled(true);
+ status.setEnabled(true);
return true;
// disable these with multiple cells selected
case LFUN_WRAP_INSERT:
case LFUN_ERT_INSERT: {
if (tablemode(cur)) {
- status.enabled(false);
+ status.setEnabled(false);
return true;
} else
return cell(cur.idx())->getStatus(cur, cmd, status);
// disable in non-fixed-width cells
case LFUN_NEWLINE_INSERT:
- case LFUN_BREAK_PARAGRAPH:
- case LFUN_BREAK_PARAGRAPH_SKIP: {
+ case LFUN_BREAK_PARAGRAPH: {
if (tabular.getPWidth(cur.idx()).zero()) {
- status.enabled(false);
+ status.setEnabled(false);
return true;
} else
return cell(cur.idx())->getStatus(cur, cmd, status);
case LFUN_PASTE:
if (tabularStackDirty() && theClipboard().isInternal()) {
- status.enabled(true);
+ status.setEnabled(true);
return true;
} else
return cell(cur.idx())->getStatus(cur, cmd, status);
case LFUN_INSET_MODIFY:
if (insetCode(cmd.getArg(0)) == TABULAR_CODE) {
- status.enabled(true);
+ status.setEnabled(true);
return true;
}
// Fall through
while (paste_tabular->column_info.size() > columns)
paste_tabular->deleteColumn(columns);
- // We clear all the InsetTableCell pointers, since they
- // might now become invalid and there is no point in having
- // them point to temporary things in paste_tabular.
- for (row_type i = 0; i < paste_tabular->row_info.size(); ++i)
- for (col_type j = 0; j < paste_tabular->column_info.size(); ++j) {
- paste_tabular->cellInset(i,j)->setCellData(0);
- paste_tabular->cellInset(i,j)->setTabular(0);
- }
+ paste_tabular->setBuffer(tabular.buffer());
odocstringstream os;
OutputParams const runparams(0);
}
shared_ptr<InsetTableCell> inset(
new InsetTableCell(*paste_tabular->cellInset(r1, c1)));
- // note that setCellInset will call InsetTableCell::setCellData()
- // and InsetTableCell::setTabular()
tabular.setCellInset(r2, c2, inset);
// FIXME: change tracking (MG)
inset->setChange(Change(cur.buffer().params().trackChanges ?
}
-bool InsetTabular::forceEmptyLayout(idx_type cell) const
+bool InsetTabular::forcePlainLayout(idx_type cell) const
{
return !tabular.getPWidth(cell).zero();
}