X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2Fformulabase.C;h=3d36585989575072d4ee786e6855e1b72dfc94e3;hb=cf629f43316e5f20f97128a10ea14e0b4215b056;hp=b048f29c46db02b4a74f440326277d682dc46160;hpb=88b5d739b5f25ff9012be11620256e98ba3789bb;p=lyx.git diff --git a/src/mathed/formulabase.C b/src/mathed/formulabase.C index b048f29c46..3d36585989 100644 --- a/src/mathed/formulabase.C +++ b/src/mathed/formulabase.C @@ -1,9 +1,8 @@ - /* -* File: formula.C -* Purpose: Implementation of formula inset +/* +* File: formulabase.C +* Purpose: Implementation of common parts of the LyX math insets * Author: Alejandro Aguilar Sierra * Created: January 1996 -* Description: Allows the edition of math paragraphs inside Lyx. * * Copyright: 1996-1998 Alejandro Aguilar Sierra * @@ -17,6 +16,7 @@ #include #include "Lsstream.h" +#include "support/LAssert.h" #ifdef __GNUG__ #pragma implementation @@ -26,32 +26,29 @@ #include "formulamacro.h" #include "commandtags.h" #include "math_cursor.h" -#include "math_parser.h" #include "BufferView.h" #include "lyxtext.h" #include "lyxfunc.h" #include "gettext.h" #include "LaTeXFeatures.h" #include "debug.h" -#include "support/LOstream.h" +#include "support.h" +#include "support/lstrings.h" #include "LyXView.h" #include "Painter.h" #include "font.h" #include "math_arrayinset.h" #include "math_spaceinset.h" +#include "math_macrotable.h" +#include "math_factory.h" #include "support/lyxlib.h" -#include "mathed/support.h" #include "undo_funcs.h" using std::endl; using std::ostream; using std::vector; -extern char const * latex_special_chars; - -int greek_kb_flag = 0; extern char const * latex_mathenv[]; -LyXFont * Math_Fonts = 0; MathCursor * mathcursor = 0; @@ -63,32 +60,21 @@ int sel_x; int sel_y; bool sel_flag; -void mathed_init_fonts(); - -string nicelabel(string const & label) -{ - return "(" + (label.empty() ? "#" : label) + ")"; -} - void handleFont(BufferView * bv, MathTextCodes t) { - if (mathcursor->Selection()) + if (mathcursor->selection()) bv->lockedInsetStoreUndo(Undo::EDIT); mathcursor->handleFont(t); } -void handleAccent(BufferView * bv, int code) -{ - bv->lockedInsetStoreUndo(Undo::EDIT); - mathcursor->handleAccent(code); -} -void handleDelim(BufferView * bv, int l, int r) +void handleAccent(BufferView * bv, string const & name) { bv->lockedInsetStoreUndo(Undo::EDIT); - mathcursor->handleDelim(l, r); + mathcursor->insert(createMathInset(name)); } + bool openNewInset(BufferView * bv, UpdatableInset * new_inset) { LyXText * lt = bv->getLyXText(); @@ -104,191 +90,42 @@ bool openNewInset(BufferView * bv, UpdatableInset * new_inset) } -} // namespaces - - - -LyXFont WhichFont(short type, int size) -{ - LyXFont f; - - if (!Math_Fonts) - mathed_init_fonts(); - - switch (type) { - case LM_TC_SYMB: - f = Math_Fonts[2]; - break; - - case LM_TC_BSYM: - f = Math_Fonts[2]; - break; - - case LM_TC_VAR: - case LM_TC_IT: - f = Math_Fonts[0]; - break; - - case LM_TC_BF: - f = Math_Fonts[3]; - break; - - case LM_TC_SF: - f = Math_Fonts[7]; - break; - - case LM_TC_CAL: - f = Math_Fonts[4]; - break; - - case LM_TC_TT: - f = Math_Fonts[5]; - break; - - case LM_TC_SPECIAL: //f = Math_Fonts[0]; break; - case LM_TC_TEXTRM: - case LM_TC_RM: - f = Math_Fonts[6]; - break; - - default: - f = Math_Fonts[1]; - break; - } - - switch (size) { - case LM_ST_DISPLAY: - if (type == LM_TC_BSYM) { - f.incSize(); - f.incSize(); - } - break; - - case LM_ST_TEXT: - break; - - case LM_ST_SCRIPT: - f.decSize(); - break; - - case LM_ST_SCRIPTSCRIPT: - f.decSize(); - f.decSize(); - break; - - default: - lyxerr << "Math Error: wrong font size: " << size << endl; - break; - } - - if (type != LM_TC_TEXTRM) - f.setColor(LColor::math); - - return f; -} - - -namespace { - -void mathed_init_fonts() -{ - Math_Fonts = new LyXFont[8]; //DEC cxx cannot initialize all fonts - //at once (JMarc) rc - - for (int i = 0 ; i < 8 ; ++i) { - Math_Fonts[i] = LyXFont(LyXFont::ALL_SANE); - } - - Math_Fonts[0].setShape(LyXFont::ITALIC_SHAPE); - - Math_Fonts[1].setFamily(LyXFont::SYMBOL_FAMILY); - - Math_Fonts[2].setFamily(LyXFont::SYMBOL_FAMILY); - Math_Fonts[2].setShape(LyXFont::ITALIC_SHAPE); - - Math_Fonts[3].setSeries(LyXFont::BOLD_SERIES); - - Math_Fonts[4].setFamily(LyXFont::SANS_FAMILY); - Math_Fonts[4].setShape(LyXFont::ITALIC_SHAPE); - - Math_Fonts[5].setFamily(LyXFont::TYPEWRITER_FAMILY); - - Math_Fonts[6].setFamily(LyXFont::ROMAN_FAMILY); - - Math_Fonts[7].setFamily(LyXFont::SANS_FAMILY); -} - - -// returns the nearest enclosing matrix -MathArrayInset * matrixpar(int & idx) +// returns the nearest enclosing grid +MathArrayInset * matrixpar(MathInset::idx_type & idx) { idx = 0; - return - static_cast - (mathcursor ? mathcursor->enclosing(LM_OT_MATRIX, idx) : 0); + return mathcursor ? mathcursor->enclosingArray(idx) : 0; } } // namespace anon -InsetFormulaBase::InsetFormulaBase(MathInset * par) - : par_(par) -{} - -InsetFormulaBase::InsetFormulaBase(InsetFormulaBase const & f) - : UpdatableInset(f), par_(static_cast(f.par_->clone())) -{} - - -InsetFormulaBase::~InsetFormulaBase() +InsetFormulaBase::InsetFormulaBase() + : view_(0), font_(), xo_(0), yo_(0) { -#ifdef WITH_WARNINGS -#warning leak this for a while... -#endif - //delete par_; + // This is needed as long the math parser is not re-entrant + MathMacroTable::builtinMacros(); + //lyxerr << "sizeof MathInset: " << sizeof(MathInset) << "\n"; } -void InsetFormulaBase::read(Buffer const *, LyXLex & lex) -{ - read(lex); -} - -void InsetFormulaBase::write(Buffer const *, ostream & os) const -{ - write(os); -} - -int InsetFormulaBase::latex(Buffer const *, ostream & os, - bool fragile, bool spacing) const -{ - return latex(os, fragile, spacing); -} - -int InsetFormulaBase::ascii(Buffer const *, ostream & os, int spacing) const -{ - return ascii(os, spacing); -} +// Check if uses AMS macros +void InsetFormulaBase::validate(LaTeXFeatures &) const +{} -int InsetFormulaBase::linuxdoc(Buffer const *, ostream & os) const -{ - return linuxdoc(os); -} -int InsetFormulaBase::docBook(Buffer const *, ostream & os) const +void InsetFormulaBase::metrics(BufferView * bv, LyXFont const & f) const { - return docBook(os); + if (bv) + view_ = bv; + font_ = f; + MathMetricsInfo mi(view_, font_, display() ? LM_ST_DISPLAY : LM_ST_TEXT); + par()->metrics(mi); } - -// Check if uses AMS macros -void InsetFormulaBase::validate(LaTeXFeatures &) const -{} - - string const InsetFormulaBase::editMessage() const { return _("Math editor mode"); @@ -297,43 +134,47 @@ string const InsetFormulaBase::editMessage() const void InsetFormulaBase::edit(BufferView * bv, int x, int /*y*/, unsigned int) { - mathcursor = new MathCursor(this); - if (!bv->lockInset(this)) lyxerr[Debug::MATHED] << "Cannot lock inset!!!" << endl; - par_->Metrics(LM_ST_TEXT); + mathcursor = new MathCursor(this, x == 0); + metrics(bv); + // if that is removed, we won't get the magenta box when entering an + // inset for the first time bv->updateInset(this, false); - if (x == 0) { - mathcursor->first(); - } else { - mathcursor->last(); - } sel_x = 0; sel_y = 0; sel_flag = false; } +void InsetFormulaBase::edit(BufferView * bv, bool front) +{ + // looks hackish but seems to work + edit(bv, front ? 0 : 1, 0, 0); +} + + void InsetFormulaBase::insetUnlock(BufferView * bv) { if (mathcursor) { - if (mathcursor->InMacroMode()) { - mathcursor->MacroModeClose(); - updateLocal(bv); + if (mathcursor->inMacroMode()) { + mathcursor->macroModeClose(); + updateLocal(bv, true); } delete mathcursor; + mathcursor = 0; } - mathcursor = 0; bv->updateInset(this, false); } void InsetFormulaBase::getCursorPos(BufferView *, int & x, int & y) const { - mathcursor->GetPos(x, y); - x -= par_->xo(); - y -= par_->yo(); + mathcursor->getPos(x, y); + x += xo_; + y += yo_ - 3; + //lyxerr << "getCursorPos: " << x << " " << y << "\n"; } @@ -345,17 +186,18 @@ void InsetFormulaBase::toggleInsetCursor(BufferView * bv) if (isCursorVisible()) bv->hideLockedInsetCursor(); else { + metrics(bv); int x; int y; - mathcursor->GetPos(x, y); - //x -= par_->xo(); - y -= par_->yo(); - - LyXFont font = WhichFont(LM_TC_TEXTRM, LM_ST_TEXT); - int const asc = lyxfont::maxAscent(font); - int const desc = lyxfont::maxDescent(font); - - bv->showLockedInsetCursor(x, y, asc, desc); + mathcursor->getPos(x, y); + y -= 3; + y -= yo_; + int asc = 0; + int des = 0; + MathMetricsInfo mi(bv, font_, LM_ST_TEXT); + math_font_max_dim(LM_TC_TEXTRM, mi, asc, des); + bv->showLockedInsetCursor(x, y, asc, des); + //lyxerr << "toggleInsetCursor: " << x << " " << y << "\n"; } toggleCursorVisible(); @@ -368,13 +210,14 @@ void InsetFormulaBase::showInsetCursor(BufferView * bv, bool) if (mathcursor) { int x; int y; - mathcursor->GetPos(x, y); - x -= par_->xo(); - y -= par_->yo(); - LyXFont font = WhichFont(LM_TC_TEXTRM, LM_ST_TEXT); - int const asc = lyxfont::maxAscent(font); - int const desc = lyxfont::maxDescent(font); - bv->fitLockedInsetCursor(x, y, asc, desc); + mathcursor->getPos(x, y); + int asc = 0; + int des = 0; + MathMetricsInfo mi(bv, font_, LM_ST_TEXT); + math_font_max_dim(LM_TC_TEXTRM, mi, asc, des); + //bv->fitLockedInsetCursor(x, y, asc, des); + //metrics(bv); + //lyxerr << "showInsetCursor: " << x << " " << y << "\n"; } toggleInsetCursor(bv); } @@ -390,10 +233,8 @@ void InsetFormulaBase::hideInsetCursor(BufferView * bv) void InsetFormulaBase::toggleInsetSelection(BufferView * bv) { - if (!mathcursor) - return; - - bv->updateInset(this, false); + if (mathcursor) + bv->updateInset(this, false); } @@ -403,10 +244,10 @@ vector const InsetFormulaBase::getLabelList() const } -void InsetFormulaBase::updateLocal(BufferView * bv) +void InsetFormulaBase::updateLocal(BufferView * bv, bool dirty) { - par_->Metrics(LM_ST_TEXT); - bv->updateInset(this, true); + metrics(bv); + bv->updateInset(this, dirty); } @@ -415,9 +256,8 @@ void InsetFormulaBase::insetButtonRelease(BufferView * bv, { if (mathcursor) { hideInsetCursor(bv); - x += par_->xo(); - y += par_->yo(); - mathcursor->SetPos(x, y); + mathcursor->setPos(x + xo_, y + yo_); + //lyxerr << "insetButtonRelease: " << x + xo_ << " " << y + yo_ << "\n"; showInsetCursor(bv); if (sel_flag) { sel_flag = false; @@ -435,8 +275,8 @@ void InsetFormulaBase::insetButtonPress(BufferView * bv, sel_flag = false; sel_x = x; sel_y = y; - if (mathcursor && mathcursor->Selection()) { - mathcursor->SelClear(); + if (mathcursor && mathcursor->selection()) { + mathcursor->selClear(); bv->updateInset(this, false); } } @@ -448,17 +288,15 @@ void InsetFormulaBase::insetMotionNotify(BufferView * bv, if (sel_x && sel_y && abs(x-sel_x) > 4 && !sel_flag) { sel_flag = true; hideInsetCursor(bv); - mathcursor->SetPos(sel_x + par_->xo(), sel_y + par_->yo()); - mathcursor->SelStart(); + mathcursor->setPos(sel_x, sel_y); + mathcursor->selStart(); showInsetCursor(bv); - mathcursor->GetPos(sel_x, sel_y); + mathcursor->getPos(sel_x, sel_y); } else if (sel_flag) { hideInsetCursor(bv); - x += par_->xo(); - y += par_->yo(); - mathcursor->SetPos(x, y); + mathcursor->setPos(x, y); showInsetCursor(bv); - mathcursor->GetPos(x, y); + mathcursor->getPos(x, y); if (sel_x != x || sel_y != y) bv->updateInset(this, false); sel_x = x; @@ -469,32 +307,31 @@ void InsetFormulaBase::insetMotionNotify(BufferView * bv, void InsetFormulaBase::insetKeyPress(XKeyEvent *) { - lyxerr[Debug::MATHED] - << "Used InsetFormulaBase::InsetKeyPress." << endl; + lyxerr[Debug::MATHED] << "Used InsetFormulaBase::InsetKeyPress." << endl; } - UpdatableInset::RESULT InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, string const & arg) { - //lyxerr << "InsetFormulaBase::LocalDispatch: act: " << action + //lyxerr << "InsetFormulaBase::localDispatch: act: " << action // << " arg: '" << arg << "' cursor: " << mathcursor << "\n"; if (!mathcursor) return UNDISPATCHED; - MathTextCodes varcode = LM_TC_MIN; - bool was_macro = mathcursor->InMacroMode(); - bool sel = false; - bool was_selection = mathcursor->Selection(); - RESULT result = DISPATCHED; + if (mathcursor->asHyperActiveInset()) { + lyxerr << " uurr.... getting dificult now\n"; + return mathcursor->asHyperActiveInset()->localDispatch(bv, action, arg); + } - hideInsetCursor(bv); + RESULT result = DISPATCHED; + bool sel = false; + bool was_macro = mathcursor->inMacroMode(); + bool was_selection = mathcursor->selection(); - if (mathcursor->getLastCode() == LM_TC_TEX) - varcode = LM_TC_TEX; + hideInsetCursor(bv); mathcursor->normalize(); @@ -506,8 +343,8 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, sel = true; // fall through... case LFUN_RIGHT: - result = DISPATCH_RESULT(mathcursor->Right(sel)); - updateLocal(bv); + result = mathcursor->right(sel) ? DISPATCHED : FINISHED_RIGHT; + updateLocal(bv, false); break; @@ -515,8 +352,8 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, sel = true; // fall through case LFUN_LEFT: - result = DISPATCH_RESULT(mathcursor->Left(sel)); - updateLocal(bv); + result = mathcursor->left(sel) ? DISPATCHED : FINISHED; + updateLocal(bv, false); break; @@ -524,8 +361,8 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, sel = true; case LFUN_UP: - result = DISPATCH_RESULT(mathcursor->Up(sel)); - updateLocal(bv); + result = mathcursor->up(sel) ? DISPATCHED : FINISHED_UP; + updateLocal(bv, false); break; @@ -533,56 +370,59 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, sel = true; case LFUN_DOWN: - result = DISPATCH_RESULT(mathcursor->Down(sel)); - updateLocal(bv); + result = mathcursor->down(sel) ? DISPATCHED : FINISHED_DOWN; + updateLocal(bv, false); break; + case LFUN_HOMESEL: + sel = true; + case LFUN_HOME: - mathcursor->Home(); - updateLocal(bv); + mathcursor->home(sel); + updateLocal(bv, false); break; + case LFUN_ENDSEL: + sel = true; + case LFUN_END: - mathcursor->End(); - updateLocal(bv); + mathcursor->end(sel); + updateLocal(bv, false); break; case LFUN_DELETE_LINE_FORWARD: bv->lockedInsetStoreUndo(Undo::DELETE); - mathcursor->DelLine(); - updateLocal(bv); + mathcursor->delLine(); + updateLocal(bv, true); break; case LFUN_TAB: mathcursor->idxNext(); - updateLocal(bv); + updateLocal(bv, false); break; case LFUN_SHIFT_TAB: mathcursor->idxPrev(); - updateLocal(bv); + updateLocal(bv, false); break; case LFUN_TABINSERT: bv->lockedInsetStoreUndo(Undo::EDIT); mathcursor->splitCell(); - updateLocal(bv); + updateLocal(bv, true); break; + case LFUN_DELETE_WORD_BACKWARD: case LFUN_BACKSPACE: - if (!mathcursor->InMacroMode() && mathcursor->pos() == 0) { - bv->lockedInsetStoreUndo(Undo::DELETE); - mathcursor->pullArg(); - bv->updateInset(this, true); - break; - } - if (!mathcursor->Left()) - break; - // fall through... + bv->lockedInsetStoreUndo(Undo::DELETE); + mathcursor->backspace(); + bv->updateInset(this, true); + break; + case LFUN_DELETE_WORD_FORWARD: case LFUN_DELETE: bv->lockedInsetStoreUndo(Undo::DELETE); - mathcursor->Delete(); + mathcursor->erase(); bv->updateInset(this, true); break; @@ -590,172 +430,128 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, // sprintf(dispatch_buffer, "%d %d",); // dispatch_result = dispatch_buffer; // break; - case LFUN_SETXY: - { + case LFUN_SETXY: { lyxerr << "LFUN_SETXY broken!\n"; - int x; - int y; - int x1; - int y1; + int x = 0; + int y = 0; istringstream is(arg.c_str()); is >> x >> y; - par_->GetXY(x1, y1); - mathcursor->SetPos(x1 + x, y1 + y); - updateLocal(bv); + mathcursor->setPos(x, y); + updateLocal(bv, false); + break; } - break; - - // cursor selection ---------------------------- case LFUN_PASTE: if (was_macro) - mathcursor->MacroModeClose(); + mathcursor->macroModeClose(); bv->lockedInsetStoreUndo(Undo::INSERT); - mathcursor->SelPaste(); - updateLocal(bv); + mathcursor->selPaste(); + updateLocal(bv, true); break; case LFUN_CUT: bv->lockedInsetStoreUndo(Undo::DELETE); - mathcursor->SelCut(); - updateLocal(bv); + mathcursor->selCut(); + updateLocal(bv, true); break; case LFUN_COPY: - mathcursor->SelCopy(); + mathcursor->selCopy(); break; - case LFUN_HOMESEL: - case LFUN_ENDSEL: case LFUN_WORDRIGHTSEL: case LFUN_WORDLEFTSEL: break; // --- accented characters ------------------------------ - case LFUN_UMLAUT: handleAccent(bv, LM_ddot); break; - case LFUN_CIRCUMFLEX: handleAccent(bv, LM_hat); break; - case LFUN_GRAVE: handleAccent(bv, LM_grave); break; - case LFUN_ACUTE: handleAccent(bv, LM_acute); break; - case LFUN_TILDE: handleAccent(bv, LM_tilde); break; - case LFUN_MACRON: handleAccent(bv, LM_bar); break; - case LFUN_DOT: handleAccent(bv, LM_dot); break; - case LFUN_CARON: handleAccent(bv, LM_check); break; - case LFUN_BREVE: handleAccent(bv, LM_breve); break; - case LFUN_VECTOR: handleAccent(bv, LM_vec); break; - - // Greek mode - case LFUN_GREEK: - if (!greek_kb_flag) { - greek_kb_flag = 1; - bv->owner()->message(_("Math greek mode on")); - } else - greek_kb_flag = 0; + case LFUN_UMLAUT: handleAccent(bv, "ddot"); break; + case LFUN_CIRCUMFLEX: handleAccent(bv, "hat"); break; + case LFUN_GRAVE: handleAccent(bv, "grave"); break; + case LFUN_ACUTE: handleAccent(bv, "acute"); break; + case LFUN_TILDE: handleAccent(bv, "tilde"); break; + case LFUN_MACRON: handleAccent(bv, "bar"); break; + case LFUN_DOT: handleAccent(bv, "dot"); break; + case LFUN_CARON: handleAccent(bv, "check"); break; + case LFUN_BREVE: handleAccent(bv, "breve"); break; + case LFUN_VECTOR: handleAccent(bv, "vec"); break; + + // Math fonts + case LFUN_GREEK_TOGGLE: handleFont(bv, LM_TC_GREEK); break; + case LFUN_BOLD: handleFont(bv, LM_TC_BF); break; + case LFUN_SANS: handleFont(bv, LM_TC_SF); break; + case LFUN_EMPH: handleFont(bv, LM_TC_CAL); break; + case LFUN_ROMAN: handleFont(bv, LM_TC_RM); break; + case LFUN_CODE: handleFont(bv, LM_TC_TT); break; + case LFUN_NOUN: handleFont(bv, LM_TC_BB); break; + case LFUN_DEFAULT: handleFont(bv, LM_TC_VAR); break; + + case LFUN_GREEK: + handleFont(bv, LM_TC_GREEK1); + if (arg.size()) + mathcursor->interpret(arg); break; - // Greek keyboard - case LFUN_GREEK_TOGGLE: - greek_kb_flag = greek_kb_flag ? 0 : 2; - if (greek_kb_flag) - bv->owner()->message(_("Math greek keyboard on")); - else - bv->owner()->message(_("Math greek keyboard off")); - break; - - // Math fonts - case LFUN_BOLD: handleFont(bv, LM_TC_BF); break; - case LFUN_SANS: handleFont(bv, LM_TC_SF); break; - case LFUN_EMPH: handleFont(bv, LM_TC_CAL); break; - case LFUN_ROMAN: handleFont(bv, LM_TC_RM); break; - case LFUN_CODE: handleFont(bv, LM_TC_TT); break; - case LFUN_DEFAULT: handleFont(bv, LM_TC_VAR); break; - case LFUN_MATH_MODE: handleFont(bv, LM_TC_TEXTRM); //bv->owner()->message(_("math text mode toggled")); break; -#ifndef NO_LATEX - case LFUN_TEX: - if (!mathcursor->Selection()) { - mathcursor->handleFont(LM_TC_TEX); - //bv->owner()->message(_("TeX mode toggled")); - } - break; -#endif - case LFUN_MATH_LIMITS: bv->lockedInsetStoreUndo(Undo::INSERT); if (mathcursor->toggleLimits()) - updateLocal(bv); + updateLocal(bv, true); break; case LFUN_MATH_SIZE: +#if 0 if (!arg.empty()) { bv->lockedInsetStoreUndo(Undo::INSERT); - latexkeys const * l = in_word_set(arg); - mathcursor->SetSize(MathStyles(l ? l->id : static_cast(-1))); - updateLocal(bv); + mathcursor->setSize(arg); + updateLocal(bv, true); } +#endif break; case LFUN_INSERT_MATRIX: if (!arg.empty()) { bv->lockedInsetStoreUndo(Undo::INSERT); - mathcursor->Interpret("matrix " + arg); - updateLocal(bv); + mathcursor->interpret("matrix " + arg); + updateLocal(bv, true); } break; - case LFUN_INSERT_MATH: - if (!arg.empty()) { - bv->lockedInsetStoreUndo(Undo::INSERT); - mathcursor->Interpret(arg); - updateLocal(bv); - } + case LFUN_MATH_SPACE: + { + bv->lockedInsetStoreUndo(Undo::EDIT); + mathcursor->insert(MathAtom(new MathSpaceInset(1))); + updateLocal(bv, true); break; + } case LFUN_MATH_DELIM: { bv->lockedInsetStoreUndo(Undo::INSERT); - int ilt = '('; - int irt = '.'; - static const string vdelim("(){}[]./|"); - lyxerr << "formulabase::LFUN_MATH_DELIM, arg: '" << arg << "'\n"; - - if (arg.empty()) - break; - + //lyxerr << "formulabase::LFUN_MATH_DELIM, arg: '" << arg << "'\n"; + string ls; + string rs; istringstream is(arg.c_str()); - string lt; - string rt; - is >> lt >> rt; - lyxerr << "formulabase::LFUN_MATH_DELIM, lt: '" << lt << "'\n"; - lyxerr << "formulabase::LFUN_MATH_DELIM, rt: '" << rt << "'\n"; - - if (lt.size() > 1) { - latexkeys const * l = in_word_set(lt); - if (l) - ilt = l->id; - } else if (vdelim.find(lt[0]) != string::npos) - ilt = lt[0]; - - if (rt.size() > 1) { - latexkeys const * l = in_word_set(rt); - if (l) - irt = l->id; - } else if (vdelim.find(rt[0]) != string::npos) - irt = rt[0]; - - handleDelim(bv, ilt, irt); - updateLocal(bv); + is >> ls >> rs; + if (!is) { + lyxerr << "can't parse delimeters from '" << arg << "'\n"; + break; + } + bv->lockedInsetStoreUndo(Undo::EDIT); + mathcursor->handleDelim(ls, rs); + updateLocal(bv, true); break; } case LFUN_PROTECTEDSPACE: + //lyxerr << " called LFUN_PROTECTEDSPACE\n"; bv->lockedInsetStoreUndo(Undo::INSERT); - mathcursor->insert(new MathSpaceInset(1)); - updateLocal(bv); + mathcursor->insert(MathAtom(new MathSpaceInset(1))); + updateLocal(bv, true); break; case LFUN_UNDO: @@ -767,12 +563,12 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, { bv->lockedInsetStoreUndo(Undo::INSERT); lyxerr << "handling halign '" << arg << "'\n"; - int idx; + MathInset::idx_type idx; MathArrayInset * p = matrixpar(idx); if (!p) break; p->halign(arg.size() ? arg[0] : 'c', p->col(idx)); - updateLocal(bv); + updateLocal(bv, true); break; } @@ -780,62 +576,62 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, { bv->lockedInsetStoreUndo(Undo::INSERT); lyxerr << "handling valign '" << arg << "'\n"; - int idx; + MathInset::idx_type idx; MathArrayInset * p = matrixpar(idx); if (!p) break; p->valign(arg.size() ? arg[0] : 'c'); - updateLocal(bv); + updateLocal(bv, true); break; } case LFUN_MATH_ROW_INSERT: { bv->lockedInsetStoreUndo(Undo::INSERT); - int idx; + MathInset::idx_type idx; MathArrayInset * p = matrixpar(idx); lyxerr << " calling LFUN_MATH_ROW_INSERT on " << p << endl; if (!p) break; p->addRow(p->row(idx)); - updateLocal(bv); + updateLocal(bv, true); break; } case LFUN_MATH_ROW_DELETE: { bv->lockedInsetStoreUndo(Undo::INSERT); - int idx; + MathInset::idx_type idx; MathArrayInset * p = matrixpar(idx); lyxerr << " calling LFUN_MATH_ROW_DELETE on " << p << endl; if (!p) break; p->delRow(p->row(idx)); - updateLocal(bv); + updateLocal(bv, true); break; } case LFUN_MATH_COLUMN_INSERT: { bv->lockedInsetStoreUndo(Undo::INSERT); - int idx; + MathInset::idx_type idx; MathArrayInset * p = matrixpar(idx); if (!p) break; p->addCol(p->col(idx)); - updateLocal(bv); + updateLocal(bv, true); break; } case LFUN_MATH_COLUMN_DELETE: { bv->lockedInsetStoreUndo(Undo::INSERT); - int idx; + MathInset::idx_type idx; MathArrayInset * p = matrixpar(idx); if (!p) break; p->delCol(p->col(idx)); - updateLocal(bv); + updateLocal(bv, true); break; } @@ -843,141 +639,37 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, result = UNDISPATCHED; break; - default: - if ((action == -1 || action == LFUN_SELFINSERT) && !arg.empty()) { - unsigned char c = arg[0]; - //lyxerr << "char: '" << c << "' int: " << int(c) << endl; - //owner_->getIntl()->getTrans().TranslateAndInsert(c, lt); - //lyxerr << "trans: '" << c << "' int: " << int(c) << endl; + case LFUN_BREAKPARAGRAPH: + case LFUN_BREAKPARAGRAPHKEEPLAYOUT: + //lyxerr << "LFUN ignored\n"; + break; + + case -1: + case LFUN_INSERT_MATH: + case LFUN_SELFINSERT: + if (!arg.empty()) { bv->lockedInsetStoreUndo(Undo::INSERT); + mathcursor->interpret(arg); + updateLocal(bv, true); + } + break; - if (c == 0) { // Dead key, do nothing - //lyxerr << "deadkey" << endl; - break; - } + case LFUN_MATH_PANEL: + result = UNDISPATCHED; + break; - if (isalpha(c)) { - if (mathcursor->getLastCode() == LM_TC_TEX) { - mathcursor->MacroModeOpen(); - mathcursor->clearLastCode(); - varcode = LM_TC_MIN; - } else if (!varcode) { - short f = mathcursor->getLastCode() ? - mathcursor->getLastCode() : - mathcursor->nextCode(); - varcode = MathIsAlphaFont(f) ? - static_cast(f) : - LM_TC_VAR; - } - - // lyxerr << "Varcode << vardoce; - MathTextCodes char_code = varcode; - if (greek_kb_flag) { - char greek[26] = - {'A', 'B', 'X', 0 , 'E', 0 , 0 , 'H', 'I', 0 , - 'K', 0 , 'M', 'N', 'O', 0 , 0 , 'P', 0 , 'T', - 'Y', 0, 0, 0, 0 , 'Z' }; - - if ('A' <= c && c <= 'Z' && greek[c - 'A']) { - char_code = LM_TC_RM; - c = greek[c - 'A']; - } else - char_code = LM_TC_SYMB; - } - - mathcursor->insert(c, char_code); - - if (greek_kb_flag && char_code == LM_TC_RM ) - mathcursor->setLastCode(LM_TC_VAR); - - varcode = LM_TC_MIN; - - if (greek_kb_flag < 2) - greek_kb_flag = 0; - - } else if (strchr("!,:;{}", c) && (varcode == LM_TC_TEX||was_macro)) { - mathcursor->insert(c, LM_TC_TEX); - if (c == '{') { - mathcursor->insert('}', LM_TC_TEX); - mathcursor->Left(); - } - mathcursor->clearLastCode(); - // varcode = LM_TC_MIN; - } else if (c == '_' && varcode == LM_TC_TEX) { - mathcursor->insert(c, LM_TC_SPECIAL); - mathcursor->clearLastCode(); - // varcode = LM_TC_MIN; - } else if ('0' <= c && c <= '9' && (varcode == LM_TC_TEX||was_macro)) { - mathcursor->MacroModeOpen(); - mathcursor->clearLastCode(); - mathcursor->insert(c, LM_TC_MIN); - } else if (('0' <= c && c <= '9') || strchr(";:!|[]().,?", c)) { - MathTextCodes code = mathcursor->getLastCode(); - if (code != LM_TC_TEXTRM) - code = LM_TC_CONST; - mathcursor->insert(c, code); - } else if (strchr("+/-*<>=", c)) { - MathTextCodes code = mathcursor->getLastCode(); - if (code != LM_TC_TEXTRM) - code = LM_TC_BOP; - mathcursor->insert(c, code); - } else if (strchr(latex_special_chars, c) && c != '_') { - MathTextCodes code = mathcursor->getLastCode(); - if (code != LM_TC_TEXTRM) - code = LM_TC_SPECIAL; - mathcursor->insert(c, code); - } else if (c == '_' || c == '^') { - char s[2]; - s[0] = c; - s[1] = 0; - mathcursor->Interpret(s); - } else if (c == ' ') { - if (!varcode) { - short f = (mathcursor->getLastCode()) ? - mathcursor->getLastCode() : - mathcursor->nextCode(); - varcode = MathIsAlphaFont(f) ? - static_cast(f) : - LM_TC_VAR; - } - - if (varcode == LM_TC_TEXTRM) { - mathcursor->insert(c, LM_TC_TEXTRM); - } else if (was_macro) { - mathcursor->MacroModeClose(); - } else { - if (!mathcursor->pop()) - result = FINISHED; - mathcursor->plainRight(); - } - } else if (c == '\'' || c == '@') { - mathcursor->insert (c, LM_TC_VAR); - } else if (c == '\\') { - if (was_macro) - mathcursor->MacroModeClose(); - bv->owner()->message(_("TeX mode")); - mathcursor->setLastCode(LM_TC_TEX); - } - updateLocal(bv); - } else if (action == LFUN_MATH_PANEL) { - result = UNDISPATCHED; - } else { - lyxerr << "Closed by action " << action << endl; - result = FINISHED; - } + default: + result = UNDISPATCHED; } - mathcursor->normalize(); + lyx::Assert(mathcursor); + //mathcursor->normalize(); - if (mathcursor && was_macro != mathcursor->InMacroMode() - && action >= 0 - && action != LFUN_BACKSPACE) - updateLocal(bv); + if (//was_macro != mathcursor->inMacroMode() && + action >= 0 && action != LFUN_BACKSPACE) + updateLocal(bv, true); - //if (mathcursor) - // updateLocal(bv); - - if (mathcursor && (mathcursor->Selection() || was_selection)) + if (mathcursor->selection() || was_selection) toggleInsetSelection(bv); if (result == DISPATCHED || result == DISPATCHED_NOUPDATE || @@ -990,121 +682,89 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, } - -/* FIXME: math-greek-toggle seems to work OK, but math-greek doesn't turn - * on greek mode */ -bool math_insert_greek(BufferView * bv, char c) -{ - if (!bv->available()) - return false; - - if (!isalpha(c)) - return false; - - string tmp; - tmp = c; - if (!bv->theLockingInset() || bv->theLockingInset()->isTextInset()) { - int greek_kb_flag_save = greek_kb_flag; - InsetFormula * new_inset = new InsetFormula(); - bv->beforeChange(bv->text); - if (!bv->insertInset(new_inset)) { - delete new_inset; - return false; - } - //Update(1);//BUG - new_inset->edit(bv, 0, 0, 0); - new_inset->localDispatch(bv, LFUN_SELFINSERT, tmp); - if (greek_kb_flag_save < 2) { - bv->unlockInset(new_inset); // bv->theLockingInset()); - bv->text->cursorRight(bv, true); - } - } else - if (bv->theLockingInset()->lyxCode() == Inset::MATH_CODE || - bv->theLockingInset()->lyxCode() == Inset::MATHMACRO_CODE) - static_cast(bv->theLockingInset())->localDispatch(bv, LFUN_SELFINSERT, tmp); - else - lyxerr << "Math error: attempt to write on a wrong " - "class of inset." << endl; - return true; -} - - - Inset::Code InsetFormulaBase::lyxCode() const { return Inset::MATH_CODE; } -LyXFont const InsetFormulaBase::convertFont(LyXFont const & f) const +int InsetFormulaBase::upperY() const { - // We have already discussed what was here - LyXFont font(f); -#ifndef NO_LATEX - font.setLatex(LyXFont::OFF); -#endif - return font; + return yo_ - ascent(view_, font_); } -MathInset * InsetFormulaBase::par() const + +int InsetFormulaBase::lowerY() const { - return par_; + return yo_ + descent(view_, font_); } +///////////////////////////////////////////////////////////////////// + + void mathDispatchCreation(BufferView * bv, string const & arg, bool display) { if (bv->available()) { -// Feature "Read math inset from selection" disabled. -// // use selection if available.. -// string sel; -// if (action == LFUN_MATH_IMPORT_SELECTION) -// sel = ""; -// else -// sel = bv->getLyXText()->selectionAsString(bv->buffer()); - - InsetFormula * f; -// if (sel.empty()) { - f = new InsetFormula; - if (openNewInset(bv, f)) { - // don't do that also for LFUN_MATH_MODE unless you want end up with - // always changing to mathrm when opening an inlined inset - // -- I really hate "LyXfunc overloading"... - if (display) - f->localDispatch(bv, LFUN_MATH_DISPLAY, string()); - f->localDispatch(bv, LFUN_INSERT_MATH, arg); - } -// } else { -// f = new InsetFormula(sel); -// bv->getLyXText()->cutSelection(bv); -// openNewInset(bv, f); -// } + // use selection if available.. + //string sel; + //if (action == LFUN_MATH_IMPORT_SELECTION) + // sel = ""; + //else + + string sel = bv->getLyXText()->selectionAsString(bv->buffer(), false); + + InsetFormulaBase * f; + if (sel.empty()) { + f = new InsetFormula; + if (openNewInset(bv, f)) { + // don't do that also for LFUN_MATH_MODE unless you want end up with + // always changing to mathrm when opening an inlined inset + // -- I really hate "LyXfunc overloading"... + if (display) + f->localDispatch(bv, LFUN_MATH_DISPLAY, string()); + f->localDispatch(bv, LFUN_INSERT_MATH, arg); + } + } else { + // create a macro if we see "\\newcommand" somewhere, and an ordinary + // formula otherwise + if (sel.find("\\newcommand") == string::npos) + f = new InsetFormula(sel); + else + f = new InsetFormulaMacro(sel); + bv->getLyXText()->cutSelection(bv); + openNewInset(bv, f); + } } bv->owner()->getLyXFunc()->setMessage(N_("Math editor mode")); } + void mathDispatchMathDisplay(BufferView * bv, string const & arg) { mathDispatchCreation(bv, arg, true); } + void mathDispatchMathMode(BufferView * bv, string const & arg) { mathDispatchCreation(bv, arg, false); } + void mathDispatchMathImportSelection(BufferView * bv, string const & arg) { mathDispatchCreation(bv, arg, true); } + void mathDispatchMathMacro(BufferView * bv, string const & arg) { if (bv->available()) { - string s(arg); - if (s.empty()) + if (arg.empty()) bv->owner()->getLyXFunc()->setErrorMessage(N_("Missing argument")); else { + string s(arg); string const s1 = token(s, ' ', 1); int const na = s1.empty() ? 0 : lyx::atoi(s1); openNewInset(bv, new InsetFormulaMacro(token(s, ' ', 0), na)); @@ -1112,6 +772,7 @@ void mathDispatchMathMacro(BufferView * bv, string const & arg) } } + void mathDispatchMathDelim(BufferView * bv, string const & arg) { if (bv->available()) { @@ -1129,15 +790,29 @@ void mathDispatchInsertMatrix(BufferView * bv, string const & arg) } } + void mathDispatchInsertMath(BufferView * bv, string const & arg) { if (bv->available()) { if (arg.size() && arg[0] == '\\') { InsetFormula * f = new InsetFormula(arg); - openNewInset(bv, f); - } else { + if (!bv->insertInset(f)) + delete f; + } else mathDispatchMathMode(bv, arg); - } } } + +void mathDispatchGreek(BufferView * bv, string const & arg) +{ + if (bv->available()) { + InsetFormula * f = new InsetFormula; + if (openNewInset(bv, f)) { + bv->theLockingInset()->localDispatch(bv, LFUN_GREEK, arg); + bv->unlockInset(f); + } + } +} + +