[LyX/master] New attempt on #9906: allow following hyperlinks via context menu.

Pavel Sanda sanda at lyx.org
Sat Aug 15 18:01:04 UTC 2020


On Fri, Aug 14, 2020 at 07:23:09PM +0200, Pavel Sanda wrote:
> commit 48b1e8a0aca2f3f3faa8f1f800568e47792ba9a0
> Author: Pavel Sanda <sanda at lyx.org>
> Date:   Fri Aug 14 19:46:13 2020 +0200
> 
>     New attempt on #9906: allow following hyperlinks via context menu.
>     
>     Now safer version with the help of Qt.

As a somewhat related issue I have very rough code (i.e. intended for my
private patchset) which allows viewing papers cited in the document via
the context menu of citation inset.

ATM it is really shaped for my needs but I am curious how far I am
from getting something along those lines (see attachment) to the upstream...

What it essentially does is that:
1. Adds context menu item for citation to read the paper
2. Once triggered, first author's name and year is handed over
   to external shell script, which is capable to find the most 
   appropriate pdfs on my drive and launches pdfviewer on them.

Now, while this mostly satisfies my needs its way too peculiar for master.
Namely it heavily relies on the fact that I have all my bibliography
localy stored in way that name+year is easy searchable (though not always unique).

It would not be terribly hard to extend the patch, so the functionality actually is:
1. For given reference find
- path+filename of pdf if stored in bibliographic database & launch pdf viewer
- if not found then URL to the paper & launch browser
- if not found then give name + year to user-defined script (essentially my hack above)

It could be enhanced by listing all possible targets in contex menu 
(because citation might include more papers and each one might have more pdf's).

How much opposition would be to commit something like this?

Pavel
-------------- next part --------------
diff --git a/lib/ui/stdcontext.inc b/lib/ui/stdcontext.inc
index c2beb316f4..2dc4f76db7 100644
--- a/lib/ui/stdcontext.inc
+++ b/lib/ui/stdcontext.inc
@@ -128,6 +128,7 @@ Menuset
 		CiteStyles
 		Separator
 		Item "Settings...|S" "inset-settings"
+		Item "Find citation|F" "inset-edit"
 	End
 
 
diff --git a/src/FuncCode.h b/src/FuncCode.h
index 585d1e1580..391faf71ce 100644
--- a/src/FuncCode.h
+++ b/src/FuncCode.h
@@ -490,6 +490,7 @@ enum FuncCode
 	LFUN_MASTER_BUFFER_FORALL,      // spitz 20191231
 	LFUN_IF_RELATIVES,              // spitz 20200102
 	LFUN_WINDOW_RAISE,              // forenr, 20202104
+	LFUN_CITATION_OPEN,             // sanda, 20200815
 	LFUN_LASTACTION                 // end of the table
 };
 
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index 3de816a68f..a867a9248e 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -1239,6 +1239,7 @@ void LyXAction::init()
  * \endvar
  */
 		{ LFUN_CITATION_INSERT, "citation-insert", Noop, Edit },
+		{ LFUN_CITATION_OPEN, "citation-open", Noop, Edit },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_CLIPBOARD_PASTE
diff --git a/src/frontends/qt/GuiView.cpp b/src/frontends/qt/GuiView.cpp
index 1b9f0ef27c..28b53c15f7 100644
--- a/src/frontends/qt/GuiView.cpp
+++ b/src/frontends/qt/GuiView.cpp
@@ -2371,6 +2371,10 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
 		flag.setOnOff(lyxrc.spellcheck_continuously);
 		break;
 
+	case LFUN_CITATION_OPEN:
+		enable = true;
+		break;
+
 	default:
 		return false;
 	}
@@ -4620,6 +4624,13 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 			dr.screenUpdate(Update::Force);
 			break;
 
+		case LFUN_CITATION_OPEN: {
+			string arg = cmd.getArg(1) + " " + cmd.getArg(0);
+			//TODO: get url from citation
+			//TODO: get file from citation
+			frontend::showTarget(arg);
+		}
+
 		default:
 			// The LFUN must be for one of BufferView, Buffer or Cursor;
 			// let's try that:
diff --git a/src/frontends/qt/qt_helpers.cpp b/src/frontends/qt/qt_helpers.cpp
index 9d44c3f9c1..5afcc0faf2 100644
--- a/src/frontends/qt/qt_helpers.cpp
+++ b/src/frontends/qt/qt_helpers.cpp
@@ -21,7 +21,10 @@
 
 #include "BufferParams.h"
 #include "FloatList.h"
