Author: forenr
Date: Sat May 14 01:14:46 2011
New Revision: 38746
URL: http://www.lyx.org/trac/changeset/38746

Log:
Backport the TEXINPUTS prefix feature. This should also fix bug #1751.

Modified:
   lyx-devel/branches/BRANCH_2_0_X/src/Buffer.cpp
   lyx-devel/branches/BRANCH_2_0_X/src/Converter.cpp
   lyx-devel/branches/BRANCH_2_0_X/src/Format.cpp
   lyx-devel/branches/BRANCH_2_0_X/src/LaTeX.cpp
   lyx-devel/branches/BRANCH_2_0_X/src/LaTeX.h
   lyx-devel/branches/BRANCH_2_0_X/src/LyXRC.cpp
   lyx-devel/branches/BRANCH_2_0_X/src/LyXRC.h
   lyx-devel/branches/BRANCH_2_0_X/src/VCBackend.cpp
   lyx-devel/branches/BRANCH_2_0_X/src/frontends/qt4/GuiPrefs.cpp
   lyx-devel/branches/BRANCH_2_0_X/src/frontends/qt4/ui/PrefPathsUi.ui
   lyx-devel/branches/BRANCH_2_0_X/src/support/Systemcall.cpp
   lyx-devel/branches/BRANCH_2_0_X/src/support/Systemcall.h
   lyx-devel/branches/BRANCH_2_0_X/src/support/SystemcallPrivate.h
   lyx-devel/branches/BRANCH_2_0_X/src/support/filetools.cpp
   lyx-devel/branches/BRANCH_2_0_X/src/support/filetools.h
   lyx-devel/branches/BRANCH_2_0_X/src/support/os.h
   lyx-devel/branches/BRANCH_2_0_X/src/support/os_cygwin.cpp
   lyx-devel/branches/BRANCH_2_0_X/src/support/os_unix.cpp
   lyx-devel/branches/BRANCH_2_0_X/src/support/os_win32.cpp
   lyx-devel/branches/BRANCH_2_0_X/status.20x

Modified: lyx-devel/branches/BRANCH_2_0_X/src/Buffer.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/Buffer.cpp      Sat May 14 00:39:21 
2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/Buffer.cpp      Sat May 14 01:14:46 
2011        (r38746)
@@ -2028,7 +2028,7 @@
 
                // Execute the command in the background
                Systemcall call;
-               call.startscript(Systemcall::DontWait, command);
+               call.startscript(Systemcall::DontWait, command, filePath());
                break;
        }
 
@@ -2206,7 +2206,8 @@
                                command2 += quoteName(psname);
                                // First run dvips.
                                // If successful, then spool command
-                               res = one.startscript(Systemcall::Wait, 
command);
+                               res = one.startscript(Systemcall::Wait, command,
+                                                     filePath());
 
                                if (res == 0) {
                                        // If there's no GUI, we have to wait 
on this command. Otherwise,
@@ -2214,7 +2215,8 @@
                                        // file, before it can be printed!!
                                        Systemcall::Starttype stype = use_gui ?
                                                Systemcall::DontWait : 
Systemcall::Wait;
-                                       res = one.startscript(stype, command2);
+                                       res = one.startscript(stype, command2,
+                                                             filePath());
                                }
                        } else {
                                // case 2: print directly to a printer
@@ -2223,7 +2225,8 @@
                                // as above....
                                Systemcall::Starttype stype = use_gui ?
                                        Systemcall::DontWait : Systemcall::Wait;
-                               res = one.startscript(stype, command + 
quoteName(dviname));
+                               res = one.startscript(stype, command +
+                                               quoteName(dviname), filePath());
                        }
 
                } else {
@@ -2246,7 +2249,7 @@
                        // as above....
                        Systemcall::Starttype stype = use_gui ?
                                Systemcall::DontWait : Systemcall::Wait;
-                       res = one.startscript(stype, command);
+                       res = one.startscript(stype, command, filePath());
                }
 
                if (res == 0) 

Modified: lyx-devel/branches/BRANCH_2_0_X/src/Converter.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/Converter.cpp   Sat May 14 00:39:21 
2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/Converter.cpp   Sat May 14 01:14:46 
2011        (r38746)
@@ -307,7 +307,8 @@
                        LYXERR(Debug::FILES, "No converter defined! "
                                   "I use convertDefault.py:\n\t" << command);
                        Systemcall one;
