]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/formula.C
first go at mathed file cleanup
[lyx.git] / src / mathed / formula.C
index a17b6db0e91593ad513bdbb84c1bba51cd2ef7e8..67363caa0c79af950aa495617fd1e062865befb7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  File:        formula.h
+ *  File:        formula.C
  *  Purpose:     Implementation of formula inset
  *  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx> 
  *  Created:     January 1996
 
 #include <config.h>
 
-#ifdef HAVE_SSTREAM
-#include <sstream>
-using std::istringstream;
-#else
-#include <strstream>
-#endif
+#include "Lsstream.h"
 
 #ifdef __GNUG__
 #pragma implementation "formula.h"
@@ -42,39 +37,50 @@ using std::istringstream;
 #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 char * mathed_label;
+extern string mathed_label;
 
 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
@@ -83,70 +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;
-    }
-
-    if (type != LM_TC_TEXTRM) 
-      f.setColor(LColor::math);
-    return f;
+       default:
+               lyxerr << "Mathed Error: wrong font size: " << size << endl;
+               break;
+       }
+       
+       if (type != LM_TC_TEXTRM) 
+               f.setColor(LColor::math);
+       return f;
 }
 
 
@@ -186,102 +192,34 @@ void mathed_init_fonts() //removed 'static' because DEC cxx does not
 }
 
 
-LyXFont mathed_get_font(short type, int size)
-{
-       LyXFont f = WhichFont(type, size);
-       if (type == LM_TC_TEX) {
-               f.setLatex(LyXFont::ON);
-       }
-       return f;
-}
-
-
-int mathed_string_width(short type, int size, byte const * s, int ls)
-{
-    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 lyxfont::width(reinterpret_cast<char const *>(s), ls, f);
-}
 
 
-int mathed_char_width(short type, int size, byte c)
-{
-    int t = (MathIsBinary(type)) ? mathed_string_width(type, size, &c, 1) :
-           lyxfont::width(c, WhichFont(type, size));
-    return t;
-}
 
 
-int mathed_string_height(short type, int size, byte const * s,
-                        int ls, int & asc, int & des)
-{
-   LyXFont font = WhichFont(type, size);
-   asc = des = 0;
-   for (int i = 0; i < ls; ++i) {
-      if (lyxfont::descent(s[i], font) > des)
-       des = lyxfont::descent(s[i], font);
-      if (lyxfont::ascent(s[i], font) > asc)
-       asc = lyxfont::ascent(s[i], font);
-   }
-   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 = lyxfont::descent(c, font);
-   asc = lyxfont::ascent(c, font);
-   return asc + des;
-}
 
 
-// In a near future maybe we use a better fonts renderer
-void MathedInset::drawStr(Painter & pain, short type, int size,
-                         int x, int y, byte const * s, int ls)
-{
-       string st;
-       if (MathIsBinary(type)) {
-               for (int i = 0; i < ls; ++i) {
-                       st += string(" ") + char(s[i]) + ' ';
-               }
-       } else {
-               st = string(reinterpret_cast<char const *>(s), ls);
-       }
-       LyXFont mf = mathed_get_font(type, size);
-       pain.text(x, y, st, mf);
-}
 
 
 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;
@@ -297,7 +235,7 @@ InsetFormula::~InsetFormula()
 }
 
 
-Inset * InsetFormula::Clone() const
+Inset * InsetFormula::Clone(Buffer const &) const
 {
     InsetFormula * f = new InsetFormula(par);
     f->label = label;
@@ -305,55 +243,65 @@ Inset * InsetFormula::Clone() const
 }
 
 
-void InsetFormula::Write(ostream & os) const
+void InsetFormula::Write(Buffer const * buf, ostream & os) const
 {
        os << "Formula ";
-       Latex(os, false, false);
+       Latex(buf, os, false, false);
 }
 
 
-int InsetFormula::Latex(ostream & os, bool fragile, bool) const
+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.
-    if (fragile) // this is where fragile != 0 was used (Lgb)
-           par->Write(os, fragile);
-    else
-           mathed_write(par, os, &ret, fragile, label.c_str());
+    mathed_write(par, os, &ret, fragile, label);
     return ret;
 }
 
 
-int InsetFormula::Linuxdoc(ostream &) const
+int InsetFormula::Ascii(Buffer const *, ostream & os, int) const
 {
+    par->Write(os, false);
     return 0;
 }
 
 
-int InsetFormula::DocBook(ostream&) const
+int InsetFormula::Linuxdoc(Buffer const * buf, ostream & os) const
 {
-    return 0;
+    return Ascii(buf, os, 0);
+}
+
+
+int InsetFormula::DocBook(Buffer const * buf, ostream & os) const
+{
+    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);
@@ -361,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
@@ -372,29 +331,32 @@ void InsetFormula::Read(LyXLex & lex)
 }
 
 
-int InsetFormula::ascent(Painter &, LyXFont const &) const
+int InsetFormula::ascent(BufferView *, LyXFont const &) const
 {
    return par->Ascent() + ((disp_flag) ? 8 : 1);
 }
 
 
