]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/math_hullinset.C
Make Helge happy: no more crash on arrow up/down in math macro
[lyx.git] / src / mathed / math_hullinset.C
index 534c77fc0f347f26fdb37931af6d2ac8f9eced56..092b15decdc6b9b05577072876d7bfab41b37497 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "BufferView.h"
 #include "CutAndPaste.h"
+#include "FuncStatus.h"
 #include "LColor.h"
 #include "LaTeXFeatures.h"
 #include "cursor.h"
@@ -30,6 +31,7 @@
 #include "lyx_main.h"
 #include "lyxrc.h"
 #include "outputparams.h"
+#include "sgml.h"
 #include "textpainter.h"
 #include "undo.h"
 
 #include "graphics/PreviewImage.h"
 #include "graphics/PreviewLoader.h"
 
+#include "support/lstrings.h"
+
 #include <boost/bind.hpp>
 
 #include <sstream>
 
 using lyx::cap::grabAndEraseSelection;
+using lyx::support::bformat;
+using lyx::support::subst;
 
 using std::endl;
 using std::max;
@@ -110,7 +116,7 @@ namespace {
                if (s == "gather")    return 9;
                if (s == "flalign")   return 10;
                lyxerr << "unknown hull type '" << s << "'" << endl;
-               return 0;
+               return -1;
        }
 
        bool smaller(string const & s, string const & t)
@@ -154,21 +160,23 @@ MathHullInset::~MathHullInset()
 {}
 
 
-auto_ptr<InsetBase> MathHullInset::clone() const
+auto_ptr<InsetBase> MathHullInset::doClone() const
 {
        return auto_ptr<InsetBase>(new MathHullInset(*this));
 }
 
 
-void MathHullInset::operator=(MathHullInset const & other)
+MathHullInset & MathHullInset::operator=(MathHullInset const & other)
 {
        if (this == &other)
-               return;
+               return *this;
        *static_cast<MathGridInset*>(this) = MathGridInset(other);
        type_  = other.type_;
        nonum_ = other.nonum_;
        label_ = other.label_;
        preview_.reset(new RenderPreview(*other.preview_, this));
+
+       return *this;
 }
 
 
@@ -530,6 +538,16 @@ void MathHullInset::footer_write(WriteStream & os) const
 }
 
 
