mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 10:00:33 +00:00
Improve CITATION_OPEN
* The lyxpaperview script now only provides the paths and let us do the opening * We use our own viewers for local files rather than QDesktopServices Plus several minor improvements and code cleanup
This commit is contained in:
parent
0912f7c356
commit
4dc9e0c4e6
@ -10,19 +10,10 @@
|
|||||||
# Full author contact details are available in file CREDITS
|
# Full author contact details are available in file CREDITS
|
||||||
|
|
||||||
# This script searches the home directory for a PDF or PS
|
# This script searches the home directory for a PDF or PS
|
||||||
# file with a name containing year and author. If found,
|
# file with a name containing specific keywords (year and author by default).
|
||||||
# it opens the file in a viewer.
|
# If found, it returns the path(s), separated by \n.
|
||||||
|
|
||||||
import getopt, os, sys, subprocess
|
import os, sys, subprocess
|
||||||
|
|
||||||
pdf_viewers = ('pdfview', 'kpdf', 'okular', 'qpdfview --unique',
|
|
||||||
'evince', 'xreader', 'kghostview', 'xpdf', 'SumatraPDF',
|
|
||||||
'acrobat', 'acroread', 'mupdf',
|
|
||||||
'gv', 'ghostview', 'AcroRd32', 'gsview64', 'gsview32')
|
|
||||||
|
|
||||||
ps_viewers = ("kghostview", "okular", "qpdfview --unique",
|
|
||||||
"evince", "xreader", "gv", "ghostview -swap",
|
|
||||||
"gsview64", "gsview32")
|
|
||||||
|
|
||||||
def message(message):
|
def message(message):
|
||||||
sys.stderr.write("lyxpaperview: %s\n" % message)
|
sys.stderr.write("lyxpaperview: %s\n" % message)
|
||||||
@ -32,7 +23,7 @@ def error(message):
|
|||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
def usage(prog_name):
|
def usage(prog_name):
|
||||||
msg = "Usage: %s [-v pdfviewer] [-w psviewer] titletoken-1 [titletoken-2] ... [titletoken-n]\n" \
|
msg = "Usage: %s titletoken-1 [titletoken-2] ... [titletoken-n]\n" \
|
||||||
" Each title token must occur in the filename (at an arbitrary position).\n" \
|
" Each title token must occur in the filename (at an arbitrary position).\n" \
|
||||||
" You might use quotes to enter multi-word tokens"
|
" You might use quotes to enter multi-word tokens"
|
||||||
return msg % prog_name
|
return msg % prog_name
|
||||||
@ -66,13 +57,6 @@ def find_exe(candidates):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def find_exe_or_terminate(candidates):
|
|
||||||
exe = find_exe(candidates)
|
|
||||||
if exe == None:
|
|
||||||
error("Unable to find executable from '%s'" % " ".join(candidates))
|
|
||||||
|
|
||||||
return exe
|
|
||||||
|
|
||||||
def find(args, path):
|
def find(args, path):
|
||||||
if os.name != 'nt':
|
if os.name != 'nt':
|
||||||
# use locate if possible (faster)
|
# use locate if possible (faster)
|
||||||
@ -84,10 +68,9 @@ def find(args, path):
|
|||||||
# have this already
|
# have this already
|
||||||
continue
|
continue
|
||||||
px = subprocess.Popen(['grep', '-i', arg], stdin=px.stdout, stdout=subprocess.PIPE)
|
px = subprocess.Popen(['grep', '-i', arg], stdin=px.stdout, stdout=subprocess.PIPE)
|
||||||
p4 = subprocess.Popen(['head', '-n 1'], stdin=px.stdout, stdout=subprocess.PIPE)
|
|
||||||
p1.stdout.close()
|
p1.stdout.close()
|
||||||
output = p4.communicate()
|
output = px.communicate()
|
||||||
return output[0].decode("utf8")[:-1]# strip trailing '\n'
|
return output[0].decode("utf8").strip('\n')
|
||||||
# FIXME add something for windows as well?
|
# FIXME add something for windows as well?
|
||||||
# Maybe dir /s /b %WINDIR%\*author* | findstr .*year.*\."ps pdf"
|
# Maybe dir /s /b %WINDIR%\*author* | findstr .*year.*\."ps pdf"
|
||||||
|
|
||||||
@ -107,44 +90,14 @@ def find(args, path):
|
|||||||
def main(argv):
|
def main(argv):
|
||||||
progname = argv[0]
|
progname = argv[0]
|
||||||
|
|
||||||
opts, args = getopt.getopt(sys.argv[1:], "v:w:")
|
args = sys.argv[1:]
|
||||||
pdfviewer = ""
|
|
||||||
psviewer = ""
|
|
||||||
for o, v in opts:
|
|
||||||
if o == "-v":
|
|
||||||
pdfviewer = v
|
|
||||||
if o == "-w":
|
|
||||||
psviewer = v
|
|
||||||
|
|
||||||
if len(args) < 1:
|
if len(args) < 1:
|
||||||
error(usage(progname))
|
error(usage(progname))
|
||||||
|
|
||||||
result = find(args, path = os.environ["HOME"])
|
result = find(args, path = os.environ["HOME"])
|
||||||
if result == "":
|
|
||||||
message("no document found!")
|
|
||||||
exit(2)
|
|
||||||
else:
|
|
||||||
message("found document %s" % result)
|
|
||||||
|
|
||||||
viewer = ""
|
|
||||||
if result.lower().endswith('.ps'):
|
|
||||||
if psviewer == "":
|
|
||||||
viewer = find_exe_or_terminate(ps_viewers)
|
|
||||||
else:
|
|
||||||
viewer = psviewer
|
|
||||||
else:
|
|
||||||
if pdfviewer == "":
|
|
||||||
viewer = find_exe_or_terminate(pdf_viewers)
|
|
||||||
else:
|
|
||||||
viewer = pdfviewer
|
|
||||||
|
|
||||||
cmdline = viewer.split(" -", 1)
|
|
||||||
|
|
||||||
if len(cmdline) == 1:
|
|
||||||
subprocess.Popen([viewer, result], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
|
|
||||||
elif len(cmdline) == 2:
|
|
||||||
subprocess.Popen([cmdline[0], "-" + cmdline[1] , result], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
|
|
||||||
|
|
||||||
|
print(result)
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -5072,12 +5072,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
|||||||
|
|
||||||
case LFUN_CITATION_OPEN: {
|
case LFUN_CITATION_OPEN: {
|
||||||
LASSERT(doc_buffer, break);
|
LASSERT(doc_buffer, break);
|
||||||
string pdfv, psv;
|
frontend::showTarget(argument, *doc_buffer);
|
||||||
if (theFormats().getFormat("pdf"))
|
|
||||||
pdfv = theFormats().getFormat("pdf")->viewer();
|
|
||||||
if (theFormats().getFormat("ps"))
|
|
||||||
psv = theFormats().getFormat("ps")->viewer();
|
|
||||||
frontend::showTarget(argument, doc_buffer->absFileName(), pdfv, psv);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "qt_helpers.h"
|
#include "qt_helpers.h"
|
||||||
|
|
||||||
|
#include "Format.h"
|
||||||
#include "LengthCombo.h"
|
#include "LengthCombo.h"
|
||||||
#include "LyXRC.h"
|
#include "LyXRC.h"
|
||||||
|
|
||||||
@ -32,6 +33,7 @@
|
|||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QInputDialog>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
@ -295,30 +297,61 @@ void showDirectory(FileName const & directory)
|
|||||||
qstring_to_ucs4(qurl.toString())));
|
qstring_to_ucs4(qurl.toString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void showTarget(string const & target, string const & docpath,
|
void showTarget(string const & target_in, Buffer const & buf)
|
||||||
string const & pdfv, string const & psv)
|
|
||||||
{
|
{
|
||||||
LYXERR(Debug::INSETS, "Showtarget:" << target << "\n");
|
LYXERR(Debug::INSETS, "Showtarget:" << target_in << "\n");
|
||||||
|
|
||||||
|
string target = target_in;
|
||||||
|
string const & docpath = buf.absFileName();
|
||||||
|
|
||||||
|
bool const is_external = prefixIs(target, "EXTERNAL ");
|
||||||
|
if (is_external) {
|
||||||
|
if (!lyxrc.citation_search)
|
||||||
|
return;
|
||||||
|
string tmp, tar;
|
||||||
|
tar = split(target, tmp, ' ');
|
||||||
|
string const scriptcmd = subst(lyxrc.citation_search_view, "$${python}", os::python());
|
||||||
|
string const command = scriptcmd + " " + tar;
|
||||||
|
cmd_ret const ret = runCommand(commandPrep(command));
|
||||||
|
if (!ret.valid) {
|
||||||
|
// Script failed
|
||||||
|
frontend::Alert::error(_("Could not open file"),
|
||||||
|
_("The lyxpaperview script failed."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// lyxpaperview returns a \n-separated list of paths
|
||||||
|
vector<string> targets = getVectorFromString(rtrim(ret.result, "\n"), "\n");
|
||||||
|
if (targets.empty()) {
|
||||||
|
frontend::Alert::error(_("Could not open file"),
|
||||||
|
bformat(_("No file was found using the pattern `%1$s'."),
|
||||||
|
from_utf8(tar)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (targets.size() > 1) {
|
||||||
|
QStringList files;
|
||||||
|
for (auto const & t : targets)
|
||||||
|
files << toqstr(t);
|
||||||
|
bool ok;
|
||||||
|
QString file = QInputDialog::getItem(nullptr, qt_("Multiple files found!"),
|
||||||
|
qt_("Select the file that should be opened:"),
|
||||||
|
files, 0, false, &ok);
|
||||||
|
if (!ok || file.isEmpty())
|
||||||
|
return;
|
||||||
|
target = fromqstr(file);
|
||||||
|
} else
|
||||||
|
target = targets.front();
|
||||||
|
}
|
||||||
// security measure: ask user before opening if document is not marked trusted.
|
// security measure: ask user before opening if document is not marked trusted.
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
if (!settings.value("trusted documents/" + toqstr(docpath), false).toBool()) {
|
if (!settings.value("trusted documents/" + toqstr(docpath), false).toBool()) {
|
||||||
QCheckBox * dontShowAgainCB = new QCheckBox();
|
QCheckBox * dontShowAgainCB = new QCheckBox();
|
||||||
dontShowAgainCB->setText(qt_("&Trust this document and do not ask me again!"));
|
dontShowAgainCB->setText(qt_("&Trust this document and do not ask me again!"));
|
||||||
dontShowAgainCB->setToolTip(qt_("If you check this, LyX will open all targets without asking for the given document in the future."));
|
dontShowAgainCB->setToolTip(qt_("If you check this, LyX will open all targets without asking for the given document in the future."));
|
||||||
docstring const warn =
|
docstring const warn = bformat(_("LyX wants to open the following target in an external application:\n"
|
||||||
prefixIs(target, "EXTERNAL ") ?
|
"%1$s\n"
|
||||||
bformat(_("LyX will search your directory for files with the following keywords in their name "
|
"Be aware that this might entail security infringements!\n"
|
||||||
"and then open it in an external application, if a file is found:\n"
|
"Only do this if you trust origin of the document and the target of the link!\n"
|
||||||
"'%1$s'\n"
|
"How do you want to proceed?"), from_utf8(target));
|
||||||
"Be aware that this might entail security infringements!\n"
|
|
||||||
"Only do this if you trust origin of the document and the keywords used!\n"
|
|
||||||
"How do you want to proceed?"), from_utf8(target).substr(9, docstring::npos))
|
|
||||||
: bformat(_("LyX wants to open the following link in an external application:\n"
|
|
||||||
"%1$s\n"
|
|
||||||
"Be aware that this might entail security infringements!\n"
|
|
||||||
"Only do this if you trust origin of the document and the target of the link!\n"
|
|
||||||
"How do you want to proceed?"), from_utf8(target));
|
|
||||||
QMessageBox box(QMessageBox::Warning, qt_("Open external target?"), toqstr(warn),
|
QMessageBox box(QMessageBox::Warning, qt_("Open external target?"), toqstr(warn),
|
||||||
QMessageBox::NoButton, qApp->focusWidget());
|
QMessageBox::NoButton, qApp->focusWidget());
|
||||||
QPushButton * openButton = box.addButton(qt_("&Open Target"), QMessageBox::ActionRole);
|
QPushButton * openButton = box.addButton(qt_("&Open Target"), QMessageBox::ActionRole);
|
||||||
@ -333,32 +366,22 @@ void showTarget(string const & target, string const & docpath,
|
|||||||
+ toqstr(docpath), true);
|
+ toqstr(docpath), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefixIs(target, "EXTERNAL ")) {
|
bool success = false;
|
||||||
if (!lyxrc.citation_search)
|
QUrl url = is_external
|
||||||
return;
|
? QUrl::fromLocalFile(toqstr(target))
|
||||||
string tmp, tar, opts;
|
: QUrl(toqstr(target), QUrl::TolerantMode);
|
||||||
tar = split(target, tmp, ' ');
|
if (url.isLocalFile()) {
|
||||||
if (!pdfv.empty())
|
// For local files, we use our own viewers
|
||||||
opts = " -v \"" + pdfv + "\"";
|
// (QDesktopServices employs xdg-open which
|
||||||
if (!psv.empty())
|
// does not yet work everywhere)
|
||||||
opts += " -w \"" + psv + "\"";
|
FileName fn(fromqstr(url.path()));
|
||||||
if (!opts.empty())
|
string const format = theFormats().getFormatFromFile(fn);
|
||||||
opts += " ";
|
success = theFormats().view(buf, fn, format);
|
||||||
Systemcall one;
|
} else
|
||||||
string const viewer = subst(lyxrc.citation_search_view, "$${python}", os::python());
|
// For external files, we rely on QDesktopServices
|
||||||
string const command = viewer + " " + opts + tar;
|
success = QDesktopServices::openUrl(url);
|
||||||
int const result = one.startscript(Systemcall::Wait, command);
|
|
||||||
if (result == 1)
|
if (!success)
|
||||||
// Script failed
|
|
||||||
frontend::Alert::error(_("Could not open file"),
|
|
||||||
_("The lyxpaperview script failed."));
|
|
||||||
else if (result == 2)
|
|
||||||
frontend::Alert::error(_("Could not open file"),
|
|
||||||
bformat(_("No file was found using the pattern `%1$s'."),
|
|
||||||
from_utf8(tar)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!QDesktopServices::openUrl(QUrl(toqstr(target), QUrl::TolerantMode)))
|
|
||||||
frontend::Alert::error(_("Could not open file"),
|
frontend::Alert::error(_("Could not open file"),
|
||||||
bformat(_("The target `%1$s' could not be resolved."),
|
bformat(_("The target `%1$s' could not be resolved."),
|
||||||
from_utf8(target)));
|
from_utf8(target)));
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#ifndef QTHELPERS_H
|
#ifndef QTHELPERS_H
|
||||||
#define QTHELPERS_H
|
#define QTHELPERS_H
|
||||||
|
|
||||||
|
#include "Buffer.h"
|
||||||
#include "ColorSet.h"
|
#include "ColorSet.h"
|
||||||
#include "support/Length.h"
|
#include "support/Length.h"
|
||||||
#include "support/qstring_helpers.h"
|
#include "support/qstring_helpers.h"
|
||||||
@ -93,12 +94,9 @@ void setMessageColour(std::list<QWidget *> highlighted,
|
|||||||
void showDirectory(support::FileName const & directory);
|
void showDirectory(support::FileName const & directory);
|
||||||
/// handle request for showing citation content - shows pdf/ps or
|
/// handle request for showing citation content - shows pdf/ps or
|
||||||
/// web page in target; external script can be used for pdf/ps view
|
/// web page in target; external script can be used for pdf/ps view
|
||||||
/// \p docpath holds the document path,
|
/// \p docpath holds the document path
|
||||||
/// \p pdfv takes a pad viewer, \p psv a ps viewer
|
|
||||||
void showTarget(std::string const & target,
|
void showTarget(std::string const & target,
|
||||||
std::string const & docpath,
|
Buffer const & buf);
|
||||||
std::string const & pdfv,
|
|
||||||
std::string const & psv);
|
|
||||||
|
|
||||||
} // namespace frontend
|
} // namespace frontend
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user