X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView.cpp;h=fc7c7bb80828f9a977d39c12ef906120a7c6a56c;hb=7c63b4f2603f2bccb00a9266fed08a14dcc0fb9c;hp=74152382887da3693edc317eaa5aea7515e5ffdb;hpb=e1ba93a068d8f4b8bc5a677545605e95cbab85cc;p=lyx.git diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 7415238288..fc7c7bb808 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -58,9 +58,9 @@ #include "insets/InsetCommand.h" // ChangeRefs #include "insets/InsetExternal.h" #include "insets/InsetGraphics.h" +#include "insets/InsetNote.h" #include "insets/InsetRef.h" #include "insets/InsetText.h" -#include "insets/InsetNote.h" #include "frontends/alert.h" #include "frontends/Application.h" @@ -107,10 +107,7 @@ T * getInsetByCode(Cursor const & cur, InsetCode code) return 0; } - -bool findInset(DocIterator & dit, vector const & codes, - bool same_content); - +/// Note that comparing contents can only be used for InsetCommand bool findNextInset(DocIterator & dit, vector const & codes, docstring const & contents) { @@ -118,12 +115,17 @@ bool findNextInset(DocIterator & dit, vector const & codes, while (tmpdit) { Inset const * inset = tmpdit.nextInset(); - if (inset - && std::find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end() - && (contents.empty() || - static_cast(inset)->getFirstNonOptParam() == contents)) { - dit = tmpdit; - return true; + if (inset) { + bool const valid_code = std::find(codes.begin(), codes.end(), + inset->lyxCode()) != codes.end(); + InsetCommand const * ic = inset->asInsetCommand(); + bool const same_or_no_contents = contents.empty() + || (ic && (ic->getFirstNonOptParam() == contents)); + + if (valid_code && same_or_no_contents) { + dit = tmpdit; + return true; + } } tmpdit.forwardInset(); } @@ -133,6 +135,7 @@ bool findNextInset(DocIterator & dit, vector const & codes, /// Looks for next inset with one of the given codes. +/// Note that same_content can only be used for InsetCommand bool findInset(DocIterator & dit, vector const & codes, bool same_content) { @@ -142,11 +145,14 @@ bool findInset(DocIterator & dit, vector const & codes, if (!tmpdit) return false; - if (same_content) { - Inset const * inset = tmpdit.nextInset(); - if (inset - && std::find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end()) { - contents = static_cast(inset)->getFirstNonOptParam(); + Inset const * inset = tmpdit.nextInset(); + if (same_content && inset) { + InsetCommand const * ic = inset->asInsetCommand(); + if (ic) { + bool const valid_code = std::find(codes.begin(), codes.end(), + ic->lyxCode()) != codes.end(); + if (valid_code) + contents = ic->getFirstNonOptParam(); } } @@ -220,8 +226,9 @@ struct BufferView::Private Private(BufferView & bv): wh_(0), cursor_(bv), anchor_pit_(0), anchor_ypos_(0), inlineCompletionUniqueChars_(0), - last_inset_(0), mouse_position_cache_(), - bookmark_edit_position_(0), gui_(0) + last_inset_(0), clickable_inset_(false), + mouse_position_cache_(), + bookmark_edit_position_(-1), gui_(0) {} /// @@ -262,7 +269,9 @@ struct BufferView::Private /** kept to send setMouseHover(false). * Not owned, so don't delete. */ - Inset * last_inset_; + Inset const * last_inset_; + /// are we hovering something that we can click + bool clickable_inset_; /// position of the mouse at the time of the last mouse move /// This is used to update the hovering status of inset in @@ -299,8 +308,7 @@ BufferView::BufferView(Buffer & buf) d->cursor_.resetAnchor(); d->cursor_.setCurrentFont(); - if (graphics::Previews::status() != LyXRC::PREVIEW_OFF) - thePreviews().generateBufferPreviews(buffer_); + buffer_.updatePreviews(); } @@ -413,6 +421,8 @@ void BufferView::processUpdateFlags(Update::flags flags) << ", singlepar = " << (flags & Update::SinglePar) << "] buffer: " << &buffer_); + // FIXME Does this really need doing here? It's done in updateBuffer, and + // if the Buffer doesn't need updating, then do the macros? buffer_.updateMacros(); // Now do the first drawing step if needed. This consists on updating @@ -568,7 +578,7 @@ docstring BufferView::contextMenu(int x, int y) const } -void BufferView::scrollDocView(int value) +void BufferView::scrollDocView(int value, bool update) { int const offset = value - d->scrollbarParameters_.position; @@ -587,7 +597,7 @@ void BufferView::scrollDocView(int value) // cut off at the top if (value <= d->scrollbarParameters_.min) { DocIterator dit = doc_iterator_begin(&buffer_); - showCursor(dit, false); + showCursor(dit, false, update); LYXERR(Debug::SCROLLING, "scroll to top"); return; } @@ -596,7 +606,7 @@ void BufferView::scrollDocView(int value) if (value >= d->scrollbarParameters_.max) { DocIterator dit = doc_iterator_end(&buffer_); dit.backwardPos(); - showCursor(dit, false); + showCursor(dit, false, update); LYXERR(Debug::SCROLLING, "scroll to bottom"); return; } @@ -614,14 +624,14 @@ void BufferView::scrollDocView(int value) // It seems we didn't find the correct pit so stay on the safe side and // scroll to bottom. LYXERR0("scrolling position not found!"); - scrollDocView(d->scrollbarParameters_.max); + scrollDocView(d->scrollbarParameters_.max, update); return; } DocIterator dit = doc_iterator_begin(&buffer_); dit.pit() = i; LYXERR(Debug::SCROLLING, "value = " << value << " -> scroll to pit " << i); - showCursor(dit, false); + showCursor(dit, false, update); } @@ -806,19 +816,20 @@ int BufferView::workWidth() const void BufferView::recenter() { - showCursor(d->cursor_, true); + showCursor(d->cursor_, true, true); } void BufferView::showCursor() { - showCursor(d->cursor_, false); + showCursor(d->cursor_, false, true); } -void BufferView::showCursor(DocIterator const & dit, bool recenter) +void BufferView::showCursor(DocIterator const & dit, + bool recenter, bool update) { - if (scrollToCursor(dit, recenter)) { + if (scrollToCursor(dit, recenter) && update) { buffer_.changed(true); updateHoveredInset(); } @@ -934,7 +945,6 @@ void BufferView::updateDocumentClass(DocumentClass const * const olddc) setCursor(backcur.asDocIterator(&buffer_)); buffer_.errors("Class Switch"); - buffer_.updateBuffer(); } /** Return the change status at cursor position, taking in account the @@ -991,8 +1001,8 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) // FIXME: This is a bit problematic because we don't check if this is // a document BufferView or not for these LFUNs. We probably have to // dispatch both to currentBufferView() and, if that fails, - // to documentBufferView(); same as we do know for current Buffer and - // document Buffer. Ideally those LFUN should go to Buffer as they* + // to documentBufferView(); same as we do now for current Buffer and + // document Buffer. Ideally those LFUN should go to Buffer as they // operate on the full Buffer and the cursor is only needed either for // an Undo record or to restore a cursor position. But we don't know // how to do that inside Buffer of course. @@ -1006,10 +1016,14 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) break; case LFUN_UNDO: - flag.setEnabled(buffer_.undo().hasUndoStack()); + // We do not use the LyXAction flag for readonly because Undo sets the + // buffer clean/dirty status by itself. + flag.setEnabled(!buffer_.isReadonly() && buffer_.undo().hasUndoStack()); break; case LFUN_REDO: - flag.setEnabled(buffer_.undo().hasRedoStack()); + // We do not use the LyXAction flag for readonly because Redo sets the + // buffer clean/dirty status by itself. + flag.setEnabled(!buffer_.isReadonly() && buffer_.undo().hasRedoStack()); break; case LFUN_FILE_INSERT: case LFUN_FILE_INSERT_PLAINTEXT_PARA: @@ -1111,7 +1125,7 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) if (cur.inset().lyxCode() == CAPTION_CODE) return cur.inset().getStatus(cur, cmd, flag); // FIXME we should consider passthru paragraphs too. - flag.setEnabled(!cur.inset().getLayout().isPassThru()); + flag.setEnabled(!(cur.inTexted() && cur.paragraph().isPassThru())); break; case LFUN_CITATION_INSERT: { @@ -1201,7 +1215,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) // 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. - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force | Update::FitCursor); + dr.forceBufferUpdate(); break; } @@ -1212,7 +1227,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) buffer_.params().clearLayoutModules(); buffer_.params().makeDocumentClass(); updateDocumentClass(oldClass); - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force); + dr.forceBufferUpdate(); break; } @@ -1229,14 +1245,23 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) buffer_.params().addLayoutModule(argument); buffer_.params().makeDocumentClass(); updateDocumentClass(oldClass); - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force); + dr.forceBufferUpdate(); break; } case LFUN_TEXTCLASS_APPLY: { - if (!LayoutFileList::get().load(argument, buffer_.temppath()) && - !LayoutFileList::get().load(argument, buffer_.filePath())) + // since this shortcircuits, the second call is made only if + // the first fails + bool const success = + LayoutFileList::get().load(argument, buffer_.temppath()) || + LayoutFileList::get().load(argument, buffer_.filePath()); + if (!success) { + docstring s = bformat(_("The document class `%1$s' " + "could not be loaded."), from_utf8(argument)); + frontend::Alert::error(_("Could not load class"), s); break; + } LayoutFile const * old_layout = buffer_.params().baseClass(); LayoutFile const * new_layout = &(LayoutFileList::get()[argument]); @@ -1245,21 +1270,31 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) // nothing to do break; - //Save the old, possibly modular, layout for use in conversion. + // Save the old, possibly modular, layout for use in conversion. DocumentClass const * const oldDocClass = buffer_.params().documentClassPtr(); cur.recordUndoFullDocument(); buffer_.params().setBaseClass(argument); buffer_.params().makeDocumentClass(); updateDocumentClass(oldDocClass); - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force); + dr.forceBufferUpdate(); break; } - case LFUN_TEXTCLASS_LOAD: - LayoutFileList::get().load(argument, buffer_.temppath()) || - LayoutFileList::get().load(argument, buffer_.filePath()); + case LFUN_TEXTCLASS_LOAD: { + // since this shortcircuits, the second call is made only if + // the first fails + bool const success = + LayoutFileList::get().load(argument, buffer_.temppath()) || + LayoutFileList::get().load(argument, buffer_.filePath()); + if (!success) { + docstring s = bformat(_("The document class `%1$s' " + "could not be loaded."), from_utf8(argument)); + frontend::Alert::error(_("Could not load class"), s); + } break; + } case LFUN_LAYOUT_RELOAD: { DocumentClass const * const oldClass = buffer_.params().documentClassPtr(); @@ -1268,7 +1303,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) buffer_.params().setBaseClass(bc); buffer_.params().makeDocumentClass(); updateDocumentClass(oldClass); - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force); + dr.forceBufferUpdate(); break; } @@ -1278,7 +1314,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) if (!cur.textUndo()) dr.setMessage(_("No further undo information")); else - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force | Update::FitCursor); + dr.forceBufferUpdate(); break; case LFUN_REDO: @@ -1287,7 +1324,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) if (!cur.textRedo()) dr.setMessage(_("No further redo information")); else - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force | Update::FitCursor); + dr.forceBufferUpdate(); break; case LFUN_FONT_STATE: @@ -1309,8 +1347,13 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) saveBookmark(0); } } - if (!label.empty()) + if (!label.empty()) { gotoLabel(label); + // at the moment, this is redundant, since gotoLabel will + // eventually call LFUN_PARAGRAPH_GOTO, but it seems best + // to have it here. + dr.screenUpdate(Update::Force | Update::FitCursor); + } break; } @@ -1335,7 +1378,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) // Set the cursor dit.pos() = pos; setCursor(dit); - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force | Update::FitCursor); } else { // Switch to other buffer view and resend cmd lyx::dispatch(FuncRequest( @@ -1389,18 +1432,19 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) case LFUN_CHANGE_NEXT: findNextChange(this); // FIXME: Move this LFUN to Buffer so that we don't have to do this: - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(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: - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force | Update::FitCursor); break; case LFUN_CHANGES_MERGE: if (findNextChange(this) || findPreviousChange(this)) { - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force | Update::FitCursor); + dr.forceBufferUpdate(); showDialog("changes"); } break; @@ -1413,7 +1457,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) // 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: - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force | Update::FitCursor); + dr.forceBufferUpdate(); break; case LFUN_ALL_CHANGES_REJECT: @@ -1425,7 +1470,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) // 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: - dr.update(Update::Force | Update::FitCursor); + dr.screenUpdate(Update::Force | Update::FitCursor); + dr.forceBufferUpdate(); break; case LFUN_WORD_FIND_FORWARD: @@ -1446,7 +1492,9 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) bool const fw = act == LFUN_WORD_FIND_FORWARD; docstring const data = find2string(searched_string, true, false, fw); - find(this, FuncRequest(LFUN_WORD_FIND, data)); + bool found = lyxfind(this, FuncRequest(LFUN_WORD_FIND, data)); + if (found) + dr.screenUpdate(Update::Force | Update::FitCursor); break; } @@ -1458,8 +1506,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "findreplace")); break; } - if (find(this, req)) - showCursor(); + if (lyxfind(this, req)) + dr.screenUpdate(Update::Force | Update::FitCursor); else message(_("String not found!")); d->search_request_cache_ = req; @@ -1473,13 +1521,17 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) DocIterator end = cur.selectionEnd(); if (beg.pit() == end.pit()) { for (pos_type p = beg.pos() ; p < end.pos() ; ++p) { - if (!cur.inMathed() - && cur.paragraph().isDeleted(p)) + if (!cur.inMathed() && cur.paragraph().isDeleted(p)) { has_deleted = true; + break; + } } } } - replace(this, cmd, has_deleted); + if (lyxreplace(this, cmd, has_deleted)) { + dr.forceBufferUpdate(); + dr.screenUpdate(Update::Force | Update::FitCursor); + } break; } @@ -1487,10 +1539,14 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) FindAndReplaceOptions opt; istringstream iss(to_utf8(cmd.argument())); iss >> opt; - if (findAdv(this, opt)) + if (findAdv(this, opt)) { + dr.screenUpdate(Update::Force | Update::FitCursor); cur.dispatched(); - else + dispatched = true; + } else { cur.undispatched(); + dispatched = false; + } break; } @@ -1531,8 +1587,10 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) InsetBibtex * inset = getInsetByCode(tmpcur, BIBTEX_CODE); if (inset) { - if (inset->addDatabase(cmd.argument())) - buffer_.updateBibfilesCache(); + if (inset->addDatabase(cmd.argument())) { + buffer_.invalidateBibfileCache(); + dr.forceBufferUpdate(); + } } break; } @@ -1543,8 +1601,10 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) InsetBibtex * inset = getInsetByCode(tmpcur, BIBTEX_CODE); if (inset) { - if (inset->delDatabase(cmd.argument())) - buffer_.updateBibfilesCache(); + if (inset->delDatabase(cmd.argument())) { + buffer_.invalidateBibfileCache(); + dr.forceBufferUpdate(); + } } break; } @@ -1624,13 +1684,16 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) //FIXME: what to do with cur.x_target()? bool update = in_texted && cur.bv().checkDepm(cur, old); cur.finishUndo(); - if (update) - dr.update(Update::Force | Update::FitCursor); + if (update) { + dr.screenUpdate(Update::Force | Update::FitCursor); + dr.forceBufferUpdate(); + } break; } case LFUN_SCROLL: lfunScroll(cmd); + dr.forceBufferUpdate(); break; case LFUN_SCREEN_UP_SELECT: { @@ -1646,7 +1709,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) y = getPos(cur).y_; cur.finishUndo(); - dr.update(Update::SinglePar | Update::FitCursor); + dr.screenUpdate(Update::SinglePar | Update::FitCursor); break; } @@ -1663,7 +1726,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) y = getPos(cur).y_; cur.finishUndo(); - dr.update(Update::SinglePar | Update::FitCursor); + dr.screenUpdate(Update::SinglePar | Update::FitCursor); break; } @@ -1688,7 +1751,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) Inset * ins = cur.nextInset(); if (!ins) break; - docstring insname = ins->name(); + docstring insname = ins->layoutName(); while (!insname.empty()) { if (insname == name || name == from_utf8("*")) { cur.recordUndo(); @@ -1706,7 +1769,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) cur.endUndoGroup(); cur = savecur; cur.fixIfBroken(); - dr.update(Update::Force); + dr.screenUpdate(Update::Force); + dr.forceBufferUpdate(); if (iterations >= max_iter) { dr.setError(true); @@ -1787,7 +1851,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) icp["key"] = from_utf8(arg); if (!opt1.empty()) icp["before"] = from_utf8(opt1); - string icstr = InsetCommand::params2string("citation", icp); + string icstr = InsetCommand::params2string(icp); FuncRequest fr(LFUN_INSET_INSERT, icstr); lyx::dispatch(fr); break; @@ -1808,18 +1872,21 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) cur.recordUndo(); FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument()); inset->dispatch(cur, fr); - dr.update(Update::SinglePar | Update::FitCursor); + dr.screenUpdate(cur.result().screenUpdate()); + if (cur.result().needBufferUpdate()) + dr.forceBufferUpdate(); break; } default: - dispatched = false; + // OK, so try the Buffer itself... + buffer_.dispatch(cmd, dr); + dispatched = dr.dispatched(); break; } buffer_.undo().endUndoGroup(); dr.dispatched(dispatched); - return; } @@ -1907,8 +1974,12 @@ Inset const * BufferView::getCoveringInset(Text const & text, void BufferView::updateHoveredInset() const { // Get inset under mouse, if there is one. - Inset const * covering_inset = getCoveringInset(buffer_.text(), - d->mouse_position_cache_.x_, d->mouse_position_cache_.y_); + int const x = d->mouse_position_cache_.x_; + int const y = d->mouse_position_cache_.y_; + Inset const * covering_inset = getCoveringInset(buffer_.text(), x, y); + + d->clickable_inset_ = covering_inset && covering_inset->clickable(x, y); + if (covering_inset == d->last_inset_) // Same inset, no need to do anything... return; @@ -1920,14 +1991,12 @@ void BufferView::updateHoveredInset() const d->last_inset_ = 0; } - // const_cast because of setMouseHover(). - Inset * inset = const_cast(covering_inset); - if (inset && inset->setMouseHover(this, true)) { + if (covering_inset && covering_inset->setMouseHover(this, true)) { need_redraw = true; // Only the insets that accept the hover state, do // clear the last_inset_, so only set the last_inset_ // member if the hovered setting is accepted. - d->last_inset_ = inset; + d->last_inset_ = covering_inset; } if (need_redraw) { @@ -2015,8 +2084,8 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0) theSelection().haveSelection(cursor().selection()); // If the command has been dispatched, - if (cur.result().dispatched() || cur.result().update()) - processUpdateFlags(cur.result().update()); + if (cur.result().dispatched() || cur.result().screenUpdate()) + processUpdateFlags(cur.result().screenUpdate()); } @@ -2147,8 +2216,8 @@ bool BufferView::setCursorFromInset(Inset const * inset) void BufferView::gotoLabel(docstring const & label) { - std::vector bufs = buffer().allRelatives(); - std::vector::iterator it = bufs.begin(); + ListOfBuffers bufs = buffer().allRelatives(); + ListOfBuffers::iterator it = bufs.begin(); for (; it != bufs.end(); ++it) { Buffer const * buf = *it; @@ -2174,6 +2243,7 @@ TextMetrics const & BufferView::textMetrics(Text const * t) const TextMetrics & BufferView::textMetrics(Text const * t) { + LASSERT(t, /**/); TextMetricsCache::iterator tmc_it = d->text_metrics_.find(t); if (tmc_it == d->text_metrics_.end()) { tmc_it = d->text_metrics_.insert( @@ -2226,7 +2296,7 @@ bool BufferView::checkDepm(Cursor & cur, Cursor & old) d->cursor_ = cur; - buffer_.updateBuffer(); + cur.forceBufferUpdate(); buffer_.changed(true); return true; } @@ -2270,6 +2340,8 @@ bool BufferView::mouseSetCursor(Cursor & cur, bool select) d->cursor_.finishUndo(); d->cursor_.setCurrentFont(); + if (update) + cur.forceBufferUpdate(); return update; } @@ -2288,9 +2360,42 @@ void BufferView::putSelectionAt(DocIterator const & cur, } else d->cursor_.setSelection(d->cursor_, length); } - // Ensure a redraw happens in any case because the new selection could - // possibly be on the same screen as the previous selection. - processUpdateFlags(Update::Force | Update::FitCursor); +} + + +bool BufferView::selectIfEmpty(DocIterator & cur) +{ + if (!cur.paragraph().empty()) + return false; + + pit_type const beg_pit = cur.pit(); + if (beg_pit > 0) { + // The paragraph associated to this item isn't + // the first one, so it can be selected + cur.backwardPos(); + } else { + // We have to resort to select the space between the + // end of this item and the begin of the next one + cur.forwardPos(); + } + if (cur.empty()) { + // If it is the only item in the document, + // nothing can be selected + return false; + } + pit_type const end_pit = cur.pit(); + pos_type const end_pos = cur.pos(); + d->cursor_.clearSelection(); + d->cursor_.reset(); + d->cursor_.setCursor(cur); + d->cursor_.pit() = beg_pit; + d->cursor_.pos() = 0; + d->cursor_.setSelection(false); + d->cursor_.resetAnchor(); + d->cursor_.pit() = end_pit; + d->cursor_.pos() = end_pos; + d->cursor_.setSelection(); + return true; } @@ -2448,8 +2553,8 @@ void BufferView::insertLyXFile(FileName const & fname) message(bformat(_("Inserting document %1$s..."), disp_fn)); docstring res; - Buffer buf("", false); - if (buf.loadLyXFile(filename)) { + Buffer buf(filename.absFileName(), false); + if (buf.loadLyXFile() == Buffer::ReadSuccess) { ErrorList & el = buffer_.errorList("Parse"); // Copy the inserted document error list into the current buffer one. el = buf.errorList("Parse"); @@ -2464,7 +2569,6 @@ void BufferView::insertLyXFile(FileName const & fname) buffer_.changed(true); // emit message signal. message(bformat(res, disp_fn)); - buffer_.errors("Parse"); } @@ -2791,6 +2895,12 @@ DocIterator const & BufferView::inlineCompletionPos() const } +void BufferView::resetInlineCompletionPos() +{ + d->inlineCompletionPos_ = DocIterator(); +} + + bool samePar(DocIterator const & a, DocIterator const & b) { if (a.empty() && b.empty()) @@ -2830,11 +2940,17 @@ void BufferView::setInlineCompletion(Cursor & cur, DocIterator const & pos, // set update flags if (changed) { - if (singlePar && !(cur.result().update() & Update::Force)) - cur.updateFlags(cur.result().update() | Update::SinglePar); + if (singlePar && !(cur.result().screenUpdate() & Update::Force)) + cur.screenUpdateFlags(cur.result().screenUpdate() | Update::SinglePar); else - cur.updateFlags(cur.result().update() | Update::Force); + cur.screenUpdateFlags(cur.result().screenUpdate() | Update::Force); } } + +bool BufferView::clickableInset() const +{ + return d->clickable_inset_; +} + } // namespace lyx