-                       one.startscript(Systemcall::Wait, command);
+                       one.startscript(Systemcall::Wait, command, buffer ?
+                                       buffer->filePath() : string());
                        if (to_file.isReadableFile()) {
                                if (conversionflags & try_cache)
                                        ConverterCache::get().add(orig_from,
@@ -443,12 +444,15 @@
                        int res;
                        if (dummy) {
                                res = one.startscript(Systemcall::DontWait,
-                                       to_filesystem8bit(from_utf8(command)));
+                                       to_filesystem8bit(from_utf8(command)),
+                                       buffer ? buffer->filePath() : string());
                                // We're not waiting for the result, so we 
can't do anything
                                // else here.
                        } else {
                                res = one.startscript(Systemcall::Wait,
-                                               
to_filesystem8bit(from_utf8(command)));
+                                               
to_filesystem8bit(from_utf8(command)),
+                                               buffer ? buffer->filePath()
+                                                      : string());
                                if (!real_outfile.empty()) {
                                        Mover const & mover = getMover(conv.to);
                                        if (!mover.rename(outfile, 
real_outfile))
@@ -468,7 +472,8 @@
                                                " < " + quoteName(infile2 + 
".out") +
                                                " > " + quoteName(logfile);
                                        one.startscript(Systemcall::Wait,
-                                               
to_filesystem8bit(from_utf8(command2)));
+                                               
to_filesystem8bit(from_utf8(command2)),
+                                               buffer->filePath());
                                        if (!scanLog(*buffer, command, 
makeAbsPath(logfile, path), errorList))
                                                return false;
                                }
@@ -612,7 +617,8 @@
 
        // do the LaTeX run(s)
        string const name = buffer.latexName();
-       LaTeX latex(command, runparams, FileName(makeAbsPath(name)));
+       LaTeX latex(command, runparams, FileName(makeAbsPath(name)),
+                   buffer.filePath());
        TeXErrors terr;
        ShowMessage show(buffer);
        latex.message.connect(show);

