]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/formula.C
compilation fixes when using lyxstring
[lyx.git] / src / mathed / formula.C
index 82565a529881c2888ace6290353eabca2366d090..48d0b55581e30c0bd417f6a58e98afc618fa8b36 100644 (file)
@@ -1,25 +1,25 @@
 /*
- *  File:        formula.h
- *  Purpose:     Implementation of formula inset
- *  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx> 
- *  Created:     January 1996
- *  Description: Allows the edition of math paragraphs inside Lyx. 
- *
- *  Copyright: (c) 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.
- */
+*  File:        formula.C
+*  Purpose:     Implementation of formula inset
+*  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
+*  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 <config.h>
+#include <fstream>
 
-#include <cctype>
-#include <cstdlib>
+#include "Lsstream.h"
 
 #ifdef __GNUG__
-#pragma implementation "formula.h"
+#pragma implementation
 #endif
 
 #include "formula.h"
 #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 "support/lyxlib.h"
+#include "support/syscall.h"
 #include "LyXView.h"
+#include "Painter.h"
+#include "font.h"
+#include "lyxrc.h"
+#include "math_inset.h"
+#include "math_parinset.h"
+#include "math_matrixinset.h"
+#include "math_rowst.h"
+#include "math_spaceinset.h"
+#include "math_deliminset.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;
+using std::max;
+
+extern string mathed_label;
 
-extern void UpdateInset(Inset * inset, bool mark_dirty = true);
-extern void LockedInsetStoreUndo(Undo::undo_kind);
-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 *);
-
+extern char const * latex_special_chars;
 
-extern GC canvasGC, mathGC, mathLineGC, latexGC, cursorGC, mathFrameGC;
-extern char * mathed_label;
+int greek_kb_flag = 0;
+extern char const * latex_mathenv[];
 
-extern int mono_video;
-extern int fast_selection;
+// this is only used by Whichfont and mathed_init_fonts (Lgb)
+LyXFont * Math_Fonts = 0;
 
-extern BufferView * current_view;
-extern BufferList bufferlist;
-extern char const * latex_special_chars;
 
-short greek_kb_flag = 0;
+MathedCursor * mathcursor = 0;
 
-LyXFont * Math_Fonts = 0; // this is only used by Whichfont and mathed_init_fonts (Lgb)
 
-static LyXFont::FONT_SIZE lfont_size = LyXFont::SIZE_NORMAL;
+namespace {
 
-// local global 
-static int sel_x, sel_y;
-static bool sel_flag;
-MathedCursor * InsetFormula::mathcursor = 0; 
+LyXFont::FONT_SIZE lfont_size = LyXFont::SIZE_NORMAL;
 
+// local global
+int sel_x;
+int sel_y;
+bool sel_flag;
 
-int MathedInset::df_asc;
-int MathedInset::df_des;
-int MathedInset::df_width;
+int mathed_write(MathParInset *, std::ostream &, bool fragile,
+                string const & label = string());
 
+void mathed_init_fonts();
 
-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);
 
+} // namespaces
 
-static
-void mathedValidate(LaTeXFeatures & features, MathParInset * par);
 
 
 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;   
-   }
-    
-    f.setSize(lfont_size);
-    
-    switch (size) {
-     case LM_ST_DISPLAY:     
-       if (type == LM_TC_BSYM) {
-           f.incSize();
-           f.incSize();
+       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;
        }
-       break;
-     case LM_ST_TEXT:
-       break;
-     case LM_ST_SCRIPT:
-       f.decSize();
-       break;
-     case LM_ST_SCRIPTSCRIPT:
-       f.decSize();
-       f.decSize();
-       break;
-     default:
-            lyxerr << "Mathed Error: wrong font size: " << size << endl;
-       break;
-    }
-    
-    if (type != LM_TC_TEXTRM) 
-      f.setColor(LyXFont::MATH);
-    return f;
-}
 
+       f.setSize(lfont_size);
 
-void mathed_init_fonts() //removed 'static' because DEC cxx does not
-                        //like it (JMarc)
-       // Probably because this func is declared as a friend in math_defs.h
-       // Lgb
-{
+       switch (size) {
+       case LM_ST_DISPLAY:
+               if (type == LM_TC_BSYM) {
+                       f.incSize();
+                       f.incSize();
+               }
+               break;
 
-    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;
-    }
-    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);
-    
-    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');    
-}
+       case LM_ST_TEXT:
+               break;
 
+       case LM_ST_SCRIPT:
+               f.decSize();
+               break;
 
-void mathed_set_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();
+       case LM_ST_SCRIPTSCRIPT:
+               f.decSize();
+               f.decSize();
+               break;
+
+       default:
+               lyxerr << "Mathed Error: wrong font size: " << size << endl;
+               break;
+       }
+
+       if (type != LM_TC_TEXTRM)
+               f.setColor(LColor::math);
+
+       return f;
 }
 
 
-int mathed_string_width(short type, int size, byte const * s, int ls)
+namespace {
+
+void mathed_init_fonts() //removed 'static' because DEC cxx does not
+//like it (JMarc)
+// Probably because this func is declared as a friend in math_defs.h
+// Lgb
 {
-    LyXFont f = WhichFont(type, size);
-
-    byte sx[80];
-    if (MathIsBinary(type)) {
-       byte * ps = &sx[0];
-       for (int i = 0; i < ls && i < 75; ++i) {
-           *(ps++) = ' ';
-           *(ps++) = s[i];
-           *(ps++) = ' ';
+       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);
        }
-       *(ps++) = '\0';
-       ls *= 3;
-       s = &sx[0];
-    }
-    return f.textWidth(reinterpret_cast<char const *>(s), ls);
-}
 
+       Math_Fonts[0].setShape(LyXFont::ITALIC_SHAPE);
 
-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);
-    return t;
-}
+       Math_Fonts[1].setFamily(LyXFont::SYMBOL_FAMILY);
 
+       Math_Fonts[2].setFamily(LyXFont::SYMBOL_FAMILY);
+       Math_Fonts[2].setShape(LyXFont::ITALIC_SHAPE);
 
-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 < ls; ++i) {
-      if (font.descent(s[i]) > des)
-       des = font.descent(s[i]);
-      if (font.ascent(s[i]) > asc)
-       asc = font.ascent(s[i]);
-   }
-   return asc + des;
-}
+       Math_Fonts[3].setSeries(LyXFont::BOLD_SERIES);
 
+       Math_Fonts[4].setFamily(LyXFont::SANS_FAMILY);
+       Math_Fonts[4].setShape(LyXFont::ITALIC_SHAPE);
 
-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;
-}
+       Math_Fonts[5].setFamily(LyXFont::TYPEWRITER_FAMILY);
 
+       Math_Fonts[6].setFamily(LyXFont::ROMAN_FAMILY);
 
-// 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)
-{
-    mathed_set_font(type, siz);
-    byte sx[80];
-    if (MathIsBinary(type)) {
-       byte * ps = &sx[0];
-       for (int i = 0; i < ls && i < 75; ++i) {
-           *(ps++) = ' ';
-           *(ps++) = s[i];
-           *(ps++) = ' ';
-       }
-       //    *ps = ' ';
-       ls *= 3;
-       s = &sx[0];
-    }
-    GC gc = (type == LM_TC_TEX) ? latexGC: mathGC;
-    XDrawString(fl_display, pm, gc, x, y, reinterpret_cast<char*>(s), ls);
-    XFlush(fl_display);
+       Math_Fonts[7].setFamily(LyXFont::SANS_FAMILY);
+
+       LyXFont f = WhichFont(LM_TC_VAR, LM_ST_TEXT);
+       MathedInset::defaultAscent(lyxfont::maxAscent(f));
+       MathedInset::defaultDescent(lyxfont::maxDescent(f));
+       MathedInset::defaultWidth(lyxfont::width('I', f));
 }
 
+} // namespace anon
+
+
+// quite a hack i know. Should be done with return values...
+int number_of_newlines = 0;
+
 
 InsetFormula::InsetFormula(bool display)
 {
-  par = new MathParInset; // this leaks
-  //   mathcursor = 0;
-  disp_flag = display;
-  //label = 0;
-  if (disp_flag) {
-    par->SetType(LM_OT_PAR);
-    par->SetStyle(LM_ST_DISPLAY);
-  }
+       par = new MathParInset; // this leaks
+       //  mathcursor = 0;
+       disp_flag_ = display;
+       if (disp_flag_) {
+               par->SetType(LM_OT_PAR);
+               par->SetStyle(LM_ST_DISPLAY);
+       }
 }
 
 
 InsetFormula::InsetFormula(MathParInset * p)
 {
-   par = (p->GetType()>= LM_OT_MPAR) ? 
-         new MathMatrixInset(static_cast<MathMatrixInset*>(p)): 
-         new MathParInset(p);
-//   mathcursor = 0;
-   
-   disp_flag = (par->GetType()>0);
-   //label = 0;
+       if (is_matrix_type(p->GetType()))
+               lyxerr << "InsetFormula::InsetFormula: This shouldn't happen" << endl;
+
+       par = is_multiline(p->GetType()) ?
+               new MathMatrixInset(*static_cast<MathMatrixInset*>(p)):
+               new MathParInset(*p);
+       //   mathcursor = 0;
+
+       disp_flag_ = par->GetType() > 0;
 }
 
 
 InsetFormula::~InsetFormula()
 {
-   delete par;
+#ifdef WITH_WARNINGS
+#warning leak this for a while...
+#endif
+       //delete par;
 }
 
 
-Inset * InsetFormula::Clone() const
+Inset * InsetFormula::Clone(Buffer const &) const
 {
-    InsetFormula * f = new InsetFormula(par);
-    f->label = label;
-    return f;
+       return new InsetFormula(par);
 }
 
 
-void InsetFormula::Write(ostream & os)
+void InsetFormula::Write(Buffer const * buf, ostream & os) const
 {
        os << "Formula ";
-       Latex(os, 0);
+       Latex(buf, os, false, false);
 }
 
 
-int InsetFormula::Latex(ostream & os, 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);
-    os << output;
-    return ret;
+       return mathed_write(par, os, fragile, par->label()); 
 }
 
 
-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 
+// Check if uses AMS macros
 void InsetFormula::Validate(LaTeXFeatures & features) const
 {
-    // Validation only necesary if not using an AMS Style
-    if (!features.amsstyle)
-      mathedValidate(features, par);
+       if (is_ams(par->GetType()))
+               features.amsstyle = true;
+
+       // Validation is necessary only if not using AMS math.
+       // To be safe, we will always run mathedValidate.
+       //if (!features.amsstyle)
+       mathedValidate(features, par);
 }
 
 
-void InsetFormula::Read(LyXLex & lex)
+void InsetFormula::Read(Buffer const *buffer, LyXLex & lex)
 {
        istream & is = lex.getStream();
-    
-       mathed_parser_file(is, lex.GetLineNo());   
-   
-       // Silly hack to read labels. 
-       mathed_label = 0;
-       mathed_parse(0, 0, &par);
+
+       mathed_parser_file(is, lex.GetLineNo());
+
+       MathedArray ar;
+       mathed_parse(ar, par, 0);
+       if (par->isMatrix()) {
+               //lyxerr << "################## InsetFormula::Read: IsMatrix\n";
+               static_cast<MathMatrixInset*>(par)->setData(ar);
+       }
+       else {
+               par->setData(ar);
+               //lyxerr << "################## InsetFormula::Read: keine Matrix\n";
+       }
+
+       //lyxerr << "InsetFormula::Read: par: " << par << " " << par->GetData() << endl;
+
        par->Metrics();
-       disp_flag = (par->GetType() > 0);
-       
+       disp_flag_ = (par->GetType() > 0);
+
        // Update line number
        lex.setLineNo(mathed_parser_lineno());
-       
-       if (mathed_label) {
-               label = mathed_label;
-               mathed_label = 0;
+
+       // 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(lyxerr);
-#endif
+
+       if (lyxerr.debugging(Debug::MATHED))
+               Write(buffer, lyxerr);
 }
 
 
-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 * bv, LyXFont const & f) const
 {
-    lfont_size = f.size();
-    par->Metrics();
-    return par->Width(); //+2;
+       MathedInset::workWidth = bv->workWidth();
+       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();
-       
-   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),
-                       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 = static_cast<MathMatrixInset*>(par);
-          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;
+       MathedInset::workWidth = bv->workWidth();
+       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);
+
+       // 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 (is_numbered(par->GetType())) {
+               LyXFont wfont = WhichFont(LM_TC_BF, par->size());
+               wfont.setLatex(LyXFont::OFF);
+
+               if (is_singlely_numbered(par->GetType())) {
+                       string str;
+                       if (!par->label().empty())
+                               str = string("(") + par->label() + ")";
+                       else
+                               str = string("(#)");
+                       pain.text(int(x + 20), baseline, str, wfont);
+               } else {
+                       MathedRowContainer::iterator crow = par->getRowSt().begin();
+                       while (crow) {
+                               int const 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;
+                       }
+               }
+       }
+       setCursorVisible(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);
-    sel_x = sel_y = 0;
-    sel_flag = false;
+       return _("Math editor mode");
 }
 
 
-void InsetFormula::InsetUnlock()
+void InsetFormula::Edit(BufferView * bv, int x, int y, unsigned int)
 {
-   if (mathcursor) {
-       if (mathcursor->InMacroMode()) {
-          mathcursor->MacroModeClose();
-          UpdateLocal();
-       }                                         
-     delete mathcursor;
-   }
-   mathcursor = 0;
-   UpdateInset(this, false);
-}
+       mathcursor = new MathedCursor(par);
 
+       if (!bv->lockInset(this))
+               lyxerr[Debug::MATHED] << "Cannot lock inset!!!" << endl;
 
-// Now a symbol can be inserted only if the inset is locked
-void InsetFormula::InsertSymbol(char const * s)
-{ 
-   if (!s || !mathcursor) return;   
-   mathcursor->Interpret(s);
-   UpdateLocal();
+       par->Metrics();
+       bv->updateInset(this, false);
+       x += par->xo();
+       y += par->yo();
+       mathcursor->SetPos(x, y);
+       sel_x = 0;
+       sel_y = 0;
+       sel_flag = false;
 }
 
-   
-void InsetFormula::GetCursorPos(int& x, int& y) const
+
+void InsetFormula::InsetUnlock(BufferView * bv)
 {
-    mathcursor->GetPos(x, y);
-    x -= par->xo; 
-    y -= par->yo;
+       if (mathcursor) {
+               if (mathcursor->InMacroMode()) {
+                       mathcursor->MacroModeClose();
+                       UpdateLocal(bv);
+               }
+               delete mathcursor;
+       }
+       mathcursor = 0;
+       bv->updateInset(this, false);
 }
 
