]> git.lyx.org Git - lyx.git/blobdiff - src/support/Package.cpp
Fix bug #4269
[lyx.git] / src / support / Package.cpp
index 61bce681e75baa7dcf691f522d4d56d1453f6421..8b6fa0b03ae8becd97c3bc5c7b6caaa3245ecca7 100644 (file)
 #include "support/lassert.h"
 #include "support/lstrings.h"
 #include "support/os.h"
+#include "support/PathChanger.h"
+#include "support/Systemcall.h"
 
 #if defined (USE_WINDOWS_PACKAGING)
 # include "support/os_win32.h"
 #endif
 
 
+#include <iostream>
 #include <list>
 
 #if !defined (USE_WINDOWS_PACKAGING) && \
     !defined (USE_MACOSX_PACKAGING) && \
+    !defined (USE_HAIKU_PACKAGING) && \
     !defined (USE_POSIX_PACKAGING)
-#error USE_FOO_PACKAGING must be defined for FOO = WINDOWS, MACOSX or POSIX.
+#error USE_FOO_PACKAGING must be defined for FOO = WINDOWS, MACOSX, HAIKU or POSIX.
 #endif
 
 #if defined (USE_MACOSX_PACKAGING)
-# include <CoreServices/CoreServices.h> // FSFindFolder, FSRefMakePath
+# include "support/qstring_helpers.h"
+# include <QDir>
+# include <QDesktopServices>
 #endif
 
 using namespace std;
@@ -49,31 +55,23 @@ namespace {
 Package package_;
 bool initialised_ = false;
 
-} // namespace anon
+} // namespace
 
 
 void init_package(string const & command_line_arg0,
                  string const & command_line_system_support_dir,
-                 string const & command_line_user_support_dir,
-                 exe_build_dir_to_top_build_dir top_build_dir_location)
+                 string const & command_line_user_support_dir)
 {
        package_ = Package(command_line_arg0,
                           command_line_system_support_dir,
-                          command_line_user_support_dir,
-                          top_build_dir_location);
+                          command_line_user_support_dir);
        initialised_ = true;
 }
 
 
-bool packageInitialized()
-{
-       return initialised_;
-}
-
-
 Package const & package()
 {
-       LASSERT(initialised_, /**/);
+       LAPPERR(initialised_);
        return package_;
 }
 
