]> git.lyx.org Git - lyx.git/blobdiff - src/text3.C
Fix bug 2485 and crash on middle mouse paste on math
[lyx.git] / src / text3.C
index 65e803f4d2876a557c945ddf97a2037ea123080f..fadfb888f581d3f96d65f0c6b273c430529dae69 100644 (file)
@@ -81,6 +81,7 @@ using lyx::support::token;
 using std::endl;
 using std::string;
 using std::istringstream;
+using std::ostringstream;
 
 
 extern string current_layout;
@@ -135,6 +136,9 @@ namespace {
                string sel = cur.selectionAsString(false);
                //lyxerr << "selection is: '" << sel << "'" << endl;
 
+               // It may happen that sel is empty but there is a selection
+               replaceSelection(cur);
+
                if (sel.empty()) {
                        const int old_pos = cur.pos();
                        cur.insert(new MathHullInset("simple"));
@@ -150,22 +154,26 @@ namespace {
                        // is empty
                        if (!cmd.argument.empty())
                                cur.dispatch(FuncRequest(LFUN_INSERT_MATH,
-                                                        cmd.argument));
+                                                        cmd.argument));
                } else {
                        // create a macro if we see "\\newcommand"
                        // somewhere, and an ordinary formula
                        // otherwise
-                       cutSelection(cur, true, true);
+                       istringstream is(sel);
                        if (sel.find("\\newcommand") == string::npos
                            && sel.find("\\def") == string::npos)
                        {
-                               cur.insert(new MathHullInset("simple"));
-                               cur.dispatch(FuncRequest(LFUN_RIGHT));
-                               cur.dispatch(FuncRequest(LFUN_INSERT_MATH, sel));
-                       } else {
-                               istringstream is(sel);
+                               MathHullInset * formula = new MathHullInset;
+                               LyXLex lex(0, 0);
+                               lex.setStream(is);
+                               formula->read(cur.buffer(), lex);
+                               if (formula->getType() == "none")
+                                       // Don't create pseudo formulas if
+                                       // delimiters are left out
+                                       formula->mutate("simple");
+                               cur.insert(formula);
+                       } else
                                cur.insert(new MathMacroTemplate(is));
-                       }
                }
                cur.message(N_("Math editor mode"));
        }
@@ -306,10 +314,10 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
        bool singleParUpdate = lyxaction.funcHasFlag(cmd.action,
                LyXAction::SingleParUpdate);
        // Signals that a full-screen update is required