+bool MathHullInset::rowChangeOK() const
+{
+       return
+               type_ == "eqnarray" || type_ == "align" ||
+               type_ == "flalign" || type_ == "alignat" ||
+               type_ == "xalignat" || type_ == "xxalignat" ||
+               type_ == "gather" || type_ == "multline";
+}
+
+
 bool MathHullInset::colChangeOK() const
 {
        return
@@ -540,6 +558,8 @@ bool MathHullInset::colChangeOK() const
 
 void MathHullInset::addRow(row_type row)
 {
+       if (!rowChangeOK())
+               return;
        nonum_.insert(nonum_.begin() + row + 1, !numberedType());
        label_.insert(label_.begin() + row + 1, string());
        MathGridInset::addRow(row);
@@ -548,7 +568,7 @@ void MathHullInset::addRow(row_type row)
 
 void MathHullInset::swapRow(row_type row)
 {
-       if (nrows() == 1)
+       if (nrows() <= 1)
                return;
        if (row + 1 == nrows())
                --row;
@@ -560,7 +580,7 @@ void MathHullInset::swapRow(row_type row)
 
 void MathHullInset::delRow(row_type row)
 {
-       if (nrows() <= 1)
+       if (nrows() <= 1 || !rowChangeOK())
                return;
        MathGridInset::delRow(row);
        nonum_.erase(nonum_.begin() + row);
@@ -570,19 +590,17 @@ void MathHullInset::delRow(row_type row)
 
 void MathHullInset::addCol(col_type col)
 {
-       if (colChangeOK())
-               MathGridInset::addCol(col);
-       else
-               lyxerr << "Can't change number of columns in '" << type_ << "'" << endl;
+       if (!colChangeOK())
+               return;
+       MathGridInset::addCol(col);
 }
 
 
 void MathHullInset::delCol(col_type col)
 {
-       if (colChangeOK())
-               MathGridInset::delCol(col);
-       else
-               lyxerr << "Can't change number of columns in '" << type_ << "'" << endl;
+       if (ncols() <= 1 || !colChangeOK())
+               return;
+       MathGridInset::delCol(col);
 }
 
 
@@ -700,6 +718,10 @@ void MathHullInset::mutate(string const & newtype)
                // done
        }
 
+       else if (typecode(newtype) < 0) {
+               // unknown type
+       }
+
        else if (type_ == "none") {
                setType("simple");
                numbered(0, false);
@@ -950,7 +972,7 @@ void MathHullInset::doExtern(LCursor & cur, FuncRequest & func)
 }
 
 
-void MathHullInset::priv_dispatch(LCursor & cur, FuncRequest & cmd)
+void MathHullInset::doDispatch(LCursor & cur, FuncRequest & cmd)
 {
        switch (cmd.action) {
 
@@ -958,7 +980,7 @@ void MathHullInset::priv_dispatch(LCursor & cur, FuncRequest & cmd)
        case LFUN_FINISHED_RIGHT:
        case LFUN_FINISHED_UP:
        case LFUN_FINISHED_DOWN:
-               MathGridInset::priv_dispatch(cur, cmd);
+               MathGridInset::doDispatch(cur, cmd);
                notifyCursorLeaves(cur);
                break;
 
@@ -974,7 +996,7 @@ void MathHullInset::priv_dispatch(LCursor & cur, FuncRequest & cmd)
                        cur.idx() = 0;
                        cur.pos() = cur.lastpos();
                }
-               MathGridInset::priv_dispatch(cur, cmd);
+               MathGridInset::doDispatch(cur, cmd);
                break;
 
        case LFUN_MATH_NUMBER:
@@ -1056,7 +1078,7 @@ void MathHullInset::priv_dispatch(LCursor & cur, FuncRequest & cmd)
        }
 
        default:
-               MathGridInset::priv_dispatch(cur, cmd);
+               MathGridInset::doDispatch(cur, cmd);
                break;
        }
 }
@@ -1074,27 +1096,49 @@ bool MathHullInset::getStatus(LCursor & cur, FuncRequest const & cmd,
        case LFUN_MATH_MUTATE:
        case LFUN_MATH_DISPLAY:
                // we handle these
+               flag.enabled(true);
                return true;
        case LFUN_TABULAR_FEATURE: {
-               // should be more precise
                istringstream is(cmd.argument);
                string s;
                is >> s;
-               if ((type_ == "simple" || type_ == "equation")
-        && (s == "append-column"
-         || s == "delete-column"
-         || s == "swap-column"
-         || s == "copy-column"
-         || s == "delete-column"
-         || s == "append-row"
-         || s == "delete-row"
-         || s == "swap-row"
-         || s == "copy-row"))
-                       return false;
-               if ((type_ == "eqnarray")
-        && (s == "appen-column"
-         || s == "delete-column"))
-                       return false;
+               if (!rowChangeOK()
+                   && (s == "append-row"
+                       || s == "delete-row"
+                       || s == "copy-row")) {
+                       flag.message(bformat(
+                               N_("Can't change number of rows in '%1$s'"),
+                               type_));
+                       flag.enabled(false);
+                       return true;
+               }
+               if (!colChangeOK()
+                   && (s == "append-column"
+                       || s == "delete-column"
+                       || s == "copy-column")) {
+                       flag.message(bformat(
+                               N_("Can't change number of columns in '%1$s'"),
+                               type_));
+                       flag.enabled(false);
+                       return true;
+               }
+               if ((type_ == "simple" 
+                 || type_ == "equation" 
+                 || type_ == "none") &&
+                   (s == "add-hline-above" || s == "add-hline-below")) {
+                       flag.message(bformat(
+                               N_("Can't add horizontal grid lines in '%1$s'"),
+                               type_));
+                       flag.enabled(false);
+                       return true;
+               }
+               if (s == "add-vline-left" || s == "add-vline-right") { 
+                       flag.message(bformat(
+                               N_("Can't add vertical grid lines in '%1$s'"),
+                               type_));
+                       flag.enabled(false);
+                       return true;
+               }
                return MathGridInset::getStatus(cur, cmd, flag);
        }
        default:
@@ -1118,7 +1162,6 @@ bool MathHullInset::getStatus(LCursor & cur, FuncRequest const & cmd,
 #include "frontends/LyXView.h"
 #include "frontends/Dialogs.h"
 
-#include "support/lstrings.h"
 #include "support/lyxlib.h"
 
 
@@ -1338,19 +1381,41 @@ int MathHullInset::docbook(Buffer const & buf, ostream & os,
                name = "informalequation";
 
        string bname = name;
-       if (! label(0).empty()) bname += " id=\"" + label(0)+ "\"";
+       if (!label(0).empty())
+               bname += " id=\"" + sgml::cleanID(buf, runparams, label(0)) + "\"";
        ms << MTag(bname.c_str());
 
+       ostringstream ls;
        if (runparams.flavor == OutputParams::XML) {
-               ms <<   MTag("math");
+               ms << MTag("alt role=\"tex\" ");
+               // 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);
+               MathGridInset::write(wi);
+               ms << subst(subst(ls.str(), "&", "&amp;"), "<", "&lt;");
+               ms << ETag("alt");
+               ms << MTag("math");
                MathGridInset::mathmlize(ms);
-               ms <<   ETag("math");
+               ms << ETag("math");
        } else {
-               ms <<   MTag("alt");
-               res = latex(buf, ms.os(), runparams);
-               ms <<   ETag("alt");
+               ms << MTag("alt role=\"tex\"");
+               res = latex(buf, ls, runparams);
+               ms << subst(subst(ls.str(), "&", "&amp;"), "<", "&lt;");
+               ms << ETag("alt");
        }
 
+       ms <<  "<graphic fileref=\"eqn/";
+       if ( !label(0).empty())
+               ms << sgml::cleanID(buf, runparams, label(0));
+       else {
+               ms << sgml::uniqueID("anon");
+       }
+       if (runparams.flavor == OutputParams::XML)
+               ms << "\"/>";
+       else
+               ms << "\">";
+
        ms << ETag(name.c_str());
        return ms.line() + res;
 }