]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/InsetMathHull.cpp
Fix bug 5802 (http://bugzilla.lyx.org/show_bug.cgi?id=5802)
[lyx.git] / src / mathed / InsetMathHull.cpp
index 410ae5dc1c6b66287a8389789c8355dd5562df38..15096fb9918f7426764708908ec01a8ee8279b84 100644 (file)
@@ -3,7 +3,7 @@
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
- * \author André Pönitz
+ * \author André Pönitz
  *
  * Full author contact details are available in file CREDITS.
  */
@@ -35,6 +35,7 @@
 #include "Cursor.h"
 #include "DispatchResult.h"
 #include "FuncRequest.h"
+#include "Language.h"
 #include "LyXRC.h"
 #include "OutputParams.h"
 #include "ParIterator.h"
@@ -117,7 +118,8 @@ HullType hullType(docstring const & s)
        if (s == "multline")  return hullMultline;
        if (s == "gather")    return hullGather;
        if (s == "flalign")   return hullFlAlign;
-       lyxerr << "unknown hull type '" << to_utf8(s) << "'" << endl;
+       if (s == "regexp")    return hullRegexp;
+       lyxerr << "unknown hull type '" << to_utf8(s) << "'" << endl;
        return HullType(-1);
 }
 
@@ -136,7 +138,8 @@ docstring hullName(HullType type)
                case hullMultline:   return from_ascii("multline");
                case hullGather:     return from_ascii("gather");
                case hullFlAlign:    return from_ascii("flalign");
-               default:
+               case hullRegexp:     return from_ascii("regexp");
+               default:
                        lyxerr << "unknown hull type '" << type << "'" << endl;
                        return from_ascii("none");
        }
@@ -341,7 +344,7 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const
                dim.wid += 1;
                if (display())
                        dim.des += displayMargin();
-               // Cache the inset dimension. 
+               // Cache the inset dimension.
                setDimCache(mi, dim);
                return;
        }
@@ -379,16 +382,17 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const
 }
 
 
-void InsetMathHull::draw(PainterInfo & pi, int x, int y) const
+void InsetMathHull::drawBackground(PainterInfo & pi, int x, int y) const
 {
-       use_preview_ = previewState(pi.base.bv);
        Dimension const dim = dimension(*pi.base.bv);
+       pi.pain.fillRectangle(x + 1, y - dim.asc + 1, dim.wid - 2,
+               dim.asc + dim.des - 1, pi.backgroundColor(this));
+}
+
 