@@ -82,9 +80,10 @@ namespace {
 
 FileName const abs_path_from_binary_name(string const & exe);
 
-void buildDirs(FileName const & abs_binary,
-       exe_build_dir_to_top_build_dir top_build_dir_location,
-       FileName &, FileName &);
+
+bool inBuildDir(FileName const & abs_binary, FileName &, FileName &);
+
+FileName findLyxBinary(FileName const & abs_binary);
 
 FileName const get_document_dir(FileName const & home_dir);
 
@@ -102,13 +101,12 @@ string const & with_version_suffix();
 
 string const fix_dir_name(string const & name);
 
-} // namespace anon
+} // namespace
 
 
 Package::Package(string const & command_line_arg0,
                 string const & command_line_system_support_dir,
-                string const & command_line_user_support_dir,
-                exe_build_dir_to_top_build_dir top_build_dir_location)
+                string const & command_line_user_support_dir)
        : explicit_user_support_dir_(false)
 {
        // Specification of temp_dir_ may be reset by LyXRC,
@@ -125,31 +123,16 @@ Package::Package(string const & command_line_arg0,
        lyx_dir_ = FileName(lyx_dir_.realPath());
 
        // Is LyX being run in-place from the build tree?
-       buildDirs(abs_binary, top_build_dir_location,
-               build_support_dir_, system_support_dir_);
+       in_build_dir_ = inBuildDir(abs_binary, build_support_dir_, system_support_dir_);
 
-       if (build_support_dir_.empty())
+       if (!in_build_dir_) {
                system_support_dir_ =
                        get_system_support_dir(abs_binary,
                                               command_line_system_support_dir);
-
-       // The LyX executable is one level above binary_dir_ if we are running
-       // tex2lyx in place. Otherwise it is in binary_dir_.
-       string abs_lyx_dir;
-       if (build_support_dir_.empty() ||
-           top_build_dir_location == top_build_dir_is_one_level_up)
-               abs_lyx_dir = binary_dir_.absFileName();
-       else {
-               FileName fn(addPath(binary_dir_.absFileName(), "../"));
-               abs_lyx_dir = fn.realPath();
        }
-       // The LyX executable may have a package suffix if we are not running
-       // in place.
-       if (build_support_dir_.empty())
-               lyx_binary_ = FileName(addName(abs_lyx_dir,
-                                              "lyx" + string(PROGRAM_SUFFIX)));
-       else
-               lyx_binary_ = FileName(addName(abs_lyx_dir, "lyx"));
+
+       // Find the LyX executable
+       lyx_binary_ = findLyxBinary(abs_binary);
 
        locale_dir_ = get_locale_dir(system_support_dir_);
 
@@ -159,10 +142,6 @@ Package::Package(string const & command_line_arg0,
        explicit_user_support_dir_ = userSupportDir(default_user_support_dir,
                                     command_line_user_support_dir, user_support_dir_);
 
-       FileName const configure_script(addName(system_support().absFileName(), "configure.py"));
-       configure_command_ = os::python() + ' ' +
-                       quoteName(configure_script.toFilesystemEncoding(), quote_python) +
-                       with_version_suffix();
 
        LYXERR(Debug::INIT, "<package>\n"
                << "\tbinary_dir " << binary_dir().absFileName() << '\n'
@@ -177,6 +156,31 @@ Package::Package(string const & command_line_arg0,
 }
 
 
+int Package::reconfigureUserLyXDir(string const & option) const
+{
+       if (configure_command_.empty()) {
+               FileName const configure_script(addName(system_support().absFileName(), "configure.py"));
+               configure_command_ = os::python() + ' ' +
+                       quoteName(configure_script.toFilesystemEncoding()) +
+                       with_version_suffix() + " --binary-dir=" +
+                       quoteName(FileName(binary_dir().absFileName()).toFilesystemEncoding());
+       }
+
+       lyxerr << to_utf8(_("LyX: reconfiguring user directory")) << endl;
+       PathChanger p(user_support());
+       Systemcall one;
+       int const ret = one.startscript(Systemcall::Wait, configure_command_ + option);
+       lyxerr << "LyX: " << to_utf8(_("Done!")) << endl;
+       return ret;
+}
+
+
+string Package::getConfigureLockName() const
+{
+       return addName(user_support().absFileName(), ".lyx_configure_lock");
+}
+
+
 void Package::set_temp_dir(FileName const & temp_dir) const
 {
        if (temp_dir.empty())
@@ -185,6 +189,22 @@ void Package::set_temp_dir(FileName const & temp_dir) const
                temp_dir_ = temp_dir;
 }
 
+
+FileName Package::messages_file(string const & c) const
+{
+       if (in_build_dir_) {
+               FileName res = FileName(lyx_dir().absFileName() + "/po/" + c + ".gmo");
+               if (!res.isReadableFile())
+                       res = FileName(lyx_dir().absFileName() + "../po/" + c + ".gmo");
+               if (!res.isReadableFile())
+                       res = FileName(top_srcdir().absFileName() + "/po/" + c + ".gmo");
+               return res;
+       } else
+               return FileName(locale_dir_.absFileName() + "/" + c
+                       + "/LC_MESSAGES/" PACKAGE ".mo");
+}
+
+
 // The specification of home_dir_ is fixed for a given OS.
 // A typical example on Windows: "C:/Documents and Settings/USERNAME"
 // and on a Posix-like machine: "/home/USERNAME".
@@ -192,6 +212,8 @@ FileName const & Package::get_home_dir()
 {
 #if defined (USE_WINDOWS_PACKAGING)
        static FileName const home_dir(getEnv("USERPROFILE"));
+#elif defined (USE_MACOSX_PACKAGING)
+       static FileName const home_dir(fromqstr(QDir::homePath()));
 #else // Posix-like.
        static FileName const home_dir(getEnv("HOME"));
 #endif
@@ -227,7 +249,7 @@ string const & with_version_suffix()
        return program_suffix.empty() ? program_suffix : with_version_suffix;
 }
 
-} // namespace anon
+} // namespace
 
 
 FileName const & Package::top_srcdir()
@@ -270,24 +292,27 @@ string const fix_dir_name(string const & name)
 }
 
 
-FileName buildSupportDir(string const & binary_dir,
-                     exe_build_dir_to_top_build_dir top_build_dir_location)
+
+bool isBuildDir(FileName const & abs_binary, string const & dir_location,
+       FileName & build_support_dir)
 {
-       string indirection;
-       switch (top_build_dir_location) {
-       case top_build_dir_is_one_level_up:
-               indirection = "../lib";
-               break;
-       case top_build_dir_is_two_levels_up:
-               indirection = "../../lib";
-               break;
-       }
-       return FileName(addPath(binary_dir, indirection));
+    string search_dir = onlyPath(abs_binary.absFileName()) + dir_location;
+
+    // Makefile by automake
+    build_support_dir = FileName(addPath(search_dir, "lib"));
+    if (!fileSearch(build_support_dir.absFileName(), "Makefile").empty()) {
+        return true;
+    }
+    //  cmake file, no Makefile in lib
+    FileName build_src_dir = FileName(addPath(search_dir, "src"));
+    if (!fileSearch(build_src_dir.absFileName(), "cmake_install.cmake").empty()) {
+        return true;
+    }
+
+    return false;
 }
 
-
-void buildDirs(FileName const & abs_binary,
-  exe_build_dir_to_top_build_dir top_build_dir_location,
+bool inBuildDir(FileName const & abs_binary,
        FileName & build_support_dir, FileName & system_support_dir)
 {
        string const check_text = "Checking whether LyX is run in place...";
@@ -300,19 +325,19 @@ void buildDirs(FileName const & abs_binary,
 
        // Note that the name of the lyx binary may be a symbolic link.
        // If that is the case, then we follow the links too.
-       FileName binary = abs_binary;
+    FileName binary = abs_binary;
        while (true) {
                // Try and find "lyxrc.defaults".
-               string binary_dir = onlyPath(binary.absFileName());
-               build_support_dir = buildSupportDir(binary_dir, top_build_dir_location);
-               if (!fileSearch(build_support_dir.absFileName(), "Makefile").empty()) {
+               if( isBuildDir(binary, "../", build_support_dir) ||
+            isBuildDir(binary, "../../", build_support_dir))
+        {
                        // Try and find "chkconfig.ltx".
                        system_support_dir =
                                FileName(addPath(Package::top_srcdir().absFileName(), "lib"));
 
                        if (!fileSearch(system_support_dir.absFileName(), "chkconfig.ltx").empty()) {
                                LYXERR(Debug::INIT, check_text << " yes");
-                               return;
+                               return true;
                        }
                }
 
@@ -333,6 +358,59 @@ void buildDirs(FileName const & abs_binary,
        LYXERR(Debug::INIT, check_text << " no");
        system_support_dir = FileName();
        build_support_dir = FileName();
+
+    return false;
+}
+
+
+bool doesFileExist(FileName & result, string const & search_dir, string const & name)
+{
+    result = fileSearch(search_dir, name);
+    if (!result.empty()) {
+        return true;
+    }
+    return false;
+}
+
+
+bool lyxBinaryPath(FileName & lyx_binary, string const & search_dir, string const & ext)
+{
+    lyx_binary = FileName();
+    if(false) {
+    } else if (doesFileExist(lyx_binary, search_dir, "lyx" + ext)) {
+    } else if (doesFileExist(lyx_binary, search_dir, "LyX" + ext)) {
+    } else if (doesFileExist(lyx_binary, search_dir, "lyx" + string(PROGRAM_SUFFIX) + ext)) {
+    } else if (doesFileExist(lyx_binary, search_dir, "LyX" + string(PROGRAM_SUFFIX) + ext)){
+    }
+    return !lyx_binary.empty() ? true : false;
+}
+
+
+FileName findLyxBinary(FileName const & abs_binary)
+{
+    string ext;
+    string checkname = abs_binary.toFilesystemEncoding();
+    int check_len = checkname.length();
+    int prgsuffixlen = string(PROGRAM_SUFFIX).length();
+    if ((prgsuffixlen > 0) && (check_len > prgsuffixlen) &&
+       (checkname.substr(check_len-prgsuffixlen) == string(PROGRAM_SUFFIX))) {
+       ext = "";
+    }
+    else if (!abs_binary.extension().empty()) {
+        ext = "." + abs_binary.extension();
+    }
+
+    string binary_dir = onlyPath(abs_binary.absFileName());
+
+    FileName lyx_binary;
+    if (lyxBinaryPath(lyx_binary, binary_dir, ext))
+        return lyx_binary;
+
+    string search_dir = onlyPath(FileName(addPath(binary_dir, "/../")).absFileName());
+    if (lyxBinaryPath(lyx_binary, search_dir, ext))
+        return lyx_binary;
+
+    return FileName();
 }
 
 
@@ -344,6 +422,12 @@ FileName const get_document_dir(FileName const & home_dir)
        (void)home_dir; // Silence warning about unused variable.
        os::GetFolderPath win32_folder_path;
        return FileName(win32_folder_path(os::GetFolderPath::PERSONAL));
+#elif defined (USE_MACOSX_PACKAGING) && (QT_VERSION >= 0x050000)
+       (void)home_dir; // Silence warning about unused variable.
+       return FileName(fromqstr(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)));
+#elif defined (USE_MACOSX_PACKAGING)
+       (void)home_dir; // Silence warning about unused variable.
+       return FileName(fromqstr(QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation)));
 #else // Posix-like.
        return home_dir;
 #endif
@@ -569,9 +653,6 @@ get_system_support_dir(FileName const & abs_binary,
                                "to the LyX system directory containing the "
                                "file `chkconfig.ltx'."),
                          from_utf8(searched_dirs_str), from_ascii(LYX_DIR_VER)));
-
-       // Keep the compiler happy.
-       return FileName();
 }
 
 
@@ -607,25 +688,16 @@ FileName const get_default_user_support_dir(FileName const & home_dir)
        os::GetFolderPath win32_folder_path;
        return FileName(addPath(win32_folder_path(os::GetFolderPath::APPDATA), PACKAGE));
 
-#elif defined (USE_MACOSX_PACKAGING)
+#elif defined (USE_MACOSX_PACKAGING) && (QT_VERSION >= 0x050000)
        (void)home_dir; // Silence warning about unused variable.
+       return FileName(addPath(fromqstr(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)), PACKAGE));
 
-       FSRef fsref;
-       OSErr const error_code =
-               FSFindFolder(kUserDomain, kApplicationSupportFolderType,
-                            kDontCreateFolder, &fsref);
-       if (error_code != 0)
-               return FileName();
-
-       // FSRefMakePath returns the result in utf8
-       char store[PATH_MAX + 1];
-       OSStatus const status_code =
-               FSRefMakePath(&fsref,
-                             reinterpret_cast<UInt8*>(store), PATH_MAX);
-       if (status_code != 0)
-               return FileName();
+#elif defined (USE_MACOSX_PACKAGING)
+       (void)home_dir; // Silence warning about unused variable.
+       return FileName(addPath(fromqstr(QDesktopServices::storageLocation(QDesktopServices::DataLocation)), PACKAGE));
 
-       return FileName(addPath(reinterpret_cast<char const *>(store), PACKAGE));
+#elif defined (USE_HAIKU_PACKAGING)
+       return FileName(addPath(home_dir.absFileName(), string("/config/settings/") + PACKAGE));
 
 #else // USE_POSIX_PACKAGING
        return FileName(addPath(home_dir.absFileName(), string(".") + PACKAGE));
@@ -729,7 +801,7 @@ string const relative_system_support_dir()
        return result;
 }
 
-} // namespace anon
+} // namespace
 
 } // namespace support
 } // namespace lyx