On 11/09/2011 04:37 AM, Benjamin Piwowarski wrote:
Hi,

in order to get more interaction between bibliography managers (in this case 
Papers) and LyX, I would like to implement two things:
(1) modify citation-insert (add a new parameter), or add a new function, so 
that if a citation xxx was already inserted at the cursor, the new citation yyy 
is merged with the previous one (e.g. \cite{xxx,yyyy})

This is bug #4842, I think. It's something people have long wanted, so I'm glad you're interested in it.

(2) add a function (LFUN_LIST_CITATIONS list-citations) that list the cited 
publications within the current LyX document

Where would this be output? One can already see this list, more or less, in the Outliner.

Also, I am unsure about where to find the list of citations: is
         buffer_.tocBackend().toc("citation");
the right way to get it?

That gets you something from which you can get a list of cited works, yes. But there's another way to do this. The Buffer has a cache for this kind of info, which you access from within the Buffer as:
    d->bibinfo_
If you call
    d->bibinfo_.collectCitedEntries()
then
    d->bibinfo_.citedEntries()
will give you a list of the keys, and you can then use
    d->bibinfo_[key]
to get the BibTeX information associated with a given key.

That said, if it's really the entry info you want, we might want to refactor the collectCitedEntries() routine a bit. As it is, it finds all this info, but only uses it for sorting. What we should do depends upon exactly what you want to do.

I was thinking of adding both in BufferView::getStatus (in BufferView.cpp).
Would this be OK? If anyone could give me some hints on how to implement (1), 
it would appreciate.

Since this depends on the place of the cursor, you could do it in BufferView. But it's probably more natural to handle it in Cursor itself. It might be possible to use the "AtPoint" machinery that you'll find in Cursor::getStatus and Cursor::dispatch.

The attached patch is a kind of first go at that approach. It may even work as is. I haven't tested it at all, so I probably broke something. Check it out and modify it as you see fit. Maybe, though, as you suggested, this should be a new LFUN altogether. If so, then it would just need to be added as a new one to FuncCode.h and LyXAction.cpp, and some minor changes made to the code in the patch. Probably that one should also default to acting like LFUN_CITATION_INSERT if it isn't handled by the AtPoint machinery, which would probably just mean doing this:
    case LFUN_CITATION_INSERT:
    case LFUN_CITATION_ADD: // or whatever the new name is
at the relevant places in BufferView.cpp.

Richard

>From c6998287f09c2afb3485802496ba9a3c6920d10e Mon Sep 17 00:00:00 2001
From: Richard Heck <rgh...@lyx.org>
Date: Wed, 9 Nov 2011 12:26:13 -0500
Subject: [PATCH] Initial attempt at #4842.

---
 src/LyXAction.cpp            |    2 +-
 src/insets/InsetCitation.cpp |   48 ++++++++++++++++++++++++++++++++++++++++++
 src/insets/InsetCitation.h   |    3 ++
 3 files changed, 52 insertions(+), 1 deletions(-)

diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index 507a9d0..d111430 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -1418,7 +1418,7 @@ void LyXAction::init()
  * \li Origin: AAS, 97-02-23
  * \endvar
  */
-		{ LFUN_CITATION_INSERT, "citation-insert", Noop, Edit },
+		{ LFUN_CITATION_INSERT, "citation-insert", AtPoint, Edit },
 /*!
  * \var lyx::FuncCode lyx::LFUN_BIBTEX_DATABASE_ADD
  * \li Action: Adds database, which will be used for bibtex citations.
diff --git a/src/insets/InsetCitation.cpp b/src/insets/InsetCitation.cpp
index 6f9035c..05a1669 100644
--- a/src/insets/InsetCitation.cpp
+++ b/src/insets/InsetCitation.cpp
@@ -18,9 +18,11 @@
 #include "buffer_funcs.h"
 #include "BufferParams.h"
 #include "BufferView.h"
+#include "Cursor.h"
 #include "DispatchResult.h"
 #include "FuncCode.h"
 #include "FuncRequest.h"
+#include "FuncStatus.h"
 #include "LaTeXFeatures.h"
 #include "output_xhtml.h"
 #include "ParIterator.h"
@@ -101,8 +103,54 @@ bool InsetCitation::isCompatibleCommand(string const & cmd)
 }
 
 
+bool InsetCitation::getStatus(Cursor & cur, FuncRequest const & cmd,
+		FuncStatus & status) const
+{
+	switch (cmd.action()) {
+	case LFUN_CITATION_INSERT:
+		status.setEnabled(true);
+		return true;
+	default:
+		break;
+	}
+	return InsetCommand::getStatus(cur, cmd, status);
+}
+
+
 void InsetCitation::doDispatch(Cursor & cur, FuncRequest & cmd)
 {
+	if (cmd.action() == LFUN_CITATION_INSERT) {
+		docstring const & argument = cmd.argument();
+		// we'll let this be handled elsewhere
+		if (argument.empty()) {
+			// this is by default set to dispatched() by
+			// Cursor::dispatch()
+			cur.undispatched();
+			return;
+		}
+
+		// we can have one optional argument, delimited by '|'
+		//     citation-insert <key>|<text_before>
+		// but we will not use it.
+		docstring arg = argument;
+		if (contains(argument, '|'))
+			arg = token(argument, '|', 0);
+		docstring const & key = getParam("key");
+		if (key.empty())
+			setParam("key", arg);
+		else {
+			vector<docstring> keys = getVectorFromString(key);
+			vector<docstring>::const_iterator it = 
+				find(keys.begin(), keys.end(), arg);
+			if (it != keys.end())
+				LYXERR0("Duplicate key " << arg << " discarded");
+			else
+				setParam("key", key + from_ascii(",") + arg);
+		}
+		cur.dispatched();
+		return;
+	}
+
 	if (cmd.action() == LFUN_INSET_MODIFY)
 		cache.recalculate = true;
 	InsetCommand::doDispatch(cur, cmd);
diff --git a/src/insets/InsetCitation.h b/src/insets/InsetCitation.h
index 6eb0da0..0e2be66 100644
--- a/src/insets/InsetCitation.h
+++ b/src/insets/InsetCitation.h
@@ -41,6 +41,9 @@ public:
 	///
 	docstring toolTip(BufferView const & bv, int x, int y) const;
 	///
+	bool getStatus(Cursor & cur, FuncRequest const & cmd,
+			FuncStatus & status) const;
+	///
 	void doDispatch(Cursor & cur, FuncRequest & cmd);
 	///
 	InsetCode lyxCode() const { return CITE_CODE; }
-- 
1.7.6.4

Reply via email to