]> git.lyx.org Git - lyx.git/blobdiff - src/Text3.cpp
Allow using \binom without amsmath and add support for \brace and \brack
[lyx.git] / src / Text3.cpp
index ca96a4e648baa514b97b157fa5391517e2d71c05..17b86373236de81b595e899cc200599cb1a34502 100644 (file)
@@ -658,36 +658,24 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
-       case LFUN_NEW_LINE: {
-               // Not allowed by LaTeX (labels or empty par)
-               if (cur.pos() > cur.paragraph().beginOfBody()) {
-                       // this avoids a double undo
-                       // FIXME: should not be needed, ideally
-                       if (!cur.selection())
-                               cur.recordUndo();
-                       cap::replaceSelection(cur);
-                       cur.insert(new InsetNewline);
-                       cur.posForward();
-                       moveCursor(cur, false);
-               }
+       case LFUN_NEWLINE_INSERT: {
+               InsetNewlineParams inp;
+               docstring arg = cmd.argument();
+               // this avoids a double undo
+               // FIXME: should not be needed, ideally
+               if (!cur.selection())
+                       cur.recordUndo();
+               cap::replaceSelection(cur);
+               if (arg == "linebreak")
+                       inp.kind = InsetNewlineParams::LINEBREAK;
+               else
+                       inp.kind = InsetNewlineParams::NEWLINE;
+               cur.insert(new InsetNewline(inp));
+               cur.posForward();
+               moveCursor(cur, false);
                break;
        }
        
-       case LFUN_LINE_BREAK: {
-               // Not allowed by LaTeX (labels or empty par)
-               if (cur.pos() > cur.paragraph().beginOfBody()) {
-                       // this avoids a double undo
-                       // FIXME: should not be needed, ideally
-                       if (!cur.selection())
-                               cur.recordUndo();
-                       cap::replaceSelection(cur);
-                       cur.insert(new InsetLinebreak);
-                       cur.posForward();
-                       moveCursor(cur, false);
-               }
-               break;
-       }
-
        case LFUN_CHAR_DELETE_FORWARD:
                if (!cur.selection()) {
                        if (cur.pos() == cur.paragraph().size())
@@ -847,9 +835,17 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                needsUpdate |= dissolveInset(cur);
                break;
 
-       case LFUN_INSET_SETTINGS:
+       case LFUN_INSET_SETTINGS: {
+               // if there is an inset at cursor, access this
+               Inset * inset = cur.nextInset();
+               if (inset) {
+                       inset->showInsetDialog(bv);
+                       break;
+               }
+               // if not work, access the underlying inset.
                cur.inset().showInsetDialog(bv);
                break;
+       }
 
        case LFUN_SPACE_INSERT:
                if (cur.paragraph().layout().free_spacing)
@@ -1090,14 +1086,9 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        else
                                c = par.getChar(pos - 1);
                        string arg = to_utf8(cmd.argument());
-                       if (arg == "single")
-                               cur.insert(new InsetQuotes(c,
-                                   bufparams.quotes_language,
-                                   InsetQuotes::SingleQ));
-                       else
-                               cur.insert(new InsetQuotes(c,
-                                   bufparams.quotes_language,
-                                   InsetQuotes::DoubleQ));
+                       cur.insert(new InsetQuotes(c, bufparams.quotes_language,
+                               (arg == "single") ? InsetQuotes::SingleQuotes
+                                       : InsetQuotes::DoubleQuotes));
                        cur.posForward();
                }
                else
@@ -1131,51 +1122,65 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
 
        // Single-click on work area
-       case LFUN_MOUSE_PRESS: {
-               // Right click on a footnote flag opens float menu
-               // FIXME: Why should we clear the selection in this case?
-               if (cmd.button() == mouse_button::button3)
-                       cur.clearSelection();
-
-               bool do_selection = cmd.button() == mouse_button::button1
-                       && cmd.argument() == "region-select";
-               // Set the cursor
-               bool update = bv->mouseSetCursor(cur, do_selection);
-
-               // Insert primary selection with middle mouse
-               // if there is a local selection in the current buffer,
-               // insert this
-               if (cmd.button() == mouse_button::button2) {
-                       if (cap::selection()) {
-                               // Copy the selection buffer to the clipboard
-                               // stack, because we want it to appear in the
-                               // "Edit->Paste recent" menu.
-                               cap::copySelectionToStack();
-
-                               cap::pasteSelection(bv->cursor(), 
-                                                   bv->buffer().errorList("Paste"));
-                               bv->buffer().errors("Paste");
-                               bv->buffer().markDirty();
-                               bv->cursor().finishUndo();
-                       } else {
-                               lyx::dispatch(FuncRequest(LFUN_PRIMARY_SELECTION_PASTE, "paragraph"));
+       case LFUN_MOUSE_PRESS:
+               // We are not marking a selection with the keyboard in any case.
+               cur.bv().cursor().mark() = false;
+               switch (cmd.button()) {
+               case mouse_button::button1:
+                       // Set the cursor
+                       if (!bv->mouseSetCursor(cur, cmd.argument() == "region-select"))
+                               cur.updateFlags(Update::SinglePar | Update::FitCursor);
+                       break;                  
+
+               case mouse_button::button2:
+                       // Middle mouse pasting.
+                       if (!cap::selection()) {                        
+                               // There is no local selection in the current buffer, so try to
+                               // paste primary selection instead.
+                               lyx::dispatch(FuncRequest(LFUN_PRIMARY_SELECTION_PASTE,
+                                       "paragraph"));
+                               // Nothing else to do.
+                               cur.noUpdate();
+                               return;
                        }
-               }
-
-               // we have to update after dEPM triggered
-               if (!update && cmd.button() == mouse_button::button1) {
-                       needsUpdate = false;
-                       cur.noUpdate();
-               }
+                       // Copy the selection buffer to the clipboard stack, because we want it
+                       // to appear in the "Edit->Paste recent" menu.
+                       cap::copySelectionToStack();
+                       cap::pasteSelection(bv->cursor(), bv->buffer().errorList("Paste"));
+                       cur.updateFlags(Update::Force | Update::FitCursor);
+                       bv->buffer().errors("Paste");
+                       bv->buffer().markDirty();
+                       bv->cursor().finishUndo();
+                       break;
 
+               case mouse_button::button3:
+                       if (cur.selection()) {
+                               DocIterator const selbeg = cur.selectionBegin();
+                               DocIterator const selend = cur.selectionEnd();
+                               Cursor tmpcur = cur;
+                               tm.setCursorFromCoordinates(tmpcur, cmd.x, cmd.y);
+                               // Don't do anything if we right-click a selection, a selection
+                               // context menu should popup instead.
+                               if (tmpcur < selbeg || tmpcur >= selend) {
+                                       cur.noUpdate();
+                                       return;
+                               }
+                       }
+                       if (!bv->mouseSetCursor(cur, false)) {
+                               cur.updateFlags(Update::SinglePar | Update::FitCursor);
+                               break;                  
+                       }
+               default:
+                       break;
+               } // switch (cmd.button())
                break;
-       }
 
        case LFUN_MOUSE_MOTION: {
-               // Only use motion with button 1
-               //if (cmd.button() != mouse_button::button1)
-               //      return false;
-
+               // Mouse motion with right or middle mouse do nothing for now.
+               if (cmd.button() != mouse_button::button1) {
+                       cur.noUpdate();
+                       return;
+               }
                // ignore motions deeper nested than the real anchor
                Cursor & bvcur = cur.bv().cursor();
                if (!bvcur.anchor_.hasPart(cur)) {
@@ -1200,42 +1205,52 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        else if (cmd.y < 0)
                                lyx::dispatch(FuncRequest(LFUN_UP_SELECT));
                }
-
-               if (cur.top() == old)
-                       cur.noUpdate();
-               else {
-                       // FIXME: This is brute force! But without it the selected
-                       // area is not corrected updated while moving the mouse.
-                       cur.updateFlags(Update::Force | Update::FitCursor);
-                       // don't set anchor_
-                       bvcur.setCursor(cur);
-                       bvcur.selection() = true;
-                       //lyxerr << "MOTION: " << bv->cursor() << endl;
+               // We continue with our existing selection or start a new one, so don't
+               // reset the anchor.
+               bvcur.setCursor(cur);
+               bvcur.selection() = true;
+               if (cur.top() == old) {
+                       // We didn't move one iota, so no need to update the screen.
+                       cur.updateFlags(Update::SinglePar | Update::FitCursor);
+                       //cur.noUpdate();
+                       return;
                }
                break;
        }
 
-       case LFUN_MOUSE_RELEASE: {
-               if (cmd.button() == mouse_button::button2)
-                       break;
-
-               if (cmd.button() == mouse_button::button1) {
-                       // if there is new selection, update persistent
-                       // selection, otherwise, single click does not
-                       // clear persistent selection buffer
+       case LFUN_MOUSE_RELEASE:
+               switch (cmd.button()) {
+               case mouse_button::button1:
+                       // Cursor was set at LFUN_MOUSE_PRESS or LFUN_MOUSE_MOTION time.
+                       // If there is a new selection, update persistent selection;
+                       // otherwise, single click does not clear persistent selection
+                       // buffer.
                        if (cur.selection()) {
-                               // finish selection
-                               // if double click, cur is moved to the end of word by selectWord
-                               // but bvcur is current mouse position
-                               Cursor & bvcur = cur.bv().cursor();
-                               bvcur.selection() = true;
+                               // Finish selection.
+                               // If double click, cur is moved to the end of word by selectWord
+                               // but bvcur is current mouse position.
+                               cur.bv().cursor().selection() = true;
                        }
-                       needsUpdate = false;
+                       // FIXME: We could try to handle drag and drop of selection here.
                        cur.noUpdate();
-               }
+                       return;
+
+               case mouse_button::button2:
+                       // Middle mouse pasting is handled at mouse press time,
+                       // see LFUN_MOUSE_PRESS.
+                       cur.noUpdate();
+                       return;
+
+               case mouse_button::button3:
+                       // Cursor was set at LFUN_MOUSE_PRESS time.
+                       // FIXME: If there is a selection we could try to handle a special
+                       // drag & drop context menu.
+                       cur.noUpdate();
+                       return;
+
+               } // switch (cmd.button())
 
                break;
-       }
 
        case LFUN_SELF_INSERT: {
                if (cmd.argument().empty())
@@ -1272,7 +1287,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                }
                p["target"] = (cmd.argument().empty()) ?
                        content : cmd.argument();
-               string const data = InsetCommandMailer::params2string("href", p);
+               string const data = InsetCommand::params2string("href", p);
                if (p["target"].empty()) {
                        bv->showDialog("href", data);
                } else {
@@ -1288,7 +1303,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                p["name"] = (cmd.argument().empty()) ?
                        cur.getPossibleLabel() :
                        cmd.argument();
-               string const data = InsetCommandMailer::params2string("label", p);
+               string const data = InsetCommand::params2string("label", p);
 
                if (cmd.argument().empty()) {
                        bv->showDialog("label", data);
@@ -1413,12 +1428,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_INDEX_PRINT:
        case LFUN_NOMENCL_PRINT:
        case LFUN_TOC_INSERT:
-       case LFUN_HFILL_INSERT:
        case LFUN_LINE_INSERT:
        case LFUN_NEWPAGE_INSERT:
-       case LFUN_PAGEBREAK_INSERT:
-       case LFUN_CLEARPAGE_INSERT:
-       case LFUN_CLEARDOUBLEPAGE_INSERT:
                // do nothing fancy
                doInsertInset(cur, this, cmd, false, false);
                cur.posForward();
@@ -1662,11 +1673,17 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                                breakParagraph(cur);
                        }
 
-                       //FIXME Check if this should be emptyLayout()
-                       setLayout(cur, tclass.defaultLayoutName());
+                       docstring const laystr = cur.inset().useEmptyLayout() ?
+                               tclass.emptyLayoutName() :
+                               tclass.defaultLayoutName();
+                       setLayout(cur, laystr);
                        ParagraphParameters p;
                        setParagraphs(cur, p);
-                       insertInset(cur, new InsetFloatList(to_utf8(cmd.argument())));
+                       // FIXME This should be simplified when InsetFloatList takes a 
+                       // Buffer in its constructor.
+                       InsetFloatList * ifl = new InsetFloatList(to_utf8(cmd.argument()));
+                       ifl->setBuffer(bv->buffer());
+                       insertInset(cur, ifl);
                        cur.posForward();
                } else {
                        lyxerr << "Non-existent float type: "
@@ -1869,6 +1886,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                        code = NOTE_CODE;
                else if (cmd.argument() == "ref")
                        code = REF_CODE;
+               else if (cmd.argument() == "space")
+                       code = SPACE_CODE;
                else if (cmd.argument() == "toc")
                        code = TOC_CODE;
                else if (cmd.argument() == "vspace")
@@ -1883,7 +1902,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                code = ERT_CODE;
                break;
        case LFUN_LISTING_INSERT:
-           code = LISTINGS_CODE;
+               code = LISTINGS_CODE;
                break;
        case LFUN_FOOTNOTE_INSERT:
                code = FOOT_CODE;
@@ -1914,6 +1933,9 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                break;
        case LFUN_NOTE_INSERT:
                code = NOTE_CODE;
+               // in commands (sections etc., only Notes are allowed)
+               enable = (cmd.argument().empty() || cmd.getArg(0) == "Note" ||
+                         !cur.paragraph().layout().isCommand());
                break;
        case LFUN_FLEX_INSERT: {
                code = FLEX_CODE;
@@ -1971,7 +1993,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                // always allow this, since we will inset a raw quote
                // if an inset is not allowed.
                break;
-       case LFUN_HFILL_INSERT:
        case LFUN_SPECIALCHAR_INSERT:
                code = SPECIALCHAR_CODE;
                break;
@@ -2095,6 +2116,11 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                enable = (cur.paragraph().layout().toclevel != Layout::NOT_IN_TOC);
                break;
 
+       case LFUN_NEWLINE_INSERT:
+               // LaTeX restrictions (labels or empty par)
+               enable = (cur.pos() > cur.paragraph().beginOfBody());
+               break;
+
        case LFUN_WORD_DELETE_FORWARD:
        case LFUN_WORD_DELETE_BACKWARD:
        case LFUN_LINE_DELETE:
@@ -2126,9 +2152,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_PARAGRAPH_UP:
        case LFUN_PARAGRAPH_DOWN:
        case LFUN_LINE_BEGIN:
-       case LFUN_LINE_BREAK:
        case LFUN_LINE_END:
-       case LFUN_NEW_LINE:
        case LFUN_CHAR_DELETE_FORWARD:
        case LFUN_DELETE_FORWARD_SKIP:
        case LFUN_CHAR_DELETE_BACKWARD:
@@ -2150,9 +2174,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_SELF_INSERT:
        case LFUN_LINE_INSERT:
        case LFUN_NEWPAGE_INSERT:
-       case LFUN_PAGEBREAK_INSERT:
-       case LFUN_CLEARPAGE_INSERT:
-       case LFUN_CLEARDOUBLEPAGE_INSERT:
        case LFUN_MATH_DISPLAY:
        case LFUN_MATH_IMPORT_SELECTION:
        case LFUN_MATH_MODE: