]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/formula.C
first go at mathed file cleanup
[lyx.git] / src / mathed / formula.C
index 66641c6258e2bd76077f1dd3c1d551df81754d87..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 "lyx_cb.h"
 #include "minibuffer.h"
 #include "BufferView.h"
-#include "lyxscreen.h"
-#ifndef USE_PAINTER
-#include "lyxdraw.h"
-#endif
 #include "lyxtext.h"
 #include "gettext.h"
 #include "LaTeXFeatures.h"
 #include "support/LOstream.h"
 #include "LyXView.h"
 #include "Painter.h"
-
-extern void UpdateInset(BufferView *, Inset * inset, bool mark_dirty = true);
-
-#ifndef USE_PAINTER
-extern GC canvasGC, mathGC, mathLineGC, latexGC, cursorGC, mathFrameGC;
+#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 char * mathed_label;
+extern string mathed_label;
 
-#ifdef MONO
-extern int mono_video;
-extern int fast_selection;
-#endif
-
-extern BufferView * current_view;
 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)
 
 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; 
-
-
-int MathedInset::df_asc;
-int MathedInset::df_des;
-int MathedInset::df_width;
 
+MathedCursor * InsetFormula::mathcursor = 0; 
 
-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 mathed_init_fonts();
 
 
 static
@@ -89,75 +89,70 @@ void mathedValidate(LaTeXFeatures & features, MathParInset * par);
 
 LyXFont WhichFont(short type, int size)
 {
-    LyXFont f;
+       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();
+       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;
-    }
-
-#ifdef USE_PAINTER
-    if (type != LM_TC_TEXTRM) 
-      f.setColor(LColor::math);
-#else
-    if (type != LM_TC_TEXTRM)
-           f.setColor(LyXFont::MATH);
-#endif    
-    return f;
+       default:
+               lyxerr << "Mathed Error: wrong font size: " << size << endl;
+               break;
+       }
+       
+       if (type != LM_TC_TEXTRM) 
+               f.setColor(LColor::math);
+       return f;
 }
 
 
@@ -169,8 +164,8 @@ void mathed_init_fonts() //removed 'static' because DEC cxx does not
 
     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,149 +186,40 @@ 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);    
 }
 
-#ifdef USE_PAINTER
-LyXFont mathed_get_font(short type, int size)
-{
-       LyXFont f = WhichFont(type, size);
-       if (type == LM_TC_TEX) {
-               f.setLatex(LyXFont::ON);
-       }
-       return f;
-}
-#else
-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();
-}
-#endif
-
 
-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;
-       s = &sx[0];
-    }
-    return f.textWidth(reinterpret_cast<char const *>(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
-#ifdef USE_PAINTER
-void MathedInset::drawStr(Painter & pain, short type, int size,
-                         int x, int y, byte * s, int ls)
-{
-       string st;
-       if (MathIsBinary(type)) {
-               for (int i = 0; i < ls; ++i) {
-#warning What conversion should be done for s[i] here?
-                       st += string(" ") + char(s[i]) + ' ';
-               }
-       } else {
-               st = string(reinterpret_cast<char*>(s), ls);
-       }
-       LyXFont mf = mathed_get_font(type, size);
-       pain.text(x, y, st, mf);
-}
-#else
-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);
-}
-#endif
 
 
 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)
 {
-   par = (p->GetType()>= LM_OT_MPAR) ? 
+   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;
@@ -349,7 +235,7 @@ InsetFormula::~InsetFormula()
 }
 
 
-Inset * InsetFormula::Clone() const
+Inset * InsetFormula::Clone(Buffer const &) const
 {
     InsetFormula * f = new InsetFormula(par);
     f->label = label;
@@ -357,67 +243,65 @@ Inset * InsetFormula::Clone() const
 }
 
 