-int InsetFormula::descent(Painter &, LyXFont const &) const
+int InsetFormula::descent(BufferView *, LyXFont const &) const
 {
    return par->Descent() + ((disp_flag) ? 8 : 1);
 }
 
 
-int InsetFormula::width(Painter &, 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(Painter & pain, LyXFont const & f,
-                       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());
@@ -416,20 +378,20 @@ void InsetFormula::draw(Painter & pain, LyXFont const & f,
        } 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;
@@ -438,11 +400,11 @@ void InsetFormula::draw(Painter & pain, LyXFont const & f,
                                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();
                        }
@@ -452,7 +414,7 @@ void InsetFormula::draw(Painter & pain, LyXFont const & f,
 }
 
 
-char const * InsetFormula::EditMessage() const 
+string const InsetFormula::EditMessage() const 
 {
        return _("Math editor mode");
 }
@@ -461,7 +423,8 @@ char const * InsetFormula::EditMessage() const
 void InsetFormula::Edit(BufferView * bv, int x, int y, unsigned int)
 {
     mathcursor = new MathedCursor(par);
-    bv->lockInset(this);
+    if (!bv->lockInset(this))
+        lyxerr[Debug::MATHED] << "Cannot lock inset!!!" << endl;
     par->Metrics();
     bv->updateInset(this, false);
     x += par->xo; 
@@ -487,27 +450,29 @@ void InsetFormula::InsetUnlock(BufferView * bv)
 
 
 // Now a symbol can be inserted only if the inset is locked
-void InsetFormula::InsertSymbol(BufferView * bv, char const * s)
+void InsetFormula::InsertSymbol(BufferView * bv, string const & s)
 { 
-   if (!s || !mathcursor) return;   
+   if (s.empty() || !mathcursor) return;   
    mathcursor->Interpret(s);
    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(BufferView * bv)
 {
   if (!mathcursor)
     return;
 
-  int x, y;
+  int x;
+  int y;
   mathcursor->GetPos(x, y);
 //  x -= par->xo; 
   y -= par->yo; 
@@ -523,11 +488,12 @@ void InsetFormula::ToggleInsetCursor(BufferView * bv)
 }
 
 
-void InsetFormula::ShowInsetCursor(BufferView * bv)
+void InsetFormula::ShowInsetCursor(BufferView * bv, bool)
 {
   if (!cursor_visible) {
     if (mathcursor) {
-      int x, y;
+      int x;
+      int y;
       mathcursor->GetPos(x, y);
       //  x -= par->xo; 
       y -= par->yo;
@@ -557,7 +523,7 @@ void InsetFormula::ToggleInsetSelection(BufferView * bv)
     //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;
 
@@ -573,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;
@@ -582,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;
@@ -591,48 +557,25 @@ 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;
 }
 
 
@@ -684,8 +627,7 @@ void InsetFormula::InsetMotionNotify(BufferView * bv,
        mathcursor->SelStart();
        ShowInsetCursor(bv); 
        mathcursor->GetPos(sel_x, sel_y);
-    } else
-      if (sel_flag) {
+    } else if (sel_flag) {
          HideInsetCursor(bv);
          x += par->xo;
          y += par->yo;
@@ -710,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);
@@ -745,41 +687,57 @@ InsetFormula::LocalDispatch(BufferView * bv,
     case LFUN_RIGHT:
       {
         result = DISPATCH_RESULT(mathcursor->Right(sel));
+        if (!sel && (result == DISPATCHED))
+            result = DISPATCHED_NOUPDATE;
         break;
       }
     case LFUN_LEFTSEL: sel = true;     
     case LFUN_LEFT:
       {
         result = DISPATCH_RESULT(mathcursor->Left(sel));
+        if (!sel && (result == DISPATCHED))
+            result = DISPATCHED_NOUPDATE;
         break;
       }
     case LFUN_UPSEL: sel = true;  
     case LFUN_UP:
       result = DISPATCH_RESULT(mathcursor->Up(sel));
+      if (!sel && (result == DISPATCHED))
+         result = DISPATCHED_NOUPDATE;
       break;
        
     case LFUN_DOWNSEL: sel = true;  
     case LFUN_DOWN:
       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);
-           bv->lockedInsetStoreUndo(Undo::DELETE);
+      bv->lockedInsetStoreUndo(Undo::DELETE);
       mathcursor->DelLine();
       UpdateLocal(bv);
       break;
     case LFUN_BREAKLINE:
+    {
       bv->lockedInsetStoreUndo(Undo::INSERT);
-      mathcursor->Insert(' ', LM_TC_CR);
+      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(bv);
       break;
+    }
     case LFUN_TAB:
       bv->lockedInsetStoreUndo(Undo::INSERT);
       mathcursor->Insert(0, LM_TC_TAB);
@@ -800,8 +758,7 @@ InsetFormula::LocalDispatch(BufferView * bv,
        }
       
     case LFUN_DELETE:
-           //current_view->lockedInsetStoreUndo(Undo::INSERT);
-           bv->lockedInsetStoreUndo(Undo::DELETE);
+      bv->lockedInsetStoreUndo(Undo::DELETE);
       mathcursor->Delete();       
       bv->updateInset(this, true);
       break;    
@@ -811,12 +768,11 @@ InsetFormula::LocalDispatch(BufferView * bv,
 //      break;
     case LFUN_SETXY:
       {
-        int x, y, x1, y1;
-#ifdef HAVE_SSTREAM
+        int x;
+        int y;
+        int x1;
+        int y1;
         istringstream ist(arg.c_str());
-#else
-        istrstream ist(arg.c_str());
-#endif
         ist >> x >> y;
         par->GetXY(x1, y1);
         mathcursor->SetPos(x1 + x, y1 + y);
@@ -876,12 +832,12 @@ InsetFormula::LocalDispatch(BufferView * bv,
     }  
    
       //  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;
@@ -895,11 +851,10 @@ InsetFormula::LocalDispatch(BufferView * bv,
       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();
             }
             bv->owner()->getMiniBuffer()->Set(_("No number"));  
          } else {
@@ -914,13 +869,18 @@ InsetFormula::LocalDispatch(BufferView * bv,
     
     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(bv);
+           UpdateLocal(bv);
        }
        break;
     }
@@ -934,7 +894,7 @@ InsetFormula::LocalDispatch(BufferView * bv,
  
     case LFUN_MATH_SIZE:
        if (!arg.empty()) {
-          latexkeys * l = in_word_set (arg.c_str(), strlen(arg.c_str()));
+          latexkeys * l = in_word_set (arg);
           int sz = (l) ? l->id: -1;
           mathcursor->SetSize(sz);
           UpdateLocal(bv);
@@ -944,7 +904,7 @@ InsetFormula::LocalDispatch(BufferView * bv,
     case LFUN_INSERT_MATH:
     {
        bv->lockedInsetStoreUndo(Undo::INSERT);
-       InsertSymbol(bv, arg.c_str());
+       InsertSymbol(bv, arg);
        break;
     }
     
@@ -984,29 +944,29 @@ InsetFormula::LocalDispatch(BufferView * bv,
        
        if (arg.empty())
               break;
-       strncpy(arg2, arg.c_str(), 40); arg2[39]= '\0';
+       ::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];
@@ -1032,34 +992,54 @@ InsetFormula::LocalDispatch(BufferView * bv,
     case LFUN_INSERT_LABEL:
     {
        bv->lockedInsetStoreUndo(Undo::INSERT);
-       if (par->GetType() < LM_OT_PAR) break;
-       string lb = arg;
-       if (lb.empty()) {
-         pair<bool, string>
-               result = askForText(_("Enter new label to insert:"));
-         if (result.first) {
-            lb = result.second;
-         }
+       if (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(bv);
-       } 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);
-           bv->lockedInsetStoreUndo(Undo::EDIT);
+      bv->lockedInsetStoreUndo(Undo::EDIT);
       display(!disp_flag);
       UpdateLocal(bv);
       break;
@@ -1082,7 +1062,7 @@ InsetFormula::LocalDispatch(BufferView * bv,
 
     //------- dummy actions
     case LFUN_EXEC_COMMAND:
-       bv->owner()->getMiniBuffer()->ExecCommand(); 
+       bv->owner()->getMiniBuffer()->PrepareForCommand(); 
        break;
        
     default:
@@ -1114,7 +1094,21 @@ InsetFormula::LocalDispatch(BufferView * bv,
            }
 
 //          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 
@@ -1177,7 +1171,7 @@ InsetFormula::LocalDispatch(BufferView * bv,
                    result = FINISHED;
              }
           } else
-          if (c == '\'') {
+          if (c == '\'' || c == '@') {
              mathcursor->Insert (c, LM_TC_VAR);
           } else
           if (c == '\\') {
@@ -1187,6 +1181,8 @@ InsetFormula::LocalDispatch(BufferView * bv,
               mathcursor->setLastCode(LM_TC_TEX);
           } 
         UpdateLocal(bv);
+      } else if (action == LFUN_MATH_PANEL) {
+        result = UNDISPATCHED;
       } else {
        // lyxerr << "Closed by action " << action << endl;
        result =  FINISHED;
@@ -1200,7 +1196,8 @@ InsetFormula::LocalDispatch(BufferView * bv,
    if (mathcursor->Selection() || was_selection)
        ToggleInsetSelection(bv);
     
-   if (result == DISPATCHED)
+   if ((result == DISPATCHED) || (result == DISPATCHED_NOUPDATE) ||
+       (result == UNDISPATCHED))
       ShowInsetCursor(bv);
    else
       bv->unlockInset(this);
@@ -1209,30 +1206,6 @@ InsetFormula::LocalDispatch(BufferView * bv,
 }
 
 
-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 += (lyxfont::width('I', font) + 3) / 4;
-               pain.text(x, y, name, font);
-       }
-}
-
-
-void MathFuncInset::Metrics() 
-{
-       ln = (name) ? strlen(name): 0;
-       LyXFont  font = WhichFont(LM_TC_TEXTRM, size);
-       font.setLatex(LyXFont::ON);
-       width = lyxfont::width(name, ln, font)
-               + lyxfont::width('I', font) / 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)
@@ -1241,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) {
@@ -1254,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;
                }
            }