X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView.cpp;h=d5ee51739c26aa8ffddf2034d4a96cdb706857d8;hb=cf15bd840b71a01ccbb2fbbbabc7066237b4bfd2;hp=50d7f086f30707ac4727a785666ce24393831712;hpb=72b270ab4b146e58c26e202e134408faad8394f4;p=lyx.git diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 50d7f086f3..d5ee51739c 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -238,6 +238,13 @@ struct BufferView::Private /// vector par_height_; + /// + DocIterator inlineCompletionPos; + /// + docstring inlineCompletion; + /// + size_t inlineCompletionUniqueChars; + /// keyboard mapping object. Intl intl_; @@ -761,7 +768,7 @@ void BufferView::showCursor(DocIterator const & dit) else if (bot_pit == tm.last().first + 1) tm.newParMetricsDown(); - if (tm.has(bot_pit)) { + if (tm.contains(bot_pit)) { ParagraphMetrics const & pm = tm.parMetrics(bot_pit); BOOST_ASSERT(!pm.rows().empty()); // FIXME: smooth scrolling doesn't work in mathed. @@ -778,6 +785,10 @@ void BufferView::showCursor(DocIterator const & dit) return; } + // fix inline completion position + if (d->inlineCompletionPos.fixIfBroken()) + d->inlineCompletionPos = DocIterator(); + tm.redoParagraph(bot_pit); ParagraphMetrics const & pm = tm.parMetrics(bot_pit); int offset = coordOffset(dit, dit.boundary()).y_; @@ -1357,24 +1368,14 @@ void BufferView::clearSelection() void BufferView::resize(int width, int height) { - bool initialResize = (height_ == 0); - // Update from work area width_ = width; height_ = height; // Clear the paragraph height cache. d->par_height_.clear(); - + // Redo the metrics. updateMetrics(); - - // view got his initial size, make sure that - // the cursor has a proper position - if (initialResize) { - updateScrollbar(); - showCursor(); - } - processUpdateFlags(Update::Force | Update::FitCursor); } @@ -1416,6 +1417,7 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0) // LFUN_FILE_OPEN generated by drag-and-drop. FuncRequest cmd = cmd0; + Cursor old = cursor(); Cursor cur(*this); cur.push(buffer_.inset()); cur.selection() = d->cursor_.selection(); @@ -1477,13 +1479,19 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0) if (!cur.result().dispatched()) cur.dispatch(cmd); - //Do we have a selection? + // Notify left insets + if (cur != old) { + old.fixIfBroken(); + bool badcursor = notifyCursorLeaves(old, cur); + if (badcursor) + cursor().fixIfBroken(); + } + + // Do we have a selection? theSelection().haveSelection(cursor().selection()); // If the command has been dispatched, - if (cur.result().dispatched() - // an update is asked, - && cur.result().update()) + if (cur.result().dispatched() || cur.result().update()) processUpdateFlags(cur.result().update()); } @@ -1585,7 +1593,7 @@ void BufferView::gotoLabel(docstring const & label) { for (InsetIterator it = inset_iterator_begin(buffer_.inset()); it; ++it) { vector labels; - it->getLabelList(buffer_, labels); + it->getLabelList(labels); if (std::find(labels.begin(), labels.end(), label) != labels.end()) { setCursor(it); showCursor(); @@ -1674,8 +1682,12 @@ bool BufferView::mouseSetCursor(Cursor & cur, bool select) // Has the cursor just left the inset? bool badcursor = false; bool leftinset = (&d->cursor_.inset() != &cur.inset()); - if (leftinset) + if (leftinset) { + d->cursor_.fixIfBroken(); badcursor = notifyCursorLeaves(d->cursor_, cur); + if (badcursor) + cur.fixIfBroken(); + } // FIXME: shift-mouse selection doesn't work well across insets. bool do_selection = select && &d->cursor_.anchor().inset() == &cur.inset(); @@ -1688,24 +1700,7 @@ bool BufferView::mouseSetCursor(Cursor & cur, bool select) if (!do_selection && !badcursor && d->cursor_.inTexted()) update |= checkDepm(cur, d->cursor_); - // if the cursor was in an empty script inset and the new - // position is in the nucleus of the inset, notifyCursorLeaves - // will kill the script inset itself. So we check all the - // elements of the cursor to make sure that they are correct. - // For an example, see bug 2933: - // http://bugzilla.lyx.org/show_bug.cgi?id=2933 - // The code below could maybe be moved to a DocIterator method. - //lyxerr << "cur before " << cur << endl; - DocIterator dit = doc_iterator_begin(cur.inset()); - dit.bottom() = cur.bottom(); - size_t i = 1; - while (i < cur.depth() && dit.nextInset() == &cur[i].inset()) { - dit.push_back(cur[i]); - ++i; - } - //lyxerr << "5 cur after" << dit <cursor_.setCursor(dit); + d->cursor_.setCursor(cur); d->cursor_.boundary(cur.boundary()); if (do_selection) d->cursor_.setSelection(); @@ -1763,6 +1758,10 @@ bool BufferView::singleParUpdate() TextMetrics & tm = textMetrics(&buftext); int old_height = tm.parMetrics(bottom_pit).height(); + // make sure inline completion pointer is ok + if (d->inlineCompletionPos.fixIfBroken()) + d->inlineCompletionPos = DocIterator(); + // In Single Paragraph mode, rebreak only // the (main text, not inset!) paragraph containing the cursor. // (if this paragraph contains insets etc., rebreaking will @@ -1799,6 +1798,14 @@ void BufferView::updateMetrics() TextMetrics & tm = textMetrics(&buftext); + // make sure inline completion pointer is ok + if (d->inlineCompletionPos.fixIfBroken()) + d->inlineCompletionPos = DocIterator(); + + if (d->anchor_pit_ >= npit) + // The anchor pit must have been deleted... + d->anchor_pit_ = npit - 1; + // Rebreak anchor paragraph. tm.redoParagraph(d->anchor_pit_); ParagraphMetrics & anchor_pm = tm.par_metrics_[d->anchor_pit_]; @@ -1884,7 +1891,7 @@ void BufferView::insertLyXFile(FileName const & fname) el = buf.errorList("Parse"); buffer_.undo().recordUndo(d->cursor_); cap::pasteParagraphList(d->cursor_, buf.paragraphs(), - buf.params().getTextClassPtr(), el); + buf.params().documentClassPtr(), el); res = _("Document %1$s inserted."); } else { res = _("Could not insert document %1$s"); @@ -1992,7 +1999,7 @@ Point BufferView::getPos(DocIterator const & dit, bool boundary) const { CursorSlice const & bot = dit.bottom(); TextMetrics const & tm = textMetrics(bot.text()); - if (!tm.has(bot.pit())) + if (!tm.contains(bot.pit())) return Point(-1, -1); Point p = coordOffset(dit, boundary); // offset from outer paragraph @@ -2162,4 +2169,67 @@ void BufferView::insertPlaintextFile(FileName const & f, bool asParagraph) buffer_.changed(); } + +docstring const & BufferView::inlineCompletion() const +{ + return d->inlineCompletion; +} + + +size_t const & BufferView::inlineCompletionUniqueChars() const +{ + return d->inlineCompletionUniqueChars; +} + + +DocIterator const & BufferView::inlineCompletionPos() const +{ + return d->inlineCompletionPos; +} + + +bool samePar(DocIterator const & a, DocIterator const & b) +{ + if (a.empty() && b.empty()) + return true; + if (a.empty() || b.empty()) + return false; + return &a.innerParagraph() == &b.innerParagraph(); +} + + +void BufferView::setInlineCompletion(Cursor & cur, DocIterator const & pos, + docstring const & completion, size_t uniqueChars) +{ + uniqueChars = min(completion.size(), uniqueChars); + bool changed = d->inlineCompletion != completion + || d->inlineCompletionUniqueChars != uniqueChars; + bool singlePar = true; + d->inlineCompletion = completion; + d->inlineCompletionUniqueChars = min(completion.size(), uniqueChars); + + //lyxerr << "setInlineCompletion pos=" << pos << " completion=" << completion << " uniqueChars=" << uniqueChars << std::endl; + + // at new position? + DocIterator const & old = d->inlineCompletionPos; + if (old != pos) { + //lyxerr << "inlineCompletionPos changed" << std::endl; + // old or pos are in another paragraph? + if ((!samePar(cur, pos) && !pos.empty()) + || (!samePar(cur, old) && !old.empty())) { + singlePar = false; + //lyxerr << "different paragraph" << std::endl; + } + d->inlineCompletionPos = pos; + } + + // set update flags + if (changed) { + if (singlePar && !(cur.disp_.update() & Update::Force)) + cur.updateFlags(cur.disp_.update() | Update::SinglePar); + else + cur.updateFlags(cur.disp_.update() | Update::Force); + } +} + } // namespace lyx