#include <config.h>
#include "math_charinset.h"
+#include "math_colorinset.h"
#include "math_data.h"
#include "math_extern.h"
+#include "math_factory.h"
#include "math_hullinset.h"
#include "math_mathmlstream.h"
#include "math_streamstr.h"
#include "math_support.h"
+#include "buffer.h"
+#include "bufferparams.h"
#include "BufferView.h"
#include "CutAndPaste.h"
+#include "FuncStatus.h"
#include "LColor.h"
#include "LaTeXFeatures.h"
#include "cursor.h"
#include "undo.h"
#include "insets/render_preview.h"
+#include "insets/insetlabel.h"
-#include "frontends/Alert.h"
+#include "frontends/Dialogs.h"
+#include "frontends/LyXView.h"
#include "graphics/PreviewImage.h"
#include "graphics/PreviewLoader.h"
#include <sstream>
using lyx::cap::grabAndEraseSelection;
+using lyx::support::bformat;
using lyx::support::subst;
using std::endl;
//lyxerr << "sizeof MetricsInfo: " << sizeof(MetricsInfo) << endl;
//lyxerr << "sizeof MathCharInset: " << sizeof(MathCharInset) << endl;
//lyxerr << "sizeof LyXFont: " << sizeof(LyXFont) << endl;
+ initMath();
setDefaults();
}
: MathGridInset(getCols(type), 1), type_(type), nonum_(1), label_(1),
preview_(new RenderPreview(this))
{
+ initMath();
setDefaults();
}
{}
-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;
+}
+
+
+InsetBase * MathHullInset::editXY(LCursor & cur, int x, int y)
+{
+ if (use_preview_) {
+ edit(cur, true);
+ return this;
+ }
+ return MathNestInset::editXY(cur, x, y);
}
char const * MathHullInset::standardFont() const
{
- if (type_ == "none")
- return "lyxnochange";
- return "mathnormal";
+ return type_ == "none" ? "lyxnochange" : "mathnormal";
}
-void MathHullInset::metrics(MetricsInfo & mi, Dimension & dim) const
+bool MathHullInset::previewState(BufferView * bv) const
{
- BOOST_ASSERT(mi.base.bv && mi.base.bv->buffer());
-
- bool use_preview = false;
- if (!editing(mi.base.bv) &&
- RenderPreview::status() == LyXRC::PREVIEW_ON) {
+ if (!editing(bv) && RenderPreview::status() == LyXRC::PREVIEW_ON) {
lyx::graphics::PreviewImage const * pimage =
- preview_->getPreviewImage(*mi.base.bv->buffer());
- use_preview = pimage && pimage->image();
+ preview_->getPreviewImage(*bv->buffer());
+ return pimage && pimage->image();
}
+ return false;
+}
- if (use_preview) {
+
+void MathHullInset::metrics(MetricsInfo & mi, Dimension & dim) const
+{
+ if (previewState(mi.base.bv)) {
preview_->metrics(mi, dim);
// insert a one pixel gap in front of the formula
dim.wid += 1;
void MathHullInset::draw(PainterInfo & pi, int x, int y) const
{
- BOOST_ASSERT(pi.base.bv && pi.base.bv->buffer());
-
- bool use_preview = false;
- if (!editing(pi.base.bv) &&
- RenderPreview::status() == LyXRC::PREVIEW_ON) {
- lyx::graphics::PreviewImage const * pimage =
- preview_->getPreviewImage(*pi.base.bv->buffer());
- use_preview = pimage && pimage->image();
- }
+ use_preview_ = previewState(pi.base.bv);
- if (use_preview) {
+ if (use_preview_) {
// one pixel gap in front
preview_->draw(pi, x + 1, y);
setPosCache(pi, x, y);
for (row_type row = 0; row < nrows(); ++row) {
int const yy = y + rowinfo_[row].offset_;
FontSetChanger dummy(pi.base, "mathrm");
- drawStr(pi, pi.base.font, xx, yy, nicelabel(row));
+ pi.draw(xx, yy, nicelabel(row));
}
}
setPosCache(pi, x, y);
string MathHullInset::label(row_type row) const
{
- row_type n = nrows();
- BOOST_ASSERT(row < n);
+ BOOST_ASSERT(row < nrows());
return label_[row];
}
}
+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
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);
void MathHullInset::swapRow(row_type row)
{
- if (nrows() == 1)
+ if (nrows() <= 1)
return;
if (row + 1 == nrows())
--row;
void MathHullInset::delRow(row_type row)
{
- if (nrows() <= 1)
+ if (nrows() <= 1 || !rowChangeOK())
return;
MathGridInset::delRow(row);
+ // The last dummy row has no number info nor a label.
+ // Test nrows() + 1 because we have already erased the row.
+ if (row == nrows() + 1)
+ row--;
nonum_.erase(nonum_.begin() + row);
label_.erase(label_.begin() + 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);
}
void MathHullInset::mutate(string const & newtype)
{
- lyxerr << "mutating from '" << type_ << "' to '" << newtype << "'" << endl;
+ //lyxerr << "mutating from '" << type_ << "' to '" << newtype << "'" << endl;
// we try to move along the chain
// none <-> simple <-> equation <-> eqnarray -> *align* -> multline, gather -+
}
-string MathHullInset::eolString(row_type row, bool fragile) const
+string MathHullInset::eolString(row_type row, bool emptyline, bool fragile) const
{
string res;
if (numberedType()) {
if (nonum_[row] && (type_ != "multline"))
res += "\\nonumber ";
}
- return res + MathGridInset::eolString(row, fragile);
+ return res + MathGridInset::eolString(row, emptyline, fragile);
}
}
-void MathHullInset::priv_dispatch(LCursor & cur, FuncRequest & cmd)
+void MathHullInset::doDispatch(LCursor & cur, FuncRequest & cmd)
{
+ //lyxerr << "action: " << cmd.action << endl;
switch (cmd.action) {
case LFUN_FINISHED_LEFT:
case LFUN_FINISHED_RIGHT:
case LFUN_FINISHED_UP:
case LFUN_FINISHED_DOWN:
- MathGridInset::priv_dispatch(cur, cmd);
+ //lyxerr << "action: " << cmd.action << endl;
+ MathGridInset::doDispatch(cur, cmd);
notifyCursorLeaves(cur);
+ cur.undispatched();
break;
case LFUN_BREAKPARAGRAPH:
// some magic for the common case
if (type_ == "simple" || type_ == "equation") {
recordUndoInset(cur);
- mutate("eqnarray");
+ bool const align =
+ cur.bv().buffer()->params().use_amsmath == BufferParams::AMS_ON;
+ mutate(align ? "align" : "eqnarray");
cur.idx() = 0;
cur.pos() = cur.lastpos();
}
- MathGridInset::priv_dispatch(cur, cmd);
+ MathGridInset::doDispatch(cur, cmd);
break;
case LFUN_MATH_NUMBER:
recordUndoInset(cur);
row_type r = (type_ == "multline") ? nrows() - 1 : cur.row();
string old_label = label(r);
- string new_label = cmd.argument;
-
- if (new_label.empty()) {
- string const default_label =
- (lyxrc.label_init_length >= 0) ? "eq:" : "";
- pair<bool, string> const res = old_label.empty()
- ? Alert::askForText(_("Enter new label to insert:"), default_label)
- : Alert::askForText(_("Enter label:"), old_label);
- if (res.first)
- new_label = lyx::support::trim(res.second);
- else
- new_label = old_label;
+ string const default_label =
+ (lyxrc.label_init_length >= 0) ? "eq:" : "";
+ if (old_label.empty())
+ old_label = default_label;
+ string const contents = cmd.argument.empty() ?
+ old_label : cmd.argument;
+
+ InsetCommandParams p("label", contents);
+ string const data = InsetCommandMailer::params2string("label", p);
+
+ if (cmd.argument.empty()) {
+ cur.bv().owner()->getDialogs().show("label", data, 0);
+ } else {
+ FuncRequest fr(LFUN_INSET_INSERT, data);
+ dispatch(cur, fr);
}
+ break;
+ }
- if (!new_label.empty())
- numbered(r, true);
- label(r, new_label);
+ case LFUN_INSET_INSERT: {
+ //lyxerr << "arg: " << cmd.argument << endl;
+ string const name = cmd.getArg(0);
+ if (name == "label") {
+ InsetCommandParams p;
+ InsetCommandMailer::string2params(name, cmd.argument, p);
+ string str = p.getContents();
+ recordUndoInset(cur);
+ row_type const r = (type_ == "multline") ? nrows() - 1 : cur.row();
+ str = lyx::support::trim(str);
+ if (!str.empty())
+ numbered(r, true);
+ string old = label(r);
+ if (str != old) {
+ cur.bv().buffer()->changeRefsIfUnique(old, str);
+ label(r, str);
+ }
+ break;
+ }
+ MathArray ar;
+ if (createMathInset_fromDialogStr(cmd.argument, ar)) {
+ recordUndo(cur);
+ cur.insert(ar);
+ } else
+ cur.undispatched();
break;
}
}
default:
- MathGridInset::priv_dispatch(cur, cmd);
+ MathGridInset::doDispatch(cur, cmd);
break;
}
}
bool MathHullInset::getStatus(LCursor & cur, FuncRequest const & cmd,
- FuncStatus & flag) const
+ FuncStatus & status) const
{
switch (cmd.action) {
+ case LFUN_FINISHED_LEFT:
+ case LFUN_FINISHED_RIGHT:
+ case LFUN_FINISHED_UP:
+ case LFUN_FINISHED_DOWN:
+ status.enabled(true);
+ return true;
case LFUN_BREAKLINE:
case LFUN_MATH_NUMBER:
case LFUN_MATH_NONUMBER:
- case LFUN_INSERT_LABEL:
case LFUN_MATH_EXTERN:
case LFUN_MATH_MUTATE:
case LFUN_MATH_DISPLAY:
// we handle these
+ status.enabled(true);
return true;
+ case LFUN_INSERT_LABEL:
+ status.enabled(type_ != "simple");
+ return true;
+ case LFUN_INSET_INSERT: {
+ // Don't test createMathInset_fromDialogStr(), since
+ // getStatus is not called with a valid reference and the
+ // dialog would not be applyable.
+ string const name = cmd.getArg(0);
+ status.enabled(name == "ref" ||
+ (name == "label" && type_ != "simple"));
+ break;
+ }
case LFUN_TABULAR_FEATURE: {
- // should be more precise
istringstream is(cmd.argument);
string s;
is >> s;
- if ((type_ == "simple" || type_ == "equation")
+ if (!rowChangeOK()
+ && (s == "append-row"
+ || s == "delete-row"
+ || s == "copy-row")) {
+ status.message(bformat(
+ N_("Can't change number of rows in '%1$s'"),
+ type_));
+ status.enabled(false);
+ return true;
+ }
+ if (!colChangeOK()
&& (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;
- return MathGridInset::getStatus(cur, cmd, flag);
+ || s == "copy-column")) {
+ status.message(bformat(
+ N_("Can't change number of columns in '%1$s'"),
+ type_));
+ status.enabled(false);
+ return true;
+ }
+ if ((type_ == "simple"
+ || type_ == "equation"
+ || type_ == "none") &&
+ (s == "add-hline-above" || s == "add-hline-below")) {
+ status.message(bformat(
+ N_("Can't add horizontal grid lines in '%1$s'"),
+ type_));
+ status.enabled(false);
+ return true;
+ }
+ if (s == "add-vline-left" || s == "add-vline-right") {
+ status.message(bformat(
+ N_("Can't add vertical grid lines in '%1$s'"),
+ type_));
+ status.enabled(false);
+ return true;
+ }
+ if (s == "valign-top" || s == "valign-middle"
+ || s == "valign-bottom" || s == "align-left"
+ || s == "align-center" || s == "align-right") {
+ status.enabled(false);
+ return true;
+ }
+ return MathGridInset::getStatus(cur, cmd, status);
}
default:
- return MathGridInset::getStatus(cur, cmd, flag);
+ return MathGridInset::getStatus(cur, cmd, status);
}
+
+ // This cannot really happen, but inserted to shut-up gcc
+ return MathGridInset::getStatus(cur, cmd, status);
}
bool b;
bv_funcs::string2font(arg, font, b);
if (font.color() != LColor::inherit) {
- MathAtom at = createMathInset("color");
- asArray(lcolor.getGUIName(font.color()), at.nucleus()->cell(0));
- cur.handleNest(at, 1);
+ MathAtom at = MathAtom(new MathColorInset(true, font.color()));
+ cur.handleNest(at, 0);
}
}
}
-void MathHullInset::getCursorDim(int & asc, int & desc) const
-{
- asc = 10;
- desc = 2;
- //math_font_max_dim(font_, asc, des);
-}
-
-
void MathHullInset::revealCodes(LCursor & cur) const
{
if (!cur.inMathed())
name = "informalequation";
string bname = name;
- if (!label(0).empty())
- bname += " id=\"" + sgml::cleanID(label(0)) + "\"";
+ if (!label(0).empty())
+ bname += " id=\"" + sgml::cleanID(buf, runparams, label(0)) + "\"";
ms << MTag(bname.c_str());
ostringstream ls;
MathGridInset::mathmlize(ms);
ms << ETag("math");
} else {
- ms << MTag("alt role=\"tex\"");
+ ms << MTag("alt role=\"tex\"");
res = latex(buf, ls, runparams);
ms << subst(subst(ls.str(), "&", "&"), "<", "<");
ms << ETag("alt");
}
-
+
ms << "<graphic fileref=\"eqn/";
- if ( !label(0).empty())
- ms << sgml::cleanID(label(0));
- else {
- // Some arbitrary unique number for this os.
- // Note that each call of math_hullinset::docbook()
- // will increase the os position by at least 60 chars or more
+ if ( !label(0).empty())
+ ms << sgml::cleanID(buf, runparams, label(0));
+ else
ms << sgml::uniqueID("anon");
- }
- if (runparams.flavor == OutputParams::XML)
+
+ if (runparams.flavor == OutputParams::XML)
ms << "\"/>";
- else
+ else
ms << "\">";
-
+
ms << ETag(name.c_str());
return ms.line() + res;
}
+
+
+int MathHullInset::textString(Buffer const & buf, ostream & os,
+ OutputParams const & op) const
+{
+ return plaintext(buf, os, op);
+}