break;
case LFUN_REFERENCE_TO_PARAGRAPH: {
- int const id = convert<int>(cmd.getArg(0));
- flag.setEnabled(id >= 0);
+ vector<string> const pids = getVectorFromString(cmd.getArg(0));
+ for (string const & s : pids) {
+ int const id = convert<int>(s);
+ if (id < 0) {
+ flag.setEnabled(false);
+ break;
+ }
+ }
+ flag.setEnabled(true);
break;
}
}
case LFUN_REFERENCE_TO_PARAGRAPH: {
- int const id = convert<int>(cmd.getArg(0));
+ vector<string> const pids = getVectorFromString(cmd.getArg(0));
+ string const type = cmd.getArg(1);
+ int id = convert<int>(pids.front());
if (id < 0)
break;
- string const type = cmd.getArg(1);
int i = 0;
for (Buffer * b = &buffer_; i == 0 || b != &buffer_;
b = theBufferList().next(b)) {
- DocIterator const dit = b->getParFromID(id);
+ DocIterator dit = b->getParFromID(id);
if (dit.empty()) {
LYXERR(Debug::INFO, "No matching paragraph found! [" << id << "].");
++i;
continue;
}
- string const label = dit.innerParagraph().getLabelForXRef();
+ string label = dit.innerParagraph().getLabelForXRef();
if (!label.empty()) {
// if the paragraph has a label, we refer to this
string const arg = (type.empty()) ? label : label + " " + type;
lyx::dispatch(FuncRequest(LFUN_REFERENCE_INSERT, arg));
break;
} else {
- // if there is not a label yet, go to the paragraph ...
+ // if there is not a label yet, or we do not see it
+ // (since it is in a different buffer),
+ // go to the paragraph (including nested insets) ...
lyx::dispatch(FuncRequest(LFUN_BOOKMARK_SAVE, "0"));
- lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_GOTO, cmd.argument()));
- // ... insert the label
- // we do not want to open the dialog, hence we
- // do not employ LFUN_LABEL_INSERT
- InsetCommandParams p(LABEL_CODE);
- docstring const label = dit.getPossibleLabel();
- p["name"] = label;
- string const data = InsetCommand::params2string(p);
- lyx::dispatch(FuncRequest(LFUN_INSET_INSERT, data));
+ for (string const & s : pids) {
+ id = convert<int>(s);
+ if (id < 0)
+ break;
+ dit = b->getParFromID(id);
+ lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_GOTO, s));
+ }
+ // ... and try again if we find a label ...
+ label = dit.innerParagraph().getLabelForXRef();
+ string arg;
+ if (!label.empty()) {
+ // if the paragraph has a label, we refer to this
+ arg = (type.empty()) ? label : label + " " + type;
+ } else {
+ // ... if not, insert a new label
+ // we do not want to open the dialog, hence we
+ // do not employ LFUN_LABEL_INSERT
+ InsetCommandParams p(LABEL_CODE);
+ docstring const new_label = dit.getPossibleLabel();
+ p["name"] = new_label;
+ string const data = InsetCommand::params2string(p);
+ lyx::dispatch(FuncRequest(LFUN_INSET_INSERT, data));
+ arg = (type.empty()) ? to_utf8(new_label)
+ : to_utf8(new_label) + " " + type;
+ }
// ... and go back to the original position
lyx::dispatch(FuncRequest(LFUN_BOOKMARK_GOTO, "0"));
// ... to insert the ref
- string const arg = (type.empty()) ? to_utf8(label)
- : to_utf8(label) + " " + type;
lyx::dispatch(FuncRequest(LFUN_REFERENCE_INSERT, arg));
break;
}
* \li Notion: The function checks of the paragraph already has a label.
* If so, it uses that. Otherwise it inserts a label and uses this.
* \li Syntax: reference-to-paragraph <PAR_ID> [<TYPE>]
- * \li Params: <PAR_ID>: paragraph id \n
- <TYPE>: cross-references type
+ * \li Params: <PAR_IDs>: paragraph ids, might be a comma-separated list\n
+ * if it is in a nested inset\n
+ * <TYPE>: cross-references type
* \li Origin: spitz, 28 Jul 2024
* \endvar
*/
///
docstring const & prettyStr() const { return pretty_str_; }
///
- void prettyStr (docstring const & s) { pretty_str_ = s; }
+ void prettyStr(docstring const & s) { pretty_str_ = s; }
///
bool isOutput() const { return output_; }
///
bool isMissing() const { return missing_; }
///
void setAction(FuncRequest const & a) { action_ = a; }
+ /// return comma-separated list of all par IDs (including nested insets)
+ /// this is used by captioned elements
+ docstring const parIDs() const { return par_ids_; }
+ ///
+ void setParIDs(docstring const & ids) { par_ids_ = ids; }
/// custom action, or the default one (paragraph-goto) if not customised
FuncRequest action() const;
- ///
+ /// return only main par ID
int id() const;
/// String for display, e.g. it has a mark if output is inactive
docstring const asString() const;
bool missing_;
/// Custom action
FuncRequest action_;
+ /// Paragraph IDs including nested insets (comma-separated).
+ docstring par_ids_;
};
bool output_active)
{
// first show the float before moving to the caption
+ docstring parids = dit.paragraphGotoArgument(true);
docstring arg = "paragraph-goto " + dit.paragraphGotoArgument();
- if (!stack_.empty())
+ if (!stack_.empty()) {
arg = "paragraph-goto " +
(*toc_)[stack_.top().pos].dit().paragraphGotoArgument() + ";" + arg;
+ parids = (*toc_)[stack_.top().pos].dit().paragraphGotoArgument(true) + "," + parids;
+ }
FuncRequest func(LFUN_COMMAND_SEQUENCE, arg);
if (!stack_.empty() && !stack_.top().is_captioned) {
TocItem & captionable = (*toc_)[stack_.top().pos];
captionable.str(s);
captionable.setAction(func);
+ captionable.setParIDs(parids);
stack_.top().is_captioned = true;
} else {
// This is a new entry.
docstring const type = cmd.argument();
TocItem const & item =
gui_view_.tocModels().currentItem(current_type_, index);
- if (item.action().action() == LFUN_PARAGRAPH_GOTO) {
- // easy case
- docstring const id = item.dit().paragraphGotoArgument(true);
- docstring const arg = (type.empty()) ? id : id + " " + type;
- dispatch(FuncRequest(cmd, arg));
- break;
- }
- // Captions etc.
- // Here we cannot employ LFUN_REFERENCE_TO_PARAGRAPH
- // as it won't land in the inset. Seo we do it ourselves;
- // 1. save current position
- lyx::dispatch(FuncRequest(LFUN_BOOKMARK_SAVE, "0"));
- // go to the item
- sendDispatch(item.action());
- // check if it has a label
- docstring label = from_utf8(cur.innerParagraph().getLabelForXRef());
- if (label.empty()) {
- // if not:
- // insert a new label
- // we do not want to open the dialog, hence we
- // do not employ LFUN_LABEL_INSERT
- InsetCommandParams p(LABEL_CODE);
- label = cur.getPossibleLabel();
- p["name"] = label;
- string const data = InsetCommand::params2string(p);
- lyx::dispatch(FuncRequest(LFUN_INSET_INSERT, data));
- }
- // now go back to the original position ...
- lyx::dispatch(FuncRequest(LFUN_BOOKMARK_GOTO, "0"));
- // ... to insert the ref
- docstring const arg = (type.empty()) ? label
- : label + from_ascii(" ") + type;
- lyx::dispatch(FuncRequest(LFUN_REFERENCE_INSERT, arg));
+ docstring const id = (item.parIDs().empty())
+ ? item.dit().paragraphGotoArgument(true)
+ : item.parIDs();
+ docstring const arg = (type.empty()) ? id : id + " " + type;
+ dispatch(FuncRequest(cmd, arg));
break;
}