X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2Fformula.C;h=5b10679fb142b219f6d7a2125bc00f4a90453ebd;hb=d597ece5e7efac2a25251034d89fa761759d28f7;hp=7362f3bfea201a480ddb9c532a65ce4a89a1b11f;hpb=1d7d3cc4afa2205c801ccc2aa71c7ac59359dc5f;p=lyx.git diff --git a/src/mathed/formula.C b/src/mathed/formula.C index 7362f3bfea..5b10679fb1 100644 --- a/src/mathed/formula.C +++ b/src/mathed/formula.C @@ -1,11 +1,11 @@ /* - * File: formula.h + * 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: (c) 1996-1998 Alejandro Aguilar Sierra + * Copyright: 1996-1998 Alejandro Aguilar Sierra * * Version: 0.4, Lyx project. * @@ -15,8 +15,7 @@ #include -#include -#include +#include "Lsstream.h" #ifdef __GNUG__ #pragma implementation "formula.h" @@ -27,72 +26,53 @@ #include "math_cursor.h" #include "math_parser.h" #include "lyx_main.h" -#include "bufferlist.h" -#include "lyx_cb.h" #include "minibuffer.h" #include "BufferView.h" -#include "lyxscreen.h" -#include "lyxdraw.h" #include "lyxtext.h" #include "gettext.h" #include "LaTeXFeatures.h" #include "debug.h" #include "lyx_gui_misc.h" +#include "support/LOstream.h" +#include "LyXView.h" +#include "Painter.h" +#include "font.h" +#include "support/lyxlib.h" -extern void UpdateInset(Inset* inset, bool mark_dirty = true); -extern void LockedInsetStoreUndo(Undo::undo_kind); -extern MiniBuffer *minibuffer; -extern void ShowLockedInsetCursor(long, long, int, int); -extern void HideLockedInsetCursor(long, long, int, int); -extern void FitLockedInsetCursor(long, long, int, int); -extern int LockInset(UpdatableInset*); -extern int UnlockInset(UpdatableInset*); +using std::ostream; +using std::istream; +using std::pair; +using std::endl; +using std::vector; +using std::max; +//extern char * mathed_label; +extern string mathed_label; -extern GC canvasGC, mathGC, mathLineGC, latexGC, cursorGC, mathFrameGC; -extern char *mathed_label; +extern char const * latex_special_chars; -extern int mono_video; -extern int fast_selection; +int greek_kb_flag = 0; -extern BufferView *current_view; -extern BufferList bufferlist; -extern char const *latex_special_chars; - -short greek_kb_flag = 0; - -LyXFont *Math_Fonts = 0; // this is only used by Whichfont and mathed_init_fonts (Lgb) +LyXFont * Math_Fonts = 0; // this is only used by Whichfont and mathed_init_fonts (Lgb) static LyXFont::FONT_SIZE lfont_size = LyXFont::SIZE_NORMAL; -// local global -static int sel_x, sel_y; +// local global +static int sel_x; +static int sel_y; static bool sel_flag; -MathedCursor* InsetFormula::mathcursor = 0; + +MathedCursor * InsetFormula::mathcursor = 0; int MathedInset::df_asc; int MathedInset::df_des; int MathedInset::df_width; -// wrong name on this one should be called "IsAscii" -inline bool IsAlpha(char c) -{ - return ('A' <= c && c<= 'Z' || 'a' <= c && c<= 'z'); -} -inline bool IsDigit(char c) -{ - return ('0' <= c && c <= '9'); -} +static +void mathedValidate(LaTeXFeatures & features, MathParInset * par); -inline bool IsMacro(short token, int id) -{ - return (token!= LM_TK_FRAC && token!= LM_TK_SQRT && - !((token == LM_TK_SYM || token == LM_TC_BSYM) && id<255)); -} - -void mathedValidate(LaTeXFeatures &features, MathParInset *par); LyXFont WhichFont(short type, int size) { @@ -156,21 +136,23 @@ LyXFont WhichFont(short type, int size) lyxerr << "Mathed Error: wrong font size: " << size << endl; break; } - - if (type!= LM_TC_TEXTRM) - f.setColor(LyXFont::MATH); + + if (type != LM_TC_TEXTRM) + f.setColor(LColor::math); return f; } void mathed_init_fonts() //removed 'static' because DEC cxx does not - //like it (JMarc) + //like it (JMarc) + // Probably because this func is declared as a friend in math_defs.h + // Lgb { 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::ALL_SANE; + for (int i = 0 ; i < 8 ; ++i) { + Math_Fonts[i] = LyXFont(LyXFont::ALL_SANE); } Math_Fonts[0].setShape(LyXFont::ITALIC_SHAPE); @@ -191,98 +173,99 @@ void mathed_init_fonts() //removed 'static' because DEC cxx does not Math_Fonts[7].setFamily(LyXFont::SANS_FAMILY); LyXFont f = WhichFont(LM_TC_VAR, LM_ST_TEXT); - MathedInset::df_asc = f.maxAscent(); - MathedInset::df_des = f.maxDescent(); - MathedInset::df_width = f.width('I'); + MathedInset::df_asc = lyxfont::maxAscent(f); + MathedInset::df_des = lyxfont::maxDescent(f); + MathedInset::df_width = lyxfont::width('I', f); } -void mathed_set_font(short type, int size) +LyXFont mathed_get_font(short type, int size) { - if (!canvasGC) { - cursorGC = getGC(gc_thin_on_off_line); - canvasGC = getGC(gc_lighted); - latexGC = getGC(gc_latex); - mathLineGC = getGC(gc_math); - mathFrameGC = getGC(gc_math_frame); - } - LyXFont f = WhichFont(type, size); - if (type == LM_TC_TEX) { - f.setLatex(LyXFont::ON); - latexGC = f.getGC(); - } else - mathGC = f.getGC(); + LyXFont f = WhichFont(type, size); + if (type == LM_TC_TEX) { + f.setLatex(LyXFont::ON); + } + return f; } -int mathed_string_width(short type, int size, byte const* s, int ls) +int mathed_string_width(short type, int size, byte const * s, int ls) { - LyXFont f = WhichFont(type, size); - - byte sx[80]; - if (MathIsBinary(type)) { - byte *ps = &sx[0]; - for (int i= 0; i(s), ls); + + LyXFont const f = WhichFont(type, size); + return lyxfont::width(st, f); +} + +int mathed_string_width(short type, int size, string const & str) +{ + return mathed_string_width(type, size, reinterpret_cast(str.c_str()), str.length()); } + int mathed_char_width(short type, int size, byte c) { - int t= (MathIsBinary(type)) ? mathed_string_width(type, size, &c, 1): - WhichFont(type, size).width(c); + int t = (MathIsBinary(type)) ? mathed_string_width(type, size, &c, 1) : + lyxfont::width(c, WhichFont(type, size)); return t; } -int mathed_string_height(short type, int size, byte const * s, int ls, int& asc, int& des) + +int mathed_string_height(short type, int size, byte const * s, + int ls, int & asc, int & des) { LyXFont font = WhichFont(type, size); asc = des = 0; - for (int i= 0; i des) - des = font.descent(s[i]); - if (font.ascent(s[i]) > asc) - asc = font.ascent(s[i]); + for (int i = 0; i < ls; ++i) { + des = max(des, lyxfont::descent(s[i], font)); + asc = max(asc, lyxfont::ascent(s[i], font)); } - return asc+des; + return asc + des; } -int mathed_char_height(short type, int size, byte c, int& asc, int& des) + +int mathed_string_height(short type, int size, string const & str, + int & asc, int & des) +{ + return mathed_string_height(type, size, + reinterpret_cast(str.c_str()), str.length(), + asc, des); +} + + +int mathed_char_height(short type, int size, byte c, int & asc, int & des) { LyXFont font = WhichFont(type, size); - asc = des = 0; - des = font.descent(c); - asc = font.ascent(c); - return asc+des; + des = lyxfont::descent(c, font); + asc = lyxfont::ascent(c, font); + return asc + des; } // In a near future maybe we use a better fonts renderer -void MathedInset::drawStr(short type, int siz, int x, int y, byte* s, int ls) +void MathedInset::drawStr(Painter & pain, short type, int siz, + int x, int y, byte const * s, int ls) { - mathed_set_font(type, siz); - byte sx[80]; - if (MathIsBinary(type)) { - byte *ps = &sx[0]; - for (int i= 0; i(s), ls); - XFlush(fl_display); + string st; + if (MathIsBinary(type)) + for (int i = 0; i < ls; ++i) { + st += ' '; + st += char(s[i]); + st += ' '; + } + else + st = string(reinterpret_cast(s), ls); + + LyXFont const mf = mathed_get_font(type, siz); + pain.text(x, y, st, mf); } @@ -298,10 +281,11 @@ InsetFormula::InsetFormula(bool display) } } -InsetFormula::InsetFormula(MathParInset *p) + +InsetFormula::InsetFormula(MathParInset * p) { par = (p->GetType()>= LM_OT_MPAR) ? - new MathMatrixInset((MathMatrixInset*)p): + new MathMatrixInset(static_cast(p)): new MathParInset(p); // mathcursor = 0; @@ -309,63 +293,59 @@ InsetFormula::InsetFormula(MathParInset *p) //label = 0; } + InsetFormula::~InsetFormula() { delete par; - //if (label) delete label; } -InsetFormula * InsetFormula::Clone() const + +Inset * InsetFormula::Clone(Buffer const &) const { InsetFormula * f = new InsetFormula(par); f->label = label; return f; } -void InsetFormula::Write(FILE *file) + +void InsetFormula::Write(Buffer const * buf, ostream & os) const { - fprintf(file, "Formula "); - Latex(file, 0); + os << "Formula "; + Latex(buf, os, false, false); } -int InsetFormula::Latex(FILE *file, signed char fragile) + +int InsetFormula::Latex(Buffer const *, ostream & os, bool fragile, bool) const { int ret = 0; //#warning Alejandro, the number of lines is not returned in this case // This problem will disapear at 0.13. - string output; - InsetFormula::Latex(output, fragile); - fprintf(file, "%s", output.c_str()); + mathed_write(par, os, &ret, fragile, label); return ret; } -int InsetFormula::Latex(string &file, signed char fragile) + +int InsetFormula::Ascii(Buffer const *, ostream & os, int) const { - int ret = 0; -//#warning Alejandro, the number of lines is not returned in this case -// This problem will disapear at 0.13. - if (fragile < 0) - par->Write(file); - else - mathed_write(par, file, &ret, fragile, label.c_str()); - return ret; + par->Write(os, false); + return 0; } -int InsetFormula::Linuxdoc(string &/*file*/) +int InsetFormula::Linuxdoc(Buffer const * buf, ostream & os) const { - return 0; + return Ascii(buf, os, 0); } -int InsetFormula::DocBook(string &/*file*/) +int InsetFormula::DocBook(Buffer const * buf, ostream & os) const { - return 0; + return Ascii(buf, os, 0); } // Check if uses AMS macros -void InsetFormula::Validate(LaTeXFeatures &features) const +void InsetFormula::Validate(LaTeXFeatures & features) const { // Validation only necesary if not using an AMS Style if (!features.amsstyle) @@ -373,189 +353,227 @@ void InsetFormula::Validate(LaTeXFeatures &features) const } -void InsetFormula::Read(LyXLex &lex) +void InsetFormula::Read(Buffer const *, LyXLex & lex) { - FILE *file = lex.getFile(); + istream & is = lex.getStream(); - mathed_parser_file(file, lex.GetLineNo()); + mathed_parser_file(is, lex.GetLineNo()); - // Silly hack to read labels. - mathed_label = 0; - mathed_parse(0, 0, &par); - par->Metrics(); - disp_flag = (par->GetType()>0); - - // Update line number - lex.setLineNo(mathed_parser_lineno()); - - if (mathed_label) { - label = mathed_label; - mathed_label = 0; - } + // Silly hack to read labels. + //mathed_label = 0; + mathed_label.erase(); + + mathed_parse(0, 0, &par); + par->Metrics(); + disp_flag = (par->GetType() > 0); + + // Update line number + lex.setLineNo(mathed_parser_lineno()); + + //if (mathed_label) { + if (!mathed_label.empty()) { + label = mathed_label; + //mathed_label = 0; + mathed_label.erase(); + } + + // reading of end_inset in the inset!!! + while (lex.IsOK()) { + lex.nextToken(); + if (lex.GetString() == "\\end_inset") + break; + lyxerr << "InsetFormula::Read: Garbage before \\end_inset," + " or missing \\end_inset!" << endl; + } #ifdef DEBUG - Write(stdout); - fflush(stdout); + Write(lyxerr); #endif } -int InsetFormula::Ascent(LyXFont const &) const + +int InsetFormula::ascent(BufferView *, LyXFont const &) const { - return par->Ascent() + ((disp_flag) ? 8: 1); + return par->Ascent() + ((disp_flag) ? 8 : 1); } -int InsetFormula::Descent(LyXFont const &) const + +int InsetFormula::descent(BufferView *, LyXFont const &) const { - return par->Descent() + ((disp_flag) ? 8: 1); + return par->Descent() + ((disp_flag) ? 8 : 1); } -int InsetFormula::Width(LyXFont const &f) const + +int InsetFormula::width(BufferView *, LyXFont const & f) const { lfont_size = f.size(); par->Metrics(); return par->Width(); //+2; } -void InsetFormula::Draw(LyXFont f, LyXScreen &scr, int baseline, float &x) + +void InsetFormula::draw(BufferView * bv, LyXFont const & f, + int baseline, float & x, bool) const { - // This is Alejandros domain so I'll use this - unsigned long pm = scr.getForeground(); + Painter & pain = bv->painter(); + // Seems commenting out solves a problem. + LyXFont font = mathed_get_font(LM_TC_TEXTRM, LM_ST_TEXT); + font.setSize(f.size()); + lfont_size = font.size(); + /// Let's try to wait a bit with this... (Lgb) + //UpdatableInset::draw(pain, font, baseline, x); - lfont_size = f.size(); - mathed_set_font(LM_TC_TEXTRM, LM_ST_TEXT); // otherwise a segfault could occur - // in some XDrawRectangles (i.e. matrix) (Matthias) - if (mathcursor && mathcursor->GetPar() == par) { - if (mathcursor->Selection()) { - int n; - XPoint * p = mathcursor->SelGetArea(n); - XFillPolygon(fl_display, pm, getGC(gc_selection), //LyXGetSelectionGC(), - p, n, Nonconvex, CoordModeOrigin); - } - mathcursor->Draw(pm, (int)x, baseline); - } else { -// par->Metrics(); - par->setDrawable(pm); - par->Draw((int)x, baseline); - } - x += (float)Width(f); - - if (par->GetType() == LM_OT_PARN || par->GetType() == LM_OT_MPARN) { - char s[80]; - LyXFont font = WhichFont(LM_TC_BF, par->size); - font.setLatex(LyXFont::OFF); - - if (par->GetType() == LM_OT_PARN) { - if (!label.empty()) - sprintf(s, "(%s)", label.c_str()); - else - sprintf(s, "(#)"); - font.drawString(s, pm, baseline, int(x+20)); - } else - if (par->GetType() == LM_OT_MPARN) { - MathMatrixInset *mt = (MathMatrixInset*)par; - //int i= 0; - int y; - MathedRowSt const* crow = mt->getRowSt(); - while (crow) { - y = baseline + crow->getBaseline(); - if (crow->isNumbered()) { - if (crow->getLabel()) - sprintf(s, "(%s)", crow->getLabel()); - else - sprintf(s, "(#)"); - font.drawString(s, pm, y, int(x+20)); - } - crow = crow->getNext(); - } - } - } - cursor_visible = false; + // otherwise a segfault could occur + // in some XDrawRectangles (i.e. matrix) (Matthias) + if (mathcursor && mathcursor->GetPar() == par) { + if (mathcursor->Selection()) { + int n; + int * xp = 0; + int * yp = 0; + mathcursor->SelGetArea(&xp, &yp, n); + pain.fillPolygon(xp, yp, n, LColor::selection); + } + mathcursor->draw(pain, int(x), baseline); + } else { + par->draw(pain, int(x), baseline); + } + x += float(width(bv, font)); + + if (par->GetType() == LM_OT_PARN || par->GetType() == LM_OT_MPARN) { + LyXFont wfont = WhichFont(LM_TC_BF, par->size); + wfont.setLatex(LyXFont::OFF); + + if (par->GetType() == LM_OT_PARN) { + string str; + if (!label.empty()) + str = string("(") + label + ")"; + else + str = string("(#)"); + pain.text(int(x + 20), baseline, str, wfont); + } else if (par->GetType() == LM_OT_MPARN) { + MathMatrixInset * mt = + static_cast(par); + int y; + MathedRowSt const * crow = mt->getRowSt(); + while (crow) { + y = baseline + crow->getBaseline(); + if (crow->isNumbered()) { + string str; + if (!crow->getLabel().empty()) + str = string("(") + crow->getLabel() + ")"; + else + str = "(#)"; + pain.text(int(x + 20), y, str, wfont); + } + crow = crow->getNext(); + } + } + } + cursor_visible = false; } -void InsetFormula::Edit(int x, int y) +string const InsetFormula::EditMessage() const { - mathcursor = new MathedCursor(par); - LockInset(this); - par->Metrics(); - UpdateInset(this, false); - x += par->xo; - y += par->yo; - mathcursor->SetPos(x, y); + return _("Math editor mode"); +} + + +void InsetFormula::Edit(BufferView * bv, int x, int y, unsigned int) +{ + mathcursor = new MathedCursor(par); + if (!bv->lockInset(this)) + lyxerr[Debug::MATHED] << "Cannot lock inset!!!" << endl; + par->Metrics(); + bv->updateInset(this, false); + x += par->xo; + y += par->yo; + mathcursor->SetPos(x, y); sel_x = sel_y = 0; sel_flag = false; } - -void InsetFormula::InsetUnlock() + + +void InsetFormula::InsetUnlock(BufferView * bv) { if (mathcursor) { if (mathcursor->InMacroMode()) { mathcursor->MacroModeClose(); - UpdateLocal(); + UpdateLocal(bv); } delete mathcursor; } mathcursor = 0; - UpdateInset(this, false); + bv->updateInset(this, false); } + // Now a symbol can be inserted only if the inset is locked -void InsetFormula::InsertSymbol(char const* s) +void InsetFormula::InsertSymbol(BufferView * bv, string const & s) { - if (!s || !mathcursor) return; + if (s.empty() || !mathcursor) return; mathcursor->Interpret(s); - UpdateLocal(); + UpdateLocal(bv); } + -void InsetFormula::GetCursorPos(int& x, int& y) +void InsetFormula::GetCursorPos(BufferView *, int & x, int & y) const { mathcursor->GetPos(x, y); x -= par->xo; y -= par->yo; } -void InsetFormula::ToggleInsetCursor() + +void InsetFormula::ToggleInsetCursor(BufferView * bv) { if (!mathcursor) return; - int x, y, asc, desc; + int x; + int y; mathcursor->GetPos(x, y); // x -= par->xo; y -= par->yo; LyXFont font = WhichFont(LM_TC_TEXTRM, LM_ST_TEXT); - asc = font.maxAscent(); - desc = font.maxDescent(); + int asc = lyxfont::maxAscent(font); + int desc = lyxfont::maxDescent(font); if (cursor_visible) - HideLockedInsetCursor(x, y, asc, desc); + bv->hideLockedInsetCursor(); else - ShowLockedInsetCursor(x, y, asc, desc); + bv->showLockedInsetCursor(x, y, asc, desc); cursor_visible = !cursor_visible; } -void InsetFormula::ShowInsetCursor(){ - if (!cursor_visible){ - int x, y, asc, desc; - if (mathcursor){ + +void InsetFormula::ShowInsetCursor(BufferView * bv, bool) +{ + if (!cursor_visible) { + 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); - asc = font.maxAscent(); - desc = font.maxDescent(); - FitLockedInsetCursor(x, y, asc, desc); + int asc = lyxfont::maxAscent(font); + int desc = lyxfont::maxDescent(font); + bv->fitLockedInsetCursor(x, y, asc, desc); } - ToggleInsetCursor(); + ToggleInsetCursor(bv); } } -void InsetFormula::HideInsetCursor(){ + +void InsetFormula::HideInsetCursor(BufferView * bv) +{ if (cursor_visible) - ToggleInsetCursor(); + ToggleInsetCursor(bv); } -void InsetFormula::ToggleInsetSelection() + +void InsetFormula::ToggleInsetSelection(BufferView * bv) { if (!mathcursor) return; @@ -564,22 +582,23 @@ void InsetFormula::ToggleInsetSelection() //int n; //XPoint * p = //mathcursor->SelGetArea(n); -// XFillPolygon(fl_display, pm, LyXGetSelectionGC(), p, n, Nonconvex, CoordModeOrigin); +// XFillPolygon(fl_get_display(), pm, LyXGetSelectionGC(), p, n, Nonconvex, CoordModeOrigin); // x -= par->xo; // y -= par->yo; - UpdateInset(this, false); + bv->updateInset(this, false); } + void InsetFormula::display(bool dspf) { - if (dspf!= disp_flag) { + if (dspf != disp_flag) { if (dspf) { par->SetType(LM_OT_PAR); par->SetStyle(LM_ST_DISPLAY); } else { - if (par->GetType()>= LM_OT_MPAR) { + if (par->GetType() >= LM_OT_MPAR) { MathParInset * p = new MathParInset(par); delete par; par = p; @@ -588,148 +607,134 @@ void InsetFormula::display(bool dspf) } par->SetType(LM_OT_MIN); par->SetStyle(LM_ST_TEXT); - if (!label.empty() && par->GetType()!= LM_OT_MPARN) { - label.clear(); + if (!label.empty() && par->GetType() != LM_OT_MPARN) { + label.erase(); } } disp_flag = dspf; - } + } } - -int InsetFormula::GetNumberOfLabels() const +vector const InsetFormula::getLabelList() const { - // This is dirty, I know. I'll clean it at 0.13 - if (par->GetType() == LM_OT_MPARN) { - MathMatrixInset * mt = (MathMatrixInset*)par; - int nl = 0; - MathedRowSt const * crow = mt->getRowSt(); - while (crow) { - if (crow->getLabel()) nl++; - crow = crow->getNext(); - } - return nl; - } else - if (!label.empty()) - return 1; - else - return 0; -} +//#warning This is dirty, I know. Ill clean it at 0.11 +// Correction, the only way to clean this is with a new kernel: 0.13. + vector label_list; -string InsetFormula::getLabel(int il) const -{ -//#warning This is dirty, I know. Ill clean it at 0.11 - // Correction, the only way to clean this is with a new kernel: 0.13. if (par->GetType() == LM_OT_MPARN) { - string lab; - MathMatrixInset * mt = (MathMatrixInset*)par; - int nl= 0; + MathMatrixInset * mt = static_cast(par); MathedRowSt const * crow = mt->getRowSt(); while (crow) { - if (crow->getLabel()) { - if (nl == il) { - lab = crow->getLabel(); - break; - } - nl++; - } + if (!crow->getLabel().empty()) + label_list.push_back(crow->getLabel()); crow = crow->getNext(); } - return lab; - } - return label; + } else if (!label.empty()) + label_list.push_back(label); + + return label_list; } -void InsetFormula::UpdateLocal() + +void InsetFormula::UpdateLocal(BufferView * bv) { par->Metrics(); // To inform lyx kernel the exact size // (there were problems with arrays). - UpdateInset(this); + bv->updateInset(this, true); } - -void InsetFormula::InsetButtonRelease(int x, int y, int /*button*/) +void InsetFormula::InsetButtonRelease(BufferView * bv, + int x, int y, int /*button*/) { - HideInsetCursor(); - x += par->xo; - y += par->yo; - mathcursor->SetPos(x, y); - ShowInsetCursor(); - if (sel_flag) { - sel_flag = false; - sel_x = sel_y = 0; - UpdateInset(this, false); + if (mathcursor) { + HideInsetCursor(bv); + x += par->xo; + y += par->yo; + mathcursor->SetPos(x, y); + ShowInsetCursor(bv); + if (sel_flag) { + sel_flag = false; + sel_x = sel_y = 0; + bv->updateInset(this, false); + } } } -void InsetFormula::InsetButtonPress(int x, int y, int /*button*/) + +void InsetFormula::InsetButtonPress(BufferView * bv, + int x, int y, int /*button*/) { sel_flag = false; - sel_x = x; sel_y = y; - if (mathcursor->Selection()) { + sel_x = x; sel_y = y; + if (mathcursor && mathcursor->Selection()) { mathcursor->SelClear(); - UpdateInset(this, false); + bv->updateInset(this, false); } } -void InsetFormula::InsetMotionNotify(int x, int y, int /*button*/) + +void InsetFormula::InsetMotionNotify(BufferView * bv, + int x, int y, int /*button*/) { - if (sel_x && sel_y && abs(x-sel_x)>4 && !sel_flag) { + if (sel_x && sel_y && abs(x-sel_x) > 4 && !sel_flag) { sel_flag = true; - HideInsetCursor(); + HideInsetCursor(bv); mathcursor->SetPos(sel_x + par->xo, sel_y + par->yo); mathcursor->SelStart(); - ShowInsetCursor(); + ShowInsetCursor(bv); mathcursor->GetPos(sel_x, sel_y); - } else - if (sel_flag) { - HideInsetCursor(); + } else if (sel_flag) { + HideInsetCursor(bv); x += par->xo; y += par->yo; mathcursor->SetPos(x, y); - ShowInsetCursor(); + ShowInsetCursor(bv); mathcursor->GetPos(x, y); if (sel_x!= x || sel_y!= y) - UpdateInset(this, false); + bv->updateInset(this, false); sel_x = x; sel_y = y; } } + void InsetFormula::InsetKeyPress(XKeyEvent *) { lyxerr[Debug::MATHED] << "Used InsetFormula::InsetKeyPress." << endl; } + // Special Mathed functions bool InsetFormula::SetNumber(bool numbf) { if (disp_flag) { short type = par->GetType(); bool oldf = (type == LM_OT_PARN || type == LM_OT_MPARN); - if (numbf && !oldf) type++; - if (!numbf && oldf) type--; + if (numbf && !oldf) ++type; + if (!numbf && oldf) --type; par->SetType(type); return oldf; } else return false; } -bool InsetFormula::LocalDispatch(int action, char const *arg) + +UpdatableInset::RESULT +InsetFormula::LocalDispatch(BufferView * bv, + int action, string const & arg) { // extern char *dispatch_result; MathedTextCodes varcode = LM_TC_MIN; - bool was_macro = mathcursor->InMacroMode(); - bool sel= false; - bool space_on = false; - bool was_selection = mathcursor->Selection(); - bool result = true; - static MathSpaceInset* sp= 0; + bool was_macro = mathcursor->InMacroMode(); + bool sel = false; + bool space_on = false; + bool was_selection = mathcursor->Selection(); + RESULT result = DISPATCHED; + static MathSpaceInset * sp= 0; - HideInsetCursor(); - if (mathcursor->Selection() && (fast_selection || mono_video)) ToggleInsetSelection(); + HideInsetCursor(bv); if (mathcursor->getLastCode() == LM_TC_TEX) { varcode = LM_TC_TEX; @@ -740,66 +745,74 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) case LFUN_RIGHTSEL: sel = true; case LFUN_RIGHT: { - result = mathcursor->Right(sel); + result = DISPATCH_RESULT(mathcursor->Right(sel)); + if (!sel && (result == DISPATCHED)) + result = DISPATCHED_NOUPDATE; break; } case LFUN_LEFTSEL: sel = true; case LFUN_LEFT: { - result = mathcursor->Left(sel); + result = DISPATCH_RESULT(mathcursor->Left(sel)); + if (!sel && (result == DISPATCHED)) + result = DISPATCHED_NOUPDATE; break; } case LFUN_UPSEL: sel = true; case LFUN_UP: - result = mathcursor->Up(sel); + result = DISPATCH_RESULT(mathcursor->Up(sel)); + if (!sel && (result == DISPATCHED)) + result = DISPATCHED_NOUPDATE; break; case LFUN_DOWNSEL: sel = true; case LFUN_DOWN: - result = mathcursor->Down(sel); + result = DISPATCH_RESULT(mathcursor->Down(sel)); + if (!sel && (result == DISPATCHED)) + result = DISPATCHED_NOUPDATE; break; case LFUN_HOME: mathcursor->Home(); + result = DISPATCHED_NOUPDATE; break; case LFUN_END: mathcursor->End(); + result = DISPATCHED_NOUPDATE; break; case LFUN_DELETE_LINE_FORWARD: - //LockedInsetStoreUndo(Undo::INSERT); - LockedInsetStoreUndo(Undo::DELETE); + bv->lockedInsetStoreUndo(Undo::DELETE); mathcursor->DelLine(); - UpdateLocal(); + UpdateLocal(bv); break; case LFUN_BREAKLINE: - LockedInsetStoreUndo(Undo::INSERT); + bv->lockedInsetStoreUndo(Undo::INSERT); mathcursor->Insert(' ', LM_TC_CR); par = mathcursor->GetPar(); - UpdateLocal(); + UpdateLocal(bv); break; case LFUN_TAB: - LockedInsetStoreUndo(Undo::INSERT); + bv->lockedInsetStoreUndo(Undo::INSERT); mathcursor->Insert(0, LM_TC_TAB); //UpdateInset(this); break; case LFUN_TABINSERT: - LockedInsetStoreUndo(Undo::INSERT); + bv->lockedInsetStoreUndo(Undo::INSERT); mathcursor->Insert('T', LM_TC_TAB); - UpdateLocal(); + UpdateLocal(bv); break; case LFUN_BACKSPACE: if (!mathcursor->Left()) break; - if (!mathcursor-> InMacroMode() && mathcursor->pullArg()) { - UpdateInset(this); + if (!mathcursor->InMacroMode() && mathcursor->pullArg()) { + bv->updateInset(this, true); break; } case LFUN_DELETE: - //LockedInsetStoreUndo(Undo::INSERT); - LockedInsetStoreUndo(Undo::DELETE); + bv->lockedInsetStoreUndo(Undo::DELETE); mathcursor->Delete(); - UpdateInset(this); + bv->updateInset(this, true); break; // case LFUN_GETXY: // sprintf(dispatch_buffer, "%d %d",); @@ -807,10 +820,14 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) // break; case LFUN_SETXY: { - int x, y, x1, y1; - sscanf(arg, "%d %d", &x, &y); + int x; + int y; + int x1; + int y1; + istringstream ist(arg.c_str()); + ist >> x >> y; par->GetXY(x1, y1); - mathcursor->SetPos(x1+x, y1+y); + mathcursor->SetPos(x1 + x, y1 + y); } break; @@ -819,11 +836,11 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) case LFUN_PASTE: if (was_macro) mathcursor->MacroModeClose(); - LockedInsetStoreUndo(Undo::INSERT); - mathcursor->SelPaste(); UpdateLocal(); break; + bv->lockedInsetStoreUndo(Undo::INSERT); + mathcursor->SelPaste(); UpdateLocal(bv); break; case LFUN_CUT: - LockedInsetStoreUndo(Undo::DELETE); - mathcursor->SelCut(); UpdateLocal(); break; + bv->lockedInsetStoreUndo(Undo::DELETE); + mathcursor->SelCut(); UpdateLocal(bv); break; case LFUN_COPY: mathcursor->SelCopy(); break; case LFUN_HOMESEL: case LFUN_ENDSEL: @@ -849,7 +866,7 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) { if (!greek_kb_flag) { greek_kb_flag = 1; - minibuffer->Set(_("Math greek mode on")); + bv->owner()->getMiniBuffer()->Set(_("Math greek mode on")); } else greek_kb_flag = 0; break; @@ -858,11 +875,11 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) // Greek keyboard case LFUN_GREEK_TOGGLE: { - greek_kb_flag = (greek_kb_flag) ? 0: 2; + greek_kb_flag = (greek_kb_flag) ? 0 : 2; if (greek_kb_flag) - minibuffer->Set(_("Math greek keyboard on")); + bv->owner()->getMiniBuffer()->Set(_("Math greek keyboard on")); else - minibuffer->Set(_("Math greek keyboard off")); + bv->owner()->getMiniBuffer()->Set(_("Math greek keyboard off")); break; } @@ -877,28 +894,28 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) { // varcode = LM_TC_TEX; mathcursor->setLastCode(LM_TC_TEX); - minibuffer->Set(_("TeX mode")); + bv->owner()->getMiniBuffer()->Set(_("TeX mode")); break; } case LFUN_MATH_NUMBER: { - LockedInsetStoreUndo(Undo::INSERT); + bv->lockedInsetStoreUndo(Undo::INSERT); if (disp_flag) { short type = par->GetType(); bool oldf = (type == LM_OT_PARN || type == LM_OT_MPARN); if (oldf) { - type--; + --type; if (!label.empty()) { - label.clear(); + label.erase(); } - minibuffer->Set(_("No number")); + bv->owner()->getMiniBuffer()->Set(_("No number")); } else { - type++; - minibuffer->Set(_("Number")); + ++type; + bv->owner()->getMiniBuffer()->Set(_("Number")); } par->SetType(type); - UpdateLocal(); + UpdateLocal(bv); } break; } @@ -911,76 +928,77 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) // mt->SetNumbered(!mt->IsNumbered()); mathcursor->setNumbered(); - UpdateLocal(); + UpdateLocal(bv); } break; } case LFUN_MATH_LIMITS: { - LockedInsetStoreUndo(Undo::INSERT); + bv->lockedInsetStoreUndo(Undo::INSERT); if (mathcursor->Limits()) - UpdateLocal(); + UpdateLocal(bv); } case LFUN_MATH_SIZE: - if (arg) { - latexkeys *l = in_word_set (arg, strlen(arg)); + if (!arg.empty()) { + latexkeys * l = in_word_set (arg); int sz = (l) ? l->id: -1; mathcursor->SetSize(sz); - UpdateLocal(); + UpdateLocal(bv); break; } case LFUN_INSERT_MATH: { - LockedInsetStoreUndo(Undo::INSERT); - InsertSymbol(arg); + bv->lockedInsetStoreUndo(Undo::INSERT); + InsertSymbol(bv, arg); break; } case LFUN_INSERT_MATRIX: { - LockedInsetStoreUndo(Undo::INSERT); + bv->lockedInsetStoreUndo(Undo::INSERT); int k, m, n; char s[80], arg2[80]; // This is just so that too long args won't ooze out of s. - strncpy(arg2, arg, 80); arg2[79]= (char)0; + strncpy(arg2, arg.c_str(), 80); arg2[79]= '\0'; k = sscanf(arg2, "%d %d %s", &m, &n, s); - s[79] = (char)0; + s[79] = '\0'; - if (k<1) { + if (k < 1) { m = n = 1; } else if (k == 1) { n = 1; } - MathMatrixInset *p = new MathMatrixInset(m, n); + MathMatrixInset * p = new MathMatrixInset(m, n); if (mathcursor && p) { - if (k>2 && (int)strlen(s)>m) + if (k > 2 && int(strlen(s)) > m) p->SetAlign(s[0], &s[1]); mathcursor->Insert(p, LM_TC_ACTIVE_INSET); - UpdateLocal(); + UpdateLocal(bv); } break; } case LFUN_MATH_DELIM: { - LockedInsetStoreUndo(Undo::INSERT); + bv->lockedInsetStoreUndo(Undo::INSERT); char lf[40], rg[40], arg2[40]; int ilf = '(', irg = '.'; - latexkeys *l; + latexkeys * l; string vdelim("(){}[]./|"); - if (!arg) break; - strncpy(arg2, arg, 40); arg2[39]= (char)0; + if (arg.empty()) + break; + ::strncpy(arg2, arg.c_str(), 40); arg2[39]= '\0'; int n = sscanf(arg2, "%s %s", lf, rg); - lf[39] = (char)0; rg[39] = (char)0; + lf[39] = '\0'; rg[39] = '\0'; - if (n>0) { - if (IsDigit(lf[0])) - ilf = atoi(lf); + if (n > 0) { + if (isdigit(lf[0])) + ilf = lyx::atoi(lf); else if (lf[1]) { l = in_word_set(lf, strlen(lf)); @@ -990,9 +1008,9 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) if (vdelim.find(lf[0]) != string::npos) ilf = lf[0]; - if (n>1) { - if (IsDigit(rg[0])) - irg = atoi(rg); + if (n > 1) { + if (isdigit(rg[0])) + irg = lyx::atoi(rg); else if (rg[1]) { l = in_word_set(rg, strlen(rg)); @@ -1003,58 +1021,61 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) } } - MathDelimInset* p = new MathDelimInset(ilf, irg); + MathDelimInset * p = new MathDelimInset(ilf, irg); mathcursor->Insert(p, LM_TC_ACTIVE_INSET); - UpdateLocal(); + UpdateLocal(bv); break; } case LFUN_PROTECTEDSPACE: { - LockedInsetStoreUndo(Undo::INSERT); + bv->lockedInsetStoreUndo(Undo::INSERT); sp = new MathSpaceInset(1); mathcursor->Insert(sp); space_on = true; - UpdateLocal(); + UpdateLocal(bv); break; } case LFUN_INSERT_LABEL: { - LockedInsetStoreUndo(Undo::INSERT); - if (par->GetType()lockedInsetStoreUndo(Undo::INSERT); + if (par->GetType() < LM_OT_PAR) break; string lb = arg; - if (lb.empty()) - lb = string(askForText(_("Enter new label to insert:"))); - if (!lb.empty() && lb[0]> ' ') { + if (lb.empty()) { + pair + res = askForText(_("Enter new label to insert:")); + if (res.first) { + lb = res.second; + } + } + if (!lb.empty() && lb[0] > ' ') { SetNumber(true); if (par->GetType() == LM_OT_MPARN) { - mathcursor->setLabel(lb.c_str()); + mathcursor->setLabel(lb); // MathMatrixInset *mt = (MathMatrixInset*)par; // mt->SetLabel(lb); } else { //if (label.notEmpty()) delete label; label = lb; } - UpdateLocal(); + UpdateLocal(bv); } else - label.clear(); - //label = 0; + label.erase(); break; } case LFUN_MATH_DISPLAY: - //LockedInsetStoreUndo(Undo::INSERT); - LockedInsetStoreUndo(Undo::EDIT); + bv->lockedInsetStoreUndo(Undo::EDIT); display(!disp_flag); - UpdateLocal(); + UpdateLocal(bv); break; // Invalid actions under math mode case LFUN_MATH_MODE: { if (mathcursor->getLastCode()!= LM_TC_TEXTRM) { - minibuffer->Set(_("math text mode")); + bv->owner()->getMiniBuffer()->Set(_("math text mode")); varcode = LM_TC_TEXTRM; } else { varcode = LM_TC_VAR; @@ -1063,18 +1084,18 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) break; } case LFUN_UNDO: - minibuffer->Set(_("Invalid action in math mode!")); + bv->owner()->getMiniBuffer()->Set(_("Invalid action in math mode!")); break; //------- dummy actions case LFUN_EXEC_COMMAND: - minibuffer->ExecCommand(); + bv->owner()->getMiniBuffer()->PrepareForCommand(); break; default: - if ((action == -1 || action == LFUN_SELFINSERT) && arg) { + if ((action == -1 || action == LFUN_SELFINSERT) && !arg.empty()) { unsigned char c = arg[0]; - LockedInsetStoreUndo(Undo::INSERT); + bv->lockedInsetStoreUndo(Undo::INSERT); if (c == ' ' && mathcursor->getAccent() == LM_hat) { c = '^'; @@ -1092,13 +1113,29 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) } else if (!varcode) { short f = (mathcursor->getLastCode()) ? - mathcursor->getLastCode(): - (MathedTextCodes)mathcursor->GetFCode(); - varcode = MathIsAlphaFont(f) ? (MathedTextCodes)f:LM_TC_VAR; + mathcursor->getLastCode() : + static_cast(mathcursor->GetFCode()); + varcode = MathIsAlphaFont(f) ? + static_cast(f) : + LM_TC_VAR; } // lyxerr << "Varcode << vardoce; - mathcursor->Insert(c, (greek_kb_flag) ? LM_TC_SYMB: varcode); + MathedTextCodes 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 @@ -1125,7 +1162,7 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) if (('0'<= c && c<= '9') || strchr(";:!|[]().,?", c)) mathcursor->Insert(c, LM_TC_CONST); else - if (strchr("+/-*<>= ", c)) + if (strchr("+/-*<>=", c)) mathcursor->Insert(c, LM_TC_BOP); else if (strchr(latex_special_chars, c) && c!= '_') @@ -1140,9 +1177,11 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) if (c == ' ') { if (!varcode) { short f = (mathcursor->getLastCode()) ? - mathcursor->getLastCode(): - (MathedTextCodes)mathcursor->GetFCode(); - varcode = MathIsAlphaFont(f) ? (MathedTextCodes)f:LM_TC_VAR; + mathcursor->getLastCode() : + static_cast(mathcursor->GetFCode()); + varcode = MathIsAlphaFont(f) ? + static_cast(f) : + LM_TC_VAR; } if (varcode == LM_TC_TEXTRM) { mathcursor->Insert(c, LM_TC_TEXTRM); @@ -1156,90 +1195,92 @@ bool InsetFormula::LocalDispatch(int action, char const *arg) space_on = true; } else { if (!mathcursor->Pop() && mathcursor->IsEnd()) - result = false; + result = FINISHED; } } else - if (c == '\'') { + if (c == '\'' || c == '@') { mathcursor->Insert (c, LM_TC_VAR); } else if (c == '\\') { if (was_macro) mathcursor->MacroModeClose(); - minibuffer->Set(_("TeX mode")); + bv->owner()->getMiniBuffer()->Set(_("TeX mode")); mathcursor->setLastCode(LM_TC_TEX); } - UpdateLocal(); + UpdateLocal(bv); } else { // lyxerr << "Closed by action " << action << endl; - result = false; + result = FINISHED; } } - if (was_macro!= mathcursor->InMacroMode()&&action>= 0&&action!= LFUN_BACKSPACE) - UpdateLocal(); + if (was_macro != mathcursor->InMacroMode() + && action >= 0 + && action != LFUN_BACKSPACE) + UpdateLocal(bv); if (sp && !space_on) sp = 0; - if (mathcursor->Selection() || (was_selection && !(fast_selection || mono_video))) - ToggleInsetSelection(); + if (mathcursor->Selection() || was_selection) + ToggleInsetSelection(bv); - if (result) - ShowInsetCursor(); + if ((result == DISPATCHED) || (result == DISPATCHED_NOUPDATE)) + ShowInsetCursor(bv); else - UnlockInset(this); + bv->unlockInset(this); return result; } void -MathFuncInset::Draw(int x, int y) +MathFuncInset::draw(Painter & pain, int x, int y) { - if (name && name[0]>' ') { - LyXFont font = WhichFont(LM_TC_TEXTRM, size); + if (!name.empty() && name[0] > ' ') { + LyXFont font = WhichFont(LM_TC_TEXTRM, size); font.setLatex(LyXFont::ON); - x += (font.textWidth("I", 1)+3)/4; - if (mono_video) { - int a= font.maxAscent(), d= font.maxDescent(); - XFillRectangle (fl_display, pm, getGC(gc_copy), - x, y-a, - font.textWidth(name, strlen(name)), a+d); - XFlush(fl_display); - } - font.drawString(name, pm, y, x); + x += (lyxfont::width('I', font) + 3) / 4; + pain.text(x, y, name, font); } } void MathFuncInset::Metrics() { - ln = (name) ? strlen(name): 0; + //ln = (name) ? strlen(name): 0; LyXFont font = WhichFont(LM_TC_TEXTRM, size); font.setLatex(LyXFont::ON); - width = font.textWidth(name, ln) + font.textWidth("I", 1)/2; - mathed_string_height(LM_TC_TEXTRM, size, (byte const *) name, - strlen(name), ascent, descent); + if (name.empty()) { + width = df_width; + descent = df_des; + ascent = df_asc; + } else { + width = lyxfont::width(name, font) + + lyxfont::width('I', font) / 2; + mathed_string_height(LM_TC_TEXTRM, size, name, ascent, descent); + } } -void mathedValidate(LaTeXFeatures &features, MathParInset *par) +static +void mathedValidate(LaTeXFeatures & features, MathParInset * par) { MathedIter it(par->GetData()); while (it.OK() && !(features.binom && features.boldsymbol)) { if (it.IsInset()) { if(it.IsActive()) { - MathParInset *p = it.GetActiveInset(); + MathParInset * p = it.GetActiveInset(); if (!features.binom && p->GetType() == LM_OT_MACRO && - strcmp(p->GetName(), "binom") == 0) { + p->GetName() == "binom") { features.binom = true; } else { - for (int i= 0; i<= p->getMaxArgumentIdx(); i++) { + for (int i = 0; i <= p->getMaxArgumentIdx(); ++i) { p->setArgumentIdx(i); mathedValidate(features, p); } } } else { MathedInset* p = it.GetInset(); - if (!features.boldsymbol && p->GetName() && - strcmp(p->GetName(), "boldsymbol") == 0) { + if (!features.boldsymbol && + p->GetName() == "boldsymbol") { features.boldsymbol = true; } }