X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathGrid.cpp;h=67300403907d947f43f1ca71e2b75323bf2192e6;hb=31cd421bcd26647cb7edbb694b05473271fe9153;hp=536f4bd163a671347d7a15150f7da6c407a1d4bb;hpb=764a2163bb6437fdd150a6a60db2573412f10d37;p=lyx.git diff --git a/src/mathed/InsetMathGrid.cpp b/src/mathed/InsetMathGrid.cpp index 536f4bd163..6730040390 100644 --- a/src/mathed/InsetMathGrid.cpp +++ b/src/mathed/InsetMathGrid.cpp @@ -22,10 +22,12 @@ #include "Buffer.h" #include "BufferParams.h" #include "BufferView.h" -#include "CutAndPaste.h" -#include "FuncStatus.h" #include "Cursor.h" +#include "CutAndPaste.h" #include "FuncRequest.h" +#include "FuncStatus.h" +#include "LaTeXFeatures.h" +#include "TexRow.h" #include "frontends/Clipboard.h" #include "frontends/Painter.h" @@ -34,7 +36,6 @@ #include "support/docstream.h" #include "support/gettext.h" #include "support/lstrings.h" - #include "support/lassert.h" #include @@ -81,7 +82,7 @@ static void resetGrid(InsetMathGrid & grid) InsetMathGrid::CellInfo::CellInfo() - : multi_(CELL_NORMAL), glue_(0), begin_(0), end_(0) + : multi_(CELL_NORMAL) {} @@ -181,7 +182,7 @@ void InsetMathGrid::setDefaults() bool InsetMathGrid::interpretString(Cursor & cur, docstring const & str) { if (str == "\\hline") { - FuncRequest fr = FuncRequest(LFUN_INSET_MODIFY, "tabular add-hline-above"); + FuncRequest fr = FuncRequest(LFUN_TABULAR_FEATURE, "add-hline-above"); FuncStatus status; if (getStatus(cur, fr, status)) { if (status.enabled()) { @@ -417,7 +418,6 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const rowinfo_[row].ascent_ = asc; rowinfo_[row].descent_ = desc; } - rowinfo_[0].ascent_ += hlinesep() * rowinfo_[0].lines_; rowinfo_[nrows()].ascent_ = 0; rowinfo_[nrows()].descent_ = 0; @@ -481,12 +481,12 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const colinfo_[ncols()].width_ = 0; // compute horizontal offsets - colinfo_[0].offset_ = border(); + 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 - 1].skip_ + + displayColSpace(col - 1) + colsep() + colinfo_[col].lines_ * vlinesep(); } @@ -508,7 +508,7 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const int const nextoffset = colinfo_[first].offset_ + wid + - colinfo_[last].skip_ + + displayColSpace(last) + colsep() + colinfo_[last+1].lines_ * vlinesep(); int const dx = nextoffset - colinfo_[last+1].offset_; @@ -534,7 +534,7 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const dim.des = rowinfo_[nrows() - 1].offset_ + rowinfo_[nrows() - 1].descent_ + hlinesep() * rowinfo_[nrows()].lines_ - + border(); + + border() + 1; /* @@ -587,82 +587,71 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const cxrow->setBaseline(cxrow->getBaseline() - ascent); } */ - metricsMarkers2(dim); - // Cache the inset dimension. - setDimCache(mi, dim); + dim.wid += leftMargin() + rightMargin(); } -void InsetMathGrid::draw(PainterInfo & pi, int x, int y) const +int InsetMathGrid::vLineHOffset(col_type col, unsigned int line) const { - drawWithMargin(pi, x, y, 1, 1); + if (col < ncols()) + 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_ + + line * vlinesep() + + vlinesep()/2 + colsep()/2; + } } -void InsetMathGrid::drawWithMargin(PainterInfo & pi, int x, int y, - int lmargin, int rmargin) const +int InsetMathGrid::hLineVOffset(row_type row, unsigned int line) const +{ + return rowinfo_[row].offset_ + - rowinfo_[row].ascent_ + - line * hlinesep() + - hlinesep()/2 - rowsep()/2; +} + + +void InsetMathGrid::draw(PainterInfo & pi, int x, int y) const { - Dimension const dim = dimension(*pi.base.bv); BufferView const & bv = *pi.base.bv; for (idx_type idx = 0; idx < nargs(); ++idx) { if (cellinfo_[idx].multi_ != CELL_PART_OF_MULTICOLUMN) { cell(idx).draw(pi, - x + lmargin + cellXOffset(bv, idx), - y + cellYOffset(idx)); - - // draw inner lines cell by cell because of possible multicolumns - // FIXME: multicolumn lines are not yet considered - row_type const r = row(idx); - col_type const c = col(idx); - if (r > 0 && r < nrows()) { - for (unsigned int i = 0; i < rowinfo_[r].lines_; ++i) { - int yy = y + rowinfo_[r].offset_ - - rowinfo_[r].ascent_ - - i * hlinesep() - - hlinesep()/2 - rowsep()/2; - pi.pain.line( - x + lmargin + colinfo_[c].offset_, - yy, - x + lmargin + colinfo_[c+1].offset_, - yy, Color_foreground); - } - } - if (c > 0 && c < ncols()) { + x + leftMargin() + cellXOffset(bv, idx), + y + cellYOffset(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); + auto draw_left_borders = [&](col_type c) { for (unsigned int i = 0; i < colinfo_[c].lines_; ++i) { - int xx = x + lmargin - + colinfo_[c].offset_ - - i * vlinesep() - - vlinesep()/2 - colsep()/2; - pi.pain.line(xx, - rowinfo_[r].offset_ - rowinfo_[r].ascent_, - xx, - rowinfo_[r].offset_ + rowinfo_[r].descent_, - Color_foreground); + int const xx = x + vLineHOffset(c, i); + pi.pain.line(xx, yy1, xx, yy2, Color_foreground); } - } + }; + col_type c = col(idx); + // Draw inner left borders cell-by-cell because of multicolumns + draw_left_borders(c); + // Draw the right border (only once) + if (c == 0) + draw_left_borders(ncols()); } } - // draw outer lines in one go - for (row_type row = 0; row <= nrows(); row += nrows()) - for (unsigned int i = 0; i < rowinfo_[row].lines_; ++i) { - int yy = y + rowinfo_[row].offset_ - rowinfo_[row].ascent_ - - i * hlinesep() - hlinesep()/2 - rowsep()/2; - pi.pain.line(x + lmargin + 1, yy, - x + dim.width() - rmargin - 1, yy, - Color_foreground); + // 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); + pi.pain.line(xx1, yy, xx2, yy, Color_foreground); } - - for (col_type col = 0; col <= ncols(); col += ncols()) - for (unsigned int i = 0; i < colinfo_[col].lines_; ++i) { - int xx = x + lmargin + colinfo_[col].offset_ - - i * vlinesep() - vlinesep()/2 - colsep()/2; - pi.pain.line(xx, y - dim.ascent() + 1, - xx, y + dim.descent() - 1, - Color_foreground); - } - drawMarkers2(pi, x, y); + } } @@ -690,7 +679,6 @@ void InsetMathGrid::metricsT(TextMetricsInfo const & mi, Dimension & dim) const rowinfo_[row].ascent_ = asc; rowinfo_[row].descent_ = desc; } - //rowinfo_[0].ascent_ += hlinesep() * rowinfo_[0].lines_; rowinfo_[nrows()].ascent_ = 0; rowinfo_[nrows()].descent_ = 0; @@ -741,7 +729,7 @@ void InsetMathGrid::metricsT(TextMetricsInfo const & mi, Dimension & dim) const colinfo_[col].offset_ = colinfo_[col - 1].offset_ + colinfo_[col - 1].width_ + - colinfo_[col - 1].skip_ + + displayColSpace(col - 1) + 1 ; //colsep() + //colinfo_[col].lines_ * vlinesep(); } @@ -953,7 +941,7 @@ int InsetMathGrid::cellWidth(idx_type idx) const col_type c2 = c1 + ncellcols(idx); return colinfo_[c2].offset_ - colinfo_[c1].offset_ - - colinfo_[c2].skip_ + - displayColSpace(c2) - colsep() - colinfo_[c2].lines_ * vlinesep(); } @@ -1237,6 +1225,20 @@ void InsetMathGrid::htmlize(HtmlStream & os) const } +void InsetMathGrid::validate(LaTeXFeatures & features) const +{ + if (features.runparams().math_flavor == OutputParams::MathAsHTML + && (nrows() > 1 || ncols() > 1)) { + // CSS taken from InsetMathCases + features.addCSSSnippet( + "table.mathtable{display: inline-block; text-align: center; border: none;" + "border-left: thin solid black; vertical-align: middle; padding-left: 0.5ex;}\n" + "table.mathtable td {text-align: left; border: none;}"); + } + InsetMathNest::validate(features); +} + + void InsetMathGrid::write(WriteStream & os) const { write(os, 0, 0, nrows(), ncols()); @@ -1269,13 +1271,13 @@ void InsetMathGrid::write(WriteStream & os, for (col_type col = beg_col; col < end_col;) { int nccols = 1; idx_type const idx = index(row, col); - TexRow::RowEntry entry = os.texrow().mathEntry(id(),idx); - os.texrow().startMath(id(),idx); + TexRow::RowEntry entry = TexRow::mathEntry(id(),idx); + os.texrow().start(entry); if (col >= lastcol) { ++col; continue; } - os.pushRowEntry(entry); + Changer dummy = os.changeRowEntry(entry); if (cellinfo_[idx].multi_ == CELL_BEGIN_OF_MULTICOLUMN) { size_t s = col + 1; while (s < ncols() && @@ -1293,7 +1295,6 @@ void InsetMathGrid::write(WriteStream & os, os << '}'; os << eocString(col + nccols - 1, lastcol); col += nccols; - os.popRowEntry(); } eol = eolString(row, os.fragile(), os.latex(), last_eoln); os << eol; @@ -1378,6 +1379,11 @@ char InsetMathGrid::displayColAlign(idx_type idx) const } +int InsetMathGrid::displayColSpace(col_type col) const +{ + return colinfo_[col].skip_; +} + void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) { //lyxerr << "*** InsetMathGrid: request: " << cmd << endl; @@ -1411,7 +1417,7 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_CELL_BACKWARD: // See below. - cur.setSelection(false); + cur.selection(false); if (!idxPrev(cur)) { cmd = FuncRequest(LFUN_FINISHED_BACKWARD); cur.undispatched(); @@ -1421,7 +1427,7 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_CELL_FORWARD: // Can't handle selection by additional 'shift' as this is // hard bound to LFUN_CELL_BACKWARD - cur.setSelection(false); + cur.selection(false); if (!idxNext(cur)) { cmd = FuncRequest(LFUN_FINISHED_FORWARD); cur.undispatched(); @@ -1450,17 +1456,12 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) break; } - case LFUN_INSET_MODIFY: { + case LFUN_TABULAR_FEATURE: { cur.recordUndoInset(); //lyxerr << "handling tabular-feature " << to_utf8(cmd.argument()) << endl; istringstream is(to_utf8(cmd.argument())); string s; is >> s; - if (s != "tabular") { - InsetMathNest::doDispatch(cur, cmd); - return; - } - is >> s; if (s == "valign-top") setVerticalAlignment('t'); else if (s == "valign-middle") @@ -1575,13 +1576,13 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) parseflg |= Parse::VERBATIM; // fall through case LFUN_PASTE: { - if (cur.currentMode() <= TEXT_MODE) + if (cur.currentMode() != MATH_MODE) parseflg |= Parse::TEXTMODE; cur.message(_("Paste")); cap::replaceSelection(cur); docstring topaste; if (cmd.argument().empty() && !theClipboard().isInternal()) - topaste = theClipboard().getAsText(Clipboard::PlainTextType); + topaste = theClipboard().getAsText(frontend::Clipboard::PlainTextType); else { idocstringstream is(cmd.argument()); int n = 0; @@ -1597,7 +1598,7 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) } bool hline_enabled = false; - FuncRequest fr = FuncRequest(LFUN_INSET_MODIFY, "tabular add-hline-above"); + FuncRequest fr = FuncRequest(LFUN_TABULAR_FEATURE, "add-hline-above"); FuncStatus status; if (getStatus(cur, fr, status)) hline_enabled = status.enabled(); @@ -1665,13 +1666,9 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) } case LFUN_LINE_BEGIN: - case LFUN_WORD_BACKWARD: - case LFUN_WORD_LEFT: cur.screenUpdateFlags(Update::Decoration | Update::FitCursor); // fall through case LFUN_LINE_BEGIN_SELECT: - case LFUN_WORD_BACKWARD_SELECT: - case LFUN_WORD_LEFT_SELECT: cur.selHandle(act == LFUN_WORD_BACKWARD_SELECT || act == LFUN_WORD_LEFT_SELECT || act == LFUN_LINE_BEGIN_SELECT); @@ -1690,13 +1687,9 @@ void InsetMathGrid::doDispatch(Cursor & cur, FuncRequest & cmd) } break; - case LFUN_WORD_FORWARD: - case LFUN_WORD_RIGHT: case LFUN_LINE_END: cur.screenUpdateFlags(Update::Decoration | Update::FitCursor); // fall through - case LFUN_WORD_FORWARD_SELECT: - case LFUN_WORD_RIGHT_SELECT: case LFUN_LINE_END_SELECT: cur.selHandle(act == LFUN_WORD_FORWARD_SELECT || act == LFUN_WORD_RIGHT_SELECT || @@ -1727,14 +1720,8 @@ bool InsetMathGrid::getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus & status) const { switch (cmd.action()) { - case LFUN_INSET_MODIFY: { - istringstream is(to_utf8(cmd.argument())); - string s; - is >> s; - if (s != "tabular") { - // We only now about table actions here. - break; - } + case LFUN_TABULAR_FEATURE: { + string s = cmd.getArg(0); if (&cur.inset() != this) { // Table actions requires that the cursor is _inside_ the // table. @@ -1742,7 +1729,6 @@ bool InsetMathGrid::getStatus(Cursor & cur, FuncRequest const & cmd, status.message(from_utf8(N_("Cursor not in table"))); return true; } - is >> s; if (nrows() <= 1 && (s == "delete-row" || s == "swap-row")) { status.setEnabled(false); status.message(from_utf8(N_("Only one row"))); @@ -1797,7 +1783,8 @@ bool InsetMathGrid::getStatus(Cursor & cur, FuncRequest const & cmd, } else { status.setEnabled(false); status.message(bformat( - from_utf8(N_("Unknown tabular feature '%1$s'")), lyx::from_ascii(s))); + from_utf8(N_("Unknown tabular feature '%1$s'")), + from_utf8(s))); } #if 0 @@ -1838,4 +1825,69 @@ bool InsetMathGrid::getStatus(Cursor & cur, FuncRequest const & cmd, } +// static +char InsetMathGrid::colAlign(HullType type, col_type col) +{ + switch (type) { + case hullEqnArray: + return "rcl"[col % 3]; + + case hullMultline: + case hullGather: + return 'c'; + + case hullAlign: + case hullAlignAt: + case hullXAlignAt: + case hullXXAlignAt: + case hullFlAlign: + return "rl"[col & 1]; + + case hullUnknown: + case hullNone: + case hullSimple: + case hullEquation: + case hullRegexp: + return 'c'; + } + // avoid warning + return 'c'; +} + + +//static +int InsetMathGrid::colSpace(HullType type, col_type col) +{ + int alignInterSpace = 0; + switch (type) { + case hullUnknown: + case hullNone: + case hullSimple: + case hullEquation: + case hullMultline: + case hullGather: + case hullRegexp: + return 0; + + case hullEqnArray: + return 5; + + case hullAlign: + alignInterSpace = 20; + break; + case hullAlignAt: + alignInterSpace = 0; + break; + case hullXAlignAt: + alignInterSpace = 40; + break; + case hullXXAlignAt: + case hullFlAlign: + alignInterSpace = 60; + break; + } + return (col % 2) ? alignInterSpace : 0; +} + + } // namespace lyx