diff --git a/src/BufferView.cpp b/src/BufferView.cpp index cb7ea79050..a6b2ae2ac4 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -1411,7 +1411,11 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) case LFUN_PARAGRAPH_GOTO: { int const id = convert(cmd.getArg(0)); - int const pos = convert(cmd.getArg(1)); + pos_type const pos = convert(cmd.getArg(1)); + if (id < 0) + break; + string const str_id_end = cmd.getArg(2); + string const str_pos_end = cmd.getArg(3); int i = 0; for (Buffer * b = &buffer_; i == 0 || b != &buffer_; b = theBufferList().next(b)) { @@ -1428,10 +1432,20 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) << b->absFileName() << "'."); if (b == &buffer_) { - // Set the cursor - cur.pos() = pos; - mouseSetCursor(cur); - dr.screenUpdate(Update::Force | Update::FitCursor); + bool success; + if (str_id_end.empty() || str_pos_end.empty()) { + // Set the cursor + cur.pos() = pos; + mouseSetCursor(cur); + success = true; + } else { + int const id_end = convert(str_id_end); + pos_type const pos_end = convert(str_pos_end); + success = setCursorFromEntries({id, pos}, + {id_end, pos_end}); + } + if (success) + dr.screenUpdate(Update::Force | Update::FitCursor); } else { // Switch to other buffer view and resend cmd lyx::dispatch(FuncRequest( @@ -2329,36 +2343,40 @@ int BufferView::scrollUp(int offset) } -void BufferView::setCursorFromRow(int row) +bool BufferView::setCursorFromRow(int row) { - setCursorFromRow(row, buffer_.texrow()); + return setCursorFromRow(row, buffer_.texrow()); } -void BufferView::setCursorFromRow(int row, TexRow const & texrow) +bool BufferView::setCursorFromRow(int row, TexRow const & texrow) { - DocIterator start, end; - tie(start,end) = texrow.getDocIteratorFromRow(row, buffer_); - // we need to make sure that the DocIterators - // we got back are valid, because the buffer may well - // have changed since we last generated the LaTeX. - if (!start) { - LYXERR(Debug::LATEX, - "setCursorFromRow: invalid position for row " << row); - frontend::Alert::error(_("Inverse Search Failed"), - _("Invalid position requested by inverse search.\n" - "You may need to update the viewed document.")); - return; - } + TextEntry start, end; + tie(start,end) = texrow.getEntriesFromRow(row); + LYXERR(Debug::LATEX, + "setCursorFromRow: for row " << row << ", TexRow has found " + "start (id=" << start.id << ",pos=" << start.pos << "), " + "end (id=" << end.id << ",pos=" << end.pos << ")"); + return setCursorFromEntries(start, end); +} + + +bool BufferView::setCursorFromEntries(TextEntry start, TextEntry end) +{ + DocIterator dit_start, dit_end; + tie(dit_start,dit_end) = + TexRow::getDocIteratorsFromEntries(start, end, buffer_); + if (!dit_start) + return false; // Setting selection start d->cursor_.clearSelection(); - setCursor(start); + setCursor(dit_start); // Setting selection end - if (end) { + if (dit_end) { d->cursor_.resetAnchor(); - setCursorSelectionTo(end); + setCursorSelectionTo(dit_end); } - recenter(); + return true; } diff --git a/src/BufferView.h b/src/BufferView.h index e6a29dee6b..aca6f852b2 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -46,6 +46,7 @@ class ParagraphMetrics; class Point; class TexRow; class Text; +class TextEntry; class TextMetrics; enum CursorStatus { @@ -162,9 +163,11 @@ public: void gotoLabel(docstring const & label); /// set the cursor based on the given TeX source row. - void setCursorFromRow(int row); + bool setCursorFromRow(int row); /// - void setCursorFromRow(int row, TexRow const & texrow); + bool setCursorFromRow(int row, TexRow const & texrow); + /// set the cursor based on the given start and end TextEntries. + bool setCursorFromEntries(TextEntry start, TextEntry end); /// set cursor to the given inset. Return true if found. bool setCursorFromInset(Inset const *); diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp index 836f97b7bf..6674fec18b 100644 --- a/src/LyXAction.cpp +++ b/src/LyXAction.cpp @@ -2053,12 +2053,17 @@ void LyXAction::init() * \var lyx::FuncCode lyx::LFUN_PARAGRAPH_GOTO * \li Action: Jump to a paragraph given by its id number and optionally the desired position within the paragraph. - * \li Notion: Note that id number of paragraph is not the sequential number of paragraph - seen on the screen. Moreover the id is unique for all opened buffers (documents). - * \li Syntax: paragraph-goto - * \li Params: : paragraph id \n - : desired position within the paragraph + If given four arguments id_start, pos_start, id_end, pos_end, + perform a selection from start to end. + * \li Notion: Note that id number of paragraph is not the sequential number of + paragraph seen on the screen. Moreover the id is unique for all + opened buffers (documents). Both ids must belong to the same + buffer. + * \li Syntax: paragraph-goto [ ] + * \li Params: : paragraph id \n + : desired position within the paragraph * \li Origin: Dekel, 26 Aug 2000 + gmunch, 5 Sep 2016 * \endvar */ { LFUN_PARAGRAPH_GOTO, "paragraph-goto", ReadOnly | NoInternal, Edit }, diff --git a/src/TexRow.cpp b/src/TexRow.cpp index b3b1bd4938..9fd11c2d6b 100644 --- a/src/TexRow.cpp +++ b/src/TexRow.cpp @@ -15,11 +15,13 @@ #include "Buffer.h" #include "Cursor.h" +#include "FuncRequest.h" #include "Paragraph.h" #include "TexRow.h" #include "mathed/InsetMath.h" +#include "support/convert.h" #include "support/debug.h" #include "support/docstring_list.h" #include "support/lassert.h" @@ -257,16 +259,22 @@ pair TexRow::getEntriesFromRow(int const row) const } -pair TexRow::getDocIteratorFromRow( +pair TexRow::getDocIteratorsFromRow( int const row, Buffer const & buf) const { TextEntry start, end; tie(start,end) = getEntriesFromRow(row); - LYXERR(Debug::LATEX, - "getDocIteratorFromRow: for row " << row << ", TexRow has found " - "start (id=" << start.id << ",pos=" << start.pos << "), " - "end (id=" << end.id << ",pos=" << end.pos << ")"); + return getDocIteratorsFromEntries(start, end, buf); +} + + +//static +pair TexRow::getDocIteratorsFromEntries( + TextEntry start, + TextEntry end, + Buffer const & buf) +{ // Finding start DocIterator dit_start = buf.getParFromID(start.id); if (dit_start) @@ -288,6 +296,16 @@ pair TexRow::getDocIteratorFromRow( } +//static +FuncRequest TexRow::goToFunc(TextEntry start, TextEntry end) +{ + return {LFUN_PARAGRAPH_GOTO, + convert(start.id) + " " + convert(start.pos) + " " + + convert(end.id) + " " + convert(end.pos)}; +} + + + //static RowEntry TexRow::rowEntryFromCursorSlice(CursorSlice const & slice) { @@ -574,19 +592,4 @@ void TexRow::prepend(docstring_list & tex) const } - -LyXErr & operator<<(LyXErr & l, TexRow const & texrow) -{ - if (l.enabled()) { - for (size_t i = 0; i < texrow.rows(); i++) { - int id,pos; - if (texrow.getIdFromRow(i+1,id,pos) && id>0) - l << i+1 << ":" << id << ":" << pos << "\n"; - } - } - return l; -} - - - } // namespace lyx diff --git a/src/TexRow.h b/src/TexRow.h index 7ce048e30b..a95b205d5c 100644 --- a/src/TexRow.h +++ b/src/TexRow.h @@ -35,12 +35,12 @@ namespace lyx { -class LyXErr; class Buffer; class Cursor; class CursorSlice; class DocIterator; class docstring_list; +class FuncRequest; /// types for cells and math insets typedef void const * uid_type; @@ -145,23 +145,37 @@ public: /** * getEntriesFromRow - find pids and position for a given row - * @param row row number to find + * @param row number to find * @return a pair of TextEntry denoting the start and end of the position. * The TextEntry values can be isNone(). If no row is found then the first * value isNone(). */ std::pair getEntriesFromRow(int row) const; + /** + * getDocIteratorFromEntries - find pids and positions for a given row + * @param buffer where to look + * @return a pair of DocIterators denoting the start and end of the + * position. The DocIterators can be invalid. The starting DocIterator + * being invalid means that no location was found. Note: there is no + * guarantee that the DocIterators are in the same inset or even at the + * same depth. + */ + static std::pair getDocIteratorsFromEntries( + TextEntry start, + TextEntry end, + Buffer const & buf); + + // A FuncRequest to select from start to end + static FuncRequest goToFunc(TextEntry start, TextEntry end); + /** * getDocIteratorFromRow - find pids and positions for a given row * @param row number to find - * @param buffer here to look - * @return a pair of DocIterators the start and end of the position. - * The DocIterators can be invalid. The starting DocIterator being invalid - * means that no row was found. Note: there is no guarantee that the - * DocIterators are in the same inset or even at the same depth. + * @param buffer where to look + * @return a pair of DocIterators as above. */ - std::pair getDocIteratorFromRow( + std::pair getDocIteratorsFromRow( int row, Buffer const & buf) const; //TODO: remove the following by replacing it with the above @@ -275,9 +289,6 @@ public: bool operator==(RowEntry entry1, RowEntry entry2); -LyXErr & operator<<(LyXErr &, TexRow const &); - - } // namespace lyx #endif // TEXROW_H diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 317e0a1d38..fd3a6e58b9 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -3400,8 +3400,15 @@ bool GuiView::goToFileRow(string const & argument) return false; } setBuffer(buf); - documentBufferView()->setCursorFromRow(row); - return true; + bool success = documentBufferView()->setCursorFromRow(row); + if (!success) { + LYXERR(Debug::LATEX, + "setCursorFromRow: invalid position for row " << row); + frontend::Alert::error(_("Inverse Search Failed"), + _("Invalid position requested by inverse search.\n" + "You may need to update the viewed document.")); + } + return success; }