X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView.cpp;h=de2d71a1234aff48dbd5efd5ab33c5af8bd70616;hb=4b7f1b3c3918cd32070c72b6d8e95a888981c7a2;hp=5bac1e182853def008c3a51fba510c19b38bd1c6;hpb=b67cd61d3c872af026f601ed80407507b36d67f5;p=lyx.git diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 5bac1e1828..de2d71a123 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -424,7 +424,7 @@ void BufferView::processUpdateFlags(Update::flags flags) if (flags == Update::Decoration) { d->update_strategy_ = DecorationUpdate; - buffer_.changed(); + buffer_.changed(false); return; } @@ -437,7 +437,7 @@ void BufferView::processUpdateFlags(Update::flags flags) } if (flags & Update::Decoration) { d->update_strategy_ = DecorationUpdate; - buffer_.changed(); + buffer_.changed(false); return; } // no screen update is needed. @@ -453,13 +453,13 @@ void BufferView::processUpdateFlags(Update::flags flags) if (!(flags & Update::FitCursor)) { // Nothing to do anymore. Trigger a redraw and return - buffer_.changed(); + buffer_.changed(false); return; } // updateMetrics() does not update paragraph position // This is done at draw() time. So we need a redraw! - buffer_.changed(); + buffer_.changed(false); if (fitCursor()) { // The cursor is off screen so ensure it is visible. @@ -573,8 +573,7 @@ void BufferView::scrollDocView(int value) // If the offset is less than 2 screen height, prefer to scroll instead. if (abs(offset) <= 2 * height_) { d->anchor_ypos_ -= offset; - updateMetrics(); - buffer_.changed(); + buffer_.changed(true); return; } @@ -765,7 +764,7 @@ bool BufferView::moveToPosition(pit_type bottom_pit, pos_type bottom_pos, // To center the screen on this new position we need the // paragraph position which is computed at draw() time. // So we need a redraw! - buffer_.changed(); + buffer_.changed(false); if (fitCursor()) showCursor(); } @@ -811,7 +810,7 @@ void BufferView::showCursor() void BufferView::showCursor(DocIterator const & dit, bool recenter) { if (scrollToCursor(dit, recenter)) - buffer_.changed(); + buffer_.changed(false); } @@ -939,35 +938,6 @@ static Change::Type lookupChangeType(DocIterator const & dit, bool outer = false } -static bool getLocalStatus(Cursor cursor, FuncRequest const & cmd, FuncStatus & status) -{ - // Try to fix cursor in case it is broken. - cursor.fixIfBroken(); - - // This is, of course, a mess. Better create a new doc iterator and use - // this in Inset::getStatus. This might require an additional - // BufferView * arg, though (which should be avoided) - //Cursor safe = *this; - bool res = false; - for ( ; cursor.depth(); cursor.pop()) { - //lyxerr << "\nCursor::getStatus: cmd: " << cmd << endl << *this << endl; - LASSERT(cursor.idx() <= cursor.lastidx(), /**/); - LASSERT(cursor.pit() <= cursor.lastpit(), /**/); - LASSERT(cursor.pos() <= cursor.lastpos(), /**/); - - // The inset's getStatus() will return 'true' if it made - // a definitive decision on whether it want to handle the - // request or not. The result of this decision is put into - // the 'status' parameter. - if (cursor.inset().getStatus(cursor, cmd, status)) { - res = true; - break; - } - } - return res; -} - - bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) { // Can we use a readonly buffer? @@ -989,13 +959,7 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) Cursor & cur = d->cursor_; - // Is this a function that acts on inset at point? - Inset * inset = cur.nextInset(); - if (lyxaction.funcHasFlag(cmd.action, LyXAction::AtPoint) - && inset && inset->getStatus(cur, cmd, flag)) - return true; - - if (getLocalStatus(cur, cmd, flag)) + if (cur.getStatus(cmd, flag)) return true; switch (cmd.action) { @@ -1050,7 +1014,6 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_SCREEN_SHOW_CURSOR: case LFUN_BIBTEX_DATABASE_ADD: case LFUN_BIBTEX_DATABASE_DEL: - case LFUN_NOTES_MUTATE: case LFUN_ALL_INSETS_TOGGLE: case LFUN_STATISTICS: case LFUN_BRANCH_ADD_INSERT: @@ -1062,8 +1025,8 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) break; case LFUN_REGEXP_MODE: - // FIXME: Test if current WorkArea is the search WorkArea - flag.setEnabled(buffer().isInternal() && !cur.inRegexped()); + flag.setEnabled(buffer().isInternal() && !cur.inRegexped() + && cur.inset().lyxCode() != ERT_CODE); break; case LFUN_LABEL_COPY_AS_REF: { @@ -1075,18 +1038,6 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) break; } - case LFUN_NEXT_INSET_MODIFY: { - // this is the real function we want to invoke - FuncRequest tmpcmd = cmd; - tmpcmd.action = LFUN_INSET_MODIFY; - // if there is an inset at cursor, see whether it - // handles the lfun, other start from scratch - Inset * inset = cur.nextInset(); - if (!inset || !inset->getStatus(cur, tmpcmd, flag)) - flag = lyx::getStatus(tmpcmd); - break; - } - case LFUN_LABEL_GOTO: { flag.setEnabled(!cmd.argument().empty() || getInsetByCode(cur, REF_CODE)); @@ -1125,6 +1076,7 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_SCROLL: case LFUN_SCREEN_UP_SELECT: case LFUN_SCREEN_DOWN_SELECT: + case LFUN_INSET_FORALL: flag.setEnabled(true); break; @@ -1196,7 +1148,7 @@ void BufferView::editInset(string const & name, Inset * inset) } -bool BufferView::dispatch(FuncRequest const & cmd) +void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) { //lyxerr << [ cmd = " << cmd << "]" << endl; @@ -1211,8 +1163,9 @@ bool BufferView::dispatch(FuncRequest const & cmd) Cursor & cur = d->cursor_; // Don't dispatch function that does not apply to internal buffers. - if (buffer_.isInternal() && lyxaction.funcHasFlag(cmd.action, LyXAction::NoInternal)) - return false; + if (buffer_.isInternal() + && lyxaction.funcHasFlag(cmd.action, LyXAction::NoInternal)) + return; // We'll set this back to false if need be. bool dispatched = true; @@ -1237,7 +1190,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) // We are most certainly here because of a change in the document // It is then better to make sure that all dialogs are in sync with // current document settings. - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; } @@ -1248,7 +1201,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) buffer_.params().clearLayoutModules(); buffer_.params().makeDocumentClass(); updateLayout(oldClass); - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; } @@ -1265,7 +1218,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) buffer_.params().addLayoutModule(argument); buffer_.params().makeDocumentClass(); updateLayout(oldClass); - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; } @@ -1288,7 +1241,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) buffer_.params().setBaseClass(argument); buffer_.params().makeDocumentClass(); updateLayout(oldDocClass); - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; } @@ -1304,30 +1257,30 @@ bool BufferView::dispatch(FuncRequest const & cmd) buffer_.params().setBaseClass(bc); buffer_.params().makeDocumentClass(); updateLayout(oldClass); - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; } case LFUN_UNDO: - cur.message(_("Undo")); + dr.setMessage(_("Undo")); cur.clearSelection(); if (!cur.textUndo()) - cur.message(_("No further undo information")); + dr.setMessage(_("No further undo information")); else - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; case LFUN_REDO: - cur.message(_("Redo")); + dr.setMessage(_("Redo")); cur.clearSelection(); if (!cur.textRedo()) - cur.message(_("No further redo information")); + dr.setMessage(_("No further redo information")); else - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; case LFUN_FONT_STATE: - cur.message(cur.currentState()); + dr.setMessage(cur.currentState()); break; case LFUN_BOOKMARK_SAVE: @@ -1390,7 +1343,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) // Set the cursor dit.pos() = pos; setCursor(dit); - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); } else { // Switch to other buffer view and resend cmd theLyXFunc().dispatch(FuncRequest( @@ -1444,18 +1397,18 @@ bool BufferView::dispatch(FuncRequest const & cmd) case LFUN_CHANGE_NEXT: findNextChange(this); // FIXME: Move this LFUN to Buffer so that we don't have to do this: - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; case LFUN_CHANGE_PREVIOUS: findPreviousChange(this); // FIXME: Move this LFUN to Buffer so that we don't have to do this: - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; case LFUN_CHANGES_MERGE: if (findNextChange(this) || findPreviousChange(this)) { - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); showDialog("changes"); } break; @@ -1468,7 +1421,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) // accept everything in a single step to support atomic undo buffer_.text().acceptOrRejectChanges(cur, Text::ACCEPT); // FIXME: Move this LFUN to Buffer so that we don't have to do this: - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; case LFUN_ALL_CHANGES_REJECT: @@ -1480,7 +1433,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) // Note: reject does not work recursively; the user may have to repeat the operation buffer_.text().acceptOrRejectChanges(cur, Text::REJECT); // FIXME: Move this LFUN to Buffer so that we don't have to do this: - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; case LFUN_WORD_FIND_FORWARD: @@ -1528,7 +1481,8 @@ bool BufferView::dispatch(FuncRequest const & cmd) DocIterator end = cur.selectionEnd(); if (beg.pit() == end.pit()) { for (pos_type p = beg.pos() ; p < end.pos() ; ++p) { - if (cur.paragraph().isDeleted(p)) + if (!cur.inMathed() + && cur.paragraph().isDeleted(p)) has_deleted = true; } } @@ -1537,29 +1491,36 @@ bool BufferView::dispatch(FuncRequest const & cmd) break; } - case LFUN_WORD_FINDADV: - findAdv(this, cmd); + case LFUN_WORD_FINDADV: { + FindAndReplaceOptions opt; + istringstream iss(to_utf8(cmd.argument())); + iss >> opt; + if (findAdv(this, opt)) + cur.dispatched(); + else + cur.undispatched(); break; + } case LFUN_MARK_OFF: cur.clearSelection(); - cur.message(from_utf8(N_("Mark off"))); + dr.setMessage(from_utf8(N_("Mark off"))); break; case LFUN_MARK_ON: cur.clearSelection(); cur.setMark(true); - cur.message(from_utf8(N_("Mark on"))); + dr.setMessage(from_utf8(N_("Mark on"))); break; case LFUN_MARK_TOGGLE: cur.setSelection(false); if (cur.mark()) { cur.setMark(false); - cur.message(from_utf8(N_("Mark removed"))); + dr.setMessage(from_utf8(N_("Mark removed"))); } else { cur.setMark(true); - cur.message(from_utf8(N_("Mark set"))); + dr.setMessage(from_utf8(N_("Mark set"))); } cur.resetAnchor(); break; @@ -1653,32 +1614,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) // It did not work too; no action needed. break; cur.clearSelection(); - processUpdateFlags(Update::SinglePar | Update::FitCursor); - break; - } - - case LFUN_NEXT_INSET_MODIFY: { - // create the the real function we want to invoke - FuncRequest tmpcmd = cmd; - tmpcmd.action = LFUN_INSET_MODIFY; - // if there is an inset at cursor, see whether it - // can be modified. - Inset * inset = cur.nextInset(); - if (inset) { - cur.recordUndo(); - inset->dispatch(cur, tmpcmd); - } - // if it did not work, try the underlying inset. - if (!inset || !cur.result().dispatched()) { - cur.recordUndo(); - cur.dispatch(tmpcmd); - } - - if (!cur.result().dispatched()) - // It did not work too; no action needed. - break; - cur.clearSelection(); - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::SinglePar | Update::FitCursor); break; } @@ -1701,15 +1637,14 @@ bool BufferView::dispatch(FuncRequest const & cmd) Cursor old = cur; bool const in_texted = cur.inTexted(); cur.reset(); - updateMetrics(); - buffer_.changed(); + buffer_.changed(true); d->text_metrics_[&buffer_.text()].editXY(cur, p.x_, p.y_, true, cmd.action == LFUN_SCREEN_UP); //FIXME: what to do with cur.x_target()? bool update = in_texted && cur.bv().checkDepm(cur, old); cur.finishUndo(); if (update) - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; } @@ -1730,7 +1665,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) y = getPos(cur, cur.boundary()).y_; cur.finishUndo(); - processUpdateFlags(Update::SinglePar | Update::FitCursor); + dr.update(Update::SinglePar | Update::FitCursor); break; } @@ -1747,22 +1682,60 @@ bool BufferView::dispatch(FuncRequest const & cmd) y = getPos(cur, cur.boundary()).y_; cur.finishUndo(); - processUpdateFlags(Update::SinglePar | Update::FitCursor); + dr.update(Update::SinglePar | Update::FitCursor); break; } - // This could be rewriten using some command like forall - // once the insets refactoring is done. - case LFUN_NOTES_MUTATE: { - if (cmd.argument().empty()) - break; - if (mutateNotes(cur, cmd.getArg(0), cmd.getArg(1))) { - processUpdateFlags(Update::Force); + // This would be in Buffer class if only Cursor did not + // require a bufferview + case LFUN_INSET_FORALL: { + docstring const name = from_utf8(cmd.getArg(0)); + string const commandstr = cmd.getLongArg(1); + FuncRequest const fr = lyxaction.lookupFunc(commandstr); + + // an arbitrary number to limit number of iterations + const int max_iter = 10000; + int iterations = 0; + Cursor & cur = d->cursor_; + Cursor const savecur = cur; + cur.reset(); + if (!cur.nextInset()) + cur.forwardInset(); + cur.beginUndoGroup(); + while(cur && iterations < max_iter) { + Inset * ins = cur.nextInset(); + if (!ins) + break; + docstring insname = ins->name(); + while (!insname.empty()) { + if (insname == name || name == from_utf8("*")) { + cur.recordUndo(); + lyx::dispatch(fr); + ++iterations; + break; + } + size_t const i = insname.rfind(':'); + if (i == string::npos) + break; + insname = insname.substr(0, i); + } + cur.forwardInset(); } + cur.endUndoGroup(); + cur = savecur; + cur.fixIfBroken(); + dr.update(Update::Force); + + if (iterations >= max_iter) { + dr.setError(true); + dr.setMessage(bformat(_("`inset-forall' interrupted because number of actions is larger than %1$d"), max_iter)); + } else + dr.setMessage(bformat(_("Applied \"%1$s\" to %2$d insets"), from_utf8(commandstr), iterations)); break; } + case LFUN_ALL_INSETS_TOGGLE: { string action; string const name = split(to_utf8(cmd.argument()), action, ' '); @@ -1782,7 +1755,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) it->dispatch(tmpcur, fr); } } - processUpdateFlags(Update::Force | Update::FitCursor); + dr.update(Update::Force | Update::FitCursor); break; } @@ -1870,7 +1843,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) cur.recordUndo(); FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument()); inset->dispatch(cur, fr); - processUpdateFlags(Update::SinglePar | Update::FitCursor); + dr.update(Update::SinglePar | Update::FitCursor); break; } @@ -1880,7 +1853,8 @@ bool BufferView::dispatch(FuncRequest const & cmd) } buffer_.undo().endUndoGroup(); - return dispatched; + dr.dispatched(dispatched); + return; } @@ -1918,7 +1892,7 @@ void BufferView::clearSelection() d->xsel_cache_.set = false; // The buffer did not really change, but this causes the // redraw we need because we cleared the selection above. - buffer_.changed(); + buffer_.changed(false); } @@ -2013,7 +1987,7 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0) // This event (moving without mouse click) is not passed further. // This should be changed if it is further utilized. - buffer_.changed(); + buffer_.changed(false); return; } @@ -2074,8 +2048,7 @@ void BufferView::lfunScroll(FuncRequest const & cmd) if (scroll_value) scroll(scroll_step * scroll_value); } - updateMetrics(); - buffer_.changed(); + buffer_.changed(true); } @@ -2192,7 +2165,7 @@ void BufferView::gotoLabel(docstring const & label) TocIterator end = toc.end(); for (; toc_it != end; ++toc_it) { if (label == toc_it->str()) { - dispatch(toc_it->action()); + lyx::dispatch(toc_it->action()); return; } } @@ -2261,9 +2234,7 @@ bool BufferView::checkDepm(Cursor & cur, Cursor & old) d->cursor_ = cur; buffer_.updateLabels(); - - updateMetrics(); - buffer_.changed(); + buffer_.changed(true); return true; } @@ -2295,7 +2266,8 @@ bool BufferView::mouseSetCursor(Cursor & cur, bool select) if (!do_selection && d->cursor_.inTexted()) update |= checkDepm(cur, d->cursor_); - d->cursor_.resetAnchor(); + if (!do_selection) + d->cursor_.resetAnchor(); d->cursor_.setCursor(cur); d->cursor_.boundary(cur.boundary()); if (do_selection) @@ -2496,8 +2468,7 @@ void BufferView::insertLyXFile(FileName const & fname) res = _("Could not insert document %1$s"); } - updateMetrics(); - buffer_.changed(); + buffer_.changed(true); // emit message signal. message(bformat(res, disp_fn)); buffer_.errors("Parse"); @@ -2804,8 +2775,7 @@ void BufferView::insertPlaintextFile(FileName const & f, bool asParagraph) else cur.innerText()->insertStringAsLines(cur, tmpstr, cur.current_font); - updateMetrics(); - buffer_.changed(); + buffer_.changed(true); }