-void InsetFormula::ToggleInsetCursor()
+
+// Now a symbol can be inserted only if the inset is locked
+void InsetFormula::InsertSymbol(BufferView *, string const & s)
 {
-  if (!mathcursor)
-    return;
-
-  int x, y, asc, desc;
-  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();
-  
-  if (cursor_visible)
-    HideLockedInsetCursor(x, y, asc, desc);
-  else
-    ShowLockedInsetCursor(x, y, asc, desc);
-  cursor_visible = !cursor_visible;
+       if (s.empty() || !mathcursor)
+               return;
+       mathcursor->Interpret(s);
+       // Andre: UpdateLocal(bv);
 }
 
 
-void InsetFormula::ShowInsetCursor()
+void InsetFormula::GetCursorPos(BufferView *, int & x, int & y) const
 {
-  if (!cursor_visible) {
-    int x, y, asc, desc;
-    if (mathcursor) {
-      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);
-    }
-    ToggleInsetCursor();
-  }
+       mathcursor->GetPos(x, y);
+       x -= par->xo();
+       y -= par->yo();
 }
 
 
-void InsetFormula::HideInsetCursor()
+void InsetFormula::ToggleInsetCursor(BufferView * bv)
 {
-  if (cursor_visible)
-    ToggleInsetCursor();
+       if (!mathcursor)
+               return;
+
+       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);
+
+       if (isCursorVisible())
+               bv->hideLockedInsetCursor();
+       else
+               bv->showLockedInsetCursor(x, y, asc, desc);
+
+       toggleCursorVisible();
 }
 
 
-void InsetFormula::ToggleInsetSelection()
+void InsetFormula::ShowInsetCursor(BufferView * bv, bool)
 {
-    if (!mathcursor)
-      return;
-    
-//    int x, y, w, h;
-    //int n;
-    //XPoint * p = 
-    //mathcursor->SelGetArea(n);
-//    XFillPolygon(fl_display, pm, LyXGetSelectionGC(), p, n, Nonconvex, CoordModeOrigin);
-//    x -= par->xo; 
-//    y -= par->yo;
-
-    UpdateInset(this, false);
-      
+       if (!isCursorVisible()) {
+               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);
+               }
+               ToggleInsetCursor(bv);
+       }
 }
 
 
-void InsetFormula::display(bool dspf)
+void InsetFormula::HideInsetCursor(BufferView * bv)
 {
-   if (dspf != disp_flag) {
-      if (dspf) {
-        par->SetType(LM_OT_PAR);
-        par->SetStyle(LM_ST_DISPLAY);
-      } else {
-        if (par->GetType() >= LM_OT_MPAR) { 
-           MathParInset * p = new MathParInset(par);
-           delete par;
-           par = p;
-           if (mathcursor) 
-              mathcursor->SetPar(par); 
-        }
-        par->SetType(LM_OT_MIN);
-        par->SetStyle(LM_ST_TEXT);
-        if (!label.empty() && par->GetType() != LM_OT_MPARN) {
-                label.clear();
-        }
-      }
-      disp_flag = dspf;
-   }
+       if (isCursorVisible())
+               ToggleInsetCursor(bv);
 }
 
 