Modified: lyx-devel/branches/BRANCH_2_0_X/src/Format.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/Format.cpp      Sat May 14 00:39:21 
2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/Format.cpp      Sat May 14 01:14:46 
2011        (r38746)
@@ -285,7 +285,7 @@
        }
        // viewer is 'auto'
        if (format->viewer() == "auto") {
-               if (os::autoOpenFile(filename.absFileName(), os::VIEW))
+               if (os::autoOpenFile(filename.absFileName(), os::VIEW, 
buffer.filePath()))
                        return true;
                else {
                        Alert::error(_("Cannot view file"),
@@ -320,7 +320,7 @@
        buffer.message(_("Executing command: ") + from_utf8(command));
 
        Systemcall one;
-       one.startscript(Systemcall::DontWait, command);
+       one.startscript(Systemcall::DontWait, command, buffer.filePath());
 
        // we can't report any sort of error, since we aren't waiting
        return true;
@@ -364,7 +364,7 @@
 
        // editor is 'auto'
        if (format->editor() == "auto") {
-               if (os::autoOpenFile(filename.absFileName(), os::EDIT))
+               if (os::autoOpenFile(filename.absFileName(), os::EDIT, 
buffer.filePath()))
                        return true;
                else {
                        Alert::error(_("Cannot edit file"),
@@ -387,7 +387,7 @@
        buffer.message(_("Executing command: ") + from_utf8(command));
 
        Systemcall one;
-       one.startscript(Systemcall::DontWait, command);
+       one.startscript(Systemcall::DontWait, command, buffer.filePath());
 
        // we can't report any sort of error, since we aren't waiting
        return true;

Modified: lyx-devel/branches/BRANCH_2_0_X/src/LaTeX.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/LaTeX.cpp       Sat May 14 00:39:21 
2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/LaTeX.cpp       Sat May 14 01:14:46 
2011        (r38746)
@@ -93,8 +93,8 @@
  */
 
 LaTeX::LaTeX(string const & latex, OutputParams const & rp,
-            FileName const & f)
-       : cmd(latex), file(f), runparams(rp)
+            FileName const & f, string const & p)
+       : cmd(latex), file(f), path(p), runparams(rp)
 {
        num_errors = 0;
        if (prefixIs(cmd, "pdf")) { // Do we use pdflatex ?
@@ -421,7 +421,7 @@
                     + quoteName(onlyFileName(file.toFilesystemEncoding()))
                     + " > " + os::nulldev();
        Systemcall one;
-       return one.startscript(Systemcall::Wait, tmp);
+       return one.startscript(Systemcall::Wait, tmp, path);
 }
 
 
@@ -448,7 +448,7 @@
        tmp += quoteName(f);
        tmp += params;
        Systemcall one;
-       one.startscript(Systemcall::Wait, tmp);
+       one.startscript(Systemcall::Wait, tmp, path);
        return true;
 }
 
@@ -464,7 +464,7 @@
        tmp += " -o "
                + onlyFileName(changeExtension(file.toFilesystemEncoding(), 
nls));
        Systemcall one;
-       one.startscript(Systemcall::Wait, tmp);
+       one.startscript(Systemcall::Wait, tmp, path);
        return true;
 }
 
@@ -604,7 +604,7 @@
                tmp += quoteName(onlyFileName(removeExtension(
                                it->aux_file.absFileName())));
                Systemcall one;
-               one.startscript(Systemcall::Wait, tmp);
+               one.startscript(Systemcall::Wait, tmp, path);
        }
        // Return whether bibtex was run
        return result;

Modified: lyx-devel/branches/BRANCH_2_0_X/src/LaTeX.h
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/LaTeX.h Sat May 14 00:39:21 2011        
(r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/LaTeX.h Sat May 14 01:14:46 2011        
(r38746)
@@ -151,7 +151,8 @@
           path = name of the files original path.
        */
        LaTeX(std::string const & cmd, OutputParams const &,
-             support::FileName const & file);
+             support::FileName const & file,
+             std::string const & path = empty_string());
 
        /// runs LaTeX several times
        int run(TeXErrors &);
@@ -210,6 +211,9 @@
        ///
        support::FileName file;
 
+       ///
+       std::string path;
+
        /// used by scanLogFile
        int num_errors;
 

Modified: lyx-devel/branches/BRANCH_2_0_X/src/LyXRC.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/LyXRC.cpp       Sat May 14 00:39:21 
2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/LyXRC.cpp       Sat May 14 01:14:46 
2011        (r38746)
@@ -192,6 +192,7 @@
        { "\\template_path", LyXRC::RC_TEMPLATEPATH },
        { "\\tex_allows_spaces", LyXRC::RC_TEX_ALLOWS_SPACES },
        { "\\tex_expects_windows_paths", LyXRC::RC_TEX_EXPECTS_WINDOWS_PATHS },
+       { "\\texinputs_prefix", LyXRC::RC_TEXINPUTS_PREFIX },
        { "\\thesaurusdir_path", LyXRC::RC_THESAURUSDIRPATH },
        { "\\ui_file", LyXRC::RC_UIFILE },
        { "\\use_converter_cache", LyXRC::RC_USE_CONVERTER_CACHE },
@@ -227,6 +228,8 @@
        bind_file = "cua";
        def_file = "default";
        ui_file = "default";
+       // The current document directory
+       texinputs_prefix = ".";
        // Get printer from the environment. If fail, use default "",
        // assuming that everything is set up correctly.
        printer = getEnv("PRINTER");
@@ -499,6 +502,10 @@
                        lexrc >> tex_allows_spaces;
                        break;
 
+               case RC_TEXINPUTS_PREFIX:
+                       lexrc >> texinputs_prefix;
+                       break;
+
                case RC_KBMAP:
                        lexrc >> use_kbmap;
                        break;
@@ -2213,6 +2220,14 @@
                   << "# TEX SECTION #######################################\n"
                   << "#\n\n";
 
+       case RC_TEXINPUTS_PREFIX:
+               if (ignore_system_lyxrc ||
+                   texinputs_prefix != system_lyxrc.texinputs_prefix) {
+                       os << "\\texinputs_prefix \"" << texinputs_prefix << 
"\"\n";
+               }
+               if (tag != RC_LAST)
+                       break;
+
        case RC_FONT_ENCODING:
                if (ignore_system_lyxrc ||
                    fontenc != system_lyxrc.fontenc) {
@@ -3020,6 +3035,10 @@
                if (lyxrc_orig.windows_style_tex_paths != 
lyxrc_new.windows_style_tex_paths) {
                        
os::windows_style_tex_paths(lyxrc_new.windows_style_tex_paths);
                }
+       case LyXRC::RC_TEXINPUTS_PREFIX:
+               if (lyxrc_orig.texinputs_prefix != lyxrc_new.texinputs_prefix) {
+                       lyxrc.texinputs_prefix = lyxrc_new.texinputs_prefix;
+               }
        case LyXRC::RC_THESAURUSDIRPATH:
        case LyXRC::RC_UIFILE:
        case LyXRC::RC_USER_EMAIL:
@@ -3313,7 +3332,7 @@
 
        case RC_PATH_PREFIX:
                str = _("Specify those directories which should be "
-                        "prepended to the PATH environment variable. "
+                        "prepended to the PATH environment variable.\n"
                         "Use the OS native format.");
                break;
 
@@ -3470,6 +3489,13 @@
        case RC_TEX_EXPECTS_WINDOWS_PATHS:
                break;
 
+       case RC_TEXINPUTS_PREFIX:
+               str = _("Specify those directories which should be "
+                        "prepended to the TEXINPUTS environment variable.\n"
+                        "A '.' represents the current document directory. "
+                        "Use the OS native format.");
+               break;
+
        case RC_UIFILE:
                str = _("The UI (user interface) file. Can either specify an 
absolute path, or LyX will look in its global and local ui/ directories.");
                break;

Modified: lyx-devel/branches/BRANCH_2_0_X/src/LyXRC.h
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/LyXRC.h Sat May 14 00:39:21 2011        
(r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/LyXRC.h Sat May 14 01:14:46 2011        
(r38746)
@@ -174,6 +174,7 @@
                RC_TEMPLATEPATH,
                RC_TEX_ALLOWS_SPACES,
                RC_TEX_EXPECTS_WINDOWS_PATHS,
+               RC_TEXINPUTS_PREFIX,
                RC_THESAURUSDIRPATH,
                RC_UIFILE,
                RC_USELASTFILEPOS,
@@ -469,6 +470,11 @@
         *  The string is input, stored and output in native format.
         */
        std::string path_prefix;
+       /** Prepend paths to the TEXINPUTS environment variable.
+        *  The string is input, stored and output in native format.
+        *  A '.' here stands for the current document directory.
+        */
+       std::string texinputs_prefix;
        /// Use the cache for file converters?
        bool use_converter_cache;
        /// The maximum age of cache files in seconds

Modified: lyx-devel/branches/BRANCH_2_0_X/src/VCBackend.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/VCBackend.cpp   Sat May 14 00:39:21 
2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/VCBackend.cpp   Sat May 14 01:14:46 
2011        (r38746)
@@ -43,7 +43,7 @@
        LYXERR(Debug::LYXVC, "doVCCommandCall: " << cmd);
        Systemcall one;
        support::PathChanger p(path);
-       return one.startscript(Systemcall::Wait, cmd, false);
+       return one.startscript(Systemcall::Wait, cmd, string(), false);
 }
 
 

Modified: lyx-devel/branches/BRANCH_2_0_X/src/frontends/qt4/GuiPrefs.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/frontends/qt4/GuiPrefs.cpp      Sat May 
14 00:39:21 2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/frontends/qt4/GuiPrefs.cpp      Sat May 
14 01:14:46 2011        (r38746)
@@ -1312,6 +1312,9 @@
 
        connect(pathPrefixED, SIGNAL(textChanged(QString)),
                this, SIGNAL(changed()));
+
+       connect(texinputsPrefixED, SIGNAL(textChanged(QString)),
+               this, SIGNAL(changed()));
 }
 
 
@@ -1325,6 +1328,7 @@
        rc.thesaurusdir_path = internal_path(fromqstr(thesaurusDirED->text()));
        rc.hunspelldir_path = internal_path(fromqstr(hunspellDirED->text()));
        rc.path_prefix = internal_path_list(fromqstr(pathPrefixED->text()));
+       rc.texinputs_prefix = 
internal_path_list(fromqstr(texinputsPrefixED->text()));
        // FIXME: should be a checkbox only
        rc.lyxpipes = internal_path(fromqstr(lyxserverDirED->text()));
 }
@@ -1340,6 +1344,7 @@
        thesaurusDirED->setText(toqstr(external_path(rc.thesaurusdir_path)));
        hunspellDirED->setText(toqstr(external_path(rc.hunspelldir_path)));
        pathPrefixED->setText(toqstr(external_path_list(rc.path_prefix)));
+       
texinputsPrefixED->setText(toqstr(external_path_list(rc.texinputs_prefix)));
        // FIXME: should be a checkbox only
        lyxserverDirED->setText(toqstr(external_path(rc.lyxpipes)));
 }

Modified: lyx-devel/branches/BRANCH_2_0_X/src/frontends/qt4/ui/PrefPathsUi.ui
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/frontends/qt4/ui/PrefPathsUi.ui Sat May 
14 00:39:21 2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/frontends/qt4/ui/PrefPathsUi.ui Sat May 
14 01:14:46 2011        (r38746)
@@ -19,7 +19,7 @@
    <property name="spacing" >
     <number>6</number>
    </property>
-   <item row="11" column="0" colspan="3" >
+   <item row="12" column="0" colspan="3" >
     <spacer>
      <property name="orientation" >
       <enum>Qt::Vertical</enum>
@@ -46,7 +46,28 @@
     </widget>
    </item>
    <item row="10" column="1" colspan="2" >
-    <widget class="QLineEdit" name="pathPrefixED" />
+    <widget class="QLineEdit" name="pathPrefixED">
+     <property name="toolTip">
+      <string>Specify those directories which should be prepended to the PATH 
environment variable.&#x0a;Use the OS native format.</string>
+     </property>
+    </widget>
+   </item>
+   <item row="11" column="0">
+    <widget class="QLabel" name="texinputsPrefixLA">
+     <property name="text">
+      <string>TEX&amp;INPUTS prefix:</string>
+     </property>
+     <property name="buddy">
+      <cstring>texinputsPrefixED</cstring>
+     </property>
+    </widget>
+   </item>
+   <item row="11" column="1" colspan="2">
+    <widget class="QLineEdit" name="texinputsPrefixED">
+     <property name="toolTip">
+      <string>Specify those directories which should be prepended to the 
TEXINPUTS environment variable.&#x0a;A '.' represents the current document 
directory. Use the OS native format.</string>
+     </property>
+    </widget>
    </item>
    <item row="6" column="2" >
     <widget class="QPushButton" name="thesaurusDirPB" >

Modified: lyx-devel/branches/BRANCH_2_0_X/src/support/Systemcall.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/support/Systemcall.cpp  Sat May 14 
00:39:21 2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/support/Systemcall.cpp  Sat May 14 
01:14:46 2011        (r38746)
@@ -14,6 +14,8 @@
 #include <config.h>
 
 #include "support/debug.h"
+#include "support/environment.h"
+#include "support/filetools.h"
 #include "support/lstrings.h"
 #include "support/qstring_helpers.h"
 #include "support/Systemcall.h"
@@ -21,6 +23,7 @@
 #include "support/os.h"
 #include "support/ProgressInterface.h"
 
+#include "LyXRC.h"
 
 #include <cstdlib>
 #include <iostream>
@@ -96,9 +99,26 @@
 // Reuse of instance
 #ifndef USE_QPROCESS
 int Systemcall::startscript(Starttype how, string const & what,
-                                                       bool /*process_events*/)
+                           std::string const & path, bool /*process_events*/)
 {
-       string command = what;
+       string command;
+       string const texinputs = os::latex_path_list(
+                       replaceCurdirPath(path, lyxrc.texinputs_prefix));
+       string const sep = string(1, os::path_separator(os::TEXENGINE));
+       string const env = getEnv("TEXINPUTS");
+
+       switch (os::shell()) {
+       case os::UNIX:
+               command = path.empty() || lyxrc.texinputs_prefix.empty() ? what
+                       : "env TEXINPUTS='." + sep + texinputs
+                                            + sep + env + "' " + what;
+               break;
+       case os::CMD_EXE:
+               command = path.empty() || lyxrc.texinputs_prefix.empty() ? what
+                       : "set TEXINPUTS=." + sep + texinputs
+                                           + sep + env + " & " + what;
+               break;
+       }
 
        if (how == DontWait) {
                switch (os::shell()) {
@@ -204,7 +224,8 @@
 
 
 
-int Systemcall::startscript(Starttype how, string const & what, bool 
process_events)
+int Systemcall::startscript(Starttype how, string const & what,
+                           string const & path, bool process_events)
 {
        string outfile;
        QString cmd = toqstr(parsecmd(what, outfile));
@@ -212,7 +233,7 @@
        SystemcallPrivate d(outfile);
 
 
-       d.startProcess(cmd);
+       d.startProcess(cmd, path);
        if (!d.waitWhile(SystemcallPrivate::Starting, process_events, -1)) {
                LYXERR0("Systemcall: '" << cmd << "' did not start!");
                LYXERR0("error " << d.errorMessage());
@@ -264,10 +285,24 @@
 
 
 
-void SystemcallPrivate::startProcess(const QString& cmd)
+void SystemcallPrivate::startProcess(QString const & cmd, string const & path)
 {
        cmd_ = cmd;
        if (process_) {
+               if (!path.empty() && !lyxrc.texinputs_prefix.empty()) {
+                       QString const texinputs = toqstr(os::latex_path_list(
+                               replaceCurdirPath(path, 
lyxrc.texinputs_prefix)));
+                       QChar const sep = os::path_separator(os::TEXENGINE);
+                       QString const prefix = QLatin1String("TEXINPUTS=.")
+                                               + sep + texinputs + sep;
+                       QStringList env = QProcess::systemEnvironment();
+                       if (env.filter("TEXINPUTS=").isEmpty())
+                               env << prefix;
+                       else
+                               env.replaceInStrings(QRegExp("^TEXINPUTS=(.*)"),
+                                                    prefix + "\\1");
+                       process_->setEnvironment(env);
+               }
                state = SystemcallPrivate::Starting;
                process_->start(cmd_);
        }

Modified: lyx-devel/branches/BRANCH_2_0_X/src/support/Systemcall.h
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/support/Systemcall.h    Sat May 14 
00:39:21 2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/support/Systemcall.h    Sat May 14 
01:14:46 2011        (r38746)
@@ -40,10 +40,13 @@
 
        /** Start child process.
         *  The string "what" contains a commandline with arguments separated
-        *  by spaces. Unset "process_events" in case UI should be blocked while
-        *  processing the external command.
+        *  by spaces. The string "path" contains the path to be prepended to
+        *  the TEXINPUTS environment variable. Unset "process_events" in
+        *  case UI should be blocked while processing the external command.
         */
-       int startscript(Starttype how, std::string const & what, bool 
process_events = false);
+       int startscript(Starttype how, std::string const & what,
+                       std::string const & path = empty_string(),
+                       bool process_events = false);
 };
 
 } // namespace support

Modified: lyx-devel/branches/BRANCH_2_0_X/src/support/SystemcallPrivate.h
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/support/SystemcallPrivate.h     Sat May 
14 00:39:21 2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/support/SystemcallPrivate.h     Sat May 
14 01:14:46 2011        (r38746)
@@ -44,7 +44,7 @@
        State state;
 
        bool waitWhile(State, bool processEvents, int timeout = -1);
-       void startProcess(const QString& cmd);
+       void startProcess(QString const & cmd, std::string const & path);
        
        int exitCode();
 

Modified: lyx-devel/branches/BRANCH_2_0_X/src/support/filetools.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/support/filetools.cpp   Sat May 14 
00:39:21 2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/support/filetools.cpp   Sat May 14 
01:14:46 2011        (r38746)
@@ -577,6 +577,42 @@
 }
 
 
+// Replace current directory in all elements of a path list with a given path.
+string const replaceCurdirPath(string const & path, string const & pathlist)
+{
+       string const oldpathlist = replaceEnvironmentPath(pathlist);
+       char const sep = os::path_separator();
+       string newpathlist;
+
+       for (size_t i = 0, k = 0; i != string::npos; k = i) {
+               i = oldpathlist.find(sep, i);
+               string p = oldpathlist.substr(k, i - k);
+               if (FileName::isAbsolute(p)) {
+                       newpathlist += p;
+               } else if (i > k) {
+                       size_t offset = 0;
+                       if (p == ".") {
+                               offset = 1;
+                       } else if (prefixIs(p, "./")) {
+                               offset = 2;
+                               while (p[offset] == '/')
+                                       ++offset;
+                       }
+                       newpathlist += addPath(path, p.substr(offset));
+                       if (suffixIs(p, "//"))
+                               newpathlist += '/';
+               }
+               if (i != string::npos) {
+                       newpathlist += sep;
+                       // Stop here if the last element is empty 
+                       if (++i == oldpathlist.length())
+                               break;
+               }
+       }
+       return newpathlist;
+}
+
+
 // Make relative path out of two absolute paths
 docstring const makeRelPath(docstring const & abspath, docstring const & 
basepath)
 // Makes relative path out of absolute path. If it is deeper than basepath,

Modified: lyx-devel/branches/BRANCH_2_0_X/src/support/filetools.h
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/support/filetools.h     Sat May 14 
00:39:21 2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/support/filetools.h     Sat May 14 
01:14:46 2011        (r38746)
@@ -247,6 +247,12 @@
 */
 std::string const replaceEnvironmentPath(std::string const & path);
 
+/** Replace all references to a current directory (a lonely '.' or
+    the prefix "./") in \c pathlist with \c path. Also prefixes
+    all non-absolute paths with \c path.
+*/
+std::string const replaceCurdirPath(std::string const & path, std::string 
const & pathlist);
+
 /** Set \c link to the path \c file points to as a symbolic link.
     \return true if successful.
  */

Modified: lyx-devel/branches/BRANCH_2_0_X/src/support/os.h
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/support/os.h    Sat May 14 00:39:21 
2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/support/os.h    Sat May 14 01:14:46 
2011        (r38746)
@@ -104,6 +104,12 @@
  */
 std::string latex_path(std::string const & p);
 
+/**
+ * Converts a platform style path list into a form suitable for the TeX engine.
+ * \p p is encoded in utf8.
+ */
+std::string latex_path_list(std::string const & p);
+
 /// Checks if the format string is suitable on the OS
 bool is_valid_strftime(std::string const & p);
 
@@ -112,10 +118,15 @@
  */
 char const * popen_read_mode();
 
-/** The character used to separate paths returned by the
- *  PATH environment variable.
+enum path_type {
+       PLATFORM,
+       TEXENGINE
+};
+
+/** The character used to separate paths for platform environment variables
+ *  (such as PATH) or for the TeX engine.
  */
-char path_separator();
+char path_separator(path_type type = PLATFORM);
 
 /** If @c use_windows_paths is true, LyX will output Windows-style paths to
  *  latex files rather than posix ones. Obviously, this option is used only
@@ -133,14 +144,15 @@
  *  \param mode can be opened in VIEW or EDIT mode
  *  \returns whether or not the format can be opened according to \p mode
  */
-bool canAutoOpenFile(std::string const & ext, auto_open_mode const mode = 
VIEW);
+bool canAutoOpenFile(std::string const & ext, auto_open_mode const mode);
 
 /** View or edit a file with the default viewer or editor.
  *  \param filename file to open (encoded in utf8)
  *  \param mode open in VIEW or EDIT mode
  *  \returns whether or not the file is viewed (or edited) successfully.
  */
-bool autoOpenFile(std::string const & filename, auto_open_mode const mode = 
VIEW);
+bool autoOpenFile(std::string const & filename, auto_open_mode const mode,
+                 std::string const & path = empty_string());
 
 /** Resolves a path such that it does not contain '.', '..', or symbolic links.
   * \p path and the return value are encoded in utf8.

Modified: lyx-devel/branches/BRANCH_2_0_X/src/support/os_cygwin.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/support/os_cygwin.cpp   Sat May 14 
00:39:21 2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/support/os_cygwin.cpp   Sat May 14 
01:14:46 2011        (r38746)
@@ -15,12 +15,16 @@
 
 #include <config.h>
 
+#include "LyXRC.h"
+
 #include "support/os.h"
 
+#include "support/debug.h"
+#include "support/environment.h"
 #include "support/FileName.h"
+#include "support/filetools.h"
 #include "support/lassert.h"
 #include "support/lstrings.h"
-#include "support/debug.h"
 
 #include <windows.h>
 #include <io.h>
@@ -343,6 +347,19 @@
 }
 
 
+string latex_path_list(string const & p)
+{
+       // We may need a posix style path or a windows style path (depending
+       // on windows_style_tex_paths_), but we use always forward slashes,
+       // since this is standard for all tex engines.
+
+       if (windows_style_tex_paths_)
+               return convert_path_list(p, PathStyle(windows));
+
+       return convert_path_list(p, PathStyle(posix));
+}
+
+
 bool is_valid_strftime(string const & p)
 {
        string::size_type pos = p.find_first_of('%');
@@ -387,8 +404,11 @@
 }
 
 
-char path_separator()
+char path_separator(path_type type)
 {
+       if (type == TEXENGINE)
+               return windows_style_tex_paths_ ? ';' : ':';
+
        return ':';
 }
 
@@ -415,13 +435,30 @@
 }
 
 
-bool autoOpenFile(string const & filename, auto_open_mode const mode)
+bool autoOpenFile(string const & filename, auto_open_mode const mode,
+                 string const & path)
 {
+       string const texinputs = os::latex_path_list(
+                       replaceCurdirPath(path, lyxrc.texinputs_prefix));
+       string const sep = windows_style_tex_paths_ ? ";" : ":";
+       string const oldval = getEnv("TEXINPUTS");
+       string const newval = "." + sep + texinputs + sep + oldval;
+       if (!path.empty() && !lyxrc.texinputs_prefix.empty()) {
+               setEnv("TEXINPUTS", newval);
+               cygwin_internal(CW_SYNC_WINENV);
+       }
+
        // reference: http://msdn.microsoft.com/en-us/library/bb762153.aspx
        string const win_path = to_local8bit(from_utf8(convert_path(filename, 
PathStyle(windows))));
        char const * action = (mode == VIEW) ? "open" : "edit";
-       return reinterpret_cast<int>(ShellExecute(NULL, action,
-               win_path.c_str(), NULL, NULL, 1)) > 32;
+       bool success = reinterpret_cast<int>(ShellExecute(NULL, action,
+                                       win_path.c_str(), NULL, NULL, 1)) > 32;
+
+       if (!path.empty() && !lyxrc.texinputs_prefix.empty()) {
+               setEnv("TEXINPUTS", oldval);
+               cygwin_internal(CW_SYNC_WINENV);
+       }
+       return success;
 }
 
 

Modified: lyx-devel/branches/BRANCH_2_0_X/src/support/os_unix.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/support/os_unix.cpp     Sat May 14 
00:39:21 2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/support/os_unix.cpp     Sat May 14 
01:14:46 2011        (r38746)
@@ -12,9 +12,13 @@
 
 #include <config.h>
 
+#include "LyXRC.h"
+
 #include "support/os.h"
 #include "support/docstring.h"
+#include "support/environment.h"
 #include "support/FileName.h"
+#include "support/filetools.h"
 #include "support/lstrings.h"
 #include "support/lassert.h"
 
@@ -176,6 +180,12 @@
 }
 
 
+string latex_path_list(string const & p)
+{
+       return p;
+}
+
+
 bool is_valid_strftime(string const & p)
 {
        string::size_type pos = p.find_first_of('%');
@@ -218,7 +228,7 @@
 }
 
 
-char path_separator()
+char path_separator(path_type)
 {
        return ':';
 }
@@ -258,7 +268,8 @@
 }
 
 
-bool autoOpenFile(string const & filename, auto_open_mode const mode)
+bool autoOpenFile(string const & filename, auto_open_mode const mode,
+                 string const & path)
 {
 #ifdef __APPLE__
 // Reference: 
http://developer.apple.com/documentation/Carbon/Reference/LaunchServicesReference/
@@ -279,6 +290,13 @@
        if (status == kLSApplicationNotFoundErr)
                return false;
 
+       string const texinputs = os::latex_path_list(
+                       replaceCurdirPath(path, lyxrc.texinputs_prefix));
+       string const oldval = getEnv("TEXINPUTS");
+       string const newval = ".:" + texinputs + ":" + oldval;
+       if (!path.empty() && !lyxrc.texinputs_prefix.empty())
+               setEnv("TEXINPUTS", newval);
+
        LSLaunchFSRefSpec inLaunchSpec;
        inLaunchSpec.appRef = &outAppRef;
        inLaunchSpec.numDocs = 1;
@@ -288,11 +306,15 @@
        inLaunchSpec.asyncRefCon = NULL;
        status = LSOpenFromRefSpec(&inLaunchSpec, NULL);
 
+       if (!path.empty() && !lyxrc.texinputs_prefix.empty())
+               setEnv("TEXINPUTS", oldval);
+
        return status != kLSApplicationNotFoundErr;
 #else
        // silence compiler warnings
        (void)filename;
        (void)mode;
+       (void)path;
 
        // currently, no default viewer is tried for non-windows system
        // support for KDE/Gnome/Macintosh may be added later

Modified: lyx-devel/branches/BRANCH_2_0_X/src/support/os_win32.cpp
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/src/support/os_win32.cpp    Sat May 14 
00:39:21 2011        (r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/src/support/os_win32.cpp    Sat May 14 
01:14:46 2011        (r38746)
@@ -15,10 +15,13 @@
 
 #include <config.h>
 
+#include "LyXRC.h"
+
 #include "support/os.h"
 #include "support/os_win32.h"
 
 #include "support/debug.h"
+#include "support/environment.h"
 #include "support/FileName.h"
 #include "support/gettext.h"
 #include "support/filetools.h"
@@ -385,6 +388,38 @@
 }
 
 
+string latex_path_list(string const & p)
+{
+       if (p.empty())
+               return p;
+
+       // We may need a posix style path or a windows style path (depending
+       // on windows_style_tex_paths_), but we use always forward slashes,
+       // since this is standard for all tex engines.
+
+       if (!windows_style_tex_paths_) {
+               string pathlist;
+               for (size_t i = 0, k = 0; i != string::npos; k = i) {
+                       i = p.find(';', i);
+                       string path = subst(p.substr(k, i - k), '\\', '/');
+                       if (FileName::isAbsolute(path)) {
+                               string const drive = path.substr(0, 2);
+                               string const cygprefix = cygdrive + "/"
+                                                       + drive.substr(0, 1);
+                               path = subst(path, drive, cygprefix);
+                       }
+                       pathlist += path;
+                       if (i != string::npos) {
+                               pathlist += ':';
+                               ++i;
+                       }
+               }
+               return pathlist;
+       }
+       return subst(p, '\\', '/');
+}
+
+
 bool is_valid_strftime(string const & p)
 {
        string::size_type pos = p.find_first_of('%');
@@ -429,8 +464,11 @@
 }
 
 
-char path_separator()
+char path_separator(path_type type)
 {
+       if (type == TEXENGINE)
+               return windows_style_tex_paths_ ? ';' : ':';
+
        return ';';
 }
 
@@ -507,12 +545,25 @@
 }
 
 
-bool autoOpenFile(string const & filename, auto_open_mode const mode)
+bool autoOpenFile(string const & filename, auto_open_mode const mode,
+                 string const & path)
 {
+       string const texinputs = os::latex_path_list(
+                       replaceCurdirPath(path, lyxrc.texinputs_prefix));
+       string const sep = windows_style_tex_paths_ ? ";" : ":";
+       string const oldval = getEnv("TEXINPUTS");
+       string const newval = "." + sep + texinputs + sep + oldval;
+       if (!path.empty() && !lyxrc.texinputs_prefix.empty())
+               setEnv("TEXINPUTS", newval);
+
        // reference: http://msdn.microsoft.com/en-us/library/bb762153.aspx
        char const * action = (mode == VIEW) ? "open" : "edit";
-       return reinterpret_cast<int>(ShellExecute(NULL, action,
+       bool success = reinterpret_cast<int>(ShellExecute(NULL, action,
                to_local8bit(from_utf8(filename)).c_str(), NULL, NULL, 1)) > 32;
+
+       if (!path.empty() && !lyxrc.texinputs_prefix.empty())
+               setEnv("TEXINPUTS", oldval);
+       return success;
 }
 
 

Modified: lyx-devel/branches/BRANCH_2_0_X/status.20x
==============================================================================
--- lyx-devel/branches/BRANCH_2_0_X/status.20x  Sat May 14 00:39:21 2011        
(r38745)
+++ lyx-devel/branches/BRANCH_2_0_X/status.20x  Sat May 14 01:14:46 2011        
(r38746)
@@ -30,6 +30,11 @@
 
 - Improved XHTML output of various fractions.
 
+- A prefix for the TEXINPUTS environment variable can be specified in the
+  preferences. The directory of a LyX document is represented by a single
+  dot '.' or by the prefix "./". Also, any non-absolute path will be
+  prepended with the LyX document directory.
+
 
 * USER INTERFACE
 

Reply via email to