X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView.cpp;h=0bbf6497964536773073c44e2490c486d3f25476;hb=a11780b59fcb6cdd16b15f9fa4de45d7ddfd1b2a;hp=0f36dcab8476302ca1a6e2abcc4b01994ba44c5e;hpb=e09158efee92c6a57f5228af35f1cf8e0eeb07d8;p=features.git diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 0f36dcab84..0bbf649796 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -38,6 +38,7 @@ #include "MetricsInfo.h" #include "Paragraph.h" #include "Session.h" +#include "texstream.h" #include "Text.h" #include "TextMetrics.h" #include "TexRow.h" @@ -47,6 +48,7 @@ #include "insets/InsetCitation.h" #include "insets/InsetCommand.h" // ChangeRefs #include "insets/InsetGraphics.h" +#include "insets/InsetIndex.h" #include "insets/InsetRef.h" #include "insets/InsetText.h" @@ -292,6 +294,8 @@ struct BufferView::Private bool clickable_inset_; /// shape of the caret frontend::CaretGeometry caret_geometry_; + /// + bool mouse_selecting_ = false; }; @@ -340,11 +344,14 @@ int BufferView::defaultMargin() const int BufferView::rightMargin() const { - // The additional test for the case the outliner is opened. - if (full_screen_ && lyxrc.full_screen_limit) - return max(defaultMargin(), (width_ - lyxrc.full_screen_width) / 2); + const int screen_width = inPixels(lyxrc.screen_width); - return defaultMargin(); + // The additional test for the case the outliner is opened. + if (!lyxrc.screen_limit || width_ < screen_width + 2 * defaultMargin()) { + return defaultMargin(); + } else { + return (width_ - screen_width) / 2; + } } @@ -583,7 +590,7 @@ void BufferView::processUpdateFlags(Update::flags flags) } -void BufferView::updateScrollbar() +void BufferView::updateScrollbarParameters() { if (height_ == 0 && width_ == 0) return; @@ -1089,8 +1096,6 @@ void BufferView::makeDocumentClass() void BufferView::updateDocumentClass(DocumentClassConstPtr olddc) { - message(_("Converting document to new document class...")); - StableDocIterator backcur(d->cursor_); ErrorList & el = buffer_.errorList("Class Switch"); cap::switchBetweenClasses( @@ -1481,6 +1486,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) else { dr.screenUpdate(Update::Force | Update::FitCursor); dr.forceBufferUpdate(); + resetInlineCompletionPos(); if (buffer().params().citeEngine() != engine || buffer().params().citeEngineType() != enginetype) buffer().invalidateCiteLabels(); @@ -1501,6 +1507,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) else { dr.screenUpdate(Update::Force | Update::FitCursor); dr.forceBufferUpdate(); + resetInlineCompletionPos(); if (buffer().params().citeEngine() != engine || buffer().params().citeEngineType() != enginetype) buffer().invalidateCiteLabels(); @@ -1717,6 +1724,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) } if (cur.selection()) pattern = cur.selectionAsString(false); + else if (!cur.inTexted()) + break; // not suitable for selectWord at cursor else { pos_type spos = cur.pos(); cur.innerText()->selectWord(cur, WHOLE_WORD); @@ -1753,6 +1762,78 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; } + case LFUN_INDEX_TAG_ALL: { + Inset * ins = cur.nextInset(); + if (!ins || ins->lyxCode() != INDEX_CODE) + // not at index inset + break; + + // clone the index inset + InsetIndex * cins = + new InsetIndex(static_cast(*cur.nextInset())); + // In order to avoid duplication, we compare the + // LaTeX output if we find another index inset after + // the word + odocstringstream oilatex; + otexstream oits(oilatex); + OutputParams rp(&cur.buffer()->params().encoding()); + ins->latex(oits, rp); + cap::copyInsetToTemp(cur, cins); + + // move backwards into preceding word + // skip over other index insets + cur.backwardPosIgnoreCollapsed(); + while (true) { + if (cur.inset().lyxCode() == INDEX_CODE) + cur.pop_back(); + else if (cur.prevInset() && cur.prevInset()->lyxCode() == INDEX_CODE) + cur.backwardPosIgnoreCollapsed(); + else + break; + } + if (!cur.inTexted()) { + // Nothing to do here. + setCursorFromInset(ins); + break; + } + // Get word or selection + cur.text()->selectWord(cur, WHOLE_WORD); + docstring const searched_string = cur.selectionAsString(false); + // Start from the beginning + lyx::dispatch(FuncRequest(LFUN_BUFFER_BEGIN)); + while (findOne(this, searched_string, + false,// case sensitive + true,// match whole word only + true,// forward + false,//find deleted + false,//check wrap + false,// auto-wrap + false,// instant + false// only selection + )) { + cur.clearSelection(); + Inset * ains = cur.nextInset(); + if (ains && ains->lyxCode() == INDEX_CODE) { + // We have an index inset. + // Check whether it has the same + // LaTeX content and move on if so. + odocstringstream filatex; + otexstream fits(filatex); + ains->latex(fits, rp); + if (oilatex.str() == filatex.str()) + continue; + } + // Paste the inset and possibly continue + cap::pasteFromTemp(cursor(), cursor().buffer()->errorList("Paste")); + } + // Go back to start position. + setCursorFromInset(ins); + dr.screenUpdate(cur.result().screenUpdate()); + if (cur.result().needBufferUpdate()) + dr.forceBufferUpdate(); + break; + } + case LFUN_MARK_OFF: cur.clearSelection(); dr.setMessage(from_utf8(N_("Mark off"))); @@ -1872,16 +1953,14 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) message += _("One word"); message += "\n"; if (chars_blanks != 1) - message += bformat(_("%1$d characters (including blanks)"), - chars_blanks); + message += bformat(_("%1$d characters"), chars_blanks); else - message += _("One character (including blanks)"); + message += _("One character"); message += "\n"; if (chars != 1) - message += bformat(_("%1$d characters (excluding blanks)"), - chars); + message += bformat(_("%1$d characters (no blanks)"), chars); else - message += _("One character (excluding blanks)"); + message += _("One character (no blanks)"); Alert::information(_("Statistics"), message); } @@ -1907,7 +1986,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) cur.setCursor(doc_iterator_begin(cur.buffer())); cur.selHandle(false); // Force an immediate computation of metrics because we need it below - updateMetrics(); + if (scrolled) + processUpdateFlags(Update::Force); d->text_metrics_[&buffer_.text()].editXY(cur, p.x_, p.y_, true, act == LFUN_SCREEN_UP); @@ -2063,21 +2143,22 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) // an arbitrary number to limit number of iterations const int max_iter = 100000; int iterations = 0; - Cursor & curs = d->cursor_; - Cursor const savecur = curs; - curs.reset(); - if (!curs.nextInset()) - curs.forwardInset(); - curs.beginUndoGroup(); - while(curs && iterations < max_iter) { - Inset * const ins = curs.nextInset(); + Cursor & bvcur = d->cursor_; + Cursor const savecur = bvcur; + bvcur.reset(); + if (!bvcur.nextInset()) + bvcur.forwardInset(); + bvcur.beginUndoGroup(); + while(bvcur && iterations < max_iter) { + Inset * const ins = bvcur.nextInset(); if (!ins) break; docstring insname = ins->layoutName(); while (!insname.empty()) { if (insname == name || name == from_utf8("*")) { - curs.recordUndo(); lyx::dispatch(fr, dr); + // we do not want to remember selection here + bvcur.clearSelection(); ++iterations; break; } @@ -2087,11 +2168,11 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) insname = insname.substr(0, i); } // if we did not delete the inset, skip it - if (!curs.nextInset() || curs.nextInset() == ins) - curs.forwardInset(); + if (!bvcur.nextInset() || bvcur.nextInset() == ins) + bvcur.forwardInset(); } - curs = savecur; - curs.fixIfBroken(); + bvcur = savecur; + bvcur.fixIfBroken(); /** This is a dummy undo record only to remember the cursor * that has just been set; this will be used on a redo action * (see ticket #10097) @@ -2099,8 +2180,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) * FIXME: a better fix would be to have a way to set the * cursor value directly, but I am not sure it is worth it. */ - curs.recordUndo(); - curs.endUndoGroup(); + bvcur.recordUndo(); + bvcur.endUndoGroup(); dr.screenUpdate(Update::Force); dr.forceBufferUpdate(); @@ -2464,6 +2545,12 @@ void BufferView::clearLastInset(Inset * inset) const } +bool BufferView::mouseSelecting() const +{ + return d->mouse_selecting_; +} + + void BufferView::mouseEventDispatch(FuncRequest const & cmd0) { //lyxerr << "[ cmd0 " << cmd0 << "]" << endl; @@ -2486,6 +2573,9 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0) d->mouse_position_cache_.x_ = cmd.x(); d->mouse_position_cache_.y_ = cmd.y(); + d->mouse_selecting_ = + cmd.action() == LFUN_MOUSE_MOTION && cmd.button() == mouse_button::button1; + if (cmd.action() == LFUN_MOUSE_MOTION && cmd.button() == mouse_button::none) { updateHoveredInset(); return; @@ -2527,8 +2617,8 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0) // Notify left insets if (cur != old) { - bool badcursor = old.fixIfBroken() | cur.fixIfBroken(); - badcursor |= notifyCursorLeavesOrEnters(old, cur); + bool badcursor = old.fixIfBroken() || cur.fixIfBroken(); + badcursor = badcursor || notifyCursorLeavesOrEnters(old, cur); if (badcursor) cursor().fixIfBroken(); } @@ -2617,7 +2707,7 @@ bool BufferView::setCursorFromRow(int row) { TexRow::TextEntry start, end; tie(start,end) = buffer_.texrow().getEntriesFromRow(row); - LYXERR(Debug::LATEX, + LYXERR(Debug::OUTFILE, "setCursorFromRow: for row " << row << ", TexRow has found " "start (id=" << start.id << ",pos=" << start.pos << "), " "end (id=" << end.id << ",pos=" << end.pos << ")"); @@ -3388,15 +3478,12 @@ void BufferView::checkCursorScrollOffset() //lyxerr << "cur_x=" << cur_x << ", offset=" << offset << ", row.wid=" << row.width() << ", margin=" << MARGIN << endl; - if (offset != d->horiz_scroll_offset_) + if (offset != d->horiz_scroll_offset_) { LYXERR(Debug::PAINTING, "Horiz. scroll offset changed from " << d->horiz_scroll_offset_ << " to " << offset); - - if (d->update_strategy_ == NoScreenUpdate - && offset != d->horiz_scroll_offset_) { - // FIXME: if one uses SingleParUpdate, then home/end - // will not work on long rows. Why? - d->update_strategy_ = FullScreenUpdate; + row.changed(true); + if (d->update_strategy_ == NoScreenUpdate) + d->update_strategy_ = SingleParUpdate; } d->horiz_scroll_offset_ = offset; @@ -3481,7 +3568,7 @@ void BufferView::draw(frontend::Painter & pain, bool paint_caret) // The scrollbar needs an update. // FIXME: does it always? see ticket #11947. - updateScrollbar(); + updateScrollbarParameters(); // Normalize anchor for next time pair firstpm = tm.first();