-int InsetFormula::GetNumberOfLabels() const
+void InsetFormula::ToggleInsetSelection(BufferView * bv)
 {
-   // This is dirty, I know. I'll clean it at 0.13
-   if (par->GetType() == LM_OT_MPARN) {
-       MathMatrixInset * mt = static_cast<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;
+       if (!mathcursor)
+               return;
+
+       bv->updateInset(this, false);
 }
 
 
-string InsetFormula::getLabel(int il) const
+void InsetFormula::display(bool dspf)
 {
-//#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 = static_cast<MathMatrixInset*>(par);
-               int nl = 0;
-               MathedRowSt const * crow = mt->getRowSt();
-               while (crow) {
-                       if (crow->getLabel()) {
-                               if (nl == il) {
-                                       lab = crow->getLabel();
-                                       break;
-                               }
-                               ++nl;
+       if (dspf != disp_flag_) {
+               if (dspf) {
+                       par->SetType(LM_OT_PAR);
+                       par->SetStyle(LM_ST_DISPLAY);
+               } else {
+                       if (is_multiline(par->GetType())) {
+                               if (mathcursor)
+                                       mathcursor->SetPar(par);
+                       }
+                       par->SetType(LM_OT_MIN);
+                       par->SetStyle(LM_ST_TEXT);
+#ifdef WITH_WARNINGS
+#warning Labels
+#endif
+/*
+                       if (!label_.empty()) {
+                               label_.erase();
                        }
-                       crow = crow->getNext();
+*/
                }
-               return lab;
+               disp_flag_ = dspf;
        }
-       return label;
 }
 
 
-void InsetFormula::UpdateLocal()
+vector<string> const InsetFormula::getLabelList() const
 {
-   par->Metrics();  // To inform lyx kernel the exact size 
-                  // (there were problems with arrays).
-   UpdateInset(this);
+       vector<string> label_list;
+       MathedRowContainer::iterator crow = par->getRowSt().begin();
+       for ( ; crow; ++crow)
+               label_list.push_back(crow->getLabel());
+
+       return label_list;
+}
+
+
+void InsetFormula::UpdateLocal(BufferView * bv)
+{
+       par->Metrics();  // To inform lyx kernel the exact size
+       // (there were problems with arrays).
+       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()) {
-       mathcursor->SelClear();
-       UpdateInset(this, false); 
-    }
+       sel_flag = false;
+       sel_x = x;
+       sel_y = y;
+       if (mathcursor && mathcursor->Selection()) {
+               mathcursor->SelClear();
+               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) {
-       sel_flag = true;
-       HideInsetCursor();
-       mathcursor->SetPos(sel_x + par->xo, sel_y + par->yo);
-       mathcursor->SelStart();
-       ShowInsetCursor(); 
-       mathcursor->GetPos(sel_x, sel_y);
-    } else
-      if (sel_flag) {
-         HideInsetCursor();
-         x += par->xo;
-         y += par->yo;
-         mathcursor->SetPos(x, y);
-         ShowInsetCursor();
-         mathcursor->GetPos(x, y);
-         if (sel_x!= x || sel_y!= y)
-           UpdateInset(this, false); 
-         sel_x = x;  sel_y = y;
-      }
+       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();
+               ShowInsetCursor(bv);
+               mathcursor->GetPos(sel_x, sel_y);
+       } else if (sel_flag) {
+               HideInsetCursor(bv);
+               x += par->xo();
+               y += par->yo();
+               mathcursor->SetPos(x, y);
+               ShowInsetCursor(bv);
+               mathcursor->GetPos(x, y);
+               if (sel_x != x || sel_y != y)
+                       bv->updateInset(this, false);
+               sel_x = x;
+               sel_y = y;
+       }
 }
 
 
@@ -725,558 +648,789 @@ void InsetFormula::InsetKeyPress(XKeyEvent *)
 // 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;
-      par->SetType(type);
-      return oldf;
-   } else
-     return false;
+       if (disp_flag_) {
+               short type = par->GetType();
+               bool const oldf = is_numbered(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, kb_action 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;
-
-   HideInsetCursor();
-   if (mathcursor->Selection() && (fast_selection || mono_video))
-          ToggleInsetSelection();
-
-    if (mathcursor->getLastCode() == LM_TC_TEX) { 
-       varcode = LM_TC_TEX;
-    }
-   switch (action) {
-       
-    // --- Cursor Movements ---------------------------------------------
-    case LFUN_RIGHTSEL: sel = true;
-    case LFUN_RIGHT:
-      {
-        result = mathcursor->Right(sel);
-        break;
-      }
-    case LFUN_LEFTSEL: sel = true;     
-    case LFUN_LEFT:
-      {
-        result = mathcursor->Left(sel);
-        break;
-      }
-    case LFUN_UPSEL: sel = true;  
-    case LFUN_UP:
-      result = mathcursor->Up(sel);
-      break;
-       
-    case LFUN_DOWNSEL: sel = true;  
-    case LFUN_DOWN:
-      result = mathcursor->Down(sel);
-      break;
-    case LFUN_HOME:
-      mathcursor->Home();
-      break;
-    case LFUN_END:
-      mathcursor->End();
-      break;
-    case LFUN_DELETE_LINE_FORWARD:
-           //LockedInsetStoreUndo(Undo::INSERT);
-           LockedInsetStoreUndo(Undo::DELETE);
-      mathcursor->DelLine();
-      UpdateLocal();
-      break;
-    case LFUN_BREAKLINE:
-      LockedInsetStoreUndo(Undo::INSERT);
-      mathcursor->Insert(' ', LM_TC_CR);
-      par = mathcursor->GetPar();
-      UpdateLocal();     
-      break;
-    case LFUN_TAB:
-      LockedInsetStoreUndo(Undo::INSERT);
-      mathcursor->Insert(0, LM_TC_TAB);
-      //UpdateInset(this);
-      break;     
-    case LFUN_TABINSERT:
-      LockedInsetStoreUndo(Undo::INSERT);
-      mathcursor->Insert('T', LM_TC_TAB);
-      UpdateLocal();
-      break;     
-    case LFUN_BACKSPACE:
-       if (!mathcursor->Left()) 
-        break;
-       
-       if (!mathcursor->InMacroMode() && mathcursor->pullArg()) {       
-          UpdateInset(this);
-          break;
-       }
-      
-    case LFUN_DELETE:
-           //LockedInsetStoreUndo(Undo::INSERT);
-           LockedInsetStoreUndo(Undo::DELETE);
-      mathcursor->Delete();       
-      UpdateInset(this);
-      break;    
-//    case LFUN_GETXY:
-//      sprintf(dispatch_buffer, "%d %d",);
-//      dispatch_result = dispatch_buffer;
-//      break;
-    case LFUN_SETXY:
-      {
-        int x, y, x1, y1;
-         sscanf(arg, "%d %d", &x, &y);
-        par->GetXY(x1, y1);
-        mathcursor->SetPos(x1+x, y1+y);
-      }
-      break;
-
-      /* cursor selection ---------------------------- */
-
-    case LFUN_PASTE:
-            if (was_macro)
-               mathcursor->MacroModeClose();
-           LockedInsetStoreUndo(Undo::INSERT);
-           mathcursor->SelPaste(); UpdateLocal(); break;
-    case LFUN_CUT:
-           LockedInsetStoreUndo(Undo::DELETE);
-           mathcursor->SelCut(); UpdateLocal(); break;
-    case LFUN_COPY: mathcursor->SelCopy(); break;      
-    case LFUN_HOMESEL:
-    case LFUN_ENDSEL:
-    case LFUN_WORDRIGHTSEL:
-    case LFUN_WORDLEFTSEL:
-      break;
-      
-    // --- accented characters ------------------------------
-
-    case LFUN_UMLAUT: mathcursor->setAccent(LM_ddot); break;
-    case LFUN_CIRCUMFLEX: mathcursor->setAccent(LM_hat); break;
-    case LFUN_GRAVE: mathcursor->setAccent(LM_grave); break;
-    case LFUN_ACUTE: mathcursor->setAccent(LM_acute); break;
-    case LFUN_TILDE: mathcursor->setAccent(LM_tilde); break;
-    case LFUN_MACRON: mathcursor->setAccent(LM_bar); break;
-    case LFUN_DOT: mathcursor->setAccent(LM_dot); break;
-    case LFUN_CARON: mathcursor->setAccent(LM_check); break;
-    case LFUN_BREVE: mathcursor->setAccent(LM_breve); break;
-    case LFUN_VECTOR: mathcursor->setAccent(LM_vec); break; 
-      
-    // Greek mode     
-    case LFUN_GREEK:
-    {
-       if (!greek_kb_flag) {
-         greek_kb_flag = 1;
-         current_view->owner()->getMiniBuffer()->Set(_("Math greek mode on"));
-       } else
-        greek_kb_flag = 0;
-       break;
-    }  
-      
-    // Greek keyboard      
-    case LFUN_GREEK_TOGGLE:
-    {
-       greek_kb_flag = (greek_kb_flag) ? 0 : 2;
-       if (greek_kb_flag)
-        current_view->owner()->getMiniBuffer()->Set(_("Math greek keyboard on"));
-       else
-        current_view->owner()->getMiniBuffer()->Set(_("Math greek keyboard off"));
-       break;
-    }  
-   
-      //  Math fonts 
-    case LFUN_BOLD:    mathcursor->setLastCode(LM_TC_BF); break;
-    case LFUN_SANS:  mathcursor->setLastCode( LM_TC_SF); break;
-    case LFUN_EMPH:  mathcursor->setLastCode(LM_TC_CAL); break;
-    case LFUN_ROMAN: mathcursor->setLastCode(LM_TC_RM); break;
-    case LFUN_CODE: mathcursor->setLastCode(LM_TC_TT); break;   
-    case LFUN_DEFAULT:  mathcursor->setLastCode(LM_TC_VAR ) ; break;
-    case LFUN_TEX: 
-    {
-//       varcode = LM_TC_TEX;
-       mathcursor->setLastCode(LM_TC_TEX);
-       current_view->owner()->getMiniBuffer()->Set(_("TeX mode")); 
-       break;
-    }
-
-    case LFUN_MATH_NUMBER:
-    {
-      LockedInsetStoreUndo(Undo::INSERT);
-       if (disp_flag) {
-         short type = par->GetType();
-         bool oldf = (type == LM_OT_PARN || type == LM_OT_MPARN);
-         if (oldf) {
-            type--;
-            if (!label.empty()) {
-                    label.clear();
-            }
-            current_view->owner()->getMiniBuffer()->Set(_("No number"));  
-         } else {
-            type++;
-             current_view->owner()->getMiniBuffer()->Set(_("Number"));
-         }
-         par->SetType(type);
-         UpdateLocal();
-       }
-       break;
-    }
-    
-    case LFUN_MATH_NONUMBER:
-    { 
-       if (par->GetType() == LM_OT_MPARN) {
-//        MathMatrixInset *mt = (MathMatrixInset*)par;
-          //BUG 
-//        mt->SetNumbered(!mt->IsNumbered());
-           
-           mathcursor->setNumbered();
-          UpdateLocal();
+       //lyxerr << "InsetFormula::LocalDispatch: act: " << action
+       //      << " arg: '" << arg << "' cursor: " << mathcursor << "\n";
+       //   extern char *dispatch_result;
+
+       if (!mathcursor) {
+               return UNDISPATCHED;
+       }
+
+       MathedTextCodes varcode = LM_TC_MIN;
+       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(bv);
+
+       if (mathcursor->getLastCode() == LM_TC_TEX) {
+               varcode = LM_TC_TEX;
+       }
+
+       switch (action) {
+               // --- Cursor Movements ---------------------------------------------
+       case LFUN_RIGHTSEL:
+               sel = true; // fall through...
+
+       case LFUN_RIGHT:
+               result = DISPATCH_RESULT(mathcursor->Right(sel));
+               if (!sel && (result == DISPATCHED))
+                       result = DISPATCHED_NOUPDATE;
+               UpdateLocal(bv);
+               break;
+
+
+       case LFUN_LEFTSEL:
+               sel = true; // fall through
+
+       case LFUN_LEFT:
+               result = DISPATCH_RESULT(mathcursor->Left(sel));
+               if (!sel && (result == DISPATCHED))
+                       result = DISPATCHED_NOUPDATE;
+               UpdateLocal(bv);
+               break;
+
+
+       case LFUN_UPSEL:
+               sel = true;
+
+       case LFUN_UP:
+               result = DISPATCH_RESULT(mathcursor->Up(sel));
+               if (!sel && (result == DISPATCHED))
+                       result = DISPATCHED_NOUPDATE;
+               UpdateLocal(bv);
+               break;
+
+
+       case LFUN_DOWNSEL:
+               sel = true;
+
+       case LFUN_DOWN:
+               result = DISPATCH_RESULT(mathcursor->Down(sel));
+               if (!sel && (result == DISPATCHED))
+                       result = DISPATCHED_NOUPDATE;
+               UpdateLocal(bv);
+               break;
+
+
+       case LFUN_HOME:
+               mathcursor->Home();
+               result = DISPATCHED_NOUPDATE;
+               break;
+
+       case LFUN_END:
+               mathcursor->End();
+               result = DISPATCHED_NOUPDATE;
+               break;
+
+       case LFUN_DELETE_LINE_FORWARD:
+               bv->lockedInsetStoreUndo(Undo::DELETE);
+               mathcursor->DelLine();
+               // Andre:
+               UpdateLocal(bv);
+               break;
+
+       case LFUN_BREAKLINE: 
+       {
+               bv->lockedInsetStoreUndo(Undo::INSERT);
+               byte c = arg.empty() ? '1' : arg[0];
+               mathcursor->Insert(c, LM_TC_CR);
+#ifdef WITH_WARNINGS
+#warning Labels
+#endif
+/*
+               if (!par->label().empty()) {
+                       mathcursor->setLabel(label_);
+                       label_.erase();
+               }
+*/
+               par = mathcursor->GetPar();
+               // Andre:
+               UpdateLocal(bv);
        }
        break;
-    }
-       
-    case LFUN_MATH_LIMITS:
-    {
-      LockedInsetStoreUndo(Undo::INSERT);
-       if (mathcursor->Limits())
-        UpdateLocal();
-    }
-    case LFUN_MATH_SIZE:
-       if (arg) {
-          latexkeys * l = in_word_set (arg, strlen(arg));
-          int sz = (l) ? l->id: -1;
-          mathcursor->SetSize(sz);
-          UpdateLocal();
-          break;
-       }
-       
-    case LFUN_INSERT_MATH:
-    {
-       LockedInsetStoreUndo(Undo::INSERT);
-       InsertSymbol(arg);
+
+       case LFUN_TAB:
+               bv->lockedInsetStoreUndo(Undo::INSERT);
+               mathcursor->Insert(0, LM_TC_TAB);
+               //UpdateInset(this);
+               break;
+
+       case LFUN_TABINSERT:
+               bv->lockedInsetStoreUndo(Undo::INSERT);
+               mathcursor->Insert('T', LM_TC_TAB);
+               // Andre:
+               UpdateLocal(bv);
+               break;
+
+       case LFUN_BACKSPACE:
+               if (!mathcursor->Left())
+                       break;
+
+               if (!mathcursor->InMacroMode() && mathcursor->pullArg()) {
+                       bv->updateInset(this, true);
+                       break;
+               }
+               // fall through...
+
+       case LFUN_DELETE:
+               bv->lockedInsetStoreUndo(Undo::DELETE);
+               mathcursor->Delete();
+               bv->updateInset(this, true);
+               break;
+
+               //    case LFUN_GETXY:
+               //      sprintf(dispatch_buffer, "%d %d",);
+               //      dispatch_result = dispatch_buffer;
+               //      break;
+       case LFUN_SETXY:
+       {
+               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);
+       }
        break;
-    }
-    
-    case LFUN_INSERT_MATRIX:
-    { 
-      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]= '\0';
-       k = sscanf(arg2, "%d %d %s", &m, &n, s);
-       s[79] = '\0';
-       
-       if (k < 1) {
-          m = n = 1;
-       } else if (k == 1) {
-          n = 1;
-       }
-       
-       MathMatrixInset * p = new MathMatrixInset(m, n);      
-       if (mathcursor && p) {
-         if (k > 2 && int(strlen(s)) > m)
-           p->SetAlign(s[0], &s[1]);
-         mathcursor->Insert(p, LM_TC_ACTIVE_INSET);
-         UpdateLocal();
-       }
-       break;
-    }
-      
-    case LFUN_MATH_DELIM:
-    {  
-      LockedInsetStoreUndo(Undo::INSERT);
-       char lf[40], rg[40], arg2[40];
-       int ilf = '(', irg = '.';
-       latexkeys * l;
-       string vdelim("(){}[]./|");
-       
-       if (!arg) break;
-       strncpy(arg2, arg, 40); arg2[39]= '\0';
-       int n = sscanf(arg2, "%s %s", lf, rg);
-       lf[39] = '\0'; rg[39] = '\0';
-
-       if (n > 0) {
-          if (isdigit(lf[0])) 
-            ilf = atoi(lf);
-          else 
-            if (lf[1]) {
-                l = in_word_set(lf, strlen(lf));
-                // Long words will cause l == 0; so check.
-                if(l) ilf = l->id;
-            } else
-            if (vdelim.find(lf[0]) != string::npos)
-              ilf = lf[0];
-          
-          if (n > 1) {
-              if (isdigit(rg[0]))
-                irg = atoi(rg);
-              else 
-                if (rg[1]) {
-                    l = in_word_set(rg, strlen(rg));
-                    if(l) irg = l->id;
-                } else
-                if (vdelim.find(rg[0]) != string::npos)
-                  irg = rg[0];
-          }
-       }
-       
-       MathDelimInset * p = new MathDelimInset(ilf, irg);
-       mathcursor->Insert(p, LM_TC_ACTIVE_INSET);
-       UpdateLocal();                             
-       break;
-    }
-
-    case LFUN_PROTECTEDSPACE:
-    {
-      LockedInsetStoreUndo(Undo::INSERT);
-       sp = new MathSpaceInset(1); 
-       mathcursor->Insert(sp);
-       space_on = true;
-       UpdateLocal();
-       break;
-    }
-      
-    case LFUN_INSERT_LABEL:
-    {
-       LockedInsetStoreUndo(Undo::INSERT);
-       if (par->GetType() < LM_OT_PAR) break;
-       string lb = arg;
-       if (lb.empty()) {
-         pair<bool, string>
-               result = askForText(_("Enter new label to insert:"));
-         if (result.first) {
-            lb = result.second;
-         }
-       }
-       if (!lb.empty() && lb[0] > ' ') {
-         SetNumber(true);
-         if (par->GetType() == LM_OT_MPARN) {
-             mathcursor->setLabel(lb.c_str());
-//           MathMatrixInset *mt = (MathMatrixInset*)par;
-//           mt->SetLabel(lb);
-         } else {
-                 //if (label.notEmpty()) delete label;
-             label = lb;
-         }
-         UpdateLocal();
-       } else
-              label.clear();
-       break;
-    }
-    
-    case LFUN_MATH_DISPLAY:
-           //LockedInsetStoreUndo(Undo::INSERT);
-           LockedInsetStoreUndo(Undo::EDIT);
-      display(!disp_flag);
-      UpdateLocal();
-      break;
-      
-    // Invalid actions under math mode
-    case LFUN_MATH_MODE:  
-    {
-       if (mathcursor->getLastCode()!= LM_TC_TEXTRM) {
-           current_view->owner()->getMiniBuffer()->Set(_("math text mode"));
-           varcode = LM_TC_TEXTRM;
-       } else {
-           varcode = LM_TC_VAR;
+
+               /* cursor selection ---------------------------- */
+
+       case LFUN_PASTE:
+               if (was_macro)
+                       mathcursor->MacroModeClose();
+               bv->lockedInsetStoreUndo(Undo::INSERT);
+               mathcursor->SelPaste();
+               // Andre:
+               UpdateLocal(bv);
+               break;
+
+       case LFUN_CUT:
+               bv->lockedInsetStoreUndo(Undo::DELETE);
+               mathcursor->SelCut();
+               // Andre:
+               UpdateLocal(bv);
+               break;
+
+       case LFUN_COPY:
+               mathcursor->SelCopy();
+               break;
+
+       case LFUN_HOMESEL:
+       case LFUN_ENDSEL:
+       case LFUN_WORDRIGHTSEL:
+       case LFUN_WORDLEFTSEL:
+               break;
+
+               // --- accented characters ------------------------------
+
+       case LFUN_UMLAUT:     mathcursor->setAccent(LM_ddot); break;
+       case LFUN_CIRCUMFLEX: mathcursor->setAccent(LM_hat); break;
+       case LFUN_GRAVE:      mathcursor->setAccent(LM_grave); break;
+       case LFUN_ACUTE:      mathcursor->setAccent(LM_acute); break;
+       case LFUN_TILDE:      mathcursor->setAccent(LM_tilde); break;
+       case LFUN_MACRON:     mathcursor->setAccent(LM_bar); break;
+       case LFUN_DOT:        mathcursor->setAccent(LM_dot); break;
+       case LFUN_CARON:      mathcursor->setAccent(LM_check); break;
+       case LFUN_BREVE:      mathcursor->setAccent(LM_breve); break;
+       case LFUN_VECTOR:     mathcursor->setAccent(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;
+               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:  mathcursor->toggleLastCode(LM_TC_BF); break;
+       case LFUN_SANS:  mathcursor->toggleLastCode(LM_TC_SF); break;
+       case LFUN_EMPH:  mathcursor->toggleLastCode(LM_TC_CAL); break;
+       case LFUN_ROMAN: mathcursor->toggleLastCode(LM_TC_RM); break;
+       case LFUN_CODE:  mathcursor->toggleLastCode(LM_TC_TT); break;
+       case LFUN_DEFAULT:  mathcursor->setLastCode(LM_TC_VAR); break;
+
+       case LFUN_TEX:
+               // varcode = LM_TC_TEX;
+               mathcursor->setLastCode(LM_TC_TEX);
+               bv->owner()->message(_("TeX mode"));
+               break;
+
+       case LFUN_MATH_NUMBER:
+               bv->lockedInsetStoreUndo(Undo::INSERT);
+               if (disp_flag_) {
+                       short type = par->GetType();
+                       if (is_numbered(type)) {
+                               --type;
+#ifdef WITH_WARNINGS
+#warning Labels
+#endif
+/*
+                               if (!label_.empty()) {
+                                       label_.erase();
+                               }
+*/
+                               bv->owner()->message(_("No number"));
+                       } else {
+                               ++type;
+                               bv->owner()->message(_("Number"));
+                       }
+                       par->SetType(type);
+                       // Andre:
+                       UpdateLocal(bv);
+               }
+               break;
+
+       case LFUN_MATH_NONUMBER:
+               if (is_multi_numbered(par->GetType())) {
+                               //BUG
+                               //         par->SetNumbered(!par->IsNumbered());
+
+#ifdef WITH_WARNINGS
+#warning This is a terrible hack! We should find a better solution.
+#endif
+                       while (mathcursor->getLabel() == MathedXIter::error_label) {
+                               if (LocalDispatch(bv, LFUN_LEFT, string()) == FINISHED)
+                                       return DISPATCHED;
+                       }
+                       mathcursor->setNumbered();
+                       // Andre:
+                       UpdateLocal(bv);
+               }
+               break;
+
+       case LFUN_MATH_LIMITS:
+               bv->lockedInsetStoreUndo(Undo::INSERT);
+               if (mathcursor->Limits())
+                       // Andre:
+                       UpdateLocal(bv);
+               // fall through!
+
+       case LFUN_MATH_SIZE:
+               if (!arg.empty()) {
+                       latexkeys const * l = in_word_set(arg);
+                       int const sz = l ? l->id : -1;
+                       mathcursor->SetSize(sz);
+                       // Andre:
+                       UpdateLocal(bv);
+                       break;
+               }
+               // possible fall through?
+
+       case LFUN_INSERT_MATH:
+               bv->lockedInsetStoreUndo(Undo::INSERT);
+               InsertSymbol(bv, arg);
+               UpdateLocal(bv);
+               break;
+
+
+       case LFUN_INSERT_MATRIX:
+       {
+               bv->lockedInsetStoreUndo(Undo::INSERT);
+               char s[80];
+               char arg2[80];
+               // This is just so that too long args won't ooze out of s.
+               strncpy(arg2, arg.c_str(), 80);
+               arg2[79]= '\0';
+               int m;
+               int n;
+               int const k = sscanf(arg2, "%d %d %s", &m, &n, s);
+               s[79] = '\0';
+
+               if (k < 1) {
+                       m = n = 1;
+               } else if (k == 1) {
+                       n = 1;
+               }
+
+               if (mathcursor) {
+                       MathMatrixInset * p = new MathMatrixInset(m, n);
+                       if (k > 2 && int(strlen(s)) > m)
+                               p->SetAlign(s[0], &s[1]);
+                       mathcursor->insertInset(p, LM_TC_ACTIVE_INSET);
+                       // Andre:
+                       UpdateLocal(bv);
+               }
+               break;
        }
-       mathcursor->setLastCode(varcode);
-       break; 
-    }
-    case LFUN_UNDO:
-      current_view->owner()->getMiniBuffer()->Set(_("Invalid action in math mode!"));
-      break;
-
-    //------- dummy actions
-    case LFUN_EXEC_COMMAND:
-       current_view->owner()->getMiniBuffer()->ExecCommand(); 
-       break;
-       
-    default:
-      if ((action == -1  || action == LFUN_SELFINSERT) && arg)  {
-        unsigned char c = arg[0];
-        LockedInsetStoreUndo(Undo::INSERT);
-        
-        if (c == ' ' && mathcursor->getAccent() == LM_hat) {
-            c = '^';
-            mathcursor->setAccent(0);
-        }
-        if (c == 0) {      // Dead key, do nothing 
-            //lyxerr << "deadkey" << endl;
-            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() :
-                         static_cast<MathedTextCodes>(mathcursor->GetFCode());
-               varcode = MathIsAlphaFont(f) ?
-                       static_cast<MathedTextCodes>(f) :
-                       LM_TC_VAR;
-           }
-
-//          lyxerr << "Varcode << vardoce;
-           mathcursor->Insert(c, (greek_kb_flag) ? LM_TC_SYMB: varcode);
-           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)) 
-             mathcursor->Insert(c, LM_TC_CONST);
-        else
-          if (strchr("+/-*<>=", c))
-             mathcursor->Insert(c, LM_TC_BOP);
-        else
-          if (strchr(latex_special_chars, c) && c!= '_')
-             mathcursor->Insert(c, LM_TC_SPECIAL);
-        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() :
-                             static_cast<MathedTextCodes>(mathcursor->GetFCode());
-                  varcode = MathIsAlphaFont(f) ?
-                          static_cast<MathedTextCodes>(f) :
-                          LM_TC_VAR;
-              }
-             if (varcode == LM_TC_TEXTRM) {
-                 mathcursor->Insert(c, LM_TC_TEXTRM);
-             } else
-             if (was_macro)
-               mathcursor->MacroModeClose();
-             else 
-             if (sp) {
-                int isp = (sp->GetSpace()<5) ? sp->GetSpace()+1: 0;
-                sp->SetSpace(isp);
-                space_on = true;
-             } else {
-                 if (!mathcursor->Pop() && mathcursor->IsEnd()) 
-                   result = false;
-             }
-          } else
-          if (c == '\'') {
-             mathcursor->Insert (c, LM_TC_VAR);
-          } else
-          if (c == '\\') {
-             if (was_macro)
-               mathcursor->MacroModeClose();
-             current_view->owner()->getMiniBuffer()->Set(_("TeX mode")); 
-              mathcursor->setLastCode(LM_TC_TEX);
-          } 
-        UpdateLocal();
-      } else {
-       // lyxerr << "Closed by action " << action << endl;
-       result =  false;
-      }
-   }
-   if (was_macro != mathcursor->InMacroMode()
-       && action >= 0
-       && action != LFUN_BACKSPACE)
-          UpdateLocal();
-   if (sp && !space_on) sp = 0;
-   if (mathcursor->Selection() || (was_selection && !(fast_selection || mono_video)))
-       ToggleInsetSelection();
-    
-   if (result)
-      ShowInsetCursor();
-   else
-      UnlockInset(this);
-    
-   return result;
-}
 
