]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/InsetMathNest.cpp
g-brief loads babel internally. So don't load it ourselves.
[lyx.git] / src / mathed / InsetMathNest.cpp
index 673a62d5754a920f448e331aaea7e2b8e7bc97d9..37bbd40008c490116b4e90e577858808702eab80 100644 (file)
 #include "InsetMathChar.h"
 #include "InsetMathColor.h"
 #include "InsetMathComment.h"
+#include "InsetMathDecoration.h"
 #include "InsetMathDelim.h"
 #include "InsetMathEnsureMath.h"
+#include "InsetMathFont.h"
 #include "InsetMathHull.h"
 #include "InsetMathRef.h"
 #include "InsetMathScript.h"
@@ -510,12 +512,297 @@ void InsetMathNest::handleNest(Cursor & cur, MathAtom const & nest,
 void InsetMathNest::handleFont2(Cursor & cur, docstring const & arg)
 {
        cur.recordUndoSelection();
+       bool include_previous_change = false;
+       bool selection = cur.selection();
+       DocIterator sel_begin = cur.selectionBegin();
+       DocIterator sel_end = cur.selectionEnd();
+       bool multiple_cells = sel_begin.idx() != sel_end.idx();
        Font font;
        bool b;
        font.fromString(to_utf8(arg), b);
+       docstring im;
+       InsetMathFont const * f = asFontInset();
+
+       switch(font.fontInfo().family()) {
+       case ROMAN_FAMILY:
+               if (!f || (f->name() != "textrm" && f->name() != "mathrm"))
+                       im = currentMode() != MATH_MODE ? from_ascii("textrm")
+                                                       : from_ascii("mathrm");
+               break;
+       case SANS_FAMILY:
+               if (!f || (f->name() != "textsf" && f->name() != "mathsf"))
+                       im = currentMode() != MATH_MODE ? from_ascii("textsf")
+                                                       : from_ascii("mathsf");
+               break;
+       case TYPEWRITER_FAMILY:
+               if (!f || (f->name() != "texttt" && f->name() != "mathtt"))
+                       im = currentMode() != MATH_MODE ? from_ascii("texttt")
+                                                       : from_ascii("mathtt");
+               break;
+       case SYMBOL_FAMILY:
+       case CMR_FAMILY:
+       case CMSY_FAMILY:
+       case CMM_FAMILY:
+       case CMEX_FAMILY:
+       case MSA_FAMILY:
+       case MSB_FAMILY:
+       case DS_FAMILY:
+       case EUFRAK_FAMILY:
+       case RSFS_FAMILY:
+       case STMARY_FAMILY:
+       case WASY_FAMILY:
+       case ESINT_FAMILY:
+       case INHERIT_FAMILY:
+       case IGNORE_FAMILY:
+               break;
+       }
+       if (!im.empty()) {
+               handleNest(cur, createInsetMath(im, cur.buffer()));
+               im.clear();
+               include_previous_change = true;
+       }
+
+       switch(font.fontInfo().series()) {
+       case MEDIUM_SERIES:
+               if (!f || (f->name() != "textmd" && f->name() != "mathrm"))
+                       im = currentMode() != MATH_MODE ? from_ascii("textmd")
+                                                       : from_ascii("mathrm");
+               break;
+       case BOLD_SERIES:
+               if (!f || (f->name() != "textbf" && f->name() != "mathbf"))
+                       im = currentMode() != MATH_MODE ? from_ascii("textbf")
+                                                       : from_ascii("boldsymbol");
+               break;
+       case INHERIT_SERIES:
+       case IGNORE_SERIES:
+               break;
+       }
+       if (!im.empty()) {
+               if (multiple_cells) {
+                       cur.setCursor(sel_begin);
+                       cur.idx() = 0;
+                       cur.pos() = 0;
+                       cur.resetAnchor();
+                       cur.setCursor(sel_end);
+                       cur.pos() = cur.lastpos();
+                       cur.setSelection();
+               } else if (include_previous_change && selection) {
+                       cur.setSelection();
+               }
+               handleNest(cur, createInsetMath(im, cur.buffer()));
+               im.clear();
+               include_previous_change = true;
+       }
+
+       switch(font.fontInfo().shape()) {
+       case UP_SHAPE:
+               if (!f || (f->name() != "textup" && f->name() != "mathrm"))
+                       im = currentMode() != MATH_MODE ? from_ascii("textup")
+                                                       : from_ascii("mathrm");
+               break;
+       case ITALIC_SHAPE:
+               if (!f || (f->name() != "textit" && f->name() != "mathit"))
+                       im = currentMode() != MATH_MODE ? from_ascii("textit")
+                                                       : from_ascii("mathit");
+               break;
+       case SLANTED_SHAPE:
+               if (!f || f->name() != "textsl")
+                       im = currentMode() != MATH_MODE ? from_ascii("textsl")
+                                                       : docstring();
+               break;
+       case SMALLCAPS_SHAPE:
+               if (!f || f->name() != "textsc")
+                       im = currentMode() != MATH_MODE ? from_ascii("textsc")
+                                                       : docstring();
+               break;
+       case INHERIT_SHAPE:
+       case IGNORE_SHAPE:
+               break;
+       }
+       if (!im.empty()) {
+               if (multiple_cells) {
+                       cur.setCursor(sel_begin);
+                       cur.idx() = 0;
+                       cur.pos() = 0;
+                       cur.resetAnchor();
+                       cur.setCursor(sel_end);
+                       cur.pos() = cur.lastpos();
+                       cur.setSelection();
+               } else if (include_previous_change && selection) {
+                       cur.setSelection();
+               }
+               handleNest(cur, createInsetMath(im, cur.buffer()));
+               im.clear();
+               include_previous_change = true;
+       }
+
+       switch(font.fontInfo().size()) {
+       case TINY_SIZE:
+               im = from_ascii("tiny");
+               break;
+       case SCRIPT_SIZE:
+               im = from_ascii("scriptsize");
+               break;
+       case FOOTNOTE_SIZE:
+               im = from_ascii("footnotesize");
+               break;
+       case SMALL_SIZE:
+               im = from_ascii("small");
+               break;
+       case NORMAL_SIZE:
+               im = from_ascii("normalsize");
+               break;
+       case LARGE_SIZE:
+               im = from_ascii("large");
+               break;
+       case LARGER_SIZE:
+               im = from_ascii("Large");
+               break;
+       case LARGEST_SIZE:
+               im = from_ascii("LARGE");
+               break;
+       case HUGE_SIZE:
+               im = from_ascii("huge");
+               break;
+       case HUGER_SIZE:
+               im = from_ascii("Huge");
+               break;
+       case INCREASE_SIZE:
+       case DECREASE_SIZE:
+       case INHERIT_SIZE:
+       case IGNORE_SIZE:
+               break;
+       }
+       if (!im.empty()) {
+               if (multiple_cells) {
+                       cur.setCursor(sel_begin);
+                       cur.idx() = 0;
+                       cur.pos() = 0;
+                       cur.resetAnchor();
+                       cur.setCursor(sel_end);
+                       cur.pos() = cur.lastpos();
+                       cur.setSelection();
+               } else if (include_previous_change && selection) {
+                       cur.setSelection();
+               }
+               handleNest(cur, createInsetMath(im, cur.buffer()));
+               im.clear();
+               include_previous_change = true;
+       }
+
+       InsetMathDecoration const * d = multiple_cells
+                                       ? nullptr : asDecorationInset();
+       docstring const name = d ? d->name() : docstring();
+
+       if ((font.fontInfo().underbar() == FONT_OFF && name == "uline") ||
+           (font.fontInfo().uuline() == FONT_OFF && name == "uuline") ||
+           (font.fontInfo().uwave() == FONT_OFF && name == "uwave")) {
+               if (include_previous_change) {
+                       if (!selection)
+                               cur.popForward();
+                       cur.setSelection();
+               }
+               docstring const beg = '\\' + name + '{';
+               docstring const end = from_ascii("}");
+               docstring const sel2 = cur.selectionAsString(false);
+               cutSelection(cur, false);
+               cur.pos() = 0;
+               cur.setSelection();
+               docstring const sel1 = cur.selectionAsString(false);
+               cur.pos() = cur.lastpos();
+               cur.setSelection();
+               docstring const sel3 = cur.selectionAsString(false);
+               cur.mathForward(false);
+               cur.setSelection();
+               cutSelection(cur, false);
+               MathData ar;
+               if (!sel1.empty()) {
+                       mathed_parse_cell(ar, beg + sel1 + end);
+                       cur.insert(ar);
+               }
+               cur.resetAnchor();
+               if (!sel2.empty()) {
+                       mathed_parse_cell(ar, sel2);
+                       cur.insert(ar);
+               }
+               if (!sel3.empty()) {
+                       pos_type pos = cur.pos();
+                       mathed_parse_cell(ar, beg + sel3 + end);
+                       cur.insert(ar);
+                       cur.pos() = pos;
+               }
+               cur.setSelection();
+               sel_begin = cur.selectionBegin();
+               sel_end = cur.selectionEnd();
+               include_previous_change = false;
+       }
+
+       if (font.fontInfo().underbar() == FONT_ON) {
+               if (!d || name != "uline")
+                       im = from_ascii("uline");
+       } else if (font.fontInfo().uuline() == FONT_ON) {
+               if (!d || name != "uuline")
+                       im = from_ascii("uuline");
+       } else if (font.fontInfo().uwave() == FONT_ON) {
+               if (!d || name != "uwave")
+                       im = from_ascii("uwave");
+       }
+
+       if (!im.empty()) {
+               if (multiple_cells) {
+                       cur.setCursor(sel_begin);
+                       cur.idx() = 0;
+                       cur.pos() = 0;
+                       cur.resetAnchor();
+                       cur.setCursor(sel_end);
+                       cur.pos() = cur.lastpos();
+                       cur.setSelection();
+               } else if (include_previous_change && selection) {
+                       cur.setSelection();
+               }
+               handleNest(cur, createInsetMath(im, cur.buffer()));
+               im.clear();
+               include_previous_change = true;
+       }
+
        if (font.fontInfo().color() != Color_inherit &&
-           font.fontInfo().color() != Color_ignore)
+           font.fontInfo().color() != Color_ignore) {
+               if (multiple_cells) {
+                       cur.setCursor(sel_begin);
+                       cur.idx() = 0;
+                       cur.pos() = 0;
+                       cur.resetAnchor();
+                       cur.setCursor(sel_end);
+                       cur.pos() = cur.lastpos();
+                       cur.setSelection();
+               } else if (include_previous_change && selection) {
+                       cur.setSelection();
+               }
                handleNest(cur, MathAtom(new InsetMathColor(buffer_, true, font.fontInfo().color())));
+               include_previous_change = true;
+       }
+
+       if (selection) {
+               if (multiple_cells) {
+                       cur.setCursor(sel_begin);
+                       cur.idx() = 0;
+                       cur.pos() = 0;
+                       cur.resetAnchor();
+                       cur.setCursor(sel_end);
+                       cur.pos() = cur.lastpos();
+                       cur.setSelection();
+               } else {
+                       if (include_previous_change) {
+                               sel_end = cur;
+                               cur.backwardInset();
+                       } else {
+                               cur.setCursor(sel_begin);
+                       }
+                       cur.resetAnchor();
+                       cur.setCursor(sel_end);
+                       cur.setSelection();
+               }
+       }
 
        // FIXME: support other font changes here as well?
 }