-       bool needsUpdate = !(lyxaction.funcHasFlag(cmd.action, 
+       bool needsUpdate = !(lyxaction.funcHasFlag(cmd.action,
                LyXAction::NoUpdate) || singleParUpdate);
-       // Remember the old paragraph metric
-       Dimension olddim = cur.paragraph().dim();
+       // Remember the old paragraph metric (_outer_ paragraph!)
+       Dimension olddim = cur.bottom().paragraph().dim();
 
        switch (cmd.action) {
 
@@ -380,7 +388,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                if (cur.depth() == 1) {
                        if (!cur.mark())
                                cur.clearSelection();
-                       cursorTop(cur);
+                       needsUpdate = cursorTop(cur);
                        finishChange(cur, false);
                } else {
                        cur.undispatched();
@@ -391,7 +399,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                if (cur.depth() == 1) {
                        if (!cur.selection())
                                cur.resetAnchor();
-                       cursorTop(cur);
+                       needsUpdate = cursorTop(cur);
                        finishChange(cur, true);
                } else {
                        cur.undispatched();
@@ -402,7 +410,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                if (cur.depth() == 1) {
                        if (!cur.mark())
                                cur.clearSelection();
-                       cursorBottom(cur);
+                       needsUpdate = cursorBottom(cur);
                        finishChange(cur, false);
                } else {
                        cur.undispatched();
@@ -413,7 +421,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                if (cur.depth() == 1) {
                        if (!cur.selection())
                                cur.resetAnchor();
-                       cursorBottom(cur);
+                       needsUpdate = cursorBottom(cur);
                        finishChange(cur, true);
                } else {
                        cur.undispatched();
@@ -513,7 +521,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                update(cur);
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorPrevious(cur);
+               needsUpdate = cursorPrevious(cur);
                finishChange(cur, true);
                break;
 
@@ -521,7 +529,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                update(cur);
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorNext(cur);
+               needsUpdate = cursorNext(cur);
                finishChange(cur, true);
                break;
 
@@ -529,7 +537,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                update(cur);
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorHome(cur);
+               needsUpdate = cursorHome(cur);
                finishChange(cur, true);
                break;
 
@@ -537,7 +545,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                update(cur);
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorEnd(cur);
+               needsUpdate = cursorEnd(cur);
                finishChange(cur, true);
                break;
 
@@ -597,14 +605,14 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
        case LFUN_HOME:
                if (!cur.mark())
                        cur.clearSelection();
-               cursorHome(cur);
+               needsUpdate = cursorHome(cur);
                finishChange(cur, false);
                break;
 
        case LFUN_END:
                if (!cur.mark())
                        cur.clearSelection();
-               cursorEnd(cur);
+               needsUpdate = cursorEnd(cur);
                finishChange(cur, false);
                break;
 
@@ -621,12 +629,16 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
 
        case LFUN_DELETE:
                if (!cur.selection()) {
-                       Delete(cur);
+                       if (cur.pos() == cur.paragraph().size())
+                               // Par boundary, force full-screen update
+                               singleParUpdate = false;
+                       needsUpdate = erase(cur);
                        cur.resetAnchor();
                        // It is possible to make it a lot faster still
                        // just comment out the line below...
                } else {
                        cutSelection(cur, true, false);
+                       singleParUpdate = false;
                }
                moveCursor(cur, false);
                break;
@@ -638,7 +650,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                                cursorRight(cur);
                                cursorLeft(cur);
                        }
-                       Delete(cur);
+                       erase(cur);
                        cur.resetAnchor();
                } else {
                        cutSelection(cur, true, false);
@@ -649,13 +661,17 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
        case LFUN_BACKSPACE:
                if (!cur.selection()) {
                        if (bv->owner()->getIntl().getTransManager().backspace()) {
-                               backspace(cur);
+                               // Par boundary, full-screen update
+                               if (cur.pos() == 0)
+                                       singleParUpdate = false;
+                               needsUpdate = backspace(cur);
                                cur.resetAnchor();
                                // It is possible to make it a lot faster still
                                // just comment out the line below...
                        }
                } else {
                        cutSelection(cur, true, false);
+                       singleParUpdate = false;
                }
                bv->switchKeyMap();
                break;
@@ -825,9 +841,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
        case LFUN_PASTE:
                cur.message(_("Paste"));
                lyx::cap::replaceSelection(cur);
-#ifdef WITH_WARNINGS
-#warning FIXME Check if the arg is in the domain of available selections.
-#endif
                if (isStrUnsignedInt(cmd.argument))
                        pasteSelection(cur, convert<unsigned int>(cmd.argument));
                else
@@ -849,7 +862,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
 
        case LFUN_GETXY:
                cur.message(convert<string>(cursorX(cur.top(), cur.boundary())) + ' '
-                         + convert<string>(cursorY(cur.top(), cur.boundary())));
+                         + convert<string>(cursorY(cur.top(), cur.boundary())));
                break;
 
        case LFUN_SETXY: {
@@ -953,7 +966,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                lyx::cap::replaceSelection(cur);
                Paragraph & par = cur.paragraph();
                lyx::pos_type pos = cur.pos();
-               char c;
+               lyx::char_type c;
                if (pos == 0)
                        c = ' ';
                else if (cur.prevInset() && cur.prevInset()->isSpace())
@@ -982,7 +995,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                break;
        }
 
-       case LFUN_DATE_INSERT: 
+       case LFUN_DATE_INSERT:
                if (cmd.argument.empty())
                        bv->owner()->dispatch(FuncRequest(LFUN_SELFINSERT,
                                lyx::formatted_time(lyx::current_time())));
@@ -1028,20 +1041,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                        paste_internally = true;
                }
 
-               // Clear the selection
-               cur.clearSelection();
-
-               setCursorFromCoordinates(cur, cmd.x, cmd.y);
-               cur.resetAnchor();
-               finishUndo();
-               cur.setTargetX();
-
-               // Has the cursor just left the inset?
-               if (bv->cursor().inMathed() && !cur.inMathed())
-                       bv->cursor().inset().notifyCursorLeaves(bv->cursor());
-
-               // Set cursor here.
-               bv->cursor() = cur;
+               bv->mouseSetCursor(cur);
 
                // Insert primary selection with middle mouse
                // if there is a local selection in the current buffer,
@@ -1108,6 +1108,21 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                bv->switchKeyMap();
                bv->owner()->updateMenubar();
                bv->owner()->updateToolbars();
+
+               // if view-source dialog is visible, send source code of selected
+               // text to the dialog
+               if (cmd.button() == mouse_button::button1 && cur.selection() 
+                       && bv->owner()->getDialogs().visible("view-source")) {
+                       // get *top* level paragraphs that contain the selection
+                       lyx::pit_type par_begin = bv->cursor().selectionBegin().bottom().pit();
+                       lyx::pit_type par_end = bv->cursor().selectionEnd().bottom().pit();
+                       if (par_begin > par_end)
+                               std::swap(par_begin, par_end);
+                       ostringstream ostr;
+                       bv->buffer()->getSourceCode(ostr, par_begin, par_end + 1);
+                       // display the dialog and show source code
+                       bv->owner()->getDialogs().update("view-source", ostr.str());
+               }
                break;
        }
 
@@ -1130,17 +1145,11 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                cur.clearSelection();
                LyXFont const old_font = real_current_font;
 
-               // Prevents language turds in new lyxtexts under non-english
-               BufferParams const & bufparams = cur.buffer().params();
-               Language const * lang = cur.paragraph().getParLanguage(bufparams);
-               current_font.setLanguage(lang);
-               real_current_font.setLanguage(lang);
-
                string::const_iterator cit = cmd.argument.begin();
                string::const_iterator end = cmd.argument.end();
                for (; cit != end; ++cit)
                        bv->owner()->getIntl().getTransManager().
-                               TranslateAndInsert(*cit, this);
+                               translateAndInsert(*cit, this);
 
                cur.resetAnchor();
                moveCursor(cur, false);
@@ -1448,7 +1457,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                bv->owner()->getLyXFunc().handleKeyFunc(cmd.action);
                if (!cmd.argument.empty())
                        bv->owner()->getIntl().getTransManager()
-                               .TranslateAndInsert(cmd.argument[0], this);
+                               .translateAndInsert(cmd.argument[0], this);
                break;
 
        case LFUN_FLOAT_LIST: {
@@ -1537,9 +1546,9 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                break;
 
        default:
-               lyxerr[Debug::ACTION] 
+               lyxerr[Debug::ACTION]
                        << BOOST_CURRENT_FUNCTION
-                       << ": Command " << cmd 
+                       << ": Command " << cmd
                        << " not DISPATCHED by LyXText" << endl;
                cur.undispatched();
                break;
@@ -1547,10 +1556,14 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
 
        if (singleParUpdate)
                // Inserting characters does not change par height
-               if (cur.paragraph().dim().asc == olddim.asc
-                && cur.paragraph().dim().des == olddim.des) {
+               if (cur.bottom().paragraph().dim().height()
+                   == olddim.height()) {
                        // if so, update _only_ this paragraph
-                       cur.bv().update(Update::SinglePar | Update::Force);
+                       cur.bv().update(Update::SinglePar |
+                                       Update::FitCursor |
+                                       Update::MultiParSel);
+                       cur.noUpdate();
+                       return;
                } else
                        needsUpdate = true;
        if (!needsUpdate