commit 67805de7de949dbe8fd1468f4d17fc44f4171721
Author: Guillaume Munch <g...@lyx.org>
Date:   Mon Sep 5 03:23:24 2016 +0100

    New LFUN paragraph-goto id_start pos_start id_end pos_end
    
    This selects from start to end.
    
    id_end must be in the same buffer as id_start.
---
 src/BufferView.cpp            |   68 ++++++++++++++++++++++++++---------------
 src/BufferView.h              |    7 +++-
 src/LyXAction.cpp             |   15 ++++++---
 src/TexRow.cpp                |   43 ++++++++++++++------------
 src/TexRow.h                  |   33 +++++++++++++------
 src/frontends/qt4/GuiView.cpp |   11 +++++-
 6 files changed, 112 insertions(+), 65 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index cb7ea79..a6b2ae2 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<int>(cmd.getArg(0));
-               int const pos = convert<int>(cmd.getArg(1));
+               pos_type const pos = convert<int>(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<int>(str_id_end);
+                                       pos_type const pos_end = 
convert<int>(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 e6a29de..aca6f85 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 836f97b..6674fec 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 <PAR_ID_NUMBER> <POSITION_IN_PAR>
- * \li Params: <PAR_ID_NUMBER>:  paragraph id \n
-               <POSITION_IN_PAR>: 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 <PAR_ID> <POS_IN_PAR> [<PAR_ID> <POS_IN_PAR>]
+ * \li Params: <PAR_ID>:  paragraph id \n
+               <POS_IN_PAR>: 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 b3b1bd4..9fd11c2 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<TextEntry, TextEntry> TexRow::getEntriesFromRow(int 
const row) const
 }
 
 
-pair<DocIterator, DocIterator> TexRow::getDocIteratorFromRow(
+pair<DocIterator, DocIterator> 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<DocIterator, DocIterator> TexRow::getDocIteratorsFromEntries(
+           TextEntry start,
+           TextEntry end,
+           Buffer const & buf)
+{
        // Finding start
        DocIterator dit_start = buf.getParFromID(start.id);
        if (dit_start)
@@ -289,6 +297,16 @@ pair<DocIterator, DocIterator> 
TexRow::getDocIteratorFromRow(
 
 
 //static
+FuncRequest TexRow::goToFunc(TextEntry start, TextEntry end)
+{
+       return {LFUN_PARAGRAPH_GOTO,
+                       convert<string>(start.id) + " " + 
convert<string>(start.pos) + " " +
+                       convert<string>(end.id) + " " + 
convert<string>(end.pos)};
+}
+
+
+
+//static
 RowEntry TexRow::rowEntryFromCursorSlice(CursorSlice const & slice)
 {
        RowEntry entry;
@@ -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 7ce048e..a95b205 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,7 +145,7 @@ 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().
@@ -153,15 +153,29 @@ public:
        std::pair<TextEntry,TextEntry> 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<DocIterator, DocIterator> 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<DocIterator, DocIterator> getDocIteratorFromRow(
+       std::pair<DocIterator, DocIterator> 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 317e0a1..fd3a6e5 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;
 }
 
 

Reply via email to