@@ -827,8 +1114,8 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                else if (!cur.inMacroMode())
                        cur.recordUndoSelection();
                // if the inset can not be removed from within, delete it
-               if (!cur.backspace(cmd.getArg(0) == "force")) {
-                       FuncRequest newcmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD, "force");
+               if (!cur.backspace(cmd.getArg(0) != "confirm")) {
+                       FuncRequest newcmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD);
                        cur.innerText()->dispatch(cur, newcmd);
                }
                break;
@@ -841,8 +1128,8 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                else
                        cur.recordUndoSelection();
                // if the inset can not be removed from within, delete it
-               if (!cur.erase(cmd.getArg(0) == "force")) {
-                       FuncRequest newcmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD, "force");
+               if (!cur.erase(cmd.getArg(0) != "confirm")) {
+                       FuncRequest newcmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD);
                        cur.innerText()->dispatch(cur, newcmd);
                }
                break;
@@ -860,6 +1147,8 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                }
                break;
 
+#if 0
+// FIXME: resurrect this later
        // 'Locks' the math inset. A 'locked' math inset behaves as a unit
        // that is traversed by a single <CursorLeft>/<CursorRight>.
        case LFUN_INSET_TOGGLE:
@@ -867,6 +1156,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                lock(!lock());
                cur.popForward();
                break;