+#include "FuncRequest.h"
 #include "Language.h"
+#include "LyX.h"
+#include "LyXAction.h"
 #include "TextClass.h"
 
 #include "support/convert.h"
@@ -293,6 +296,12 @@ void showDirectory(FileName const & directory)
 	if (!QDesktopServices::openUrl(qurl))
 		LYXERR0("Unable to open QUrl even though dir exists!");
 }
+
+void showTarget(string const & target){
+	//spot for generic url handling via  QUrl && QDesktopServices::openUrl
+	FuncRequest cmd = FuncRequest(LFUN_VC_COMMAND,"U . \"paperview " + target + "\"");
+	lyx::dispatch(cmd);
+}
 } // namespace frontend
 
 QString const qt_(char const * str, const char *)
diff --git a/src/frontends/qt/qt_helpers.h b/src/frontends/qt/qt_helpers.h
index 970a02707f..bd1ef9d937 100644
--- a/src/frontends/qt/qt_helpers.h
+++ b/src/frontends/qt/qt_helpers.h
@@ -101,6 +101,7 @@ void setSectionResizeMode(QHeaderView * view,
 	QHeaderView::ResizeMode mode);
 /// Shows a directory in OSs file browser
 void showDirectory(support::FileName const & directory);
+void showTarget(std::string const & target);
 
 } // namespace frontend
 
diff --git a/src/insets/InsetCitation.cpp b/src/insets/InsetCitation.cpp
index 14a05a097a..15b8d5c1c0 100644
--- a/src/insets/InsetCitation.cpp
+++ b/src/insets/InsetCitation.cpp
@@ -23,6 +23,7 @@
 #include "FuncRequest.h"
 #include "FuncStatus.h"
 #include "LaTeXFeatures.h"
+#include "LyX.h"
 #include "output_xhtml.h"
 #include "output_docbook.h"
 #include "ParIterator.h"
@@ -158,6 +159,9 @@ void InsetCitation::doDispatch(Cursor & cur, FuncRequest & cmd)
 			cmd = FuncRequest(LFUN_INSET_MODIFY, "changetype " + newcmdname);
 		}
 	}
+	case LFUN_INSET_EDIT: {
+		openCitation();
+	}
 	// fall through
 	default:
 		InsetCommand::doDispatch(cur, cmd);
@@ -165,6 +169,36 @@ void InsetCitation::doDispatch(Cursor & cur, FuncRequest & cmd)
 }
 
 
+void InsetCitation::openCitation(){
+	if (buffer_==NULL) return;
+	Buffer const & buf = *buffer_;
+	// Only after the buffer is loaded from file...
+	if (!buf.isFullyLoaded())
+		return;
+
+	BiblioInfo const & bi = buf.masterBibInfo();
+	if (bi.empty())
+		return;
+
+	docstring const & key = getParam("key");
+	if (key.empty())
+		return;
+
+	CiteItem ci;
+	ci.richtext = true;
+	vector<docstring> keys = getVectorFromString(key);
+	docstring year; docstring author;
+	if (keys.size() == 1) {
+		year = bi.getYear(keys[0], buffer(), false);
+		author = bi.getAuthorOrEditorList(keys[0], buffer());
+
+	FuncRequest cmd = FuncRequest(LFUN_CITATION_OPEN, year + " " + author);
+	lyx::dispatch(cmd);
+
+	}
+}
+
+
 bool InsetCitation::getStatus(Cursor & cur, FuncRequest const & cmd,
 	FuncStatus & status) const
 {
@@ -203,6 +237,8 @@ bool InsetCitation::getStatus(Cursor & cur, FuncRequest const & cmd,
 			}
 		}
 		return true;
+	case LFUN_INSET_EDIT:
+		return true;
 	default:
 		return InsetCommand::getStatus(cur, cmd, status);
 	}
diff --git a/src/insets/InsetCitation.h b/src/insets/InsetCitation.h
index bc15e11a6f..29e4b1f67b 100644
--- a/src/insets/InsetCitation.h
+++ b/src/insets/InsetCitation.h
@@ -94,6 +94,8 @@ public:
 	QualifiedList getQualifiedLists(docstring const & p) const;
 	///
 	static bool last_literal;
+	///
+	void openCitation();
 
 private:
 	/// tries to make a pretty label and makes a basic one if not


More information about the lyx-cvs mailing list