Dear Vincent, Guenter and Richard,
Thank you for the recommendations and feedback. Following your suggestions, I
made several changes that have resolved a few of the problems (specifically,
the LFUN no longer crashes LyX every time it gets clicked on). I still make
use of a for loop to find the next section, but I modified the method to use
the cursor interface.
The code below will correctly find the end of a section when supplied with a
valid section heading (paragraph ID), as long as it does not have to change
buffers. If the section happens to be in another buffer, it will change to the
correct document but will not find the section end. (If you execute a second
time from that document, it works.)
Do you have any ideas on the best way to first switch the buffer, and then
resend the command? My rather weak attempt below doesn't work. (I'm fairly
sure that the conditions need to be modified, but haven't had time to make the
debugger behave correctly. The Qt Creator debugger on Mac is very ...
temperamental ... and it refuses to respect my breakpoints.)
case LFUN_SECTION_GOTO_END: {
int const par_id = convert<int>(cmd.getArg(0));
// Go to the specified section
string const arg = convert<string>(par_id)
+ ' ' + convert<string>(cur.pos());
lyx::dispatch(lyx::FuncRequest(lyx::LFUN_PARAGRAPH_GOTO,arg));
// Create pointer to the buffer
Buffer const & buf = *cur.buffer();
pit_type const pit = cur.pit();
ParagraphList & pars = buf.text().paragraphs();
ParagraphList::iterator bgn = pars.begin();
// The first paragraph of the section
ParagraphList::iterator start = boost::next(bgn,pit);
// Find the final paragraph of the section
ParagraphList::iterator finish = start;
ParagraphList::iterator end = pars.end();
int const thistoclevel = start->layout().toclevel;
if (thistoclevel == Layout::NOT_IN_TOC)
break;
if (finish != end)
++finish;
for (; finish != end; ++finish, ++cur.pit()) {
int const toclevel = finish->layout().toclevel;
if (toclevel != Layout::NOT_IN_TOC && toclevel <=
thistoclevel)
break;
}
// If at end, go to end of document
if (finish == end)
lyx::dispatch(lyx::FuncRequest(lyx::LFUN_BUFFER_END));
// If at next section heading, go back one paragraph
else if ((finish != end) && (finish != bgn)) {
string const arg = convert<string>(finish->id())
+ ' ' + convert<string>(0);
lyx::dispatch(lyx::FuncRequest(lyx::LFUN_PARAGRAPH_GOTO,arg));
lyx::dispatch(lyx::FuncRequest(lyx::LFUN_PARAGRAPH_UP));
// Create a valid dit for the current paragraph
DocIterator dit_dest =
buf.getParFromID(cur.paragraph().id());
dit_dest.pos() = dit_dest.paragraph().size();
cur.setCursor(dit_dest);
}
// Switch to child document and resend command
else {
string const arg = convert<string>(par_id)
+ ' ' + convert<string>(cur.pos());
lyx::dispatch(lyx::FuncRequest(lyx::LFUN_PARAGRAPH_GOTO,arg));
lyx::dispatch(cmd);
}
}
Cheers,
Rob