]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/formula.C
first go at mathed file cleanup
[lyx.git] / src / mathed / formula.C
index 57e9348242007ee9954433ef948b13519a85bed9..67363caa0c79af950aa495617fd1e062865befb7 100644 (file)
@@ -1,11 +1,11 @@
 /*
- *  File:        formula.h
+ *  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: (c) 1996-1998 Alejandro Aguilar Sierra
+ *  Copyright: 1996-1998 Alejandro Aguilar Sierra
  *
  *  Version: 0.4, Lyx project.
  *
@@ -15,8 +15,7 @@
 
 #include <config.h>
 
-#include <cctype>
-#include <cstdlib>
+#include "Lsstream.h"
 
 #ifdef __GNUG__
 #pragma implementation "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 "LyXView.h"
+#include "Painter.h"
+#include "font.h"
+#include "support/lyxlib.h"
+#include "lyxrc.h"
+#include "math_defs.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 "support.h"
+
+using std::ostream;
+using std::istream;
+using std::pair;
+using std::endl;
+using std::vector;
+using std::max;
+
+#if 0
+using std::strncmp;
+using std::strcmp;
+using std::abs;
+using std::isdigit;
+using std::isalpha;
+#endif
 
-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*);
-
-
-extern GC canvasGC, mathGC, mathLineGC, latexGC, cursorGC, mathFrameGC;
-extern char *mathed_label;
-
-extern int mono_video;
-extern int fast_selection;
+extern string mathed_label;
 
-extern BufferView *current_view;
-extern BufferList bufferlist;
-extern char const *latex_special_chars;
+extern char const * latex_special_chars;
 
-short greek_kb_flag = 0;
+int 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;
+void mathed_init_fonts();
 
-// 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');
-}
-
-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));
-}
+static
+void mathedValidate(LaTeXFeatures & features, MathParInset * par);
 
-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);
+       LyXFont f;
     
-    switch (size) {
-     case LM_ST_DISPLAY:     
-       if (type==LM_TC_BSYM) {
-           f.incSize();
-           f.incSize();
+       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();
+               }
        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;
+       case LM_ST_TEXT:
+               break;
+       case LM_ST_SCRIPT:
+               f.decSize();
+               break;
+       case LM_ST_SCRIPTSCRIPT:
+               f.decSize();
+               f.decSize();
        break;
-    }
-    
-    if (type!=LM_TC_TEXTRM) 
-      f.setColor(LyXFont::MATH);
-    return f;
+       default:
+               lyxerr << "Mathed Error: wrong font size: " << size << endl;
+               break;
+       }
+       
+       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,117 +186,41 @@ 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)
-{
-    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();
-}
 
 
-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<ls && i<75; i++) {
-           *(ps++) = ' ';
-           *(ps++) = s[i];
-           *(ps++) = ' ';
-       }
-       *(ps++) = '\0';
-       ls = 3*ls;
-       s = &sx[0];
-    }
-    return f.textWidth((const char*)s, ls);;
-}
 
-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;
-}
 
-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;
-}
 
-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;
-}
 
 
-// In a near future maybe we use a better fonts renderer
-void MathedInset::drawStr(short type, int size, int x, int y, byte* s, int ls)
-{
-    mathed_set_font(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++) = ' ';
-       }
-       //    *ps = ' ';
-       ls = 3*ls;
-       s = &sx[0];
-    }
-    GC gc = (type==LM_TC_TEX) ? latexGC: mathGC;
-    XDrawString(fl_display, pm, gc, x, y, (char*)s, ls);
-    XFlush(fl_display);
-}
+
 
 
 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;
+       //label = 0;
+       if (disp_flag) {
+               par->SetType(LM_OT_PAR);
+               par->SetStyle(LM_ST_DISPLAY);
+       }
 }
 
-InsetFormula::InsetFormula(MathParInset *p)
+
+InsetFormula::InsetFormula(MathParInset * p)
 {
-   par = (p->GetType()>=LM_OT_MPAR) ? 
-         new MathMatrixInset((MathMatrixInset*)p): 
+   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;
    
@@ -309,253 +228,293 @@ InsetFormula::InsetFormula(MathParInset *p)
    //label = 0;
 }
 
+
 InsetFormula::~InsetFormula()
 {
    delete par;
-   //if (label) delete label;
 }
 
-Inset* InsetFormula::Clone()
+
+Inset * InsetFormula::Clone(Buffer const &) const
 {
-    InsetFormula* f = new InsetFormula(par);
+    InsetFormula * f = new InsetFormula(par);
     f->label = label;
-    return (Inset*)f;
+    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)
-      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 *, 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 * bv, LyXFont const & f) const
 {
+    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();
+       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);
        
-   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 (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 (!label.empty())
+                               str = string("(") + label + ")";
+                       else
+                               str = string("(#)");
+                       pain.text(int(x + 20), baseline, str, wfont);
+               } else {
+                       MathMatrixInset * mt =
+                               static_cast<MathMatrixInset*>(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;
+}
+
+
+string const InsetFormula::EditMessage() const 
+{
+       return _("Math editor mode");
 }
 
 
-void InsetFormula::Edit(int x, int y)
+void InsetFormula::Edit(BufferView * bv, int x, int y, unsigned int)
 {
-   mathcursor = new MathedCursor(par);
-   LockInset(this);
-   par->Metrics();
-   UpdateInset(this, false);
-   x += par->xo; 
-   y += par->yo; 
-   mathcursor->SetPos(x, y);
+    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,23 +523,24 @@ 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::SetDisplay(bool dspf)
+
+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) { 
-           MathParInset *p = new MathParInset(par);
+        if (is_multiline(par->GetType())) { 
+           MathParInset * p = new MathParInset(par);
            delete par;
            par = p;
            if (mathcursor) 
@@ -588,150 +548,136 @@ void InsetFormula::SetDisplay(bool dspf)
         }
         par->SetType(LM_OT_MIN);
         par->SetStyle(LM_ST_TEXT);
-        if (!label.empty() && par->GetType()!=LM_OT_MPARN) {
+        if (!label.empty()) {
                 label.erase();
         }
       }
       disp_flag = dspf;
-   }   
+   }
 }
-   
 
 
-int InsetFormula::GetNumberOfLabels() const
+vector<string> 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<string> 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 label;
-       MathMatrixInset *mt = (MathMatrixInset*)par;
-       int nl=0;
-       MathedRowSt const* crow = mt->getRowSt();
-       while (crow) {
-          if (crow->getLabel()) {
-              if (nl==il) {
-                  label = crow->getLabel();
-                  break;
-              }
-              nl++;
-          }
-          crow = crow->getNext();
-       }
-       return label;
-   }
-   return label;
+       if (is_multi_numbered(par->GetType())) {
+               MathMatrixInset * mt = static_cast<MathMatrixInset*>(par);
+               MathedRowSt const * crow = mt->getRowSt();
+               while (crow) {
+                       if (!crow->getLabel().empty())
+                               label_list.push_back(crow->getLabel());
+                       crow = crow->getNext();
+               }
+       } 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); 
+         if (sel_x!= x || sel_y!= y)
+           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--;
+      bool 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,
+                           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) { 
+    if (mathcursor->getLastCode() == LM_TC_TEX) { 
        varcode = LM_TC_TEX;
     }
    switch (action) {
@@ -740,66 +686,81 @@ 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);
-      mathcursor->Insert(' ', LM_TC_CR);
+    {
+      bv->lockedInsetStoreUndo(Undo::INSERT);
+      byte c = arg.empty() ? '1' : arg[0];
+      mathcursor->Insert(c, LM_TC_CR);
+      if (!label.empty()) {
+        mathcursor->setLabel(label);
+        label.erase();
+      }
       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 +768,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 +784,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 +814,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,203 +823,232 @@ 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;
     }  
    
       //  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_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);
-       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--;
+         if (is_numbered(type)) {
+            --type;
             if (!label.empty()) {
                     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;
     }
     
     case LFUN_MATH_NONUMBER:
     { 
-       if (par->GetType()==LM_OT_MPARN) {
+       if (is_multi_numbered(par->GetType())) {
 //        MathMatrixInset *mt = (MathMatrixInset*)par;
           //BUG 
 //        mt->SetNumbered(!mt->IsNumbered());
-           
+
+#warning This is a terrible hack! We should find a better solution.
+       while (mathcursor->getLabel() == MathedXIter::error_label) {
+          if (LocalDispatch(bv, LFUN_LEFT, string()) == FINISHED)
+              return DISPATCHED;
+       }
            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) {
+       } 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));
-                // Long words will cause l==0; so check.
-                if(l) ilf = l->id;
+                // 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);
+          if (n > 1) {
+              if (isdigit(rg[0]))
+                irg = lyx::atoi(rg);
               else 
                 if (rg[1]) {
                     l = in_word_set(rg, strlen(rg));
-                    if(l) irg = l->id;
+                    if (l) irg = l->id;
                 } else
                 if (vdelim.find(rg[0]) != string::npos)
                   irg = rg[0];
           }
        }
        
-       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()<LM_OT_PAR) break;
-       string lb = arg;
-       if (lb.empty())
-             lb = string(askForText(_("Enter new label to insert:")));
-       if (!lb.empty() && lb[0]> ' ') {
+       bv->lockedInsetStoreUndo(Undo::INSERT);
+       if (par->GetType() < LM_OT_PAR)
+             break;
+
+       string old_label = is_multiline(par->GetType())
+              ?  mathcursor->getLabel() : label;
+
+#warning This is a terrible hack! We should find a better solution.
+       /// This is needed becuase 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 default_label = (lyxrc.label_init_length >= 0) ? "eq:" : "";
+         pair<bool, string> 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 (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.erase();
-              //label = 0;
+
+       if (!new_label.empty() && bv->ChangeRefsIfUnique(old_label, new_label))
+             bv->redraw();
+
+       if (is_multi_numbered(par->GetType()))
+         mathcursor->setLabel(new_label);
+//       MathMatrixInset *mt = (MathMatrixInset*)par;
+//       mt->SetLabel(new_label);
+       else
+         label = new_label;
+       UpdateLocal(bv);
        break;
     }
     
     case LFUN_MATH_DISPLAY:
-           //LockedInsetStoreUndo(Undo::INSERT);
-           LockedInsetStoreUndo(Undo::EDIT);
-      SetDisplay(!disp_flag);
-      UpdateLocal();
+      bv->lockedInsetStoreUndo(Undo::EDIT);
+      display(!disp_flag);
+      UpdateLocal(bv);
       break;
       
     // Invalid actions under math mode
     case LFUN_MATH_MODE:  
     {
-       if (mathcursor->getLastCode()!=LM_TC_TEXTRM) {
-           minibuffer->Set(_("math text mode"));
+       if (mathcursor->getLastCode()!= LM_TC_TEXTRM) {
+           bv->owner()->getMiniBuffer()->Set(_("math text mode"));
            varcode = LM_TC_TEXTRM;
        } else {
            varcode = LM_TC_VAR;
@@ -1063,88 +1057,106 @@ 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) {
+        if (c == ' ' && mathcursor->getAccent() == LM_hat) {
             c = '^';
             mathcursor->setAccent(0);
         }
-        if (c==0) {      // Dead key, do nothing 
+        if (c == 0) {      // Dead key, do nothing 
             //lyxerr << "deadkey" << endl;
             break;
         } 
         if (isalpha(c)) {
-            if (mathcursor->getLastCode()==LM_TC_TEX) { 
+            if (mathcursor->getLastCode() == LM_TC_TEX) { 
               mathcursor->MacroModeOpen();
               mathcursor->clearLastCode();
               varcode = LM_TC_MIN;
            } else          
            if (!varcode) {             
                short f = (mathcursor->getLastCode()) ? 
-                         mathcursor->getLastCode():
-                         (MathedTextCodes)mathcursor->GetFCode();
-              varcode =  MathIsAlphaFont(f) ?  (MathedTextCodes)f:LM_TC_VAR;
+                         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);
+           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)) {
+          if (strchr("!,:;{}", c) && (varcode == LM_TC_TEX||was_macro)) {
               mathcursor->Insert(c, LM_TC_TEX);
-              if (c=='{') {
+              if (c == '{') {
                   mathcursor->Insert('}', LM_TC_TEX);
                   mathcursor->Left();
               }
               mathcursor->clearLastCode();
 //            varcode = LM_TC_MIN;
           } else
-          if (c=='_' && varcode==LM_TC_TEX) {
+          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)) {
+           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)) 
+          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!='_')
+          if (strchr(latex_special_chars, c) && c!= '_')
              mathcursor->Insert(c, LM_TC_SPECIAL);
         else
-          if (c=='_' || c=='^') {
+          if (c == '_' || c == '^') {
               char s[2];
               s[0] = c;
               s[1] = 0;
              mathcursor->Interpret (s);
           } else
-          if (c==' ') {            
+          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<MathedTextCodes>(mathcursor->GetFCode());
+                  varcode = MathIsAlphaFont(f) ?
+                          static_cast<MathedTextCodes>(f) :
+                          LM_TC_VAR;
               }
-             if (varcode==LM_TC_TEXTRM) {
+             if (varcode == LM_TC_TEXTRM) {
                  mathcursor->Insert(c, LM_TC_TEXTRM);
              } else
              if (was_macro)
@@ -1156,90 +1168,67 @@ 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 (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 if (action == LFUN_MATH_PANEL) {
+        result = UNDISPATCHED;
       } 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) ||
+       (result == UNDISPATCHED))
+      ShowInsetCursor(bv);
    else
-      UnlockInset(this);
+      bv->unlockInset(this);
     
    return result;
 }
 
 
-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);
-               }
-               font.drawString(name, pm, y, x);
-       }
-}
-
-
-void MathFuncInset::Metrics() 
-{
-       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);
-}
-
 
-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();
-               if (!features.binom && p->GetType()==LM_OT_MACRO && 
-                   strcmp(p->GetName(), "binom")==0) {
+           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++) {
+                   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;
                }
            }