+       case LFUN_MATH_DELIM:
+       {
+               bv->lockedInsetStoreUndo(Undo::INSERT);
+               char lf[40];
+               char rg[40];
+               char arg2[40];
+               int ilf = '(';
+               int irg = '.';
+               latexkeys const * l;
+               string vdelim("(){}[]./|");
+
+               if (arg.empty())
+                       break;
+               ::strncpy(arg2, arg.c_str(), 40);
+               arg2[39]= '\0';
+               int const n = sscanf(arg2, "%s %s", lf, rg);
+               lf[39] = '\0';
+               rg[39] = '\0';
+
+               if (n > 0) {
+                       if (isdigit(lf[0]))
+                               ilf = lyx::atoi(lf);
+                       else
+                               if (lf[1]) {
+                                       l = in_word_set(lf);
+                                       // Long words will cause l == 0; so check.
+                                       if (l)
+                                               ilf = l->id;
+                               } else if (vdelim.find(lf[0]) != string::npos)
+                                       ilf = lf[0];
+
+                       if (n > 1) {
+                               if (isdigit(rg[0]))
+                                       irg = lyx::atoi(rg);
+                               else
+                                       if (rg[1]) {
+                                               l = in_word_set(rg);
+                                               if (l)
+                                                       irg = l->id;
+                                       } else if (vdelim.find(rg[0]) != string::npos)
+                                               irg = rg[0];
+                       }
+               }
+
+               MathDelimInset * p = new MathDelimInset(ilf, irg);
+               mathcursor->insertInset(p, LM_TC_ACTIVE_INSET);
+               // Andre:
+               UpdateLocal(bv);
+               break;
+       }
+
+       case LFUN_PROTECTEDSPACE:
+               bv->lockedInsetStoreUndo(Undo::INSERT);
+               sp = new MathSpaceInset(1);
+               mathcursor->insertInset(sp, LM_TC_INSET);
+               space_on = true;
+               // Andre:
+               UpdateLocal(bv);
+               break;
+
+       case LFUN_INSERT_LABEL:
+       {
+               bv->lockedInsetStoreUndo(Undo::INSERT);
+               if (par->GetType() < LM_OT_PAR)
+                       break;
+
+               string old_label = is_multiline(par->GetType())
+                       ? mathcursor->getLabel() : par->label();
+
+#ifdef WITH_WARNINGS
+#warning This is a terrible hack! We should find a better solution.
+#endif
+               // This is needed because in some positions
+               // mathcursor->cursor->crow is equal to 0, and therefore
+               // the label cannot be inserted.
+               // So we move the cursor left until
+               // mathcursor->cursor->crow != 0.
+               while (old_label == MathedXIter::error_label) {
+                       if (LocalDispatch(bv, LFUN_LEFT, string()) == FINISHED)
+                               return DISPATCHED;
+                       old_label = mathcursor->getLabel();
+               }
+
+               string new_label = arg;
+               if (new_label.empty()) {
+                       string const default_label =
+                               (lyxrc.label_init_length >= 0) ? "eq:" : "";
+                       pair<bool, string> const res = old_label.empty()
+                               ? askForText(_("Enter new label to insert:"),
+                                            default_label)
+                               : askForText(_("Enter label:"), old_label);
+                       if (!res.first)
+                               break;
+                       new_label = frontStrip(strip(res.second));
+               }
+
+               if (new_label == old_label)
+                       break;  // Nothing to do
+
+               if (!new_label.empty())
+                       SetNumber(true);
+
+               if (!new_label.empty() && bv->ChangeRefsIfUnique(old_label, new_label))
+                       bv->redraw();
+
+#ifdef WITH_WARNINGS
+#warning Labels
+#endif
+/*
+               if (is_multi_numbered(par->GetType())) {
+                       mathcursor->setLabel(new_label);
+                       // par->SetLabel(new_label);
+               } else
+                       label_ = new_label;
+*/
+
+               // Andre:
+               UpdateLocal(bv);
+               break;
+       }
+
+       case LFUN_MATH_DISPLAY:
+               bv->lockedInsetStoreUndo(Undo::EDIT);
+               display(!disp_flag_);
+               // Andre:
+               UpdateLocal(bv);
+               break;
+
+               // Invalid actions under math mode
+       case LFUN_MATH_MODE:
+               if (mathcursor->getLastCode()!= LM_TC_TEXTRM) {
+                       bv->owner()->message(_("math text mode"));
+                       varcode = LM_TC_TEXTRM;
+               } else {
+                       varcode = LM_TC_VAR;
+               }
+               mathcursor->setLastCode(varcode);
+               break;
+
+       case LFUN_UNDO:
+               bv->owner()->message(_("Invalid action in math mode!"));
+               break;
 
