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.
This commit is contained in:
Guillaume Munch 2016-09-05 03:23:24 +01:00
parent f42379a7d6
commit 67805de7de
6 changed files with 112 additions and 65 deletions

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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 },

View File

@ -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)
@ -288,6 +296,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)
{
@ -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

View File

@ -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<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

View File

@ -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;
}