Don't change a shortcut file name when changing its path.

wxFileName::MakeRelativeTo() is only supposed to change the path of the file,
not its name, but it was doing the latter for the shortcuts as it implicitly
resolved them to the name of their target.

Fix this by ensuring we do not use wxPATH_NORM_SHORTCUT in MakeRelativeTo().

Closes #16239.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@77515 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2014-08-29 23:22:45 +00:00
parent 2090e676f9
commit 04519a46d7
3 changed files with 67 additions and 2 deletions

View File

@@ -612,6 +612,7 @@ wxMSW:
- Fix order of radial gradient stops (Alexandru Pana). - Fix order of radial gradient stops (Alexandru Pana).
- Fix font created using wxFont(wxFontInfo()) ctor. - Fix font created using wxFont(wxFontInfo()) ctor.
- Fix wxFileName::GetShortcutTarget() in console applications. - Fix wxFileName::GetShortcutTarget() in console applications.
- Fix wxFileName::MakeRelativeTo() for shortcut files (gafatoa).
3.0.1: (released 2014-06-15) 3.0.1: (released 2014-06-15)

View File

@@ -1797,8 +1797,13 @@ bool wxFileName::MakeRelativeTo(const wxString& pathBase, wxPathFormat format)
// get cwd only once - small time saving // get cwd only once - small time saving
wxString cwd = wxGetCwd(); wxString cwd = wxGetCwd();
Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE, cwd, format);
fnBase.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE, cwd, format); // Normalize the paths but avoid changing the case or turning a shortcut
// into a file that it points to.
const int normFlags = wxPATH_NORM_ALL &
~(wxPATH_NORM_CASE | wxPATH_NORM_SHORTCUT);
Normalize(normFlags, cwd, format);
fnBase.Normalize(normFlags, cwd, format);
bool withCase = IsCaseSensitive(format); bool withCase = IsCaseSensitive(format);

View File

@@ -27,6 +27,9 @@
#ifdef __WINDOWS__ #ifdef __WINDOWS__
#include "wx/msw/registry.h" #include "wx/msw/registry.h"
#include <shlobj.h>
#include "wx/msw/ole/oleutils.h"
#include "wx/msw/private/comptr.h"
#endif // __WINDOWS__ #endif // __WINDOWS__
#ifdef __UNIX__ #ifdef __UNIX__
@@ -145,6 +148,9 @@ private:
#if defined(__UNIX__) #if defined(__UNIX__)
CPPUNIT_TEST( TestSymlinks ); CPPUNIT_TEST( TestSymlinks );
#endif // __UNIX__ #endif // __UNIX__
#ifdef __WINDOWS__
CPPUNIT_TEST( TestShortcuts );
#endif // __WINDOWS__
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
void TestConstruction(); void TestConstruction();
@@ -168,6 +174,9 @@ private:
#if defined(__UNIX__) #if defined(__UNIX__)
void TestSymlinks(); void TestSymlinks();
#endif // __UNIX__ #endif // __UNIX__
#ifdef __WINDOWS__
void TestShortcuts();
#endif // __WINDOWS__
DECLARE_NO_COPY_CLASS(FileNameTestCase) DECLARE_NO_COPY_CLASS(FileNameTestCase)
}; };
@@ -996,3 +1005,53 @@ void FileNameTestCase::TestSymlinks()
} }
#endif // __UNIX__ #endif // __UNIX__
#ifdef __WINDOWS__
namespace
{
void CreateShortcut(const wxString& pathFile, const wxString& pathLink)
{
wxOleInitializer oleInit;
HRESULT hr;
wxCOMPtr<IShellLink> sl;
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (void **)&sl);
CPPUNIT_ASSERT( SUCCEEDED(hr) );
wxCOMPtr<IPersistFile> pf;
hr = sl->QueryInterface(IID_IPersistFile, (void **)&pf);
CPPUNIT_ASSERT( SUCCEEDED(hr) );
hr = sl->SetPath(pathFile.wx_str());
CPPUNIT_ASSERT( SUCCEEDED(hr) );
hr = pf->Save(pathLink.wx_str(), TRUE);
CPPUNIT_ASSERT( SUCCEEDED(hr) );
}
} // anonymous namespace
void FileNameTestCase::TestShortcuts()
{
wxFileName fn(wxFileName::CreateTempFileName("filenametest"));
CPPUNIT_ASSERT( fn.IsOk() );
wxON_BLOCK_EXIT1( wxRemoveFile, fn.GetFullPath() );
wxFileName fnLink(fn.GetPath(), "sc_" + fn.GetName(), "lnk");
CPPUNIT_ASSERT( fnLink.IsOk() );
wxON_BLOCK_EXIT1( wxRemoveFile, fnLink.GetFullPath() );
CreateShortcut(fn.GetFullPath(), fnLink.GetFullPath());
// MakeRelativeTo() is supposed to change only the path of the file, not its
// name.
wxFileName fnLinkRel(fnLink);
fnLink.MakeRelativeTo(".");
CPPUNIT_ASSERT_EQUAL(fnLink.GetFullName(), fnLinkRel.GetFullName());
}
#endif // __WINDOWS__