X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathGrid.cpp;h=0a637ec715c26ae8f32d5bf4ab5f718de9d02385;hb=21c92c8a129b5f3ff56de33bf2941a25967cffbb;hp=67300403907d947f43f1ca71e2b75323bf2192e6;hpb=89662a6852ca8f68caa557808d7b7e1d669344d4;p=lyx.git diff --git a/src/mathed/InsetMathGrid.cpp b/src/mathed/InsetMathGrid.cpp index 6730040390..0a637ec715 100644 --- a/src/mathed/InsetMathGrid.cpp +++ b/src/mathed/InsetMathGrid.cpp @@ -22,6 +22,7 @@ #include "Buffer.h" #include "BufferParams.h" #include "BufferView.h" +#include "CoordCache.h" #include "Cursor.h" #include "CutAndPaste.h" #include "FuncRequest.h" @@ -82,7 +83,7 @@ static void resetGrid(InsetMathGrid & grid) InsetMathGrid::CellInfo::CellInfo() - : multi_(CELL_NORMAL) + : multi(CELL_NORMAL) {} @@ -91,15 +92,15 @@ InsetMathGrid::CellInfo::CellInfo() InsetMathGrid::RowInfo::RowInfo() - : descent_(0), ascent_(0), offset_(0), lines_(0), skip_(0), - allow_newpage_(true) + : descent(0), ascent(0), lines(0), skip(0), + allow_newpage(true) {} int InsetMathGrid::RowInfo::skipPixels(MetricsInfo const & mi) const { - return crskip_.inPixels(mi.base); + return mi.base.inPixels(crskip); } @@ -108,7 +109,7 @@ int InsetMathGrid::RowInfo::skipPixels(MetricsInfo const & mi) const InsetMathGrid::ColInfo::ColInfo() - : align_('c'), width_(0), offset_(0), lines_(0), skip_(0) + : align('c'), width(0), offset(0), lines(0), skip(0) {} @@ -170,12 +171,12 @@ void InsetMathGrid::setDefaults() //if (nrows() <= 0) // lyxerr << "positive number of rows expected" << endl; for (col_type col = 0; col < ncols(); ++col) { - colinfo_[col].align_ = defaultColAlign(col); - colinfo_[col].skip_ = defaultColSpace(col); - colinfo_[col].special_.clear(); + colinfo_[col].align = defaultColAlign(col); + colinfo_[col].skip = defaultColSpace(col); + colinfo_[col].special.clear(); } for (idx_type idx = 0; idx < nargs(); ++idx) - cellinfo_[idx].multi_ = CELL_NORMAL; + cellinfo_[idx].multi = CELL_NORMAL; } @@ -186,7 +187,7 @@ bool InsetMathGrid::interpretString(Cursor & cur, docstring const & str) FuncStatus status; if (getStatus(cur, fr, status)) { if (status.enabled()) { - rowinfo_[cur.row()].lines_++; + rowinfo_[cur.row()].lines++; return true; } } @@ -201,7 +202,7 @@ void InsetMathGrid::setHorizontalAlignments(docstring const & hh) for (docstring::const_iterator it = hh.begin(); it != hh.end(); ++it) { char_type c = *it; if (c == '|') { - colinfo_[col].lines_++; + colinfo_[col].lines++; } else if ((c == 'p' || c == 'm' || c == 'b'|| c == '!' || c == '@' || c == '>' || c == '<') && it + 1 != hh.end() && *(it + 1) == '{') { @@ -214,18 +215,18 @@ void InsetMathGrid::setHorizontalAlignments(docstring const & hh) // Only intercolumn stuff is allowed // in the last dummy column break; - colinfo_[col].align_ = 'l'; + colinfo_[col].align = 'l'; } else { // this is intercolumn stuff - if (colinfo_[col].special_.empty()) + if (colinfo_[col].special.empty()) // Overtake possible lines - colinfo_[col].special_ = docstring(colinfo_[col].lines_, '|'); + colinfo_[col].special = docstring(colinfo_[col].lines, '|'); } int brace_open = 0; int brace_close = 0; while (it != hh.end()) { c = *it; - colinfo_[col].special_ += c; + colinfo_[col].special += c; if (c == '{') ++brace_open; else if (c == '}') @@ -236,32 +237,32 @@ void InsetMathGrid::setHorizontalAlignments(docstring const & hh) } --it; if (newcolumn) { - colinfo_[col].lines_ = count( - colinfo_[col].special_.begin(), - colinfo_[col].special_.end(), '|'); + colinfo_[col].lines = count( + colinfo_[col].special.begin(), + colinfo_[col].special.end(), '|'); LYXERR(Debug::MATHED, "special column separator: `" - << to_utf8(colinfo_[col].special_) << '\''); + << to_utf8(colinfo_[col].special) << '\''); ++col; - colinfo_[col].lines_ = 0; - colinfo_[col].special_.clear(); + colinfo_[col].lines = 0; + colinfo_[col].special.clear(); } } else if (col >= ncols()) { // Only intercolumn stuff is allowed in the last // dummy column break; } else if (c == 'c' || c == 'l' || c == 'r') { - colinfo_[col].align_ = static_cast(c); - if (!colinfo_[col].special_.empty()) { - colinfo_[col].special_ += c; - colinfo_[col].lines_ = count( - colinfo_[col].special_.begin(), - colinfo_[col].special_.end(), '|'); + colinfo_[col].align = static_cast(c); + if (!colinfo_[col].special.empty()) { + colinfo_[col].special += c; + colinfo_[col].lines = count( + colinfo_[col].special.begin(), + colinfo_[col].special.end(), '|'); LYXERR(Debug::MATHED, "special column separator: `" - << to_utf8(colinfo_[col].special_) << '\''); + << to_utf8(colinfo_[col].special) << '\''); } ++col; - colinfo_[col].lines_ = 0; - colinfo_[col].special_.clear(); + colinfo_[col].lines = 0; + colinfo_[col].special.clear(); } else { lyxerr << "unknown column separator: '" << c << "'" << endl; } @@ -272,7 +273,7 @@ void InsetMathGrid::setHorizontalAlignments(docstring const & hh) if (n > ncols()) n = ncols(); for (col_type col = 0; col < n; ++col) - colinfo_[col].align_ = hh[col]; + colinfo_[col].align = hh[col]; */ } @@ -294,9 +295,9 @@ InsetMathGrid::col_type InsetMathGrid::guessColumns(docstring const & hh) void InsetMathGrid::setHorizontalAlignment(char h, col_type col) { - colinfo_[col].align_ = h; - if (!colinfo_[col].special_.empty()) { - char_type & c = colinfo_[col].special_[colinfo_[col].special_.size() - 1]; + colinfo_[col].align = h; + if (!colinfo_[col].special.empty()) { + char_type & c = colinfo_[col].special[colinfo_[col].special.size() - 1]; if (c == 'l' || c == 'c' || c == 'r') c = h; } @@ -306,7 +307,7 @@ void InsetMathGrid::setHorizontalAlignment(char h, col_type col) char InsetMathGrid::horizontalAlignment(col_type col) const { - return colinfo_[col].align_; + return colinfo_[col].align; } @@ -314,15 +315,15 @@ docstring InsetMathGrid::horizontalAlignments() const { docstring res; for (col_type col = 0; col < ncols(); ++col) { - if (colinfo_[col].special_.empty()) { - res += docstring(colinfo_[col].lines_, '|'); - res += colinfo_[col].align_; + if (colinfo_[col].special.empty()) { + res += docstring(colinfo_[col].lines, '|'); + res += colinfo_[col].align; } else - res += colinfo_[col].special_; + res += colinfo_[col].special; } - if (colinfo_[ncols()].special_.empty()) - return res + docstring(colinfo_[ncols()].lines_, '|'); - return res + colinfo_[ncols()].special_; + if (colinfo_[ncols()].special.empty()) + return res + docstring(colinfo_[ncols()].lines, '|'); + return res + colinfo_[ncols()].special; } @@ -365,7 +366,7 @@ InsetMathGrid::row_type InsetMathGrid::row(idx_type idx) const InsetMathGrid::col_type InsetMathGrid::ncellcols(idx_type idx) const { col_type cols = 1; - if (cellinfo_[idx].multi_ == CELL_NORMAL) + if (cellinfo_[idx].multi == CELL_NORMAL) return cols; // If the cell at idx is already CELL_PART_OF_MULTICOLUMN we return // the number of remaining columns, not the ones of the complete @@ -373,7 +374,7 @@ InsetMathGrid::col_type InsetMathGrid::ncellcols(idx_type idx) const // cell with idx + ncellcols(idx) - 1. row_type const r = row(idx); while (idx+cols < nargs() && row(idx+cols) == r && - cellinfo_[idx+cols].multi_ == CELL_PART_OF_MULTICOLUMN) + cellinfo_[idx+cols].multi == CELL_PART_OF_MULTICOLUMN) cols++; return cols; } @@ -381,13 +382,13 @@ InsetMathGrid::col_type InsetMathGrid::ncellcols(idx_type idx) const void InsetMathGrid::vcrskip(Length const & crskip, row_type row) { - rowinfo_[row].crskip_ = crskip; + rowinfo_[row].crskip = crskip; } Length InsetMathGrid::vcrskip(row_type row) const { - return rowinfo_[row].crskip_; + return rowinfo_[row].crskip; } @@ -395,9 +396,10 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const { // let the cells adjust themselves for (idx_type i = 0; i < nargs(); ++i) { - if (cellinfo_[i].multi_ != CELL_PART_OF_MULTICOLUMN) { + if (cellinfo_[i].multi != CELL_PART_OF_MULTICOLUMN) { Dimension dimc; - cell(i).metrics(mi, dimc); + // the 'false' is to make sure that the cell is tall enough + cell(i).metrics(mi, dimc, false); } } @@ -409,28 +411,28 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const int desc = 0; for (col_type col = 0; col < ncols(); ++col) { idx_type const i = index(row, col); - if (cellinfo_[i].multi_ != CELL_PART_OF_MULTICOLUMN) { + if (cellinfo_[i].multi != CELL_PART_OF_MULTICOLUMN) { Dimension const & dimc = cell(i).dimension(bv); asc = max(asc, dimc.asc); desc = max(desc, dimc.des); } } - rowinfo_[row].ascent_ = asc; - rowinfo_[row].descent_ = desc; + rowinfo_[row].ascent = asc; + rowinfo_[row].descent = desc; } - rowinfo_[nrows()].ascent_ = 0; - rowinfo_[nrows()].descent_ = 0; + rowinfo_[nrows()].ascent = 0; + rowinfo_[nrows()].descent = 0; // compute vertical offsets - rowinfo_[0].offset_ = 0; + rowinfo_[0].offset[&bv] = 0; for (row_type row = 1; row <= nrows(); ++row) { - rowinfo_[row].offset_ = - rowinfo_[row - 1].offset_ + - rowinfo_[row - 1].descent_ + + rowinfo_[row].offset[&bv] = + rowinfo_[row - 1].offset[&bv] + + rowinfo_[row - 1].descent + rowinfo_[row - 1].skipPixels(mi) + rowsep() + - rowinfo_[row].lines_ * hlinesep() + - rowinfo_[row].ascent_; + rowinfo_[row].lines * hlinesep() + + rowinfo_[row].ascent; } // adjust vertical offset @@ -440,13 +442,13 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const h = 0; break; case 'b': - h = rowinfo_[nrows() - 1].offset_; + h = rowinfo_[nrows() - 1].offset[&bv]; break; default: - h = rowinfo_[nrows() - 1].offset_ / 2; + h = rowinfo_[nrows() - 1].offset[&bv] / 2; } for (row_type row = 0; row <= nrows(); ++row) - rowinfo_[row].offset_ -= h; + rowinfo_[row].offset[&bv] -= h; // multicolumn cell widths, as a map from first column to width in a @@ -460,7 +462,7 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const int wid = 0; for (row_type row = 0; row < nrows(); ++row) { idx_type const i = index(row, col); - if (cellinfo_[i].multi_ != CELL_PART_OF_MULTICOLUMN) { + if (cellinfo_[i].multi != CELL_PART_OF_MULTICOLUMN) { int const w = cell(i).dimension(bv).wid; col_type const cols = ncellcols(i); if (cols > 1 && nrows() > 1) { @@ -476,19 +478,19 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const wid = max(wid, w); } } - colinfo_[col].width_ = wid; + colinfo_[col].width = wid; } - colinfo_[ncols()].width_ = 0; + colinfo_[ncols()].width = 0; // compute horizontal offsets - colinfo_[0].offset_ = border() + colinfo_[0].lines_ * vlinesep();; + colinfo_[0].offset = border() + colinfo_[0].lines * vlinesep();; for (col_type col = 1; col <= ncols(); ++col) { - colinfo_[col].offset_ = - colinfo_[col - 1].offset_ + - colinfo_[col - 1].width_ + + colinfo_[col].offset = + colinfo_[col - 1].offset + + colinfo_[col - 1].width + displayColSpace(col - 1) + colsep() + - colinfo_[col].lines_ * vlinesep(); + colinfo_[col].lines * vlinesep(); } // increase column widths for multicolumn cells if needed @@ -506,44 +508,44 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const int const wid = it->second; col_type const first = it->first; int const nextoffset = - colinfo_[first].offset_ + + colinfo_[first].offset + wid + displayColSpace(last) + colsep() + - colinfo_[last+1].lines_ * vlinesep(); - int const dx = nextoffset - colinfo_[last+1].offset_; + colinfo_[last+1].lines * vlinesep(); + int const dx = nextoffset - colinfo_[last+1].offset; if (dx > 0) { - colinfo_[last].width_ += dx; + colinfo_[last].width += dx; for (col_type col = last + 1; col <= ncols(); ++col) - colinfo_[col].offset_ += dx; + colinfo_[col].offset += dx; } } } - dim.wid = colinfo_[ncols() - 1].offset_ - + colinfo_[ncols() - 1].width_ - + vlinesep() * colinfo_[ncols()].lines_ + dim.wid = colinfo_[ncols() - 1].offset + + colinfo_[ncols() - 1].width + + vlinesep() * colinfo_[ncols()].lines + border(); - dim.asc = - rowinfo_[0].offset_ - + rowinfo_[0].ascent_ - + hlinesep() * rowinfo_[0].lines_ + dim.asc = - rowinfo_[0].offset[&bv] + + rowinfo_[0].ascent + + hlinesep() * rowinfo_[0].lines + border(); - dim.des = rowinfo_[nrows() - 1].offset_ - + rowinfo_[nrows() - 1].descent_ - + hlinesep() * rowinfo_[nrows()].lines_ + dim.des = rowinfo_[nrows() - 1].offset[&bv] + + rowinfo_[nrows() - 1].descent + + hlinesep() * rowinfo_[nrows()].lines + border() + 1; /* // Increase ws_[i] for 'R' columns (except the first one) for (int i = 1; i < nc_; ++i) - if (align_[i] == 'R') + if (align[i] == 'R') ws_[i] += 10 * df_width; // Increase ws_[i] for 'C' column - if (align_[0] == 'C') + if (align[0] == 'C') if (ws_[0] < 7 * workwidth / 8) ws_[0] = 7 * workwidth / 8; @@ -558,7 +560,7 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const cxrow->setTab(i, df_width); isvoid = true; } - switch (align_[i]) { + switch (align[i]) { case 'l': lf = 0; break; @@ -594,22 +596,23 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const int InsetMathGrid::vLineHOffset(col_type col, unsigned int line) const { if (col < ncols()) - return leftMargin() + colinfo_[col].offset_ - - (colinfo_[col].lines_ - line - 1) * vlinesep() + return leftMargin() + colinfo_[col].offset + - (colinfo_[col].lines - line - 1) * vlinesep() - vlinesep()/2 - colsep()/2; else { LASSERT(col == ncols(), return 0); - return leftMargin() + colinfo_[col-1].offset_ + colinfo_[col-1].width_ + return leftMargin() + colinfo_[col-1].offset + colinfo_[col-1].width + line * vlinesep() + vlinesep()/2 + colsep()/2; } } -int InsetMathGrid::hLineVOffset(row_type row, unsigned int line) const +int InsetMathGrid::hLineVOffset(BufferView const & bv, row_type row, + unsigned int line) const { - return rowinfo_[row].offset_ - - rowinfo_[row].ascent_ + return rowinfo_[row].offset[&bv] + - rowinfo_[row].ascent - line * hlinesep() - hlinesep()/2 - rowsep()/2; } @@ -620,16 +623,16 @@ void InsetMathGrid::draw(PainterInfo & pi, int x, int y) const BufferView const & bv = *pi.base.bv; for (idx_type idx = 0; idx < nargs(); ++idx) { - if (cellinfo_[idx].multi_ != CELL_PART_OF_MULTICOLUMN) { + if (cellinfo_[idx].multi != CELL_PART_OF_MULTICOLUMN) { cell(idx).draw(pi, x + leftMargin() + cellXOffset(bv, idx), - y + cellYOffset(idx)); + y + cellYOffset(bv, idx)); row_type r = row(idx); - int const yy1 = y + hLineVOffset(r, 0); - int const yy2 = y + hLineVOffset(r + 1, rowinfo_[r + 1].lines_ - 1); + int const yy1 = y + hLineVOffset(bv, r, 0); + int const yy2 = y + hLineVOffset(bv, r + 1, rowinfo_[r + 1].lines - 1); auto draw_left_borders = [&](col_type c) { - for (unsigned int i = 0; i < colinfo_[c].lines_; ++i) { + for (unsigned int i = 0; i < colinfo_[c].lines; ++i) { int const xx = x + vLineHOffset(c, i); pi.pain.line(xx, yy1, xx, yy2, Color_foreground); } @@ -646,20 +649,23 @@ void InsetMathGrid::draw(PainterInfo & pi, int x, int y) const // Draw horizontal borders for (row_type r = 0; r <= nrows(); ++r) { int const xx1 = x + vLineHOffset(0, 0); - int const xx2 = x + vLineHOffset(ncols(), colinfo_[ncols()].lines_ - 1); - for (unsigned int i = 0; i < rowinfo_[r].lines_; ++i) { - int const yy = y + hLineVOffset(r, i); + int const xx2 = x + vLineHOffset(ncols(), colinfo_[ncols()].lines - 1); + for (unsigned int i = 0; i < rowinfo_[r].lines; ++i) { + int const yy = y + hLineVOffset(bv, r, i); pi.pain.line(xx1, yy, xx2, yy, Color_foreground); } } } -void InsetMathGrid::metricsT(TextMetricsInfo const & mi, Dimension & dim) const +void InsetMathGrid::metricsT(TextMetricsInfo const & /*mi*/, Dimension & /*dim*/) const { +// FIXME: this does not compile anymore with offset being a map +// It is not worth fixing it at this point since the code is basically dead. +#if 0 // let the cells adjust themselves for (idx_type i = 0; i < nargs(); ++i) - if (cellinfo_[i].multi_ != CELL_PART_OF_MULTICOLUMN) + if (cellinfo_[i].multi != CELL_PART_OF_MULTICOLUMN) cell(i).metricsT(mi, dim); // compute absolute sizes of vertical structure @@ -668,7 +674,7 @@ void InsetMathGrid::metricsT(TextMetricsInfo const & mi, Dimension & dim) const int desc = 0; for (col_type col = 0; col < ncols(); ++col) { idx_type const i = index(row, col); - if (cellinfo_[i].multi_ != CELL_PART_OF_MULTICOLUMN) { + if (cellinfo_[i].multi != CELL_PART_OF_MULTICOLUMN) { //MathData const & c = cell(i); // FIXME: BROKEN! Dimension dimc; @@ -676,22 +682,22 @@ void InsetMathGrid::metricsT(TextMetricsInfo const & mi, Dimension & dim) const desc = max(desc, dimc.descent()); } } - rowinfo_[row].ascent_ = asc; - rowinfo_[row].descent_ = desc; + rowinfo_[row].ascent = asc; + rowinfo_[row].descent = desc; } - rowinfo_[nrows()].ascent_ = 0; - rowinfo_[nrows()].descent_ = 0; + rowinfo_[nrows()].ascent = 0; + rowinfo_[nrows()].descent = 0; // compute vertical offsets - rowinfo_[0].offset_ = 0; + rowinfo_[0].offset[&bv] = 0; for (row_type row = 1; row <= nrows(); ++row) { - rowinfo_[row].offset_ = - rowinfo_[row - 1].offset_ + - rowinfo_[row - 1].descent_ + + rowinfo_[row].offset[&bv] = + rowinfo_[row - 1].offset + + rowinfo_[row - 1].descent + //rowinfo_[row - 1].skipPixels(mi) + 1 + //rowsep() + - //rowinfo_[row].lines_ * hlinesep() + - rowinfo_[row].ascent_; + //rowinfo_[row].lines * hlinesep() + + rowinfo_[row].ascent; } // adjust vertical offset @@ -701,13 +707,13 @@ void InsetMathGrid::metricsT(TextMetricsInfo const & mi, Dimension & dim) const h = 0; break; case 'b': - h = rowinfo_[nrows() - 1].offset_; + h = rowinfo_[nrows() - 1].offset; break; default: - h = rowinfo_[nrows() - 1].offset_ / 2; + h = rowinfo_[nrows() - 1].offset / 2; } for (row_type row = 0; row <= nrows(); ++row) - rowinfo_[row].offset_ -= h; + rowinfo_[row].offset -= h; // compute absolute sizes of horizontal structure @@ -716,56 +722,57 @@ void InsetMathGrid::metricsT(TextMetricsInfo const & mi, Dimension & dim) const for (row_type row = 0; row < nrows(); ++row) { // FIXME: BROKEN! //idx_type const i = index(row, col); - //if (cellinfo_[i].multi_ != CELL_PART_OF_MULTICOLUMN) + //if (cellinfo_[i].multi != CELL_PART_OF_MULTICOLUMN) // wid = max(wid, cell(i).width()); } - colinfo_[col].width_ = wid; + colinfo_[col].width = wid; } - colinfo_[ncols()].width_ = 0; + colinfo_[ncols()].width = 0; // compute horizontal offsets - colinfo_[0].offset_ = border(); + colinfo_[0].offset = border(); for (col_type col = 1; col <= ncols(); ++col) { - colinfo_[col].offset_ = - colinfo_[col - 1].offset_ + - colinfo_[col - 1].width_ + + colinfo_[col].offset = + colinfo_[col - 1].offset + + colinfo_[col - 1].width + displayColSpace(col - 1) + 1 ; //colsep() + - //colinfo_[col].lines_ * vlinesep(); + //colinfo_[col].lines * vlinesep(); } - dim.wid = colinfo_[ncols() - 1].offset_ - + colinfo_[ncols() - 1].width_ - //+ vlinesep() * colinfo_[ncols()].lines_ + dim.wid = colinfo_[ncols() - 1].offset + + colinfo_[ncols() - 1].width + //+ vlinesep() * colinfo_[ncols()].lines + 2; - dim.asc = -rowinfo_[0].offset_ - + rowinfo_[0].ascent_ - //+ hlinesep() * rowinfo_[0].lines_ + dim.asc = -rowinfo_[0].offset + + rowinfo_[0].ascent + //+ hlinesep() * rowinfo_[0].lines + 1; - dim.des = rowinfo_[nrows() - 1].offset_ - + rowinfo_[nrows() - 1].descent_ - //+ hlinesep() * rowinfo_[nrows()].lines_ + dim.des = rowinfo_[nrows() - 1].offset + + rowinfo_[nrows() - 1].descent + //+ hlinesep() * rowinfo_[nrows()].lines + 1; +#endif } void InsetMathGrid::drawT(TextPainter & /*pain*/, int /*x*/, int /*y*/) const { // for (idx_type idx = 0; idx < nargs(); ++idx) -// if (cellinfo_[idx].multi_ != CELL_PART_OF_MULTICOLUMN) +// if (cellinfo_[idx].multi != CELL_PART_OF_MULTICOLUMN) // cell(idx).drawT(pain, x + cellXOffset(idx), y + cellYOffset(idx)); } -void InsetMathGrid::updateBuffer(ParIterator const & it, UpdateType utype) +void InsetMathGrid::updateBuffer(ParIterator const & it, UpdateType utype, bool const deleted) { // pass down for (idx_type idx = 0; idx < nargs(); ++idx) - if (cellinfo_[idx].multi_ != CELL_PART_OF_MULTICOLUMN) - cell(idx).updateBuffer(it, utype); + if (cellinfo_[idx].multi != CELL_PART_OF_MULTICOLUMN) + cell(idx).updateBuffer(it, utype, deleted); } @@ -774,9 +781,9 @@ docstring InsetMathGrid::eolString(row_type row, bool fragile, { docstring eol; - if (!rowinfo_[row].crskip_.zero()) - eol += '[' + from_utf8(rowinfo_[row].crskip_.asLatexString()) + ']'; - else if(!rowinfo_[row].allow_newpage_) + if (!rowinfo_[row].crskip.zero()) + eol += '[' + from_utf8(rowinfo_[row].crskip.asLatexString()) + ']'; + else if(!rowinfo_[row].allow_newpage) eol += '*'; // make sure an upcoming '[' does not break anything @@ -807,7 +814,7 @@ void InsetMathGrid::addRow(row_type row) { rowinfo_.insert(rowinfo_.begin() + row + 1, RowInfo()); cells_.insert - (cells_.begin() + (row + 1) * ncols(), ncols(), MathData()); + (cells_.begin() + (row + 1) * ncols(), ncols(), MathData(buffer_)); cellinfo_.insert (cellinfo_.begin() + (row + 1) * ncols(), ncols(), CellInfo()); } @@ -831,8 +838,11 @@ void InsetMathGrid::delRow(row_type row) void InsetMathGrid::copyRow(row_type row) { addRow(row); - for (col_type col = 0; col < ncols(); ++col) + for (col_type col = 0; col < ncols(); ++col) { cells_[(row + 1) * ncols() + col] = cells_[row * ncols() + col]; + // copying the cell does not set the buffer + cells_[(row + 1) * ncols() + col].setBuffer(*buffer_); + } } @@ -862,11 +872,13 @@ void InsetMathGrid::addCol(col_type newcol) = cellinfo_[row * nc + col]; } swap(cells_, new_cells); + // copying cells loses the buffer reference + setBuffer(*buffer_); swap(cellinfo_, new_cellinfo); ColInfo inf; - inf.skip_ = defaultColSpace(newcol); - inf.align_ = defaultColAlign(newcol); + inf.skip = defaultColSpace(newcol); + inf.align = defaultColAlign(newcol); colinfo_.insert(colinfo_.begin() + newcol, inf); } @@ -884,6 +896,8 @@ void InsetMathGrid::delCol(col_type col) tmpcellinfo.push_back(cellinfo_[i]); } swap(cells_, tmpcells); + // copying cells loses the buffer reference + setBuffer(*buffer_); swap(cellinfo_, tmpcellinfo); colinfo_.erase(colinfo_.begin() + col); @@ -893,8 +907,11 @@ void InsetMathGrid::delCol(col_type col) void InsetMathGrid::copyCol(col_type col) { addCol(col+1); - for (row_type row = 0; row < nrows(); ++row) + for (row_type row = 0; row < nrows(); ++row) { cells_[row * ncols() + col + 1] = cells_[row * ncols() + col]; + // copying the cell does not set the buffer + cells_[row * ncols() + col + 1].setBuffer(*buffer_); + } } @@ -911,10 +928,10 @@ void InsetMathGrid::swapCol(col_type col) int InsetMathGrid::cellXOffset(BufferView const & bv, idx_type idx) const { - if (cellinfo_[idx].multi_ == CELL_PART_OF_MULTICOLUMN) + if (cellinfo_[idx].multi == CELL_PART_OF_MULTICOLUMN) return 0; col_type c = col(idx); - int x = colinfo_[c].offset_; + int x = colinfo_[c].offset; char align = displayColAlign(idx); Dimension const & celldim = cell(idx).dimension(bv); if (align == 'r' || align == 'R') @@ -925,25 +942,25 @@ int InsetMathGrid::cellXOffset(BufferView const & bv, idx_type idx) const } -int InsetMathGrid::cellYOffset(idx_type idx) const +int InsetMathGrid::cellYOffset(BufferView const & bv, idx_type idx) const { - return rowinfo_[row(idx)].offset_; + return rowinfo_[row(idx)].offset[&bv]; } int InsetMathGrid::cellWidth(idx_type idx) const { - switch (cellinfo_[idx].multi_) { + switch (cellinfo_[idx].multi) { case CELL_NORMAL: - return colinfo_[col(idx)].width_; + return colinfo_[col(idx)].width; case CELL_BEGIN_OF_MULTICOLUMN: { col_type c1 = col(idx); col_type c2 = c1 + ncellcols(idx); - return colinfo_[c2].offset_ - - colinfo_[c1].offset_ + return colinfo_[c2].offset + - colinfo_[c1].offset - displayColSpace(c2) - colsep() - - colinfo_[c2].lines_ * vlinesep(); + - colinfo_[c2].lines * vlinesep(); } case CELL_PART_OF_MULTICOLUMN: return 0; @@ -964,11 +981,18 @@ bool InsetMathGrid::idxUpDown(Cursor & cur, bool up) const cur.idx() += ncols(); } // If we are in a multicolumn cell, move to the "real" cell - while (cellinfo_[cur.idx()].multi_ == CELL_PART_OF_MULTICOLUMN) { + while (cellinfo_[cur.idx()].multi == CELL_PART_OF_MULTICOLUMN) { LASSERT(cur.idx() > 0, return false); --cur.idx(); } - cur.pos() = cur.cell().x2pos(&cur.bv(), cur.x_target() - cur.cell().xo(cur.bv())); + // FIXME: this is only a workaround to avoid a crash if the inset + // in not in coord cache. The best would be to force a FitCursor + // operation. + CoordCache::Arrays const & arraysCache = cur.bv().coordCache().arrays(); + if (arraysCache.has(&cur.cell())) + cur.pos() = cur.cell().x2pos(&cur.bv(), cur.x_target() - cur.cell().xo(cur.bv())); + else + cur.pos() = 0; return true; } @@ -980,7 +1004,7 @@ bool InsetMathGrid::idxBackward(Cursor & cur) const return false; --cur.idx(); // If we are in a multicolumn cell, move to the "real" cell - while (cellinfo_[cur.idx()].multi_ == CELL_PART_OF_MULTICOLUMN) { + while (cellinfo_[cur.idx()].multi == CELL_PART_OF_MULTICOLUMN) { LASSERT(cur.idx() > 0, return false); --cur.idx(); } @@ -996,7 +1020,7 @@ bool InsetMathGrid::idxForward(Cursor & cur) const return false; ++cur.idx(); // If we are in a multicolumn cell, move to the next cell - while (cellinfo_[cur.idx()].multi_ == CELL_PART_OF_MULTICOLUMN) { + while (cellinfo_[cur.idx()].multi == CELL_PART_OF_MULTICOLUMN) { // leave matrix if at the back edge if (cur.col() + 1 == ncols()) return false; @@ -1007,47 +1031,47 @@ bool InsetMathGrid::idxForward(Cursor & cur) const } -bool InsetMathGrid::idxFirst(Cursor & cur) const +idx_type InsetMathGrid::firstIdx() const { + size_type idx = 0; switch (v_align_) { case 't': - cur.idx() = 0; + //idx = 0; break; case 'b': - cur.idx() = (nrows() - 1) * ncols(); + idx = (nrows() - 1) * ncols(); break; default: - cur.idx() = ((nrows() - 1) / 2) * ncols(); + idx = ((nrows() - 1) / 2) * ncols(); } // If we are in a multicolumn cell, move to the "real" cell - while (cellinfo_[cur.idx()].multi_ == CELL_PART_OF_MULTICOLUMN) { - LASSERT(cur.idx() > 0, return false); - --cur.idx(); + while (cellinfo_[idx].multi == CELL_PART_OF_MULTICOLUMN) { + LASSERT(idx > 0, return 0); + --idx; } - cur.pos() = 0; - return true; + return idx; } -bool InsetMathGrid::idxLast(Cursor & cur) const +idx_type InsetMathGrid::lastIdx() const { + size_type idx = 0; switch (v_align_) { case 't': - cur.idx() = ncols() - 1; + idx = ncols() - 1; break; case 'b': - cur.idx() = nargs() - 1; + idx = nargs() - 1; break; default: - cur.idx() = ((nrows() - 1) / 2 + 1) * ncols() - 1; + idx = ((nrows() - 1) / 2 + 1) * ncols() - 1; } // If we are in a multicolumn cell, move to the "real" cell - while (cellinfo_[cur.idx()].multi_ == CELL_PART_OF_MULTICOLUMN) { - LASSERT(cur.idx() > 0, return false); - --cur.idx(); + while (cellinfo_[idx].multi == CELL_PART_OF_MULTICOLUMN) { + LASSERT(idx > 0, return false); + --idx; } - cur.pos() = cur.lastpos(); - return true; + return idx; } @@ -1098,7 +1122,7 @@ void InsetMathGrid::idxGlue(idx_type idx) } else { idx_type idx_next = idx + 1; while (idx_next < nargs() && - cellinfo_[idx_next].multi_ == CELL_PART_OF_MULTICOLUMN) + cellinfo_[idx_next].multi == CELL_PART_OF_MULTICOLUMN) ++idx_next; if (idx_next < nargs()) cell(idx).append(cell(idx_next)); @@ -1141,7 +1165,7 @@ void InsetMathGrid::normalize(NormalStream & os) const os << "[row "; for (col_type col = 0; col < ncols(); ++col) { idx_type const i = index(row, col); - switch (cellinfo_[i].multi_) { + switch (cellinfo_[i].multi) { case CELL_NORMAL: os << "[cell " << cell(i) << ']'; break; @@ -1160,32 +1184,32 @@ void InsetMathGrid::normalize(NormalStream & os) const } -void InsetMathGrid::mathmlize(MathStream & os) const +void InsetMathGrid::mathmlize(MathStream & ms) const { bool const havetable = nrows() > 1 || ncols() > 1; if (havetable) - os << MTag("mtable"); + ms << MTag("mtable"); char const * const celltag = havetable ? "mtd" : "mrow"; for (row_type row = 0; row < nrows(); ++row) { if (havetable) - os << MTag("mtr"); + ms << MTag("mtr"); for (col_type col = 0; col < ncols(); ++col) { idx_type const i = index(row, col); - if (cellinfo_[i].multi_ != CELL_PART_OF_MULTICOLUMN) { + if (cellinfo_[i].multi != CELL_PART_OF_MULTICOLUMN) { col_type const cellcols = ncellcols(i); ostringstream attr; if (havetable && cellcols > 1) attr << "colspan='" << cellcols << '\''; - os << MTag(celltag, attr.str()); - os << cell(index(row, col)); - os << ETag(celltag); + ms << MTag(celltag, attr.str()); + ms << cell(index(row, col)); + ms << ETag(celltag); } } if (havetable) - os << ETag("mtr"); + ms << ETag("mtr"); } if (havetable) - os << ETag("mtable"); + ms << ETag("mtable"); } @@ -1203,7 +1227,7 @@ void InsetMathGrid::htmlize(HtmlStream & os, string attrib) const os << MTag("tr"); for (col_type col = 0; col < ncols(); ++col) { idx_type const i = index(row, col); - if (cellinfo_[i].multi_ != CELL_PART_OF_MULTICOLUMN) { + if (cellinfo_[i].multi != CELL_PART_OF_MULTICOLUMN) { col_type const cellcols = ncellcols(i); ostringstream attr; if (cellcols > 1) @@ -1251,7 +1275,7 @@ void InsetMathGrid::write(WriteStream & os, MathEnsurer ensurer(os, false); docstring eol; for (row_type row = beg_row; row < end_row; ++row) { - os << verboseHLine(rowinfo_[row].lines_); + os << verboseHLine(rowinfo_[row].lines); // don't write & and empty cells at end of line, // unless there are vertical lines col_type lastcol = 0; @@ -1260,10 +1284,10 @@ void InsetMathGrid::write(WriteStream & os, for (col_type col = beg_col; col < end_col; ++col) { idx_type const idx = index(row, col); bool const empty_cell = cell(idx).empty(); - if (!empty_cell || cellinfo_[idx].multi_ != CELL_NORMAL) + if (!empty_cell || cellinfo_[idx].multi != CELL_NORMAL) last_eoln = false; - if (!empty_cell || cellinfo_[idx].multi_ != CELL_NORMAL || - colinfo_[col + 1].lines_) { + if (!empty_cell || cellinfo_[idx].multi != CELL_NORMAL || + colinfo_[col + 1].lines) { lastcol = col + 1; emptyline = false; } @@ -1278,20 +1302,20 @@ void InsetMathGrid::write(WriteStream & os, continue; } Changer dummy = os.changeRowEntry(entry); - if (cellinfo_[idx].multi_ == CELL_BEGIN_OF_MULTICOLUMN) { + if (cellinfo_[idx].multi == CELL_BEGIN_OF_MULTICOLUMN) { size_t s = col + 1; while (s < ncols() && - cellinfo_[index(row, s)].multi_ == CELL_PART_OF_MULTICOLUMN) + cellinfo_[index(row, s)].multi == CELL_PART_OF_MULTICOLUMN) s++; nccols = s - col; os << "\\multicolumn{" << nccols - << "}{" << cellinfo_[idx].align_ + << "}{" << cellinfo_[idx].align << "}{"; } os << cell(idx); if (os.pendingBrace()) ModeSpecifier specifier(os, TEXT_MODE); - if (cellinfo_[idx].multi_ == CELL_BEGIN_OF_MULTICOLUMN) + if (cellinfo_[idx].multi == CELL_BEGIN_OF_MULTICOLUMN) os << '}'; os << eocString(col + nccols - 1, lastcol); col += nccols; @@ -1305,7 +1329,7 @@ void InsetMathGrid::write(WriteStream & os, os << "\n"; } // @TODO use end_row instead of nrows() ? - docstring const s = verboseHLine(rowinfo_[nrows()].lines_); + docstring const s = verboseHLine(rowinfo_[nrows()].lines); if (!s.empty()) { if (eol.empty()) { if (os.fragile()) @@ -1356,7 +1380,7 @@ void InsetMathGrid::splitCell(Cursor & cur) cur.cell().erase(cur.pos(), cur.lastpos()); ++cur.idx(); while (cur.idx() << nargs() && - cellinfo_[cur.idx()].multi_ == CELL_BEGIN_OF_MULTICOLUMN) + cellinfo_[cur.idx()].multi == CELL_BEGIN_OF_MULTICOLUMN) ++cur.idx(); cur.pos() = 0; cur.cell().insert(0, ar); @@ -1365,23 +1389,23 @@ void InsetMathGrid::splitCell(Cursor & cur) char InsetMathGrid::displayColAlign(idx_type idx) const { - if (cellinfo_[idx].multi_ == CELL_BEGIN_OF_MULTICOLUMN) { - // align_ may also contain lines like "||r|", so this is + if (cellinfo_[idx].multi == CELL_BEGIN_OF_MULTICOLUMN) { + // align may also contain lines like "||r|", so this is // not complete, but we catch at least the simple cases. - if (cellinfo_[idx].align_ == "c") + if (cellinfo_[idx].align == "c") return 'c'; - if (cellinfo_[idx].align_ == "l") + if (cellinfo_[idx].align == "l") return 'l'; - if (cellinfo_[idx].align_ == "r") + if (cellinfo_[idx].align == "r") return 'r'; } - return colinfo_[col(idx)].align_; + return colinfo_[col(idx)].align; } int InsetMathGrid::displayColSpace(col_type col) const { - return colinfo_[col].skip_; + return colinfo_[col].skip; } void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) @@ -1415,25 +1439,6 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) splitCell(cur); break; - case LFUN_CELL_BACKWARD: - // See below. - cur.selection(false); - if (!idxPrev(cur)) { - cmd = FuncRequest(LFUN_FINISHED_BACKWARD); - cur.undispatched(); - } - break; - - case LFUN_CELL_FORWARD: - // Can't handle selection by additional 'shift' as this is - // hard bound to LFUN_CELL_BACKWARD - cur.selection(false); - if (!idxNext(cur)) { - cmd = FuncRequest(LFUN_FINISHED_FORWARD); - cur.undispatched(); - } - break; - case LFUN_NEWLINE_INSERT: { cur.recordUndoInset(); row_type const r = cur.row(); @@ -1502,13 +1507,13 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) cur.pos() = 0; } else if (s == "add-hline-above") - rowinfo_[cur.row()].lines_++; + rowinfo_[cur.row()].lines++; else if (s == "add-hline-below") - rowinfo_[cur.row()+1].lines_++; + rowinfo_[cur.row()+1].lines++; else if (s == "delete-hline-above") - rowinfo_[cur.row()].lines_--; + rowinfo_[cur.row()].lines--; else if (s == "delete-hline-below") - rowinfo_[cur.row()+1].lines_--; + rowinfo_[cur.row()+1].lines--; else if (s == "append-column") { row_type const r = cur.row(); col_type const c = cur.col(); @@ -1536,18 +1541,18 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) cur.pos() = 0; // trick, see above } else if (s == "add-vline-left") { - colinfo_[cur.col()].lines_++; - if (!colinfo_[cur.col()].special_.empty()) - colinfo_[cur.col()].special_ += '|'; + colinfo_[cur.col()].lines++; + if (!colinfo_[cur.col()].special.empty()) + colinfo_[cur.col()].special += '|'; } else if (s == "add-vline-right") { - colinfo_[cur.col()+1].lines_++; - if (!colinfo_[cur.col()+1].special_.empty()) - colinfo_[cur.col()+1].special_.insert(0, 1, '|'); + colinfo_[cur.col()+1].lines++; + if (!colinfo_[cur.col()+1].special.empty()) + colinfo_[cur.col()+1].special.insert(0, 1, '|'); } else if (s == "delete-vline-left") { - colinfo_[cur.col()].lines_--; - docstring & special = colinfo_[cur.col()].special_; + colinfo_[cur.col()].lines--; + docstring & special = colinfo_[cur.col()].special; if (!special.empty()) { docstring::size_type i = special.rfind('|'); LASSERT(i != docstring::npos, break); @@ -1555,8 +1560,8 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) } } else if (s == "delete-vline-right") { - colinfo_[cur.col()+1].lines_--; - docstring & special = colinfo_[cur.col()+1].special_; + colinfo_[cur.col()+1].lines--; + docstring & special = colinfo_[cur.col()+1].special; if (!special.empty()) { docstring::size_type i = special.find('|'); LASSERT(i != docstring::npos, break); @@ -1608,9 +1613,9 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) cur.cell().insert(cur.pos(), grid.cell(0)); cur.pos() += grid.cell(0).size(); if (hline_enabled) - rowinfo_[cur.row()].lines_ += grid.rowinfo_[0].lines_; + rowinfo_[cur.row()].lines += grid.rowinfo_[0].lines; else { - for (unsigned int l = 0; l < grid.rowinfo_[0].lines_; ++l) { + for (unsigned int l = 0; l < grid.rowinfo_[0].lines; ++l) { cur.cell().insert(0, MathAtom(new InsetMathUnknown(from_ascii("\\hline")))); cur.pos()++; @@ -1619,38 +1624,49 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) } else { // multiple cells cur.recordUndoInset(); - col_type const numcols = - min(grid.ncols(), ncols() - col(cur.idx())); + col_type startcol = col(cur.idx()); + row_type startrow = cur.row(); + col_type oldncols = ncols(); + col_type numcols = + min(grid.ncols(), ncols() - startcol); row_type const numrows = min(grid.nrows(), nrows() - cur.row()); for (row_type r = 0; r < numrows; ++r) { for (col_type c = 0; c < numcols; ++c) { - idx_type i = index(r + cur.row(), c + col(cur.idx())); - cell(i).insert(0, grid.cell(grid.index(r, c))); + idx_type i = index(r + startrow, c + startcol); + cell(i).insert(c == 0 ? cur.pos() : 0, + grid.cell(grid.index(r, c))); } if (hline_enabled) - rowinfo_[r].lines_ += grid.rowinfo_[r].lines_; + rowinfo_[r].lines += grid.rowinfo_[r].lines; else { - for (unsigned int l = 0; l < grid.rowinfo_[r].lines_; ++l) { - idx_type i = index(r + cur.row(), 0); + for (unsigned int l = 0; l < grid.rowinfo_[r].lines; ++l) { + idx_type i = index(r + startrow, 0); cell(i).insert(0, MathAtom(new InsetMathUnknown(from_ascii("\\hline")))); } } - // append the left over horizontal cells to the last column - idx_type i = index(r + cur.row(), ncols() - 1); - for (InsetMath::col_type c = numcols; c < grid.ncols(); ++c) + // append columns for the left over horizontal cells + for (InsetMath::col_type c = numcols; c < grid.ncols(); ++c) { + addCol(c + startcol); + idx_type i = index(r + startrow, min(c + startcol, ncols() - 1)); cell(i).append(grid.cell(grid.index(r, c))); + ++numcols; + } } - // append the left over vertical cells to the last _cell_ + // amend cursor position if cols have been appended + cur.idx() += startrow * (ncols() - oldncols); + // append rows for the left over vertical cells idx_type i = nargs() - 1; for (row_type r = numrows; r < grid.nrows(); ++r) { + row_type crow = startrow + r; + addRow(crow - 1); for (col_type c = 0; c < grid.ncols(); ++c) - cell(i).append(grid.cell(grid.index(r, c))); + cell(index(min(crow, nrows() - 1), min(c + startcol, ncols() - 1))).append(grid.cell(grid.index(r, c))); if (hline_enabled) - rowinfo_[r].lines_ += grid.rowinfo_[r].lines_; + rowinfo_[crow].lines += grid.rowinfo_[r].lines; else { - for (unsigned int l = 0; l < grid.rowinfo_[r].lines_; ++l) { + for (unsigned int l = 0; l < grid.rowinfo_[r].lines; ++l) { cell(i).insert(0, MathAtom(new InsetMathUnknown(from_ascii("\\hline")))); } @@ -1740,18 +1756,18 @@ bool InsetMathGrid::getStatus(Cursor & cur, FuncRequest const & cmd, status.message(from_utf8(N_("Only one column"))); return true; } - if ((rowinfo_[cur.row()].lines_ == 0 && + if ((rowinfo_[cur.row()].lines == 0 && s == "delete-hline-above") || - (rowinfo_[cur.row() + 1].lines_ == 0 && + (rowinfo_[cur.row() + 1].lines == 0 && s == "delete-hline-below")) { status.setEnabled(false); status.message(from_utf8(N_("No hline to delete"))); return true; } - if ((colinfo_[cur.col()].lines_ == 0 && + if ((colinfo_[cur.col()].lines == 0 && s == "delete-vline-left") || - (colinfo_[cur.col() + 1].lines_ == 0 && + (colinfo_[cur.col() + 1].lines == 0 && s == "delete-vline-right")) { status.setEnabled(false); status.message(from_utf8(N_("No vline to delete"))); @@ -1787,25 +1803,6 @@ bool InsetMathGrid::getStatus(Cursor & cur, FuncRequest const & cmd, from_utf8(s))); } -#if 0 - // FIXME: What did this code do? - // Please check whether it is still needed! - // should be more precise - if (v_align_ == '\0') { - status.enable(true); - break; - } - if (cmd.argument().empty()) { - status.enable(false); - break; - } - if (!contains("tcb", cmd.argument()[0])) { - status.enable(false); - break; - } - status.setOnOff(cmd.argument()[0] == v_align_); - status.setEnabled(true); -#endif return true; } @@ -1825,16 +1822,22 @@ bool InsetMathGrid::getStatus(Cursor & cur, FuncRequest const & cmd, } -// static -char InsetMathGrid::colAlign(HullType type, col_type col) +char InsetMathGrid::colAlign(HullType type, col_type col) const { switch (type) { case hullEqnArray: return "rcl"[col % 3]; case hullMultline: - case hullGather: return 'c'; + case hullGather: + LASSERT(isBufferValid(), + LYXERR0("Buffer not set correctly. Please report!"); + return 'c';); + if (buffer().params().is_math_indent) + return 'l'; + else + return 'c'; case hullAlign: case hullAlignAt: