From 69614db1ec3d23a9e483b4832a7ef7386c6c7e99 Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Sun, 28 Jul 2024 15:54:55 +0200 Subject: [PATCH] Implement LFUN_REFERENCE_TO_PARAGRAPH This function checks whether a paragraph (specified by ID) has a label. If so, it simply inserts a reference to this at cursor position, if not it inserts a label to that paragraph (pos 0) and then inserts a reference at cursor position. Needed to implement #1624 (insert cross references to items that do not have yet a label) (cherry picked from commit 3fe99bf6f55858c666195263b8988165639ae7b2) --- src/BufferView.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/FuncCode.h | 1 + src/LyXAction.cpp | 13 +++++++++++++ 3 files changed, 59 insertions(+) diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 1fdfa78e2a..a39144fbaf 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -1282,6 +1282,12 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) || getInsetByCode(cur, MATH_REF_CODE)); break; + case LFUN_REFERENCE_TO_PARAGRAPH: { + int const id = convert(cmd.getArg(0)); + flag.setEnabled(id > 0); + break; + } + case LFUN_CHANGES_MERGE: case LFUN_CHANGE_NEXT: case LFUN_CHANGE_PREVIOUS: @@ -1641,6 +1647,45 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; } + case LFUN_REFERENCE_TO_PARAGRAPH: { + int const id = convert(cmd.getArg(0)); + if (id < 1) + 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); + string const label = dit.innerParagraph().getLabel(); + 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 ... + 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 = cur.getPossibleLabel(); + p["name"] = label; + string const data = InsetCommand::params2string(p); + lyx::dispatch(FuncRequest(LFUN_INSET_INSERT, data)); + // ... 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; + } + } + break; + } + case LFUN_NOTE_NEXT: if (gotoInset(this, { NOTE_CODE }, false)) dr.screenUpdate(Update::Force); diff --git a/src/FuncCode.h b/src/FuncCode.h index 7f35ca391d..b8e2e0a0ac 100644 --- a/src/FuncCode.h +++ b/src/FuncCode.h @@ -511,6 +511,7 @@ enum FuncCode LFUN_STATISTICS_REFERENCE_CLAMP,// sanda, 20240324 LFUN_REFERENCE_INSERT, // spitz, 20240728 // 400 + LFUN_REFERENCE_TO_PARAGRAPH, // spitz, 20240728 LFUN_LASTACTION // end of the table }; diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp index 323a1c160b..41979ad590 100644 --- a/src/LyXAction.cpp +++ b/src/LyXAction.cpp @@ -3531,6 +3531,19 @@ void LyXAction::init() */ { LFUN_REFERENCE_NEXT, "reference-next", ReadOnly, Edit }, +/*! + * \var lyx::FuncCode lyx::LFUN_REFERENCE_TO_PARAGRAPH + * \li Action: Inserts a cross-reference to the paragraph with a given ID + * \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 [] + * \li Params: : paragraph id \n + : cross-references type + * \li Origin: spitz, 28 Jul 2024 + * \endvar + */ + { LFUN_REFERENCE_TO_PARAGRAPH, "reference-to-paragraph", ReadOnly | NoInternal, Edit }, + /*! * \var lyx::FuncCode lyx::LFUN_REGEXP_MODE