]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt/qt_helpers.cpp
No need (any longer?) to create a new view for lyxfiles-open
[lyx.git] / src / frontends / qt / qt_helpers.cpp
index 0431c042ad1c1c69658fe8e8e5e0c7ed1db24734..37e5ed5ba6b3897c2939af58263b3f108b3de4bb 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "qt_helpers.h"
 
+#include "Format.h"
 #include "LengthCombo.h"
 #include "LyXRC.h"
 
 #include <QComboBox>
 #include <QDesktopServices>
 #include <QDir>
+#include <QInputDialog>
 #include <QLineEdit>
+#include <QMessageBox>
 #include <QLocale>
 #include <QPalette>
+#include <QPushButton>
 #include <QSet>
+#include <QSettings>
 #include <QTextLayout>
 #include <QTextDocument>
 #include <QToolTip>
@@ -239,10 +244,12 @@ void setValid(QWidget * widget, bool valid)
                if (qobject_cast<QCheckBox*>(widget) != nullptr) {
                        // Check boxes need to be treated differenty, see
                        // https://forum.qt.io/topic/93253/
-                       widget->setStyleSheet("QCheckBox:unchecked{ color: red; }QCheckBox:checked{ color: red; }");
+                       if (qobject_cast<QCheckBox*>(widget)->isChecked())
+                               widget->setStyleSheet("QCheckBox:unchecked{ color: red; }QCheckBox:checked{ color: red; }");
                } else {
                        QPalette pal = widget->palette();
                        pal.setColor(QPalette::Active, QPalette::WindowText, QColor(255, 0, 0));
+                       pal.setColor(QPalette::Active, QPalette::Text, QColor(255, 0, 0));
                        widget->setPalette(pal);
                }
        }
@@ -262,6 +269,8 @@ void setMessageColour(list<QWidget *> highlighted, list<QWidget *> plain)
        QPalette pal = QApplication::palette();
        QPalette newpal(pal.color(QPalette::Active, QPalette::HighlightedText),
                        pal.color(QPalette::Active, QPalette::Highlight));
+       newpal.setColor(QPalette::WindowText,
+                       pal.color(QPalette::Active, QPalette::HighlightedText));
        for (QWidget * w : highlighted)
                w->setPalette(newpal);
        for (QWidget * w : plain)
@@ -269,24 +278,6 @@ void setMessageColour(list<QWidget *> highlighted, list<QWidget *> plain)
 }
 
 
-/// wrapper to hide the change of method name to setSectionResizeMode
-void setSectionResizeMode(QHeaderView * view,
-    int logicalIndex, QHeaderView::ResizeMode mode) {
-#if (QT_VERSION >= 0x050000)
-       view->setSectionResizeMode(logicalIndex, mode);
-#else
-       view->setResizeMode(logicalIndex, mode);
-#endif
-}
-
-void setSectionResizeMode(QHeaderView * view, QHeaderView::ResizeMode mode) {
-#if (QT_VERSION >= 0x050000)
-       view->setSectionResizeMode(mode);
-#else
-       view->setResizeMode(mode);
-#endif
-}
-
 void showDirectory(FileName const & directory)
 {
        if (!directory.exists())
@@ -306,34 +297,98 @@ void showDirectory(FileName const & directory)
                                qstring_to_ucs4(qurl.toString())));
 }
 
