X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FText3.cpp;h=41a3fedf6779da8fb0dc797580dbbe3b69bb2cfe;hb=12c7e7dde3851ad894380fd42ba741dd3d0cbcc7;hp=4fd8e84290d9f07d66bbd34622d4e5560790621c;hpb=f68fcc98a9b56e2e01471c335bab8e8afa372e5d;p=lyx.git diff --git a/src/Text3.cpp b/src/Text3.cpp index 4fd8e84290..41a3fedf67 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -37,7 +37,7 @@ #include "Language.h" #include "Layout.h" #include "LyXAction.h" -#include "LyXFunc.h" +#include "LyX.h" #include "Lexer.h" #include "LyXRC.h" #include "Paragraph.h" @@ -198,9 +198,9 @@ static void mathDispatch(Cursor & cur, FuncRequest const & cmd, bool display) void regexpDispatch(Cursor & cur, FuncRequest const & cmd) { - BOOST_ASSERT(cmd.action == LFUN_REGEXP_MODE); + LASSERT(cmd.action() == LFUN_REGEXP_MODE, return); if (cur.inRegexped()) { - cur.message(_("Already in regexp mode")); + cur.message(_("Already in regular expression mode")); return; } cur.recordUndo(); @@ -239,7 +239,7 @@ static bool doInsertInset(Cursor & cur, Text * text, ci->setButtonLabel(); cur.recordUndo(); - if (cmd.action == LFUN_INDEX_INSERT) { + if (cmd.action() == LFUN_INDEX_INSERT) { docstring ds = subst(text->getStringToIndex(cur), '\n', ' '); text->insertInset(cur, inset); if (edit) @@ -268,10 +268,10 @@ static bool doInsertInset(Cursor & cur, Text * text, cur.buffer()->errors("Paste"); cur.clearSelection(); // bug 393 cur.finishUndo(); - InsetText * insetText = dynamic_cast(inset); - if (insetText) { - insetText->fixParagraphsFont(); - if (!insetText->allowMultiPar() || cur.lastpit() == 0) { + InsetText * inset_text = inset->asInsetText(); + if (inset_text) { + inset_text->fixParagraphsFont(); + if (!inset_text->allowMultiPar() || cur.lastpit() == 0) { // reset first par to default cur.text()->paragraphs().begin() ->setPlainOrDefaultLayout(bparams.documentClass()); @@ -464,7 +464,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) // FIXME: We use the update flag to indicates wether a singlePar or a // full screen update is needed. We reset it here but shall we restore it // at the end? - cur.noUpdate(); + cur.noScreenUpdate(); LASSERT(cur.text() == this, /**/); CursorSlice oldTopSlice = cur.top(); @@ -472,21 +472,22 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) bool sel = cur.selection(); // Signals that, even if needsUpdate == false, an update of the // cursor paragraph is required - bool singleParUpdate = lyxaction.funcHasFlag(cmd.action, + 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); - switch (cmd.action) { + FuncCode const act = cmd.action(); + switch (act) { case LFUN_PARAGRAPH_MOVE_DOWN: { pit_type const pit = cur.pit(); recUndo(cur, pit, pit + 1); cur.finishUndo(); pars_.swap(pit, pit + 1); - cur.buffer()->updateLabels(); needsUpdate = true; + cur.forceBufferUpdate(); ++cur.pit(); break; } @@ -496,9 +497,9 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) recUndo(cur, pit - 1, pit); cur.finishUndo(); pars_.swap(pit, pit - 1); - cur.buffer()->updateLabels(); --cur.pit(); needsUpdate = true; + cur.forceBufferUpdate(); break; } @@ -522,7 +523,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) par.params().startOfAppendix(start); // we can set the refreshing parameters now - cur.buffer()->updateLabels(); + cur.forceBufferUpdate(); break; } @@ -552,42 +553,42 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_BUFFER_BEGIN: case LFUN_BUFFER_BEGIN_SELECT: - needsUpdate |= cur.selHandle(cmd.action == LFUN_BUFFER_BEGIN_SELECT); + needsUpdate |= cur.selHandle(act == LFUN_BUFFER_BEGIN_SELECT); if (cur.depth() == 1) needsUpdate |= cursorTop(cur); else cur.undispatched(); - cur.updateFlags(Update::FitCursor); + cur.screenUpdateFlags(Update::FitCursor); break; case LFUN_BUFFER_END: case LFUN_BUFFER_END_SELECT: - needsUpdate |= cur.selHandle(cmd.action == LFUN_BUFFER_END_SELECT); + needsUpdate |= cur.selHandle(act == LFUN_BUFFER_END_SELECT); if (cur.depth() == 1) needsUpdate |= cursorBottom(cur); else cur.undispatched(); - cur.updateFlags(Update::FitCursor); + cur.screenUpdateFlags(Update::FitCursor); break; case LFUN_INSET_BEGIN: case LFUN_INSET_BEGIN_SELECT: - needsUpdate |= cur.selHandle(cmd.action == LFUN_INSET_BEGIN_SELECT); + needsUpdate |= cur.selHandle(act == LFUN_INSET_BEGIN_SELECT); if (cur.depth() == 1 || !cur.top().at_begin()) needsUpdate |= cursorTop(cur); else cur.undispatched(); - cur.updateFlags(Update::FitCursor); + cur.screenUpdateFlags(Update::FitCursor); break; case LFUN_INSET_END: case LFUN_INSET_END_SELECT: - needsUpdate |= cur.selHandle(cmd.action == LFUN_INSET_END_SELECT); + needsUpdate |= cur.selHandle(act == LFUN_INSET_END_SELECT); if (cur.depth() == 1 || !cur.top().at_end()) needsUpdate |= cursorBottom(cur); else cur.undispatched(); - cur.updateFlags(Update::FitCursor); + cur.screenUpdateFlags(Update::FitCursor); break; case LFUN_INSET_SELECT_ALL: @@ -599,13 +600,13 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) needsUpdate |= cursorBottom(cur); } else cur.undispatched(); - cur.updateFlags(Update::FitCursor); + cur.screenUpdateFlags(Update::FitCursor); break; case LFUN_CHAR_FORWARD: case LFUN_CHAR_FORWARD_SELECT: //LYXERR0(" LFUN_CHAR_FORWARD[SEL]:\n" << cur); - needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_FORWARD_SELECT); + needsUpdate |= cur.selHandle(act == LFUN_CHAR_FORWARD_SELECT); needsUpdate |= cursorForward(cur); if (!needsUpdate && oldTopSlice == cur.top() @@ -623,7 +624,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) // provide it with two different cursors. Cursor dummy = cur; dummy.pos() = dummy.pit() = 0; - cur.bv().checkDepm(dummy, cur); + if (cur.bv().checkDepm(dummy, cur)) + cur.forceBufferUpdate();; } } break; @@ -631,7 +633,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_CHAR_BACKWARD: case LFUN_CHAR_BACKWARD_SELECT: //lyxerr << "handle LFUN_CHAR_BACKWARD[_SELECT]:\n" << cur << endl; - needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_BACKWARD_SELECT); + needsUpdate |= cur.selHandle(act == LFUN_CHAR_BACKWARD_SELECT); needsUpdate |= cursorBackward(cur); if (!needsUpdate && oldTopSlice == cur.top() @@ -649,7 +651,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) Cursor dummy = cur; dummy.pos() = cur.lastpos(); dummy.pit() = cur.lastpit(); - cur.bv().checkDepm(dummy, cur); + if (cur.bv().checkDepm(dummy, cur)) + cur.forceBufferUpdate(); } } break; @@ -657,7 +660,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_CHAR_LEFT: case LFUN_CHAR_LEFT_SELECT: if (lyxrc.visual_cursor) { - needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_LEFT_SELECT); + needsUpdate |= cur.selHandle(act == LFUN_CHAR_LEFT_SELECT); needsUpdate |= cursorVisLeft(cur); if (!needsUpdate && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) { @@ -666,11 +669,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) } } else { if (reverseDirectionNeeded(cur)) { - cmd.action = cmd.action == LFUN_CHAR_LEFT_SELECT ? - LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD; + cmd.setAction(cmd.action() == LFUN_CHAR_LEFT_SELECT ? + LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD); } else { - cmd.action = cmd.action == LFUN_CHAR_LEFT_SELECT ? - LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD; + cmd.setAction(cmd.action() == LFUN_CHAR_LEFT_SELECT ? + LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD); } dispatch(cur, cmd); return; @@ -680,7 +683,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_CHAR_RIGHT: case LFUN_CHAR_RIGHT_SELECT: if (lyxrc.visual_cursor) { - needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_RIGHT_SELECT); + needsUpdate |= cur.selHandle(cmd.action() == LFUN_CHAR_RIGHT_SELECT); needsUpdate |= cursorVisRight(cur); if (!needsUpdate && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) { @@ -689,11 +692,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) } } else { if (reverseDirectionNeeded(cur)) { - cmd.action = cmd.action == LFUN_CHAR_RIGHT_SELECT ? - LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD; + cmd.setAction(cmd.action() == LFUN_CHAR_RIGHT_SELECT ? + LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD); } else { - cmd.action = cmd.action == LFUN_CHAR_RIGHT_SELECT ? - LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD; + cmd.setAction(cmd.action() == LFUN_CHAR_RIGHT_SELECT ? + LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD); } dispatch(cur, cmd); return; @@ -706,11 +709,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_UP: case LFUN_DOWN: { // stop/start the selection - bool select = cmd.action == LFUN_DOWN_SELECT || - cmd.action == LFUN_UP_SELECT; + bool select = cmd.action() == LFUN_DOWN_SELECT || + cmd.action() == LFUN_UP_SELECT; // move cursor up/down - bool up = cmd.action == LFUN_UP_SELECT || cmd.action == LFUN_UP; + bool up = cmd.action() == LFUN_UP_SELECT || cmd.action() == LFUN_UP; bool const atFirstOrLastRow = cur.atFirstOrLastRow(up); if (!atFirstOrLastRow) { @@ -732,25 +735,25 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_PARAGRAPH_UP: case LFUN_PARAGRAPH_UP_SELECT: - needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_UP_SELECT); + needsUpdate |= cur.selHandle(cmd.action() == LFUN_PARAGRAPH_UP_SELECT); needsUpdate |= cursorUpParagraph(cur); break; case LFUN_PARAGRAPH_DOWN: case LFUN_PARAGRAPH_DOWN_SELECT: - needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_DOWN_SELECT); + needsUpdate |= cur.selHandle(cmd.action() == LFUN_PARAGRAPH_DOWN_SELECT); needsUpdate |= cursorDownParagraph(cur); break; case LFUN_LINE_BEGIN: case LFUN_LINE_BEGIN_SELECT: - needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_BEGIN_SELECT); + needsUpdate |= cur.selHandle(cmd.action() == LFUN_LINE_BEGIN_SELECT); needsUpdate |= tm->cursorHome(cur); break; case LFUN_LINE_END: case LFUN_LINE_END_SELECT: - needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_END_SELECT); + needsUpdate |= cur.selHandle(cmd.action() == LFUN_LINE_END_SELECT); needsUpdate |= tm->cursorEnd(cur); break; @@ -792,7 +795,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_WORD_RIGHT: case LFUN_WORD_RIGHT_SELECT: if (lyxrc.visual_cursor) { - needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_RIGHT_SELECT); + needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_RIGHT_SELECT); needsUpdate |= cursorVisRightOneWord(cur); if (!needsUpdate && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) { @@ -801,11 +804,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) } } else { if (reverseDirectionNeeded(cur)) { - cmd.action = cmd.action == LFUN_WORD_RIGHT_SELECT ? - LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD; + cmd.setAction(cmd.action() == LFUN_WORD_RIGHT_SELECT ? + LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD); } else { - cmd.action = cmd.action == LFUN_WORD_RIGHT_SELECT ? - LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD; + cmd.setAction(cmd.action() == LFUN_WORD_RIGHT_SELECT ? + LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD); } dispatch(cur, cmd); return; @@ -814,14 +817,34 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_WORD_FORWARD: case LFUN_WORD_FORWARD_SELECT: - needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_FORWARD_SELECT); + needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_FORWARD_SELECT); needsUpdate |= cursorForwardOneWord(cur); + + if (!needsUpdate && oldTopSlice == cur.top() + && cur.boundary() == oldBoundary) { + cur.undispatched(); + cmd = FuncRequest(LFUN_FINISHED_FORWARD); + + // we will probably be moving out the inset, so we should execute + // the depm-mechanism, but only when the cursor has a place to + // go outside this inset, i.e. in a slice above. + if (cur.depth() > 1 && cur.pos() == cur.lastpos() + && cur.pit() == cur.lastpit()) { + // The cursor hasn't changed yet. To give the + // DEPM the possibility of doing something we must + // provide it with two different cursors. + Cursor dummy = cur; + dummy.pos() = dummy.pit() = 0; + if (cur.bv().checkDepm(dummy, cur)) + cur.forceBufferUpdate();; + } + } break; case LFUN_WORD_LEFT: case LFUN_WORD_LEFT_SELECT: if (lyxrc.visual_cursor) { - needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_LEFT_SELECT); + needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_LEFT_SELECT); needsUpdate |= cursorVisLeftOneWord(cur); if (!needsUpdate && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) { @@ -830,11 +853,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) } } else { if (reverseDirectionNeeded(cur)) { - cmd.action = cmd.action == LFUN_WORD_LEFT_SELECT ? - LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD; + cmd.setAction(cmd.action() == LFUN_WORD_LEFT_SELECT ? + LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD); } else { - cmd.action = cmd.action == LFUN_WORD_LEFT_SELECT ? - LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD; + cmd.setAction(cmd.action() == LFUN_WORD_LEFT_SELECT ? + LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD); } dispatch(cur, cmd); return; @@ -843,8 +866,29 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_WORD_BACKWARD: case LFUN_WORD_BACKWARD_SELECT: - needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_BACKWARD_SELECT); + needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_BACKWARD_SELECT); needsUpdate |= cursorBackwardOneWord(cur); + + if (!needsUpdate && oldTopSlice == cur.top() + && cur.boundary() == oldBoundary) { + cur.undispatched(); + cmd = FuncRequest(LFUN_FINISHED_BACKWARD); + + // we will probably be moving out the inset, so we should execute + // the depm-mechanism, but only when the cursor has a place to + // go outside this inset, i.e. in a slice above. + if (cur.depth() > 1 && cur.pos() == 0 + && cur.pit() == 0) { + // The cursor hasn't changed yet. To give the + // DEPM the possibility of doing something we must + // provide it with two different cursors. + Cursor dummy = cur; + dummy.pos() = cur.lastpos(); + dummy.pit() = cur.lastpit(); + if (cur.bv().checkDepm(dummy, cur)) + cur.forceBufferUpdate(); + } + } break; case LFUN_WORD_SELECT: { @@ -884,8 +928,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) bv->buffer().params().trackChanges); // Update the selection pos to make sure the selection does not // change as the inserted tab will increase the logical pos. - if (cur.anchor_.pit() == pit) - cur.anchor_.forwardPos(); + if (cur.realAnchor().pit() == pit) + cur.realAnchor().forwardPos(); if (cur.pit() == pit) cur.forwardPos(); } @@ -908,24 +952,22 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) pit_type const pit_end = cur.selEnd().pit(); for (pit_type pit = cur.selBegin().pit(); pit <= pit_end; pit++) { Paragraph & par = paragraphs()[pit]; - if (par.getChar(0) == '\t') { - if (cur.pit() == pit) - cur.posBackward(); - if (cur.anchor_.pit() == pit && cur.anchor_.pos() > 0 ) - cur.anchor_.backwardPos(); - - par.eraseChar(0, tc); - } else - // If no tab was present, try to remove up to four spaces. - for (int n_spaces = 0; - par.getChar(0) == ' ' && n_spaces < 4; ++n_spaces) { + if (par.empty()) + continue; + char_type const c = par.getChar(0); + if (c == '\t' || c == ' ') { + // remove either 1 tab or 4 spaces. + int const n = (c == ' ' ? 4 : 1); + for (int i = 0; i < n + && !par.empty() && par.getChar(0) == c; ++i) { if (cur.pit() == pit) cur.posBackward(); - if (cur.anchor_.pit() == pit && cur.anchor_.pos() > 0 ) - cur.anchor_.backwardPos(); - + if (cur.realAnchor().pit() == pit + && cur.realAnchor().pos() > 0 ) + cur.realAnchor().backwardPos(); par.eraseChar(0, tc); } + } } cur.finishUndo(); } else { @@ -970,6 +1012,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) singleParUpdate = false; } moveCursor(cur, false); + cur.forceBufferUpdate(); break; case LFUN_CHAR_DELETE_BACKWARD: @@ -987,6 +1030,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) cutSelection(cur, true, false); singleParUpdate = false; } + cur.forceBufferUpdate(); break; case LFUN_BREAK_PARAGRAPH: @@ -1045,8 +1089,10 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) } case LFUN_INSET_DISSOLVE: { - if (dissolveInset(cur)) + if (dissolveInset(cur)) { needsUpdate = true; + cur.forceBufferUpdate(); + } break; } @@ -1362,7 +1408,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case mouse_button::button1: // Set the cursor if (!bv->mouseSetCursor(cur, cmd.argument() == "region-select")) - cur.updateFlags(Update::SinglePar | Update::FitCursor); + cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor); if (bvcur.wordSelection()) selectWord(bvcur, WHOLE_WORD); break; @@ -1373,7 +1419,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) lyx::dispatch( FuncRequest(LFUN_COMMAND_ALTERNATIVES, "selection-paste ; primary-selection-paste paragraph")); - cur.noUpdate(); + cur.noScreenUpdate(); break; case mouse_button::button3: { @@ -1381,11 +1427,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) // selection, a context menu will popup. if (bvcur.selection() && cur >= bvcur.selectionBegin() && cur < bvcur.selectionEnd()) { - cur.noUpdate(); + cur.noScreenUpdate(); return; } if (!bv->mouseSetCursor(cur, false)) - cur.updateFlags(Update::SinglePar | Update::FitCursor); + cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor); break; } @@ -1397,31 +1443,31 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_MOUSE_MOTION: { // Mouse motion with right or middle mouse do nothing for now. if (cmd.button() != mouse_button::button1) { - cur.noUpdate(); + cur.noScreenUpdate(); return; } // ignore motions deeper nested than the real anchor Cursor & bvcur = cur.bv().cursor(); - if (!bvcur.anchor_.hasPart(cur)) { + if (!bvcur.realAnchor().hasPart(cur)) { cur.undispatched(); break; } CursorSlice old = bvcur.top(); int const wh = bv->workHeight(); - int const y = max(0, min(wh - 1, cmd.y)); + int const y = max(0, min(wh - 1, cmd.y())); - tm->setCursorFromCoordinates(cur, cmd.x, y); - cur.setTargetX(cmd.x); - if (cmd.y >= wh) + tm->setCursorFromCoordinates(cur, cmd.x(), y); + cur.setTargetX(cmd.x()); + if (cmd.y() >= wh) lyx::dispatch(FuncRequest(LFUN_DOWN_SELECT)); - else if (cmd.y < 0) + else if (cmd.y() < 0) lyx::dispatch(FuncRequest(LFUN_UP_SELECT)); // This is to allow jumping over large insets if (cur.top() == old) { - if (cmd.y >= wh) + if (cmd.y() >= wh) lyx::dispatch(FuncRequest(LFUN_DOWN_SELECT)); - else if (cmd.y < 0) + else if (cmd.y() < 0) lyx::dispatch(FuncRequest(LFUN_UP_SELECT)); } // We continue with our existing selection or start a new one, so don't @@ -1430,8 +1476,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) bvcur.setSelection(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(); + cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor); + //cur.noScreenUpdate(); return; } break; @@ -1452,23 +1498,23 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) cur.bv().cursor().setSelection(); // We might have removed an empty but drawn selection // (probably a margin) - cur.updateFlags(Update::SinglePar | Update::FitCursor); + cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor); } else - cur.noUpdate(); + cur.noScreenUpdate(); // FIXME: We could try to handle drag and drop of selection here. return; case mouse_button::button2: // Middle mouse pasting is handled at mouse press time, // see LFUN_MOUSE_PRESS. - cur.noUpdate(); + cur.noScreenUpdate(); 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(); + cur.noScreenUpdate(); return; case mouse_button::none: @@ -1514,7 +1560,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) } p["target"] = (cmd.argument().empty()) ? content : cmd.argument(); - string const data = InsetCommand::params2string("href", p); + string const data = InsetCommand::params2string(p); if (p["target"].empty()) { bv->showDialog("href", data); } else { @@ -1530,7 +1576,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) p["name"] = (cmd.argument().empty()) ? cur.getPossibleLabel() : cmd.argument(); - string const data = InsetCommand::params2string("label", p); + string const data = InsetCommand::params2string(p); if (cmd.argument().empty()) { bv->showDialog("label", data); @@ -1569,15 +1615,16 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_ERT_INSERT: case LFUN_LISTING_INSERT: case LFUN_MARGINALNOTE_INSERT: - case LFUN_OPTIONAL_INSERT: + case LFUN_ARGUMENT_INSERT: case LFUN_INDEX_INSERT: + case LFUN_PREVIEW_INSERT: // Open the inset, and move the current selection // inside it. doInsertInset(cur, this, cmd, true, true); cur.posForward(); // Some insets are numbered, others are shown in the outline pane so // let's update the labels and the toc backend. - bv->buffer().updateLabels(); + cur.forceBufferUpdate(); break; case LFUN_TABULAR_INSERT: @@ -1631,8 +1678,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) // date metrics. FuncRequest cmd_caption(LFUN_CAPTION_INSERT); doInsertInset(cur, cur.text(), cmd_caption, true, false); - bv->buffer().updateLabels(); - cur.updateFlags(Update::Force); + cur.forceBufferUpdate(); + cur.screenUpdateFlags(Update::Force); // FIXME: When leaving the Float (or Wrap) inset we should // delete any empty paragraph left above or below the // caption. @@ -1645,7 +1692,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) p["symbol"] = bv->cursor().innerText()->getStringToIndex(bv->cursor()); else p["symbol"] = cmd.argument(); - string const data = InsetCommand::params2string("nomenclature", p); + string const data = InsetCommand::params2string(p); bv->showDialog("nomenclature", data); break; } @@ -1656,15 +1703,13 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) p["type"] = from_ascii("idx"); else p["type"] = cmd.argument(); - string const data = InsetCommand::params2string("index_print", p); + string const data = InsetCommand::params2string(p); FuncRequest fr(LFUN_INSET_INSERT, data); dispatch(cur, fr); break; } case LFUN_NOMENCL_PRINT: - case LFUN_TOC_INSERT: - case LFUN_LINE_INSERT: case LFUN_NEWPAGE_INSERT: // do nothing fancy doInsertInset(cur, this, cmd, false, false); @@ -1932,10 +1977,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_ACCENT_HUNGARIAN_UMLAUT: case LFUN_ACCENT_CIRCLE: case LFUN_ACCENT_OGONEK: - theApp()->handleKeyFunc(cmd.action); + theApp()->handleKeyFunc(cmd.action()); if (!cmd.argument().empty()) // FIXME: Are all these characters encoded in one byte in utf8? bv->translateAndInsert(cmd.argument()[0], this, cur); + cur.screenUpdateFlags(Update::FitCursor); break; case LFUN_FLOAT_LIST_INSERT: { @@ -2000,8 +2046,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_SPELLING_ADD: { docstring word = from_utf8(cmd.getArg(0)); - string code; - string variety; + Language * lang; if (word.empty()) { word = cur.selectionAsString(false); // FIXME @@ -2010,19 +2055,17 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) selectWordWhenUnderCursor(cur, WHOLE_WORD); word = cur.selectionAsString(false); } - code = cur.getFont().language()->code(); - variety = cur.getFont().language()->variety(); + lang = const_cast(cur.getFont().language()); } else - variety = split(cmd.getArg(1), code, '-'); - WordLangTuple wl(word, code, variety); + lang = const_cast(languages.getLanguage(cmd.getArg(1))); + WordLangTuple wl(word, lang); theSpellChecker()->insert(wl); break; } case LFUN_SPELLING_IGNORE: { docstring word = from_utf8(cmd.getArg(0)); - string code; - string variety; + Language * lang; if (word.empty()) { word = cur.selectionAsString(false); // FIXME @@ -2031,15 +2074,33 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) selectWordWhenUnderCursor(cur, WHOLE_WORD); word = cur.selectionAsString(false); } - code = cur.getFont().language()->code(); - variety = cur.getFont().language()->variety(); + lang = const_cast(cur.getFont().language()); } else - variety = split(cmd.getArg(1), code, '-'); - WordLangTuple wl(word, code, variety); + lang = const_cast(languages.getLanguage(cmd.getArg(1))); + WordLangTuple wl(word, lang); theSpellChecker()->accept(wl); break; } + case LFUN_SPELLING_REMOVE: { + docstring word = from_utf8(cmd.getArg(0)); + Language * lang; + if (word.empty()) { + word = cur.selectionAsString(false); + // FIXME + if (word.size() > 100 || word.empty()) { + // Get word or selection + selectWordWhenUnderCursor(cur, WHOLE_WORD); + word = cur.selectionAsString(false); + } + lang = const_cast(cur.getFont().language()); + } else + lang = const_cast(languages.getLanguage(cmd.getArg(1))); + WordLangTuple wl(word, lang); + theSpellChecker()->remove(wl); + break; + } + case LFUN_PARAGRAPH_PARAMS_APPLY: { // Given data, an encoding of the ParagraphParameters // generated in the Paragraph dialog, this function sets @@ -2076,26 +2137,26 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_OUTLINE_UP: outline(OutlineUp, cur); setCursor(cur, cur.pit(), 0); - cur.buffer()->updateLabels(); + cur.forceBufferUpdate(); needsUpdate = true; break; case LFUN_OUTLINE_DOWN: outline(OutlineDown, cur); setCursor(cur, cur.pit(), 0); - cur.buffer()->updateLabels(); + cur.forceBufferUpdate(); needsUpdate = true; break; case LFUN_OUTLINE_IN: outline(OutlineIn, cur); - cur.buffer()->updateLabels(); + cur.forceBufferUpdate(); needsUpdate = true; break; case LFUN_OUTLINE_OUT: outline(OutlineOut, cur); - cur.buffer()->updateLabels(); + cur.forceBufferUpdate(); needsUpdate = true; break; @@ -2112,7 +2173,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) // for now only Text::erase() and Text::backspace() do that. // The plan is to verify all the LFUNs and then to remove this // singleParUpdate boolean altogether. - if (cur.result().update() & Update::Force) { + if (cur.result().screenUpdate() & Update::Force) { singleParUpdate = false; needsUpdate = true; } @@ -2123,7 +2184,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) // Inserting characters does not change par height in general. So, try // to update _only_ this paragraph. BufferView will detect if a full // metrics update is needed anyway. - cur.updateFlags(Update::SinglePar | Update::FitCursor); + cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor); return; } @@ -2135,15 +2196,15 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) // FIXME: it would be better if we could just do this // //if (cur.result().update() != Update::FitCursor) - // cur.noUpdate(); + // cur.noScreenUpdate(); // // But some LFUNs do not set Update::FitCursor when needed, so we // do it for all. This is not very harmfull as FitCursor will provoke // a full redraw only if needed but still, a proper review of all LFUN // should be done and this needsUpdate boolean can then be removed. - cur.updateFlags(Update::FitCursor); + cur.screenUpdateFlags(Update::FitCursor); else - cur.updateFlags(Update::Force | Update::FitCursor); + cur.screenUpdateFlags(Update::Force | Update::FitCursor); } @@ -2156,7 +2217,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, bool enable = true; InsetCode code = NO_CODE; - switch (cmd.action) { + switch (cmd.action()) { case LFUN_DEPTH_DECREMENT: enable = changeDepthAllowed(cur, DEC_DEPTH); @@ -2206,6 +2267,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, code = NOMENCL_PRINT_CODE; else if (cmd.argument() == "label") code = LABEL_CODE; + else if (cmd.argument() == "line") + code = LINE_CODE; else if (cmd.argument() == "note") code = NOTE_CODE; else if (cmd.argument() == "phantom") @@ -2279,11 +2342,24 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, // not allowed in description items enable = !inDescriptionItem(cur); break; - case LFUN_FLOAT_LIST_INSERT: + case LFUN_FLOAT_LIST_INSERT: { code = FLOAT_LIST_CODE; // not allowed in description items enable = !inDescriptionItem(cur); + if (enable) { + FloatList const & floats = cur.buffer()->params().documentClass().floats(); + FloatList::const_iterator cit = floats[to_ascii(cmd.argument())]; + // make sure we know about such floats + if (cit == floats.end() || + // and that we know how to generate a list of them + (!cit->second.needsFloatPkg() && cit->second.listCommand().empty())) { + flag.setUnknown(true); + // probably not necessary, but... + enable = false; + } + } break; + } case LFUN_CAPTION_INSERT: code = CAPTION_CODE; // not allowed in description items @@ -2324,17 +2400,16 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_LABEL_INSERT: code = LABEL_CODE; break; - case LFUN_LINE_INSERT: - code = LINE_CODE; - break; case LFUN_INFO_INSERT: code = INFO_CODE; break; - case LFUN_OPTIONAL_INSERT: - code = OPTARG_CODE; - enable = cur.paragraph().insetList().count(OPTARG_CODE) - < cur.paragraph().layout().optionalargs; + case LFUN_ARGUMENT_INSERT: { + code = ARG_CODE; + Layout const & lay = cur.paragraph().layout(); + int const numargs = lay.reqargs + lay.optargs; + enable = cur.paragraph().insetList().count(ARG_CODE) < numargs; break; + } case LFUN_INDEX_INSERT: code = INDEX_CODE; break; @@ -2355,11 +2430,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, // not allowed in description items enable = !inDescriptionItem(cur); break; - case LFUN_TOC_INSERT: - code = TOC_CODE; - // not allowed in description items - enable = !inDescriptionItem(cur); - break; case LFUN_HYPERLINK_INSERT: if (cur.selIsMultiCell() || cur.selIsMultiLine()) { enable = false; @@ -2379,6 +2449,9 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, if (cur.inTexted()) code = SPACE_CODE; break; + case LFUN_PREVIEW_INSERT: + code = PREVIEW_CODE; + break; case LFUN_MATH_INSERT: case LFUN_MATH_AMS_MATRIX: @@ -2393,6 +2466,11 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, code = MATH_HULL_CODE; break; + case LFUN_REGEXP_MODE: + code = MATH_HULL_CODE; + enable = cur.buffer()->isInternal() && !cur.inRegexped(); + break; + case LFUN_INSET_MODIFY: // We need to disable this, because we may get called for a // tabular cell via @@ -2403,31 +2481,38 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_FONT_EMPH: flag.setOnOff(fontinfo.emph() == FONT_ON); + enable = !cur.inset().getLayout().isPassThru(); break; case LFUN_FONT_ITAL: flag.setOnOff(fontinfo.shape() == ITALIC_SHAPE); + enable = !cur.inset().getLayout().isPassThru(); break; case LFUN_FONT_NOUN: flag.setOnOff(fontinfo.noun() == FONT_ON); + enable = !cur.inset().getLayout().isPassThru(); break; case LFUN_FONT_BOLD: case LFUN_FONT_BOLDSYMBOL: flag.setOnOff(fontinfo.series() == BOLD_SERIES); + enable = !cur.inset().getLayout().isPassThru(); break; case LFUN_FONT_SANS: flag.setOnOff(fontinfo.family() == SANS_FAMILY); + enable = !cur.inset().getLayout().isPassThru(); break; case LFUN_FONT_ROMAN: flag.setOnOff(fontinfo.family() == ROMAN_FAMILY); + enable = !cur.inset().getLayout().isPassThru(); break; case LFUN_FONT_TYPEWRITER: flag.setOnOff(fontinfo.family() == TYPEWRITER_FAMILY); + enable = !cur.inset().getLayout().isPassThru(); break; case LFUN_CUT: @@ -2548,6 +2633,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_LANGUAGE: enable = !cur.inset().getLayout().isPassThru(); + flag.setOnOff(to_utf8(cmd.argument()) == cur.real_current_font.language()->lang()); break; case LFUN_BREAK_PARAGRAPH: @@ -2556,9 +2642,51 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_SPELLING_ADD: case LFUN_SPELLING_IGNORE: + case LFUN_SPELLING_REMOVE: enable = theSpellChecker(); break; + case LFUN_LAYOUT: + enable = !cur.inset().forcePlainLayout(); + break; + + case LFUN_LAYOUT_PARAGRAPH: + case LFUN_PARAGRAPH_PARAMS: + case LFUN_PARAGRAPH_PARAMS_APPLY: + case LFUN_PARAGRAPH_UPDATE: + enable = cur.inset().allowParagraphCustomization(); + break; + + // FIXME: why are accent lfuns forbidden with pass_thru layouts? + case LFUN_ACCENT_ACUTE: + case LFUN_ACCENT_BREVE: + case LFUN_ACCENT_CARON: + case LFUN_ACCENT_CEDILLA: + case LFUN_ACCENT_CIRCLE: + case LFUN_ACCENT_CIRCUMFLEX: + case LFUN_ACCENT_DOT: + case LFUN_ACCENT_GRAVE: + case LFUN_ACCENT_HUNGARIAN_UMLAUT: + case LFUN_ACCENT_MACRON: + case LFUN_ACCENT_OGONEK: + case LFUN_ACCENT_TIE: + case LFUN_ACCENT_TILDE: + case LFUN_ACCENT_UMLAUT: + case LFUN_ACCENT_UNDERBAR: + case LFUN_ACCENT_UNDERDOT: + case LFUN_FONT_DEFAULT: + case LFUN_FONT_FRAK: + case LFUN_FONT_SIZE: + case LFUN_FONT_STATE: + case LFUN_FONT_UNDERLINE: + case LFUN_FONT_STRIKEOUT: + case LFUN_FONT_UULINE: + case LFUN_FONT_UWAVE: + case LFUN_TEXTSTYLE_APPLY: + case LFUN_TEXTSTYLE_UPDATE: + enable = !cur.inset().getLayout().isPassThru(); + break; + case LFUN_WORD_DELETE_FORWARD: case LFUN_WORD_DELETE_BACKWARD: case LFUN_LINE_DELETE: @@ -2588,13 +2716,21 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_WORD_LEFT_SELECT: case LFUN_WORD_SELECT: case LFUN_SECTION_SELECT: + case LFUN_BUFFER_BEGIN: + case LFUN_BUFFER_END: + case LFUN_BUFFER_BEGIN_SELECT: + case LFUN_BUFFER_END_SELECT: + case LFUN_INSET_BEGIN: + case LFUN_INSET_END: + case LFUN_INSET_BEGIN_SELECT: + case LFUN_INSET_END_SELECT: + case LFUN_INSET_SELECT_ALL: case LFUN_PARAGRAPH_UP: case LFUN_PARAGRAPH_DOWN: case LFUN_LINE_BEGIN: case LFUN_LINE_END: case LFUN_CHAR_DELETE_FORWARD: case LFUN_CHAR_DELETE_BACKWARD: - case LFUN_INSET_INSERT: case LFUN_WORD_UPCASE: case LFUN_WORD_LOWCASE: case LFUN_WORD_CAPITALIZE: @@ -2602,52 +2738,27 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_SERVER_GET_XY: case LFUN_SERVER_SET_XY: case LFUN_SERVER_GET_LAYOUT: - case LFUN_LAYOUT: case LFUN_SELF_INSERT: - case LFUN_FONT_DEFAULT: - case LFUN_FONT_UNDERLINE: - case LFUN_FONT_STRIKEOUT: - case LFUN_FONT_UULINE: - case LFUN_FONT_UWAVE: - case LFUN_FONT_SIZE: - case LFUN_TEXTSTYLE_APPLY: - case LFUN_TEXTSTYLE_UPDATE: - case LFUN_LAYOUT_PARAGRAPH: - case LFUN_PARAGRAPH_UPDATE: - case LFUN_ACCENT_UMLAUT: - case LFUN_ACCENT_CIRCUMFLEX: - case LFUN_ACCENT_GRAVE: - case LFUN_ACCENT_ACUTE: - case LFUN_ACCENT_TILDE: - case LFUN_ACCENT_CEDILLA: - case LFUN_ACCENT_MACRON: - case LFUN_ACCENT_DOT: - case LFUN_ACCENT_UNDERDOT: - case LFUN_ACCENT_UNDERBAR: - case LFUN_ACCENT_CARON: - case LFUN_ACCENT_BREVE: - case LFUN_ACCENT_TIE: - case LFUN_ACCENT_HUNGARIAN_UMLAUT: - case LFUN_ACCENT_CIRCLE: - case LFUN_ACCENT_OGONEK: + case LFUN_UNICODE_INSERT: case LFUN_THESAURUS_ENTRY: - case LFUN_PARAGRAPH_PARAMS_APPLY: - case LFUN_PARAGRAPH_PARAMS: case LFUN_ESCAPE: - case LFUN_BUFFER_BEGIN: - case LFUN_BUFFER_END: - case LFUN_BUFFER_BEGIN_SELECT: - case LFUN_BUFFER_END_SELECT: - case LFUN_INSET_BEGIN: - case LFUN_INSET_END: - case LFUN_INSET_BEGIN_SELECT: - case LFUN_INSET_END_SELECT: - case LFUN_INSET_SELECT_ALL: - case LFUN_UNICODE_INSERT: // these are handled in our dispatch() enable = true; break; + case LFUN_INSET_INSERT: { + string const type = cmd.getArg(0); + if (type == "toc") { + code = TOC_CODE; + // not allowed in description items + //FIXME: couldn't this be merged in Inset::insetAllowed()? + enable = !inDescriptionItem(cur); + } else { + enable = true; + } + break; + } + default: return false; } @@ -2658,48 +2769,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, || cur.paragraph().layout().pass_thru)) enable = false; - switch (cmd.action) { - case LFUN_ACCENT_ACUTE: - case LFUN_ACCENT_BREVE: - case LFUN_ACCENT_CARON: - case LFUN_ACCENT_CEDILLA: - case LFUN_ACCENT_CIRCLE: - case LFUN_ACCENT_CIRCUMFLEX: - case LFUN_ACCENT_DOT: - case LFUN_ACCENT_GRAVE: - case LFUN_ACCENT_HUNGARIAN_UMLAUT: - case LFUN_ACCENT_MACRON: - case LFUN_ACCENT_OGONEK: - case LFUN_ACCENT_TIE: - case LFUN_ACCENT_TILDE: - case LFUN_ACCENT_UMLAUT: - case LFUN_ACCENT_UNDERBAR: - case LFUN_ACCENT_UNDERDOT: - case LFUN_FONT_BOLD: - case LFUN_FONT_BOLDSYMBOL: - case LFUN_FONT_TYPEWRITER: - case LFUN_FONT_DEFAULT: - case LFUN_FONT_EMPH: - case LFUN_FONT_NOUN: - case LFUN_FONT_ROMAN: - case LFUN_FONT_SANS: - case LFUN_FONT_FRAK: - case LFUN_FONT_ITAL: - case LFUN_FONT_SIZE: - case LFUN_FONT_STATE: - case LFUN_FONT_UNDERLINE: - case LFUN_FONT_STRIKEOUT: - case LFUN_FONT_UULINE: - case LFUN_FONT_UWAVE: - case LFUN_TEXTSTYLE_APPLY: - case LFUN_TEXTSTYLE_UPDATE: - if (cur.inset().getLayout().isPassThru()) - enable = false; - break; - default: - break; - } - flag.setEnabled(enable); return true; }