-void
-MathFuncInset::Draw(int x, int y)
-{ 
-       if (name && 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);
+       case LFUN_MATH_EXTERN:
+               HandleExtern(arg, bv);
+               break;
+
+               //------- dummy actions
+#ifdef WITH_WARNINGS
+#warning Is this needed here? Shouldnt the main dispatch handle this? (Lgb)
+#endif
+               //case LFUN_EXEC_COMMAND:
+               //bv->owner()->getMiniBuffer()->PrepareForCommand();
+               //break;
+
+       default:
+               if ((action == -1  || action == LFUN_SELFINSERT)
+                   && !arg.empty())  {
+                       unsigned char c = arg[0];
+                       bv->lockedInsetStoreUndo(Undo::INSERT);
+
+                       if (c == ' ' && mathcursor->getAccent() == LM_hat) {
+                               c = '^';
+                               mathcursor->setAccent(0);
+                       }
+
+                       if (c == 0) {      // Dead key, do nothing
+                               //lyxerr << "deadkey" << endl;
+                               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() :
+                                               static_cast<MathedTextCodes>(mathcursor->GetFCode());
+                                       varcode = MathIsAlphaFont(f) ?
+                                               static_cast<MathedTextCodes>(f) :
+                                               LM_TC_VAR;
+                               }
+                               
+                               //           lyxerr << "Varcode << vardoce;
+                               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 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)) {
+                               mathcursor->Insert(c, LM_TC_CONST);
+                       } else if (strchr("+/-*<>=", c)) {
+                               mathcursor->Insert(c, LM_TC_BOP);
+                       } else if (strchr(latex_special_chars, c) && c!= '_') {
+                               mathcursor->Insert(c, LM_TC_SPECIAL);
+                       } 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() :
+                                               static_cast<MathedTextCodes>(mathcursor->GetFCode());
+                                       varcode = MathIsAlphaFont(f) ?
+                                               static_cast<MathedTextCodes>(f) :
+                                               LM_TC_VAR;
+                               }
+                               
+                               if (varcode == LM_TC_TEXTRM) {
+                                       mathcursor->Insert(c, LM_TC_TEXTRM);
+                               } else if (was_macro) {
+                                       mathcursor->MacroModeClose();
+                               } else if (sp) {
+                                       int isp = (sp->GetSpace()<5) ? sp->GetSpace()+1: 0;
+                                       sp->SetSpace(isp);
+                                       space_on = true;
+                               } else if (!mathcursor->Pop() && mathcursor->IsEnd())
+                                       result = FINISHED;
+                       } else if (c == '\'' || c == '@') {
+                               mathcursor->Insert (c, LM_TC_VAR);
+                       } else if (c == '\\') {
+                               if (was_macro)
+                                       mathcursor->MacroModeClose();
+                               // This line nukes the mathcursor. Why?
+#ifdef WITH_WARNINGS
+#warning Still? (Lgb)
+#endif
+                               bv->owner()->message(_("TeX mode"));
+                               mathcursor->setLastCode(LM_TC_TEX);
+                       }
+                       // Andre:
+                       UpdateLocal(bv);
+               } else if (action == LFUN_MATH_PANEL) {
+                       result = UNDISPATCHED;
+               } else {
+                       // lyxerr << "Closed by action " << action << endl;
+                       result =  FINISHED;
                }
-               font.drawString(name, pm, y, x);
        }
+       
+       //UpdateLocal(bv);
+       
+       // Andre:
+       if ((mathcursor && was_macro != mathcursor->InMacroMode())
+           && action >= 0
+           && action != LFUN_BACKSPACE) 
+               UpdateLocal(bv);
+
+       if (sp && !space_on)
+               sp = 0;
+
+       if (mathcursor && (mathcursor->Selection() || was_selection))
+               ToggleInsetSelection(bv);
+
+       if (result == DISPATCHED || result == DISPATCHED_NOUPDATE ||
+           result == UNDISPATCHED)
+               ShowInsetCursor(bv);
+       else
+               bv->unlockInset(this);
+
+       return result;  // original version
 }
 
 
-void MathFuncInset::Metrics() 
+namespace {
+
+void mathedValidate(LaTeXFeatures & features, MathParInset * par)
 {
-       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,
-                            reinterpret_cast<unsigned char const *>(name),
-                            strlen(name), ascent, descent);
+       MathedIter it(&par->GetData());
+
+       while (it.OK() && !(features.binom && features.boldsymbol)) {
+               if (it.IsInset()) {
+                       if (it.IsActive()) {
+                               MathParInset * p = it.GetActiveInset();
+                               if (!features.binom && p->GetType() == LM_OT_MACRO &&
+                                   p->GetName() == "binom") {
+                                       features.binom = true;
+                               } else {
+                                       for (int i = 0; i <= p->getMaxArgumentIdx(); ++i) {
+                                               p->setArgumentIdx(i);
+                                               mathedValidate(features, p);
+                                       }
+                               }
+                       } else {
+                               MathedInset * p = it.GetInset();
+                               if (!features.boldsymbol && p->GetName() == "boldsymbol") {
+                                       features.boldsymbol = true;
+                               }
+                       }
+               }
+               it.Next();
+       }
 }
 
 
