diff --git a/ParaViewCore/ClientServerCore/Core/vtkProcessModule.cxx b/ParaViewCore/ClientServerCore/Core/vtkProcessModule.cxx index 4edd007c986..2e2e27f2d3a 100644 --- a/ParaViewCore/ClientServerCore/Core/vtkProcessModule.cxx +++ b/ParaViewCore/ClientServerCore/Core/vtkProcessModule.cxx @@ -453,8 +453,20 @@ bool vtkProcessModule::InitializePythonEnvironment(int argc, char** argv) vtkProcessModule::FinalizePython = true; } - std::string self_dir = vtksys::SystemTools::CollapseFullPath( - vtksys::SystemTools::GetFilenamePath(argv[0]).c_str()); + std::string self_dir, programname; + + if (argc > 0) + { + programname = vtksys::SystemTools::CollapseFullPath(argv[0]); + self_dir = vtksys::SystemTools::GetFilenamePath(programname.c_str()); + } + else + { + self_dir = vtksys::SystemTools::GetCurrentWorkingDirectory(/*collapse=*/true); + programname = self_dir + "/unknown_exe"; + } + + vtkPythonInterpreter::SetProgramName(programname.c_str()); vtkPythonAppInitPrependPath(self_dir.c_str()); #endif (void)argc; diff --git a/ParaViewCore/ClientServerCore/Core/vtkProcessModuleInitializePython.h b/ParaViewCore/ClientServerCore/Core/vtkProcessModuleInitializePython.h index 41e99c56ca2..795a3026a10 100644 --- a/ParaViewCore/ClientServerCore/Core/vtkProcessModuleInitializePython.h +++ b/ParaViewCore/ClientServerCore/Core/vtkProcessModuleInitializePython.h @@ -15,11 +15,9 @@ #ifndef __vtkProcessModulePythonInitializePython_h #define __vtkProcessModulePythonInitializePython_h - -#include -#include -#include #include "vtkPythonInterpreter.h" +#include +#include /* The maximum length of a file name. */ #if defined(PATH_MAX) @@ -31,157 +29,198 @@ #endif namespace { - // This is code that used to reside in vtkPVPythonInterpretor. We should - // sanitize and clean it up. Since I don't want to muck with the search paths - // close to a release, I am leaving this untouched. + // ParaView should setup Python Path to find the modules in the following + // locations for various platforms. There are always two cases to handle: when + // running from build-location and when running from installed-location. - // THIS NEEDS TO BE CLEANED LIKE THE PLAGUE!!! //---------------------------------------------------------------------------- - void vtkPythonAppInitPrependPythonPath(const char* dir) + void vtkPythonAppInitPrependPythonPath(const std::string& dir) { - vtkPythonInterpreter::PrependPythonPath(dir); + if (dir != "") + { + std::string collapsed_dir = + vtksys::SystemTools::CollapseFullPath(dir.c_str()); + if (vtksys::SystemTools::FileIsDirectory(collapsed_dir.c_str())) + { + vtkPythonInterpreter::PrependPythonPath(collapsed_dir.c_str()); + } + } } - //---------------------------------------------------------------------------- - bool vtkPythonAppInitPrependPath2(const std::string& prefix, const std::string& path) + //=========================================================================== + // Linux/UNIX (not OsX) + // Key: + // - SELF_DIR: directory containing the pvserver/pvpython/paraview + // executables. For installed locations, this corresponds to the "real" + // executable, not the shared-forwarded executable (if applicable). + //--------------------------------------------------------------------------- + // + BUILD_LOCATION + // + ParaView C/C++ library location + // - SELF_DIR/../lib + // + ParaView Python modules + // - SELF_DIR/../lib/site-packages + // + INSTALL_LOCATION + // + ParaView C/C++ library location + // - SELF_DIR + // + ParaView Python modules + // - SELF_DIR/site-packages + void vtkPythonAppInitPrependPathLinux(const std::string& SELF_DIR) { - std::string package_dir = prefix + path; - package_dir = vtksys::SystemTools::CollapseFullPath(package_dir.c_str()); - if (!vtksys::SystemTools::FileIsDirectory(package_dir.c_str())) + // Determine if running from build or install dir. + // If SELF_DIR/site-packages exists, it must be running from an installed + // location. + bool is_build_dir = vtksys::SystemTools::FileExists( + (SELF_DIR + "/site-packages").c_str()) == false; + if (is_build_dir) { - package_dir = prefix + "/../" + path; - package_dir = vtksys::SystemTools::CollapseFullPath(package_dir.c_str()); + vtkPythonAppInitPrependPythonPath(SELF_DIR + "/../lib"); + vtkPythonAppInitPrependPythonPath(SELF_DIR + "/../lib/site-packages"); } - - if (!vtksys::SystemTools::FileIsDirectory(package_dir.c_str())) + else { - // This is the right path for app bundles on OS X - package_dir = prefix + "/../../../../" + path; - package_dir = vtksys::SystemTools::CollapseFullPath(package_dir.c_str()); + vtkPythonAppInitPrependPythonPath(SELF_DIR); + vtkPythonAppInitPrependPythonPath(SELF_DIR + "/site-packages"); } - - if(vtksys::SystemTools::FileIsDirectory(package_dir.c_str())) + } + //=========================================================================== + + + //=========================================================================== + // Windows + // Key: + // - SELF_DIR: directory containing the pvserver/pvpython/paraview + // executables. + //--------------------------------------------------------------------------- + // + BUILD_LOCATION + // + ParaView C/C++ library location + // - SELF_DIR + // + ParaView Python modules + // - SELF_DIR/site-packages (when CMAKE_INTDIR is not defined). + // OR + // - SELF_DIR/../site-packages (when CMAKE_INTDIR is defined). + // + INSTALL_LOCATION + // + ParaView C/C++ library location + // - SELF_DIR + // - SELF_DIR/../lib/paraview-./ + // + ParaView Python modules + // - SELF_DIR/../lib/paraview-./site-packages + //=========================================================================== + void vtkPythonAppInitPrependPathWindows(const std::string& SELF_DIR) + { + std::string build_dir_site_packages; +#if defined(CMAKE_INTDIR) + build_dir_site_packages = SELF_DIR + "/../site-packages"; +#else + build_dir_site_packages = SELF_DIR + "/site-packages"; +#endif + bool is_build_dir = + vtksys::SystemTools::FileExists(build_dir_site_packages.c_str()); + if (is_build_dir) { - // This executable is running from the build tree. Prepend the - // library directory and package directory to the search path. - vtkPythonAppInitPrependPythonPath(package_dir.c_str()); - return true; + vtkPythonAppInitPrependPythonPath(SELF_DIR); + vtkPythonAppInitPrependPythonPath(build_dir_site_packages); + } + else + { + vtkPythonAppInitPrependPythonPath(SELF_DIR); + vtkPythonAppInitPrependPythonPath( + SELF_DIR + "/../lib/paraview-" PARAVIEW_VERSION); + vtkPythonAppInitPrependPythonPath( + SELF_DIR + "/../lib/paraview-" PARAVIEW_VERSION "/site-packages"); } - return false; } - //---------------------------------------------------------------------------- - void vtkPythonAppInitPrependPath(const char* self_dir) + //=========================================================================== + // OsX + // Key: + // - SELF_DIR: directory containing the pvserver/pvpython/paraview + // executables. This is different for app and non-app executables. + //--------------------------------------------------------------------------- + // + BUILD_LOCATION + // - LIB_DIR + // - SELF_DIR/../lib (when executable is not APP, e.g pvpython) + // OR + // - SELF_DIR/../../../../lib (when executable is APP, e.g. paraview) + // + ParaView C/C++ library location + // - LIB_DIR + // + ParaView Python modules + // - LIB_DIR/site-packages + // + INSTALL_LOCATION + // - APP_ROOT + // - SELF_DIR/../.. (this is same for paraview and pvpython) + // - ParaView C/C++ library location + // - APP_ROOT/Contents/Libraries/ + // - ParaView Python modules + // - APP_ROOT/Contents/Python + //=========================================================================== + void vtkPythonAppInitPrependPathOsX(const std::string &SELF_DIR) { - // Try to put the VTK python module location in sys.path. - std::string pkg_prefix = self_dir; -#if defined(CMAKE_INTDIR) - pkg_prefix += "/.."; -#endif - vtkPythonAppInitPrependPath2(pkg_prefix, "/site-packages"); - vtkPythonAppInitPrependPath2(pkg_prefix, "/lib/site-packages"); - vtkPythonAppInitPrependPath2(pkg_prefix, "/../lib/site-packages"); - vtkPythonAppInitPrependPath2(pkg_prefix, "/lib"); - vtkPythonAppInitPrependPath2(pkg_prefix, "/../lib"); + bool is_app = false; + { + // if SELF_DIR/../ is named "Contents", we are in an App. + std::string contents_dir = vtksys::SystemTools::CollapseFullPath( + (SELF_DIR + "/..").c_str()); + is_app = (vtksys::SystemTools::GetFilenameName(contents_dir) == "Contents"); + } + + std::string lib_dir = (is_app==false)? (SELF_DIR + "/../lib") : + (SELF_DIR + "/../../../../lib"); + lib_dir = vtksys::SystemTools::CollapseFullPath(lib_dir.c_str()); - if (vtkPythonAppInitPrependPath2(pkg_prefix, "Utilities/VTKPythonWrapping/site-packages")) + bool is_build_dir = vtksys::SystemTools::FileExists(lib_dir.c_str()); + if (is_build_dir) { - // This executable is running from the build tree. Prepend the - // library directory to the search path. - //vtkPythonAppInitPrependPythonPath(VTK_PYTHON_LIBRARY_DIR); + vtkPythonAppInitPrependPythonPath(lib_dir); + vtkPythonAppInitPrependPythonPath(lib_dir + "/site-packages"); } else { - // This executable is running from an install tree. Check for - // possible VTK python module locations. See - // http://python.org/doc/2.4.1/inst/alt-install-windows.html for - // information about possible install locations. If the user - // changes the prefix to something other than VTK's prefix or - // python's native prefix then he/she will have to get the - // packages in sys.path himself/herself. - const char* inst_dirs[] = { - "/paraview", - "/../Python/paraview", // MacOS bundle - "/../lib/paraview-" PARAVIEW_VERSION "/paraview", - "/../../lib/paraview-" PARAVIEW_VERSION "/paraview", - "/lib/python/paraview", // UNIX --home - "/Lib/site-packages/paraview", "/Lib/paraview", // Windows - "/site-packages/paraview", "/paraview", // Windows - "/../lib/paraview-" PARAVIEW_VERSION "/site-packages/paraview", - "/../lib/paraview-" PARAVIEW_VERSION "/site-packages", - 0 - }; - - std::string prefix = self_dir; - vtkPythonAppInitPrependPythonPath(self_dir); // Propbably not needed any longer. - -#if defined(WIN32) - // for when running from installed location. - std::string lib_dir = std::string(prefix + "/../lib/paraview-" + PARAVIEW_VERSION); - lib_dir = vtksys::SystemTools::CollapseFullPath( lib_dir.c_str()); - vtkPythonAppInitPrependPythonPath(lib_dir.c_str()); - vtkPythonAppInitPrependPythonPath( (lib_dir + "/site-packages").c_str() ); -#endif + std::string app_root = SELF_DIR + "/../.."; + app_root = vtksys::SystemTools::CollapseFullPath(app_root.c_str()); + // The Contents/Libraries may not be needed. We should verify that. + vtkPythonAppInitPrependPythonPath(app_root + "/Contents/Libraries"); + vtkPythonAppInitPrependPythonPath(app_root + "/Contents/Python"); + } + } - // These two directories should be all that is necessary when running the - // python interpreter in a build tree. - //vtkPythonAppInitPrependPythonPath(PV_PYTHON_PACKAGE_DIR "/site-packages"); - //vtkPythonAppInitPrependPythonPath(VTK_PYTHON_LIBRARY_DIR "/site-packages"); - //vtkPythonAppInitPrependPythonPath(VTK_PYTHON_LIBRARY_DIR); - -#if defined(__APPLE__) - // On OS X distributions, the libraries are in a different directory - // than the module. They are in a place relative to the executable. - std::string libs_dir = std::string(self_dir) + "/../Libraries"; - libs_dir = vtksys::SystemTools::CollapseFullPath(libs_dir.c_str()); - if(vtksys::SystemTools::FileIsDirectory(libs_dir.c_str())) - { - vtkPythonAppInitPrependPythonPath(libs_dir.c_str()); - } - vtkPythonAppInitPrependPath2(prefix, "/../Python"); -#endif - for(const char** dir = inst_dirs; *dir; ++dir) - { - std::string package_dir; - package_dir = prefix; - package_dir += *dir; - package_dir = vtksys::SystemTools::CollapseFullPath(package_dir.c_str()); - if(vtksys::SystemTools::FileIsDirectory(package_dir.c_str())) - { - // We found the modules. Add the location to sys.path, but - // without the "/vtk" suffix. - std::string path_dir = - vtksys::SystemTools::GetFilenamePath(package_dir); - vtkPythonAppInitPrependPythonPath(path_dir.c_str()); - break; - } - } - // This executable does not actually link to the python wrapper - // libraries, though it probably should now that the stub-modules - // are separated from them. Since it does not we have to make - // sure the wrapper libraries can be found by the dynamic loader - // when the stub-modules are loaded. On UNIX this executable must - // be running in an environment where the main VTK libraries (to - // which this executable does link) have been found, so the - // wrapper libraries will also be found. On Windows this - // executable may have simply found its .dll files next to itself - // so the wrapper libraries may not be found when the wrapper - // modules are loaded. Solve this problem by adding this - // executable's location to the system PATH variable. Note that - // this need only be done for an installed VTK because in the - // build tree the wrapper modules are in the same directory as the - // wrapper libraries. + //---------------------------------------------------------------------------- + void vtkPythonAppInitPrependPath(const std::string &SELF_DIR) + { #if defined(_WIN32) - static char system_path[(VTK_PYTHON_MAXPATH+1)*10] = "PATH="; - strcat(system_path, self_dir); - if(char* oldpath = getenv("PATH")) - { - strcat(system_path, ";"); - strcat(system_path, oldpath); - } - putenv(system_path); + vtkPythonAppInitPrependPathWindows(SELF_DIR); +#elif defined(__APPLE__) + vtkPythonAppInitPrependPathOsX(SELF_DIR); +#else + vtkPythonAppInitPrependPathLinux(SELF_DIR); #endif + + // *** The following maybe obsolete. Need to verify and remove. *** + + // This executable does not actually link to the python wrapper + // libraries, though it probably should now that the stub-modules + // are separated from them. Since it does not we have to make + // sure the wrapper libraries can be found by the dynamic loader + // when the stub-modules are loaded. On UNIX this executable must + // be running in an environment where the main VTK libraries (to + // which this executable does link) have been found, so the + // wrapper libraries will also be found. On Windows this + // executable may have simply found its .dll files next to itself + // so the wrapper libraries may not be found when the wrapper + // modules are loaded. Solve this problem by adding this + // executable's location to the system PATH variable. Note that + // this need only be done for an installed VTK because in the + // build tree the wrapper modules are in the same directory as the + // wrapper libraries. +#if defined(_WIN32) + static char system_path[(VTK_PYTHON_MAXPATH+1)*10] = "PATH="; + strcat(system_path, SELF_DIR.c_str()); + if(char* oldpath = getenv("PATH")) + { + strcat(system_path, ";"); + strcat(system_path, oldpath); } + putenv(system_path); +#endif } } diff --git a/Qt/Core/pqOutputWindow.cxx b/Qt/Core/pqOutputWindow.cxx index a31a59ad748..cf6c9be9379 100644 --- a/Qt/Core/pqOutputWindow.cxx +++ b/Qt/Core/pqOutputWindow.cxx @@ -74,7 +74,7 @@ void pqOutputWindow::onDisplayTextInWindow(const QString& text) format.clearBackground(); this->Implementation->Ui.consoleWidget->setFormat(format); this->Implementation->Ui.consoleWidget->printString(text); - if (this->ShowOutput) + if (this->ShowOutput && !text.trimmed().isEmpty()) { this->show(); } @@ -87,7 +87,7 @@ void pqOutputWindow::onDisplayErrorTextInWindow(const QString& text) format.clearBackground(); this->Implementation->Ui.consoleWidget->setFormat(format); this->Implementation->Ui.consoleWidget->printString(text); - if (this->ShowOutput) + if (this->ShowOutput && !text.trimmed().isEmpty()) { this->show(); } @@ -102,8 +102,7 @@ void pqOutputWindow::onDisplayText(const QString& text) this->Implementation->Ui.consoleWidget->printString(text + "\n"); cerr << text.toAscii().data() << endl; - - if (this->ShowOutput) + if (this->ShowOutput && !text.trimmed().isEmpty()) { this->show(); } @@ -128,7 +127,7 @@ void pqOutputWindow::onDisplayWarningText(const QString& text) this->Implementation->Ui.consoleWidget->printString(text + "\n"); cerr << text.toAscii().data() << endl; - if (this->ShowOutput) + if (this->ShowOutput && !text.trimmed().isEmpty()) { this->show(); } @@ -144,7 +143,7 @@ void pqOutputWindow::onDisplayGenericWarningText(const QString& text) this->Implementation->Ui.consoleWidget->printString(text + "\n"); cerr << text.toAscii().data() << endl; - if (this->ShowOutput) + if (this->ShowOutput && !text.trimmed().isEmpty()) { this->show(); } @@ -170,7 +169,7 @@ void pqOutputWindow::onDisplayErrorText(const QString& text) this->Implementation->Ui.consoleWidget->printString(text + "\n"); cerr << text.toAscii().data() << endl; - if (this->ShowOutput) + if (this->ShowOutput && !text.trimmed().isEmpty()) { this->show(); }