-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;
+    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
 {
-    // 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)
 {
        istream & is = lex.getStream();
     
        mathed_parser_file(is, lex.GetLineNo());   
    
        // Silly hack to read labels. 
-       mathed_label = 0;
+       //mathed_label = 0;
+       mathed_label.erase();
+       
        mathed_parse(0, 0, &par);
        par->Metrics();
        disp_flag = (par->GetType() > 0);
@@ -425,9 +309,20 @@ void InsetFormula::Read(LyXLex & lex)
        // Update line number
        lex.setLineNo(mathed_parser_lineno());
        
-       if (mathed_label) {
+       //if (mathed_label) {
+       if (!mathed_label.empty()) {
                label = mathed_label;
-               mathed_label = 0;
+               //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
@@ -436,55 +331,35 @@ void InsetFormula::Read(LyXLex & lex)
 }
 
 
-#ifdef USE_PAINTER
-int InsetFormula::ascent(Painter &, LyXFont const &) const
+int InsetFormula::ascent(BufferView *, LyXFont const &) const
 {
    return par->Ascent() + ((disp_flag) ? 8 : 1);
 }
-#else
-int InsetFormula::Ascent(LyXFont const &) const
-{
-   return par->Ascent() + ((disp_flag) ? 8 : 1);
-}
-#endif
 
 
-#ifdef USE_PAINTER
-int InsetFormula::descent(Painter &, LyXFont const &) const
-{
-   return par->Descent() + ((disp_flag) ? 8 : 1);
-}
-#else
-int InsetFormula::Descent(LyXFont const &) const
+int InsetFormula::descent(BufferView *, LyXFont const &) const
 {
    return par->Descent() + ((disp_flag) ? 8 : 1);
 }
-#endif
 
 
-#ifdef USE_PAINTER
-int InsetFormula::width(Painter &, LyXFont const & f) const
-{
-    lfont_size = f.size();
-    par->Metrics();
-    return par->Width(); //+2;
-}
-#else
-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;
 }
-#endif
 
 
-#ifdef USE_PAINTER
-void InsetFormula::draw(Painter & pain, LyXFont const &,
-                       int baseline, float & x) const
+void InsetFormula::draw(BufferView * bv, LyXFont const & f,
+                       int baseline, float & x, bool) const
 {
+       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);
@@ -503,20 +378,20 @@ void InsetFormula::draw(Painter & pain, LyXFont const &,
        } else {
                par->draw(pain, int(x), baseline);
        }
-       x += float(width(pain, font));
-       
-       if (par->GetType() == LM_OT_PARN || par->GetType() == LM_OT_MPARN) {
-               LyXFont font = WhichFont(LM_TC_BF, par->size);
-               font.setLatex(LyXFont::OFF);
+       x += float(width(bv, font));
+
+       if (is_numbered(par->GetType())) {
+               LyXFont wfont = WhichFont(LM_TC_BF, par->size);
+               wfont.setLatex(LyXFont::OFF);
                
-               if (par->GetType() == LM_OT_PARN) {
+               if (is_singlely_numbered(par->GetType())) {
                        string str;
                        if (!label.empty())
                                str = string("(") + label + ")";
                        else
                                str = string("(#)");
-                       pain.text(int(x + 20), baseline, str, font);
-               } else if (par->GetType() == LM_OT_MPARN) {
+                       pain.text(int(x + 20), baseline, str, wfont);
+               } else {
                        MathMatrixInset * mt =
                                static_cast<MathMatrixInset*>(par);
                        int y;
@@ -525,11 +400,11 @@ void InsetFormula::draw(Painter & pain, LyXFont const &,
                                y = baseline + crow->getBaseline();
                                if (crow->isNumbered()) {
                                        string str;
-                                       if (crow->getLabel())
+                                       if (!crow->getLabel().empty())
                                                str = string("(") + crow->getLabel() + ")";
                                        else
                                                str = "(#)";
-                                       pain.text(int(x + 20), y, str, font);
+                                       pain.text(int(x + 20), y, str, wfont);
                                }
                                crow = crow->getNext();
                        }
@@ -537,155 +412,109 @@ void InsetFormula::draw(Painter & pain, LyXFont const &,
        }
        cursor_visible = false;
 }
-#else
-void InsetFormula::Draw(LyXFont f, LyXScreen & scr, int baseline, float & x)
+
+
+string const InsetFormula::EditMessage() 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;
+       return _("Math editor mode");
 }
-#endif
 
 
-void InsetFormula::Edit(int x, int y)
+void InsetFormula::Edit(BufferView * bv, int x, int y, unsigned int)
 {
-   mathcursor = new MathedCursor(par);
-   current_view->lockInset(this);
-   par->Metrics();
-   UpdateInset(current_view, 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(current_view, 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) const
+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)
-    current_view->hideLockedInsetCursor(x, y, asc, desc);
+    bv->hideLockedInsetCursor();
   else
-    current_view->showLockedInsetCursor(x, y, asc, desc);
+    bv->showLockedInsetCursor(x, y, asc, desc);
   cursor_visible = !cursor_visible;
 }
 
 
-void InsetFormula::ShowInsetCursor()
+void InsetFormula::ShowInsetCursor(BufferView * bv, bool)
 {
   if (!cursor_visible) {
-    int x, y, asc, desc;
     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();
-      current_view->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;
@@ -694,11 +523,11 @@ 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(current_view, this, false);
+    bv->updateInset(this, false);
       
 }
 
@@ -710,7 +539,7 @@ void InsetFormula::display(bool dspf)
         par->SetType(LM_OT_PAR);
         par->SetStyle(LM_ST_DISPLAY);
       } else {
-        if (par->GetType() >= LM_OT_MPAR) { 
+        if (is_multiline(par->GetType())) { 
            MathParInset * p = new MathParInset(par);
            delete par;
            par = p;
@@ -719,8 +548,8 @@ void InsetFormula::display(bool dspf)
         }
         par->SetType(LM_OT_MIN);
         par->SetStyle(LM_ST_TEXT);
-        if (!label.empty() && par->GetType() != LM_OT_MPARN) {
-                label.clear();
+        if (!label.empty()) {
+                label.erase();
         }
       }
       disp_flag = dspf;
@@ -728,104 +557,85 @@ void InsetFormula::display(bool 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 = 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;
-}
+//#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 lab;
+       if (is_multi_numbered(par->GetType())) {
                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 (!crow->getLabel().empty())
+                               label_list.push_back(crow->getLabel());
                        crow = crow->getNext();
                }
-               return lab;
-       }
-       return label;
+       } else if (!label.empty())
+               label_list.push_back(label);
+
+       return label_list;
 }
 
 
-void InsetFormula::UpdateLocal()
+void InsetFormula::UpdateLocal(BufferView * bv)
 {
    par->Metrics();  // To inform lyx kernel the exact size 
                   // (there were problems with arrays).
-   UpdateInset(current_view, 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(current_view, 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(current_view, 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) {
        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(current_view, this, false); 
+           bv->updateInset(this, false); 
          sel_x = x;  sel_y = y;
       }
 }
@@ -842,7 +652,7 @@ bool InsetFormula::SetNumber(bool numbf)
 {
    if (disp_flag) {
       short type = par->GetType();
-      bool oldf = (type == LM_OT_PARN || type == LM_OT_MPARN);
+      bool oldf = is_numbered(type);
       if (numbf && !oldf) ++type;
       if (!numbf && oldf) --type;
       par->SetType(type);
@@ -852,22 +662,20 @@ bool InsetFormula::SetNumber(bool numbf)
 }
 
 
-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;
-
-   HideInsetCursor();
-#ifdef MONO
-   if (mathcursor->Selection() && (fast_selection || mono_video))
-          ToggleInsetSelection();
-#endif
+    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;
@@ -878,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:
-           //current_view->lockedInsetStoreUndo(Undo::INSERT);
-           current_view->lockedInsetStoreUndo(Undo::DELETE);
+      bv->lockedInsetStoreUndo(Undo::DELETE);
       mathcursor->DelLine();
-      UpdateLocal();
+      UpdateLocal(bv);
       break;
     case LFUN_BREAKLINE:
-      current_view->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:
-      current_view->lockedInsetStoreUndo(Undo::INSERT);
+      bv->lockedInsetStoreUndo(Undo::INSERT);
       mathcursor->Insert(0, LM_TC_TAB);
       //UpdateInset(this);
       break;     
     case LFUN_TABINSERT:
-      current_view->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(current_view, this);
+          bv->updateInset(this, true);
           break;
        }
       
     case LFUN_DELETE:
-           //current_view->lockedInsetStoreUndo(Undo::INSERT);
-           current_view->lockedInsetStoreUndo(Undo::DELETE);
+      bv->lockedInsetStoreUndo(Undo::DELETE);
       mathcursor->Delete();       
-      UpdateInset(current_view, this);
+      bv->updateInset(this, true);
       break;    
 //    case LFUN_GETXY:
 //      sprintf(dispatch_buffer, "%d %d",);
@@ -945,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;
 
@@ -957,11 +784,11 @@ bool InsetFormula::LocalDispatch(int action, char const * arg)
     case LFUN_PASTE:
             if (was_macro)
                mathcursor->MacroModeClose();
-           current_view->lockedInsetStoreUndo(Undo::INSERT);
-           mathcursor->SelPaste(); UpdateLocal(); break;
+           bv->lockedInsetStoreUndo(Undo::INSERT);
+           mathcursor->SelPaste(); UpdateLocal(bv); break;
     case LFUN_CUT:
-           current_view->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:
@@ -987,7 +814,7 @@ bool InsetFormula::LocalDispatch(int action, char const * arg)
     {
        if (!greek_kb_flag) {
          greek_kb_flag = 1;
-         current_view->owner()->getMiniBuffer()->Set(_("Math greek mode on"));
+         bv->owner()->getMiniBuffer()->Set(_("Math greek mode on"));
        } else
         greek_kb_flag = 0;
        break;
@@ -998,92 +825,96 @@ bool InsetFormula::LocalDispatch(int action, char const * arg)
     {
        greek_kb_flag = (greek_kb_flag) ? 0 : 2;
        if (greek_kb_flag)
-        current_view->owner()->getMiniBuffer()->Set(_("Math greek keyboard on"));
+        bv->owner()->getMiniBuffer()->Set(_("Math greek keyboard on"));
        else
-        current_view->owner()->getMiniBuffer()->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);
-       current_view->owner()->getMiniBuffer()->Set(_("TeX mode")); 
+       bv->owner()->getMiniBuffer()->Set(_("TeX mode")); 
        break;
     }
 
     case LFUN_MATH_NUMBER:
     {
-      current_view->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) {
+         if (is_numbered(type)) {
             --type;
             if (!label.empty()) {
-                    label.clear();
+                    label.erase();
             }
-            current_view->owner()->getMiniBuffer()->Set(_("No number"));  
+            bv->owner()->getMiniBuffer()->Set(_("No number"));  
          } else {
             ++type;
-             current_view->owner()->getMiniBuffer()->Set(_("Number"));
+             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:
     {
-      current_view->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:
     {
-       current_view->lockedInsetStoreUndo(Undo::INSERT);
-       InsertSymbol(arg);
+       bv->lockedInsetStoreUndo(Undo::INSERT);
+       InsertSymbol(bv, arg);
        break;
     }
     
     case LFUN_INSERT_MATRIX:
     { 
-      current_view->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]= '\0';
+       strncpy(arg2, arg.c_str(), 80); arg2[79]= '\0';
        k = sscanf(arg2, "%d %d %s", &m, &n, s);
        s[79] = '\0';
        
@@ -1098,43 +929,44 @@ bool InsetFormula::LocalDispatch(int action, char const * arg)
          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:
     {  
-      current_view->lockedInsetStoreUndo(Undo::INSERT);
+      bv->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';
+       if (arg.empty())
+              break;
+       ::strncpy(arg2, arg.c_str(), 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);
+            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;
+                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);
+                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];
@@ -1143,60 +975,80 @@ bool InsetFormula::LocalDispatch(int action, char const * arg)
        
        MathDelimInset * p = new MathDelimInset(ilf, irg);
        mathcursor->Insert(p, LM_TC_ACTIVE_INSET);
-       UpdateLocal();                             
+       UpdateLocal(bv);
        break;
     }
 
     case LFUN_PROTECTEDSPACE:
     {
-      current_view->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:
     {
-       current_view->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;
-         }
+       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 (!lb.empty() && lb[0] > ' ') {
+
+       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.clear();
+
+       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:
-           //current_view->lockedInsetStoreUndo(Undo::INSERT);
-           current_view->lockedInsetStoreUndo(Undo::EDIT);
+      bv->lockedInsetStoreUndo(Undo::EDIT);
       display(!disp_flag);
-      UpdateLocal();
+      UpdateLocal(bv);
       break;
       
     // Invalid actions under math mode
     case LFUN_MATH_MODE:  
     {
        if (mathcursor->getLastCode()!= LM_TC_TEXTRM) {
-           current_view->owner()->getMiniBuffer()->Set(_("math text mode"));
+           bv->owner()->getMiniBuffer()->Set(_("math text mode"));
            varcode = LM_TC_TEXTRM;
        } else {
            varcode = LM_TC_VAR;
@@ -1205,18 +1057,18 @@ bool InsetFormula::LocalDispatch(int action, char const * arg)
        break; 
     }
     case LFUN_UNDO:
-      current_view->owner()->getMiniBuffer()->Set(_("Invalid action in math mode!"));
+      bv->owner()->getMiniBuffer()->Set(_("Invalid action in math mode!"));
       break;
 
     //------- dummy actions
     case LFUN_EXEC_COMMAND:
-       current_view->owner()->getMiniBuffer()->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];
-        current_view->lockedInsetStoreUndo(Undo::INSERT);
+        bv->lockedInsetStoreUndo(Undo::INSERT);
         
         if (c == ' ' && mathcursor->getAccent() == LM_hat) {
             c = '^';
@@ -1242,7 +1094,21 @@ bool InsetFormula::LocalDispatch(int action, char const * arg)
            }
 
 //          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 
@@ -1302,94 +1168,44 @@ bool InsetFormula::LocalDispatch(int action, char const * arg)
                 space_on = true;
              } else {
                  if (!mathcursor->Pop() && mathcursor->IsEnd()) 
-                   result = false;
+                   result = FINISHED;
              }
           } else
-          if (c == '\'') {
+          if (c == '\'' || c == '@') {
              mathcursor->Insert (c, LM_TC_VAR);
           } else
           if (c == '\\') {
              if (was_macro)
                mathcursor->MacroModeClose();
-             current_view->owner()->getMiniBuffer()->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();
+          UpdateLocal(bv);
    if (sp && !space_on) sp = 0;
-   if (mathcursor->Selection() || (was_selection
-#ifdef MONO
-                                  && !(fast_selection || mono_video)
-#endif
-          ))
-       ToggleInsetSelection();
+   if (mathcursor->Selection() || was_selection)
+       ToggleInsetSelection(bv);
     
-   if (result)
-      ShowInsetCursor();
+   if ((result == DISPATCHED) || (result == DISPATCHED_NOUPDATE) ||
+       (result == UNDISPATCHED))
+      ShowInsetCursor(bv);
    else
-      current_view->unlockInset(this);
+      bv->unlockInset(this);
     
    return result;
 }
 
 
-#ifdef USE_PAINTER
-void
-MathFuncInset::draw(Painter & pain, 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;
-#ifdef MONO
-               if (mono_video) {
-                       int a = font.maxAscent();
-                       int d = font.maxDescent();
-                       pain.fillRectangle(x, y - a, font.textWidth(name, strlen(name)), a + d);
-               }
-#endif
-               pain.text(x, y, name, font);
-       }
-}
-#else
-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);
-       }
-}
-#endif
-
-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,
-                            reinterpret_cast<unsigned char const *>(name),
-                            strlen(name), ascent, descent);
-}
-
 
 static
 void mathedValidate(LaTeXFeatures & features, MathParInset * par)
@@ -1398,10 +1214,10 @@ void mathedValidate(LaTeXFeatures & features, MathParInset * par)
     
     while (it.OK() && !(features.binom && features.boldsymbol)) {
        if (it.IsInset()) {
-           if(it.IsActive()) {
+           if (it.IsActive()) {
                MathParInset * p = it.GetActiveInset();
                if (!features.binom && p->GetType() == LM_OT_MACRO && 
-                   strcmp(p->GetName(), "binom") == 0) {
+                   p->GetName() == "binom") {
                    features.binom = true;
                } else {
                    for (int i = 0; i <= p->getMaxArgumentIdx(); ++i) {
@@ -1411,8 +1227,8 @@ void mathedValidate(LaTeXFeatures & features, MathParInset * par)
                }
            } else {
                MathedInset* p = it.GetInset();
-               if (!features.boldsymbol && p->GetName() &&
-                   strcmp(p->GetName(), "boldsymbol") == 0) {
+               if (!features.boldsymbol &&
+                   p->GetName() == "boldsymbol") {
                    features.boldsymbol = true;
                }
            }