-static
-void mathedValidate(LaTeXFeatures & features, MathParInset * par)
+int mathed_write(MathParInset * p, ostream & os,
+                bool fragile, string const & label)
 {
-    MathedIter it(par->GetData());
-    
-    while (it.OK() && !(features.binom && features.boldsymbol)) {
-       if (it.IsInset()) {
-           if(it.IsActive()) {
-               MathParInset * p = it.GetActiveInset();
-               if (!features.binom && p->GetType() == LM_OT_MACRO && 
-                   strcmp(p->GetName(), "binom") == 0) {
-                   features.binom = true;
+       number_of_newlines = 0;
+       short mathed_env = p->GetType();
+       
+       if (mathed_env == LM_OT_MIN) {
+               if (fragile) os << "\\protect";
+               os << "\\( "; // changed from " \\( " (Albrecht Dress)
+       } else {
+               if (mathed_env == LM_OT_PAR){
+                       os << "\\[\n";
                } else {
-                   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) {
-                   features.boldsymbol = true;
+                       os << "\\begin{"
+                          << latex_mathenv[mathed_env]
+                          << "}";
+                       if (is_multicolumn(mathed_env)) {
+                               if (mathed_env != LM_OT_ALIGNAT
+                                   && mathed_env != LM_OT_ALIGNATN)
+                                       os << "%";
+                               os << "{" << p->GetColumns()/2 << "}";
+                       }
+                       os << "\n";
                }
-           }       
+               ++number_of_newlines;
        }
-       it.Next();
-    }
+       
+       if (!label.empty() && label[0] > ' '
+           && is_singlely_numbered(mathed_env)) {
+               os << "\\label{"
+                  << label
+                  << "}\n";
+               ++number_of_newlines;
+       }
+       
+       p->Write(os, fragile);
+       
+       if (mathed_env == LM_OT_MIN){
+               if (fragile) os << "\\protect";
+               os << " \\)";
+       } else if (mathed_env == LM_OT_PAR) {
+               os << "\\]\n";
+               ++number_of_newlines;
+       } else {
+               os << "\n\\end{"
+                  << latex_mathenv[mathed_env]
+                  << "}\n";
+               number_of_newlines += 2;
+       }
+       return number_of_newlines;
 }
+
+} // namespace anon
+
+
+/* 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() &&
+           (('A' <= c && c <= 'Z') ||
+            ('a'<= c && c<= 'z')))   {
+               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<InsetFormula*>(bv->theLockingInset())->LocalDispatch(bv, LFUN_SELFINSERT, tmp);
+                       else
+                               lyxerr << "Math error: attempt to write on a wrong "
+                                       "class of inset." << endl;
+               return true;
+       }
+       return false;
+}
+
+void InsetFormula::HandleExtern(const string & arg, BufferView * bv)
+{
+       //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());
+       MathedArray ar;
+       mathed_parser_file(is, 0);
+       mathed_parse(ar, par, 0);
+       par->array = ar;
+
+       UpdateLocal(bv);
+}
+
+