-void showTarget(string const & target, string const & pdfv, string const & psv)
+void showTarget(string const & target_in, Buffer const & buf)
 {
-       LYXERR(Debug::INSETS, "Showtarget:" << target << "\n");
-       if (prefixIs(target, "EXTERNAL ")) {
+       LYXERR(Debug::INSETS, "Showtarget: " << target_in << "\n");
+
+       string target = target_in;
+       string const & docpath = buf.absFileName();
+       vector<string> targets;
+
+       bool const is_external = prefixIs(target, "EXTERNAL ");
+       if (is_external) {
                if (!lyxrc.citation_search)
                        return;
-               string tmp, tar, opts;
+               string tmp, tar;
                tar = split(target, tmp, ' ');
-               if (!pdfv.empty())
-                       opts = " -v " + pdfv;
-               if (!psv.empty())
-                       opts += " -w " + psv;
-               if (!opts.empty())
-                       opts += " ";
-               Systemcall one;
-               string const command = lyxrc.citation_search_view + " " + opts + tar;
-               int const result = one.startscript(Systemcall::Wait, command);
-               if (result == 1)
+               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."));
-               else if (result == 2)
+                       return;
+               }
+               // lyxpaperview returns a \n-separated list of paths
+               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;
+                       return;
+               }
+       }
+       if (prefixIs(target, "file://")) {
+               // file might have a \n-separated list of paths
+               targets = getVectorFromString(target, "\n");
        }
-       if (!QDesktopServices::openUrl(QUrl(toqstr(target), QUrl::TolerantMode)))
+       if (!targets.empty()) {
+               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.
+       QSettings settings;
+       if (!settings.value("trusted documents/" + toqstr(docpath), false).toBool()) {
+               QCheckBox * dontShowAgainCB = new QCheckBox();
+               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."));
+               docstring const warn = bformat(_("LyX wants to open the following target in an external application:\n\n"
+                                                "%1$s\n\n"
+                                                "Be aware that this might entail security infringements!\n\n"
+                                                "Only do this if you trust the origin of the document and the target of the link!\n\n"
+                                                "How do you want to proceed?"), from_utf8(target));
+               QMessageBox box(QMessageBox::Warning, qt_("Open external target?"), toqstr(warn),
+                               QMessageBox::NoButton, qApp->focusWidget());
+               QPushButton * openButton = box.addButton(qt_("&Open Target"), QMessageBox::ActionRole);
+               box.addButton(QMessageBox::Abort);
+               box.setCheckBox(dontShowAgainCB);
+               box.setDefaultButton(QMessageBox::Abort);
+               box.exec();
+               if (box.clickedButton() != openButton)
+                       return;
+               if (dontShowAgainCB->isChecked())
+                       settings.setValue("trusted documents/"
+                               + toqstr(docpath), true);
+       }
+
+       bool success = false;
+       QUrl url = is_external
+               ? QUrl::fromLocalFile(toqstr(target))
+               : QUrl(toqstr(target), QUrl::TolerantMode);
+       if (url.isLocalFile()) {
+               // For local files, we use our own viewers
+               // (QDesktopServices employs xdg-open which
+               // does not yet work everywhere)
+               FileName fn(fromqstr(url.path()));
+               string const format = theFormats().getFormatFromFile(fn);
+               success = theFormats().view(buf, fn, format);
+       } else
+               // For external files, we rely on QDesktopServices
+               success =  QDesktopServices::openUrl(url);
+
+       if (!success)
                frontend::Alert::error(_("Could not open file"),
                        bformat(_("The target `%1$s' could not be resolved."),
                                from_utf8(target)));
@@ -614,18 +669,12 @@ struct FileFilterList
        std::vector<Filter> filters_;
 };
 
-
 FileFilterList::FileFilterList(docstring const & qt_style_filter)
 {
        // FIXME UNICODE
        string const filter = to_utf8(qt_style_filter)
                + (qt_style_filter.empty() ? string() : ";;")
-               + to_utf8(_("All Files "))
-#if defined(_WIN32)
-               + ("(*.*)");
-#else
-               + ("(*)");
-#endif
+               + to_utf8(_("All Files")) + " " + fromqstr(wildcardAllFiles());
 
        // Split data such as "TeX documents (*.tex);;LyX Documents (*.lyx)"
        // into individual filters.
@@ -670,6 +719,16 @@ void FileFilterList::parse_filter(string const & filter)
 }
 
 
+QString wildcardAllFiles()
+{
+#if defined(_WIN32)
+               return "(*.*)";
+#else
+               return "(*)";
+#endif
+}
+
+
 /** \returns the equivalent of the string passed in
  *  although any brace expressions are expanded.
  *  (E.g. "*.{png,jpg}" -> "*.png *.jpg")