-       // background of mathed under focus is not painted because
-       // selection at the top level of nested inset is difficult to handle.
-       if (!editing(pi.base.bv))
-               pi.pain.fillRectangle(x + 1, y - dim.asc + 1, dim.wid - 2,
-                               dim.asc + dim.des - 1, Color_mathbg);
+void InsetMathHull::draw(PainterInfo & pi, int x, int y) const
+{
+       use_preview_ = previewState(pi.base.bv);
 
        if (use_preview_) {
                // one pixel gap in front
@@ -445,12 +449,28 @@ void InsetMathHull::drawT(TextPainter & pain, int x, int y) const
 static docstring latexString(InsetMathHull const & inset)
 {
        odocstringstream ls;
-       WriteStream wi(ls, false, false, false);
+       // This has to be static, because a preview snippet containing math
+       // in text mode (such as $\text{$\phi$}$) gets processed twice. The
+       // first time as a whole, and the second time only the inner math.
+       // In this last case inset.buffer() would be invalid.
+       // FIXME: preview snippets should only be processed once, such that
+       // both static qualifier and isBufferValid() check can be dropped.
+       static Encoding const * encoding = 0;
+       if (inset.isBufferValid())
+               encoding = &(inset.buffer().params().encoding());
+       WriteStream wi(ls, false, true, false, encoding);
        inset.write(wi);
        return ls.str();
 }
 
 
+void InsetMathHull::initUnicodeMath() const
+{
+       // Trigger classification of the unicode symbols in this inset
+       docstring const dummy = latexString(*this);
+}
+
+
 void InsetMathHull::addPreview(graphics::PreviewLoader & ploader) const
 {
        if (RenderPreview::status() == LyXRC::PREVIEW_ON) {
@@ -463,10 +483,10 @@ void InsetMathHull::addPreview(graphics::PreviewLoader & ploader) const
 bool InsetMathHull::notifyCursorLeaves(Cursor const & /*old*/, Cursor & cur)
 {
        if (RenderPreview::status() == LyXRC::PREVIEW_ON) {
-               Buffer const & buffer = cur.buffer();
+               Buffer const * buffer = cur.buffer();
                docstring const snippet = latexString(*this);
-               preview_->addPreview(snippet, buffer);
-               preview_->startLoading(buffer);
+               preview_->addPreview(snippet, *buffer);
+               preview_->startLoading(*buffer);
                cur.updateFlags(Update::Force);
        }
        return false;
@@ -489,8 +509,12 @@ void InsetMathHull::label(row_type row, docstring const & label)
                if (label.empty()) {
                        delete label_[row];
                        label_[row] = dummy_pointer;
-               } else
+                       // We need an update of the Buffer reference cache.
+                       // This is achieved by updateLabels().
+                       buffer().updateLabels();
+               } else {
                        label_[row]->updateCommand(label);
+               }
                return;
        }
        InsetCommandParams p(LABEL_CODE);
@@ -507,6 +531,14 @@ void InsetMathHull::numbered(row_type row, bool num)
        if (nonum_[row] && label_[row]) {
                delete label_[row];
                label_[row] = 0;
+               if (!buffer_) {
+                       // The buffer is set at the end of readInset.
+                       // When parsing the inset, buffer_ is 0.
+                       return;
+               }
+               // We need an update of the Buffer reference cache.
+               // This is achieved by updateLabels().
+               buffer().updateLabels();
        }
 }
 
@@ -519,23 +551,23 @@ bool InsetMathHull::numbered(row_type row) const
 
 bool InsetMathHull::ams() const
 {
-       return
-               type_ == hullAlign ||
-               type_ == hullFlAlign ||
-               type_ == hullMultline ||
-               type_ == hullGather ||
-               type_ == hullAlignAt ||
-               type_ == hullXAlignAt ||
-               type_ == hullXXAlignAt;
+       return type_ == hullAlign
+               || type_ == hullFlAlign
+               || type_ == hullMultline
+               || type_ == hullGather
+               || type_ == hullAlignAt
+               || type_ == hullXAlignAt
+               || type_ == hullXXAlignAt;
 }
 
 
 Inset::DisplayType InsetMathHull::display() const
 {
-       return (type_ != hullSimple && type_ != hullNone) ? AlignCenter : Inline;
+       if (type_ == hullSimple || type_ == hullNone || type_ == hullRegexp)
+               return Inline;
+       return AlignCenter;
 }
 
-
 bool InsetMathHull::numberedType() const
 {
        if (type_ == hullNone)
@@ -544,6 +576,8 @@ bool InsetMathHull::numberedType() const
                return false;
        if (type_ == hullXXAlignAt)
                return false;
+       if (type_ == hullRegexp)
+               return false;
        for (row_type row = 0; row < nrows(); ++row)
                if (!nonum_[row])
                        return true;
@@ -556,7 +590,6 @@ void InsetMathHull::validate(LaTeXFeatures & features) const
        if (ams())
                features.require("amsmath");
 
-
        // Validation is necessary only if not using AMS math.
        // To be safe, we will always run mathedvalidate.
        //if (features.amsstyle)
@@ -608,6 +641,10 @@ void InsetMathHull::header_write(WriteStream & os) const
                  << '{' << static_cast<unsigned int>((ncols() + 1)/2) << "}\n";
                break;
 
+       case hullRegexp:
+               os << "\\regexp{";
+               break;
+
        default:
                os << "\\begin{unknown" << star(n) << '}';
                break;
@@ -649,6 +686,10 @@ void InsetMathHull::footer_write(WriteStream & os) const
                os << "\\end{" << hullName(type_) << "}\n";
                break;
 
+       case hullRegexp:
+               os << "}";
+               break;
+
        default:
                os << "\\end{unknown" << star(n) << '}';
                break;
@@ -1008,6 +1049,7 @@ docstring InsetMathHull::eolString(row_type row, bool emptyline, bool fragile) c
 
 void InsetMathHull::write(WriteStream & os) const
 {
+       ModeSpecifier specifier(os, MATH_MODE);
        header_write(os);
        InsetMathGrid::write(os);
        footer_write(os);
@@ -1157,7 +1199,7 @@ void InsetMathHull::doDispatch(Cursor & cur, FuncRequest & cmd)
                else
                        for (row_type row = 0; row < nrows(); ++row)
                                numbered(row, !old);
-               
+
                cur.message(old ? _("No number") : _("Number"));
                break;
        }
@@ -1260,7 +1302,7 @@ void InsetMathHull::doDispatch(Cursor & cur, FuncRequest & cmd)
                }
                if (cur.pos() > cur.lastpos())
                        cur.pos() = cur.lastpos();
-               
+
                // FIXME: find some more clever handling of the selection,
                // i.e. preserve it.
                cur.clearSelection();
@@ -1310,8 +1352,9 @@ bool InsetMathHull::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_MATH_NUMBER_LINE_TOGGLE: {
                // FIXME: what is the right test, this or the one of
                // LABEL_INSERT?
-               bool const enable = (type_ == hullMultline) ?
-                       (nrows() - 1 == cur.row()) : display();
+               bool const enable = (type_ == hullMultline)
+                       ? (nrows() - 1 == cur.row())
+                       : display() != Inline;
                row_type const r = (type_ == hullMultline) ? nrows() - 1 : cur.row();
                status.setEnabled(enable);
                status.setOnOff(numbered(r));
@@ -1441,7 +1484,7 @@ void InsetMathHull::handleFont2(Cursor & cur, docstring const & arg)
 void InsetMathHull::edit(Cursor & cur, bool front, EntryDirection entry_from)
 {
        cur.push(*this);
-       bool enter_front = (entry_from == Inset::ENTRY_DIRECTION_LEFT || 
+       bool enter_front = (entry_from == Inset::ENTRY_DIRECTION_LEFT ||
                (entry_from == Inset::ENTRY_DIRECTION_IGNORE && front));
        enter_front ? idxFirst(cur) : idxLast(cur);
        // The inset formula dimension is not necessarily the same as the
@@ -1561,7 +1604,16 @@ void InsetMathHull::read(Lexer & lex)
 }
 
 
-int InsetMathHull::plaintext(odocstream & os, OutputParams const &) const
+bool InsetMathHull::readQuiet(Lexer & lex)
+{
+       MathAtom at;
+       bool result = mathed_parse_normal(at, lex, Parse::QUIET);
+       operator=(*at->asHullInset());
+       return result;
+}
+
+
+int InsetMathHull::plaintext(odocstream & os, OutputParams const & runparams) const
 {
        if (0 && display()) {
                Dimension dim;
@@ -1575,7 +1627,7 @@ int InsetMathHull::plaintext(odocstream & os, OutputParams const &) const
                return tpain.textheight();
        } else {
                odocstringstream oss;
-               WriteStream wi(oss, false, true, false);
+               WriteStream wi(oss, false, true, false, runparams.encoding);
                wi << cell(0);
 
                docstring const str = oss.str();
@@ -1607,7 +1659,7 @@ int InsetMathHull::docbook(odocstream & os, OutputParams const & runparams) cons
                // Workaround for db2latex: db2latex always includes equations with
                // \ensuremath{} or \begin{display}\end{display}
                // so we strip LyX' math environment
-               WriteStream wi(ls, false, false, false);
+               WriteStream wi(ls, false, false, false, runparams.encoding);
                InsetMathGrid::write(wi);
                ms << from_utf8(subst(subst(to_utf8(ls.str()), "&", "&amp;"), "<", "&lt;"));
                ms << ETag("alt");