- Update CRT environment block in wxSetEnv() too.
- Fix wxMDIChildFrame::SetSize() (Lars Rosenboom).
- Fix wxTreeCtrl::UnselectItem() in single selection controls.
+- Allow customizing wxStandardPaths logic for program directory determination.
i18n:
class WXDLLIMPEXP_BASE wxStandardPaths : public wxStandardPathsBase
{
public:
- wxStandardPaths()
- {
- UseAppInfo(AppInfo_AppName | AppInfo_VendorName);
- }
-
- ~wxStandardPaths() { }
+ // ctor calls IgnoreAppBuildSubDirs() and also sets up the object to use
+ // both vendor and application name by default
+ wxStandardPaths();
// implement base class pure virtuals
virtual wxString GetExecutablePath() const;
virtual wxString GetPluginsDir() const;
virtual wxString GetDocumentsDir() const;
+
+ // MSW-specific methods
+
+ // This class supposes that data, plugins &c files are located under the
+ // program directory which is the directory containing the application
+ // binary itself. But sometimes this binary may be in a subdirectory of the
+ // main program directory, e.g. this happens in at least the following
+ // common cases:
+ // 1. The program is in "bin" subdirectory of the installation directory.
+ // 2. The program is in "debug" subdirectory of the directory containing
+ // sources and data files during development
+ //
+ // By calling this function you instruct the class to remove the last
+ // component of the path if it matches its argument. Notice that it may be
+ // called more than once, e.g. you can call both IgnoreAppSubDir("bin") and
+ // IgnoreAppSubDir("debug") to take care of both production and development
+ // cases above but that each call will only remove the last path component.
+ // Finally note that the argument can contain wild cards so you can also
+ // call IgnoreAppSubDir("vc*msw*") to ignore all build directories at once
+ // when using wxWidgets-inspired output directories names.
+ void IgnoreAppSubDir(const wxString& subdirPattern);
+
+ // This function is used to ignore all common build directories and is
+ // called from the ctor -- use DontIgnoreAppSubDir() to undo this.
+ void IgnoreAppBuildSubDirs();
+
+ // Undo the effects of all preceding IgnoreAppSubDir() calls.
+ void DontIgnoreAppSubDir();
+
protected:
// get the path corresponding to the given standard CSIDL_XXX constant
static wxString DoGetDirectory(int csidl);
// return the directory of the application itself
- static wxString GetAppDir();
+ wxString GetAppDir() const;
+
+ // directory returned by GetAppDir()
+ mutable wxString m_appDir;
};
// ----------------------------------------------------------------------------
class wxStandardPaths
{
public:
+ /**
+ MSW-specific function undoing the effect of IgnoreAppSubDir() calls.
+
+ After a call to this function the program directory will be exactly the
+ directory containing the main application binary, i.e. it undoes the
+ effect of any previous IgnoreAppSubDir() calls including the ones done
+ indirectly by IgnoreAppBuildSubDirs() called from the class
+ constructor.
+
+ @since 2.9.1
+ */
+ void DontIgnoreAppSubDir();
+
/**
Returns reference to the unique global standard paths object.
*/
*/
virtual wxString GetUserLocalDataDir() const;
+ /**
+ MSW-specific function to customize application directory detection.
+
+ This class supposes that data, plugins &c files are located under the
+ program directory which is the directory containing the application
+ binary itself. But sometimes this binary may be in a subdirectory of
+ the main program directory, e.g. this happens in at least the following
+ common cases:
+ - The program is in "bin" subdirectory of the installation directory.
+ - The program is in "debug" subdirectory of the directory containing
+ sources and data files during development
+
+ By calling this function you instruct the class to remove the last
+ component of the path if it matches its argument. Notice that it may be
+ called more than once, e.g. you can call both IgnoreAppSubDir("bin") and
+ IgnoreAppSubDir("debug") to take care of both production and development
+ cases above but that each call will only remove the last path component.
+ Finally note that the argument can contain wild cards so you can also
+ call IgnoreAppSubDir("vc*msw*") to ignore all build directories at once
+ when using wxWidgets-inspired output directories names.
+
+ @since 2.9.1
+
+ @see IgnoreAppBuildSubDirs()
+
+ @param subdirPattern
+ The subdirectory containing the application binary which should be
+ ignored when determining the top application directory. The pattern
+ is case-insensitive and may contain wild card characters @c '?' and
+ @c '*'.
+ */
+ void IgnoreAppSubDir(const wxString& subdirPattern);
+
+ /**
+ MSW-specific function to ignore all common build directories.
+
+ This function calls IgnoreAppSubDir() with all common values for build
+ directory, e.g. @c "debug" and @c "release".
+
+ It is called by the class constructor and so the build directories are
+ always ignored by default. You may use DontIgnoreAppSubDir() to avoid
+ ignoring them if this is inappropriate for your application.
+
+ @since 2.9.1
+ */
+ void IgnoreAppBuildSubDirs();
+
/**
Lets wxStandardPaths know about the real program installation prefix on a Unix
system. By default, the value returned by GetInstallPrefix() is used.
#ifndef SHGFP_TYPE_DEFAULT
#define SHGFP_TYPE_DEFAULT 1
#endif
+
// ----------------------------------------------------------------------------
// module globals
// ----------------------------------------------------------------------------
+namespace
+{
+
struct ShellFunctions
{
ShellFunctions()
// in spite of using a static variable, this is MT-safe as in the worst case it
// results in initializing the function pointer several times -- but this is
// harmless
-static ShellFunctions gs_shellFuncs;
+ShellFunctions gs_shellFuncs;
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
-static void ResolveShellFunctions()
+void ResolveShellFunctions()
{
#if wxUSE_DYNLIB_CLASS
#endif
}
+} // anonymous namespace
+
// ============================================================================
// wxStandardPaths implementation
// ============================================================================
return dir;
}
-/* static */
-wxString wxStandardPaths::GetAppDir()
+wxString wxStandardPaths::GetAppDir() const
{
- wxFileName fn(wxGetFullModuleName());
-
- // allow running the apps directly from build directory in MSVC debug builds
-#ifdef _DEBUG
- wxString lastdir;
- if ( fn.GetDirCount() )
+ if ( m_appDir.empty() )
{
- lastdir = fn.GetDirs().Last();
- lastdir.MakeLower();
- if ( lastdir.Matches(_T("debug*")) || lastdir.Matches(_T("vc*msw*")) )
- fn.RemoveLastDir();
+ m_appDir = wxFileName(wxGetFullModuleName()).GetPath();
}
-#endif // _DEBUG
- return fn.GetPath();
+ return m_appDir;
}
wxString wxStandardPaths::GetDocumentsDir() const
return DoGetDirectory(CSIDL_PERSONAL);
}
+// ----------------------------------------------------------------------------
+// MSW-specific functions
+// ----------------------------------------------------------------------------
+
+void wxStandardPaths::IgnoreAppSubDir(const wxString& subdirPattern)
+{
+ wxFileName fn = wxFileName::DirName(GetAppDir());
+
+ if ( !fn.GetDirCount() )
+ {
+ // no last directory to ignore anyhow
+ return;
+ }
+
+ const wxString lastdir = fn.GetDirs().Last().Lower();
+ if ( lastdir.Matches(subdirPattern.Lower()) )
+ {
+ fn.RemoveLastDir();
+
+ // store the cached value so that subsequent calls to GetAppDir() will
+ // reuse it instead of using just the program binary directory
+ m_appDir = fn.GetPath();
+ }
+}
+
+void wxStandardPaths::IgnoreAppBuildSubDirs()
+{
+ IgnoreAppSubDir("debug");
+ IgnoreAppSubDir("release");
+
+ wxString compilerPrefix;
+#ifdef __VISUALC__
+ compilerPrefix = "vc";
+#elif defined(__GNUG__)
+ compilerPrefix = "gcc";
+#elif defined(__BORLANDC__)
+ compilerPrefix = "bcc";
+#elif defined(__DIGITALMARS__)
+ compilerPrefix = "dmc";
+#elif defined(__WATCOMC__)
+ compilerPrefix = "wat";
+#else
+ return;
+#endif
+
+ IgnoreAppSubDir(compilerPrefix + "_msw*");
+}
+
+void wxStandardPaths::DontIgnoreAppSubDir()
+{
+ // this will force the next call to GetAppDir() to use the program binary
+ // path as the application directory
+ m_appDir.clear();
+}
+
// ----------------------------------------------------------------------------
// public functions
// ----------------------------------------------------------------------------
+wxStandardPaths::wxStandardPaths()
+{
+ // under MSW it's common to use both the applicatio nand vendor
+ UseAppInfo(AppInfo_AppName | AppInfo_VendorName);
+
+ // make it possible to run uninstalled application from the build directory
+ IgnoreAppBuildSubDirs();
+}
+
wxString wxStandardPaths::GetExecutablePath() const
{
return wxGetFullModuleName();