#include "Paragraph.h"
#include "ParagraphParameters.h"
#include "ParIterator.h"
+#include "TexRow.h"
+#include "texstream.h"
#include "TextClass.h"
#include "TextMetrics.h"
#include "support/gettext.h"
#include "support/lassert.h"
#include "support/lstrings.h"
-
-#include <boost/scoped_ptr.hpp>
+#include "support/unique_ptr.h"
#include <cstring>
#include <iostream>
///
-boost::scoped_ptr<Tabular> paste_tabular;
+unique_ptr<Tabular> paste_tabular;
struct TabularFeature {
{
// the SET/UNSET actions are used by the table dialog,
// the TOGGLE actions by the table toolbar buttons
+ // FIXME: these values have been hardcoded in InsetMathGrid and other
+ // math insets.
{ Tabular::APPEND_ROW, "append-row", false },
{ Tabular::APPEND_COLUMN, "append-column", false },
{ Tabular::DELETE_ROW, "delete-row", false },
}
-DocIterator separatorPos(InsetTableCell * cell, docstring const & align_d)
+DocIterator separatorPos(InsetTableCell const * cell, docstring const & align_d)
{
DocIterator dit = doc_iterator_begin(&(cell->buffer()), cell);
for (; dit; dit.forwardChar())
dpoint = from_utf8(lyxrc.default_decimal_point);
} else {
cellInfo(cell).alignment = align;
- cellInset(cell).get()->setContentAlignment(align);
+ cellInset(cell)->setContentAlignment(align);
}
}
}
-Tabular::CellData & Tabular::cellInfo(idx_type cell) const
+Tabular::CellData const & Tabular::cellInfo(idx_type cell) const
+{
+ return cell_info[cellRow(cell)][cellColumn(cell)];
+}
+
+
+Tabular::CellData & Tabular::cellInfo(idx_type cell)
{
return cell_info[cellRow(cell)][cellColumn(cell)];
}
// we center in multicol when no decimal point
if (column_info[c].alignment == LYX_ALIGN_DECIMAL) {
docstring const align_d = column_info[c].decimal_point;
- DocIterator const dit = separatorPos(cellInset(cell).get(), align_d);
+ DocIterator const dit = separatorPos(cellInset(cell), align_d);
ismulticol |= !dit;
}
OutputParams const & runparams) const
{
idx_type cell = cellIndex(row, 0);
- shared_ptr<InsetTableCell> inset = cellInset(cell);
+ InsetTableCell const * inset = cellInset(cell);
Paragraph const & par = inset->paragraphs().front();
string const lang = par.getParLanguage(buffer().params())->lang();
}
TeXCellPreamble(os, cell, ismulticol, ismultirow);
- shared_ptr<InsetTableCell> inset = cellInset(cell);
+ InsetTableCell const * inset = cellInset(cell);
Paragraph const & par = inset->paragraphs().front();
if (getAlignment(cell) == LYX_ALIGN_DECIMAL) {
// copy cell and split in 2
- InsetTableCell head = InsetTableCell(*cellInset(cell).get());
- head.setBuffer(buffer());
+ InsetTableCell head = InsetTableCell(*cellInset(cell));
+ head.setBuffer(const_cast<Buffer &>(buffer()));
DocIterator dit = cellInset(cell)->getText(0)->macrocontextPosition();
dit.pop_back();
dit.push_back(CursorSlice(head));
void Tabular::latex(otexstream & os, OutputParams const & runparams) const
{
bool const is_tabular_star = !tabular_width.zero();
- TexRow::RowEntry pos = TexRow::textEntry(runparams.lastid,
- runparams.lastpos);
+ RowEntry pos = TexRow::textEntry(runparams.lastid, runparams.lastpos);
//+---------------------------------------------------------------------
//+ first the opening preamble +
continue;
stringstream attr;
+
+ Length const cwidth = column_info[c].p_width;
+ if (!cwidth.zero()) {
+ string const hwidth = cwidth.asHTMLString();
+ attr << "style =\"width: " << hwidth << ";\" ";
+ }
+
attr << "align='";
switch (getAlignment(cell)) {
case LYX_ALIGN_LEFT:
else if (isMultiRow(cell))
attr << " rowspan='" << rowSpan(cell) << "'";
- xs << html::StartTag(celltag, attr.str()) << html::CR();
+ xs << html::StartTag(celltag, attr.str(), true) << html::CR();
ret += cellInset(cell)->xhtml(xs, runparams);
xs << html::EndTag(celltag) << html::CR();
++cell;
}
-shared_ptr<InsetTableCell> Tabular::cellInset(idx_type cell) const
+shared_ptr<InsetTableCell> Tabular::cellInset(idx_type cell)
{
return cell_info[cellRow(cell)][cellColumn(cell)].inset;
}
-shared_ptr<InsetTableCell> Tabular::cellInset(row_type row,
- col_type column) const
+shared_ptr<InsetTableCell> Tabular::cellInset(row_type row, col_type column)
{
return cell_info[row][column].inset;
}
+InsetTableCell const * Tabular::cellInset(idx_type cell) const
+{
+ return cell_info[cellRow(cell)][cellColumn(cell)].inset.get();
+}
+
+
void Tabular::setCellInset(row_type row, col_type column,
- shared_ptr<InsetTableCell> ins) const
+ shared_ptr<InsetTableCell> ins)
{
CellData & cd = cell_info[row][column];
cd.inset = ins;
{
bool enabled = true;
switch (cmd.action()) {
- case LFUN_LAYOUT:
- enabled = !forcePlainLayout();
- break;
- case LFUN_LAYOUT_PARAGRAPH:
- enabled = allowParagraphCustomization();
- break;
-
case LFUN_MATH_DISPLAY:
if (!hasFixedWidth()) {
enabled = false;
InsetTabular::InsetTabular(InsetTabular const & tab)
- : Inset(tab), tabular(tab.tabular)
+ : Inset(tab), tabular(tab.tabular),
+ first_visible_cell_(0), offset_valign_(0), rowselect_(false), colselect_(false)
{
}
bool InsetTabular::allowsCaptionVariation(std::string const & newtype) const
{
return tabular.is_long_tabular &&
- (newtype == "Standard" || newtype == "LongTableNoNumber");
+ (newtype == "Standard" || newtype == "Unnumbered");
}
// determine horizontal offset because of decimal align (if necessary)
int decimal_width = 0;
if (tabular.getAlignment(cell) == LYX_ALIGN_DECIMAL) {
- InsetTableCell tail = InsetTableCell(*tabular.cellInset(cell).get());
+ InsetTableCell tail = InsetTableCell(*tabular.cellInset(cell));
tail.setBuffer(tabular.buffer());
// we need to set macrocontext position everywhere
// otherwise we crash with nested insets (e.g. footnotes)
}
+bool InsetTabular::hitSelectRow(BufferView const & bv, int x) const
+{
+ int const x0 = xo(bv) + ADD_TO_TABULAR_WIDTH;
+ return x < x0 || x > x0 + tabular.width();
+}
+
+
+bool InsetTabular::hitSelectColumn(BufferView const & bv, int y) const
+{
+ int const y0 = yo(bv) - tabular.rowAscent(0) + offset_valign_;
+ // FIXME: using ADD_TO_TABULAR_WIDTH is not really correct since
+ // there is no margin added vertically to tabular insets.
+ // However, it works for now.
+ return y < y0 + ADD_TO_TABULAR_WIDTH || y > y0 + tabular.height() - ADD_TO_TABULAR_WIDTH;
+}
+
+
+bool InsetTabular::clickable(BufferView const & bv, int x, int y) const
+{
+ return hitSelectRow(bv, x) || hitSelectColumn(bv, y);
+}
+
+
void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
{
LYXERR(Debug::DEBUG, "# InsetTabular::doDispatch: cmd: " << cmd
case LFUN_MOUSE_PRESS: {
//lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl;
// select row
- if (cmd.x() < xo(cur.bv()) + ADD_TO_TABULAR_WIDTH
- || cmd.x() > xo(cur.bv()) + tabular.width()) {
+ if (hitSelectRow(cur.bv(), cmd.x())) {
row_type r = rowFromY(cur, cmd.y());
cur.idx() = tabular.getFirstCellInRow(r);
+ cur.pit() = 0;
cur.pos() = 0;
cur.resetAnchor();
cur.idx() = tabular.getLastCellInRow(r);
+ cur.pit() = cur.lastpit();
cur.pos() = cur.lastpos();
- cur.setSelection(true);
+ cur.selection(true);
bvcur = cur;
rowselect_ = true;
break;
}
// select column
- int const y0 = yo(cur.bv()) - tabular.rowAscent(0) + offset_valign_;
- if (cmd.y() < y0 + ADD_TO_TABULAR_WIDTH
- || cmd.y() > y0 + tabular.height()) {
+ if (hitSelectColumn(cur.bv(), cmd.y())) {
col_type c = columnFromX(cur, cmd.x());
cur.idx() = tabular.cellIndex(0, c);
+ cur.pit() = 0;
cur.pos() = 0;
cur.resetAnchor();
cur.idx() = tabular.cellIndex(tabular.nrows() - 1, c);
+ cur.pit() = cur.lastpit();
cur.pos() = cur.lastpos();
- cur.setSelection(true);
+ cur.selection(true);
bvcur = cur;
colselect_ = true;
break;
cur.pit() = 0;
cur.pos() = 0;
bvcur.setCursor(cur);
- bvcur.setSelection(true);
+ bvcur.selection(true);
break;
}
// select (additional) column
cur.pit() = 0;
cur.pos() = 0;
bvcur.setCursor(cur);
- bvcur.setSelection(true);
+ bvcur.selection(true);
break;
}
// only update if selection changes
cur.noScreenUpdate();
setCursorFromCoordinates(cur, cmd.x(), cmd.y());
bvcur.setCursor(cur);
- bvcur.setSelection(true);
+ bvcur.selection(true);
// if this is a multicell selection, we just set the cursor to
// the beginning of the cell's text.
if (bvcur.selIsMultiCell()) {
case LFUN_CELL_BACKWARD:
movePrevCell(cur);
- cur.setSelection(false);
+ cur.selection(false);
break;
case LFUN_CELL_FORWARD:
moveNextCell(cur);
- cur.setSelection(false);
+ cur.selection(false);
break;
case LFUN_CHAR_FORWARD_SELECT:
cur.bv().showDialog("tabular");
break;
- case LFUN_INSET_MODIFY: {
- string arg;
- if (cmd.getArg(1) == "from-dialog")
- arg = cmd.getArg(0) + to_utf8(cmd.argument().substr(19));
+ case LFUN_INSET_MODIFY:
+ // we come from the dialog
+ if (cmd.getArg(0) == "tabular")
+ tabularFeatures(cur, cmd.getLongArg(1));
else
- arg = to_utf8(cmd.argument());
- if (!tabularFeatures(cur, arg))
cur.undispatched();
break;
- }
+
+ case LFUN_TABULAR_FEATURE:
+ tabularFeatures(cur, to_utf8(cmd.argument()));
+ break;
// insert file functions
case LFUN_FILE_INSERT_PLAINTEXT_PARA:
}
-// function sets an object as defined in func_status.h:
-// states OK, Unknown, Disabled, On, Off.
-bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
- FuncStatus & status) const
+bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s,
+ string const & argument, FuncStatus & status) const
{
- switch (cmd.action()) {
- case LFUN_INSET_MODIFY: {
- if (&cur.inset() != this || cmd.getArg(0) != "tabular")
- break;
-
- // FIXME: We only check for the very first argument...
- string const s = cmd.getArg(1);
- // We always enable the lfun if it is coming from the dialog
- // because the dialog makes sure all the settings are valid,
- // even though the first argument might not be valid now.
- if (s == "from-dialog") {
- status.setEnabled(true);
- return true;
- }
int action = Tabular::LAST_ACTION;
int i = 0;
return true;
}
- string const argument = cmd.getLongArg(2);
-
row_type sel_row_start = 0;
row_type sel_row_end = 0;
col_type sel_col_start = 0;
break;
}
return true;
+}
+
+
+// function sets an object as defined in FuncStatus.h:
+// states OK, Unknown, Disabled, On, Off.
+bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
+ FuncStatus & status) const
+{
+ switch (cmd.action()) {
+ case LFUN_INSET_MODIFY:
+ if (cmd.getArg(0) != "tabular")
+ break;
+ if (cmd.getArg(1) == "for-dialog") {
+ // The dialog is asking the status of a command
+ if (&cur.inset() != this)
+ break;
+ string action = cmd.getArg(2);
+ string arg = cmd.getLongArg(3);
+ return getFeatureStatus(cur, action, arg, status);
+ } else {
+ // We always enable the lfun if it is coming from the dialog
+ // because the dialog makes sure all the settings are valid,
+ // even though the first argument might not be valid now.
+ status.setEnabled(true);
+ return true;
+ }
+
+ case LFUN_TABULAR_FEATURE: {
+ if (&cur.inset() != this)
+ break;
+ string action = cmd.getArg(0);
+ string arg = cmd.getLongArg(1);
+ return getFeatureStatus(cur, action, arg, status);
}
case LFUN_CAPTION_INSERT: {
}
// check if there is already a caption
bool have_caption = false;
- InsetTableCell itc = InsetTableCell(*tabular.cellInset(cur.idx()).get());
+ InsetTableCell itc = InsetTableCell(*tabular.cellInset(cur.idx()));
ParagraphList::const_iterator pit = itc.paragraphs().begin();
ParagraphList::const_iterator pend = itc.paragraphs().end();
for (; pit != pend; ++pit) {
Inset * InsetTabular::editXY(Cursor & cur, int x, int y)
{
//lyxerr << "InsetTabular::editXY: " << this << endl;
- cur.setSelection(false);
+ cur.selection(false);
cur.push(*this);
cur.idx() = getNearestCell(cur.bv(), x, y);
return cur.bv().textMetrics(&cell(cur.idx())->text()).editXY(cur, x, y);
}
-bool InsetTabular::tabularFeatures(Cursor & cur, string const & argument)
+void InsetTabular::tabularFeatures(Cursor & cur, string const & argument)
{
+ cur.recordUndoInset(this);
+
istringstream is(argument);
string s;
- is >> s;
- if (insetCode(s) != TABULAR_CODE)
- return false;
-
// Safe guard.
size_t safe_guard = 0;
for (;;) {
if (is.eof())
- break;
+ return;
safe_guard++;
if (safe_guard > 1000) {
LYXERR0("parameter max count reached!");
- break;
+ return;
}
is >> s;
Tabular::Feature action = Tabular::LAST_ACTION;
LYXERR(Debug::DEBUG, "Feature: " << s << "\t\tvalue: " << val);
tabularFeatures(cur, action, val);
}
- return true;
}
break;
}
- cur.recordUndoInset(this);
-
getSelection(cur, sel_row_start, sel_row_end, sel_col_start, sel_col_end);
row_type const row = tabular.cellRow(cur.idx());
col_type const column = tabular.cellColumn(cur.idx());
cur.idx() = tabular.cellIndex(sel_row_start, column);
cur.pit() = 0;
cur.pos() = 0;
- cur.setSelection(false);
+ cur.selection(false);
break;
case Tabular::DELETE_COLUMN:
cur.idx() = tabular.cellIndex(row, sel_col_start);
cur.pit() = 0;
cur.pos() = 0;
- cur.setSelection(false);
+ cur.selection(false);
break;
case Tabular::COPY_ROW:
tabular.rightLine(cur.selEnd().idx()));
cur.pit() = 0;
cur.pos() = 0;
- cur.setSelection(false);
+ cur.selection(false);
break;
}
tabular.getAlignment(cur.selEnd().idx()));
cur.pit() = 0;
cur.pos() = 0;
- cur.setSelection(false);
+ cur.selection(false);
break;
}
cur.idx() = tabular.setLTCaption(row, true);
cur.pit() = 0;
cur.pos() = 0;
- cur.setSelection(false);
+ cur.selection(false);
// If a row is set as caption, then also insert
// a caption. Otherwise the LaTeX output is broken.
// Select cell if it is non-empty
cur.idx() = tabular.setLTCaption(row, false);
cur.pit() = 0;
cur.pos() = 0;
- cur.setSelection(false);
+ cur.selection(false);
FuncRequest fr(LFUN_INSET_DISSOLVE, "caption");
if (lyx::getStatus(fr).enabled())
lyx::dispatch(fr);