+#endif
 
        case LFUN_SELF_INSERT:
                // special case first for big delimiters
@@ -1284,16 +1574,16 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                        cur.undispatched();
                break;
        }
-       case LFUN_INSET_DISSOLVE: {
-               bool const enabled = cur.inMathed()
-                       && (&cur.inset() != this || cur[cur.depth() - 1].inset().inMathed());
-               if (enabled) {
+       case LFUN_INSET_DISSOLVE:
+               if (cmd.argument().empty() && !asHullInset() && !asMacroTemplate()) {
+                       // we have been triggered via the AtPoint mechanism
+                       if (cur.nextInset() == this)
+                               cur.push(*this);
                        cur.recordUndoInset();
-                       // FIXME: this loses data
                        cur.pullArg();
                }
                break;
-       }
+
        case LFUN_MATH_LIMITS: {
                InsetMath * in = 0;
                if (cur.pos() < cur.lastpos() && cur.nextMath().allowsLimitsChange())
@@ -1472,8 +1762,7 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
 
        case LFUN_DIALOG_SHOW_NEW_INSET: {
                docstring const & name = cmd.argument();
-               if (name == "space")
-                       flag.setEnabled(false);
+               flag.setEnabled(name == "ref" || name == "mathspace");
                break;
        }
 
@@ -1498,7 +1787,29 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
                flag.setEnabled(false);
                break;
 
+       // these are nonfunctional in math
+       case LFUN_BOX_INSERT:
+       case LFUN_BRANCH_INSERT:
+       case LFUN_BRANCH_ADD_INSERT:
        case LFUN_CAPTION_INSERT:
+       case LFUN_FLEX_INSERT:
+       case LFUN_FLOAT_INSERT:
+       case LFUN_FLOAT_LIST_INSERT:
+       case LFUN_FOOTNOTE_INSERT:
+       case LFUN_HREF_INSERT:
+       case LFUN_INDEX_INSERT:
+       case LFUN_INDEX_PRINT:
+       case LFUN_INFO_INSERT:
+       case LFUN_IPA_INSERT:
+       case LFUN_LISTING_INSERT:
+       case LFUN_MARGINALNOTE_INSERT:
+       case LFUN_NEWPAGE_INSERT:
+       case LFUN_NOMENCL_INSERT:
+       case LFUN_NOMENCL_PRINT:
+       case LFUN_NOTE_INSERT:
+       case LFUN_PREVIEW_INSERT:
+       case LFUN_TABULAR_INSERT:
+       case LFUN_WRAP_INSERT:
                flag.setEnabled(false);
                break;
 
@@ -1509,13 +1820,10 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
                break;
        }
 
-       case LFUN_INSET_DISSOLVE: {
-               // Do not dissolve a math inset which is in text
-               bool const enabled = cur.inMathed()
-                       && (&cur.inset() != this || cur[cur.depth() - 1].inset().inMathed());
-               flag.setEnabled(enabled);
+       case LFUN_INSET_DISSOLVE:
+               flag.setEnabled(cmd.argument().empty() && !asHullInset() && !asMacroTemplate());
                break;
-       }
+
        case LFUN_PASTE: {
                docstring const & name = cmd.argument();
                if (name == "html" || name == "latex")
@@ -2123,6 +2431,7 @@ bool InsetMathNest::insertCompletion(Cursor & cur, docstring const & s, bool fin
 #endif
                lyx::dispatch(FuncRequest(LFUN_SELF_INSERT, " "));
        }
+       cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
 
        return true;
 }