/* * File: formula.C * Purpose: Implementation of formula inset * Author: Alejandro Aguilar Sierra * Created: January 1996 * Description: Allows the edition of math paragraphs inside Lyx. * * Copyright: 1996-1998 Alejandro Aguilar Sierra * * Version: 0.4, Lyx project. * * You are free to use and modify this code under the terms of * the GNU General Public Licence version 2 or later. */ #include #include #include "support/LOstream.h" #ifdef __GNUG__ #pragma implementation #endif #include "formula.h" #include "commandtags.h" #include "math_cursor.h" #include "math_parser.h" #include "lyx_main.h" #include "BufferView.h" #include "lyxtext.h" #include "gettext.h" #include "debug.h" #include "lyx_gui_misc.h" #include "support/LOstream.h" #include "support/lyxlib.h" #include "support/syscall.h" #include "LyXView.h" #include "Painter.h" #include "font.h" #include "lyxrc.h" #include "math_matrixinset.h" #include "mathed/support.h" using std::ostringstream; using std::ostream; using std::ifstream; using std::istream; using std::pair; using std::endl; using std::vector; extern char const * latex_mathenv[]; extern MathCursor * mathcursor; extern LyXFont WhichFont(short type, int size); // quite a hack i know. Should be done with return values... int number_of_newlines = 0; InsetFormula::InsetFormula() : InsetFormulaBase(new MathMatrixInset) {} InsetFormula::InsetFormula(MathInsetTypes t) : InsetFormulaBase(new MathMatrixInset(t)) {} Inset * InsetFormula::Clone(Buffer const &) const { return new InsetFormula(*this); } void InsetFormula::Write(Buffer const * buf, ostream & os) const { os << "Formula "; Latex(buf, os, false, false); } int InsetFormula::Latex(Buffer const *, ostream & os, bool fragile, bool) const { par()->Write(os, fragile); return 1; } int InsetFormula::Ascii(Buffer const *, ostream & os, int) const { par()->Write(os, false); return 1; } int InsetFormula::Linuxdoc(Buffer const * buf, ostream & os) const { return Ascii(buf, os, 0); } int InsetFormula::DocBook(Buffer const * buf, ostream & os) const { return Ascii(buf, os, 0); } void InsetFormula::Read(Buffer const *, LyXLex & lex) { par_ = mathed_parse(lex); } void InsetFormula::draw(BufferView * bv, LyXFont const &, int y, float & x, bool) const { MathInset::workwidth = bv->workWidth(); Painter & pain = bv->painter(); if (mathcursor) { par()->Metrics(LM_ST_TEXT); int w = par()->width() + 2; int a = par()->ascent() + 1; int h = par()->height() + 1; if (mathcursor->formula() == this) { if (mathcursor->Selection()) { int xp[10]; int yp[10]; int n; mathcursor->SelGetArea(xp, yp, n); pain.fillPolygon(xp, yp, n, LColor::selection); } pain.rectangle(int(x - 1), y - a, w, h, LColor::green); } } par()->draw(pain, int(x), y); x += par()->width(); setCursorVisible(false); } vector const InsetFormula::getLabelList() const { return par()->getLabelList(); } UpdatableInset::RESULT InsetFormula::LocalDispatch(BufferView * bv, kb_action action, string const & arg) { RESULT result = DISPATCHED; switch (action) { case LFUN_BREAKLINE: bv->lockedInsetStoreUndo(Undo::INSERT); par()->breakLine(); UpdateLocal(bv); break; case LFUN_DELETE_LINE_FORWARD: bv->lockedInsetStoreUndo(Undo::DELETE); mathcursor->DelLine(); UpdateLocal(bv); break; case LFUN_MATH_NUMBER: { //lyxerr << "toggling all numbers\n"; if (display()) { bv->lockedInsetStoreUndo(Undo::INSERT); bool old = par()->numberedType(); for (int row = 0; row < par()->nrows(); ++row) par()->numbered(row, !old); bv->owner()->message(old ? _("No number") : _("Number")); UpdateLocal(bv); } break; } case LFUN_MATH_NONUMBER: { //lyxerr << "toggling line number\n"; if (display()) { bv->lockedInsetStoreUndo(Undo::INSERT); int row = par()->nrows() - 1; bool old = par()->numbered(row); bv->owner()->message(old ? _("No number") : _("Number")); par()->numbered(row, !old); UpdateLocal(bv); } break; } case LFUN_INSERT_LABEL: { bv->lockedInsetStoreUndo(Undo::INSERT); int row = par()->nrows() - 1; string old_label = par()->label(row); string new_label = arg; if (new_label.empty()) { string const default_label = (lyxrc.label_init_length >= 0) ? "eq:" : ""; pair const res = old_label.empty() ? askForText(_("Enter new label to insert:"), default_label) : askForText(_("Enter label:"), old_label); lyxerr << "res: " << res.first << " - '" << res.second << "'\n"; if (!res.first) break; new_label = frontStrip(strip(res.second)); } //if (new_label == old_label) // break; // Nothing to do if (!new_label.empty()) { lyxerr << "setting label to '" << new_label << "'\n"; par()->numbered(row, true); } if (!new_label.empty() && bv->ChangeRefsIfUnique(old_label, new_label)) bv->redraw(); par()->label(row, new_label); UpdateLocal(bv); break; } case LFUN_MATH_EXTERN: HandleExtern(arg, bv); UpdateLocal(bv); break; case LFUN_MATH_MUTATE: par()->mutate(arg); UpdateLocal(bv); break; case LFUN_TABINSERT: lyxerr << "take index from cursor\n"; par()->splitCell(0); UpdateLocal(bv); break; case LFUN_MATH_DISPLAY: if (par()->GetType() == LM_OT_SIMPLE) par()->mutate(LM_OT_EQUATION); else par()->mutate(LM_OT_SIMPLE); UpdateLocal(bv); break; default: result = InsetFormulaBase::LocalDispatch(bv, action, arg); } return result; } void InsetFormula::HandleExtern(const string & arg, BufferView *) { //string outfile = lyx::tempName("maple.out"); string outfile = "/tmp/lyx2" + arg + ".out"; ostringstream os; par()->WriteNormal(os); string code = os.str().c_str(); string script = "lyx2" + arg + " '" + code + "' " + outfile; lyxerr << "calling: " << script << endl; Systemcalls cmd(Systemcalls::System, script, 0); ifstream is(outfile.c_str()); par_ = mathed_parse(is); } bool InsetFormula::display() const { return par_->GetType() != LM_OT_SIMPLE; } MathMatrixInset * InsetFormula::par() const { return static_cast(par_); } Inset::Code InsetFormula::LyxCode() const { return Inset::MATH_CODE; } void InsetFormula::Validate(LaTeXFeatures & features) const { par()->Validate(features); } int InsetFormula::ascent(BufferView *, LyXFont const &) const { return par()->ascent(); } int InsetFormula::descent(BufferView *, LyXFont const &) const { return par()->descent(); } int InsetFormula::width(BufferView *, LyXFont const &) const { par()->Metrics(LM_ST_TEXT); return par()->width(); } /* LyXFont const InsetFormula::ConvertFont(LyXFont const & f) const { // We have already discussed what was here LyXFont font(f); font.setLatex(LyXFont::OFF); return font; } */