Document and test that bitmap paths in XRC are percent-encoded

These paths are actually URLs and so the special URL characters must be
percent-encoded in them.

Document this and add a test checking that this is how it works.

Closes #19142.
This commit is contained in:
Vadim Zeitlin
2021-04-15 18:49:16 +01:00
parent b9bd932077
commit 2babb9e06c
2 changed files with 53 additions and 8 deletions

View File

@@ -341,8 +341,8 @@ or translations are done.
@subsection overview_xrcformat_type_bitmap Bitmap
Bitmap properties contain specification of a single bitmap or icon. In the most
basic form, their text value is simply a relative filename (or another
wxFileSystem URL) of the bitmap to use. For example:
basic form, their text value is simply a relative URL of the bitmap to use.
For example:
@code
<object class="tool" name="wxID_NEW">
<tooltip>New</tooltip>
@@ -350,7 +350,15 @@ wxFileSystem URL) of the bitmap to use. For example:
</object>
@endcode
The value is interpreted as path relative to the location of XRC file where the
reference occurs.
reference occurs, but notice that it is still an URL and not just a filename,
which means that the characters special in the URLs, such as @c '#' must be
percent-encoded, e.g. here is the correct way to specify a bitmap with the path
@c "images/#1/tool.png" in XRC:
@code
<object class="tool" name="first">
<bitmap>images/%231/tool.png</bitmap>
</object>
@endcode
Bitmap file paths can include environment variables that are expanded if
wxXRC_USE_ENVVARS was passed to the wxXmlResource constructor.

View File

@@ -20,14 +20,18 @@
#if wxUSE_XRC
#include "wx/fs_inet.h"
#include "wx/imagxpm.h"
#include "wx/xml/xml.h"
#include "wx/scopedptr.h"
#include "wx/sstream.h"
#include "wx/wfstream.h"
#include "wx/xrc/xmlres.h"
#include "wx/xrc/xh_bmp.h"
#include <stdarg.h>
#include "testfile.h"
// ----------------------------------------------------------------------------
// helpers to create/save some xrc
// ----------------------------------------------------------------------------
@@ -209,15 +213,48 @@ TEST_CASE_METHOD(XrcTestCase, "XRC::IDRanges", "[xrc]")
TEST_CASE("XRC::PathWithFragment", "[xrc][uri]")
{
wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
wxImage::AddHandler(new wxXPMHandler);
const wxString filename = "image#1.xpm";
TempFile xpmFile(filename);
// Simplest possible XPM, just to have something to create a bitmap from.
static const char* xpm =
"/* XPM */\n"
"static const char *const xpm[] = {\n"
"/* columns rows colors chars-per-pixel */\n"
"\"1 1 1 1\",\n"
"\" c None\",\n"
"/* pixels */\n"
"\" \"\n"
;
wxFFile ff;
REQUIRE( ff.Open(filename, "w") );
REQUIRE( ff.Write(wxString::FromAscii(xpm)) );
REQUIRE( ff.Close() );
// Opening a percent-encoded URI should work.
wxString url = filename;
url.Replace("#", "%23");
LoadXrcFrom
(
"<?xml version=\"1.0\" ?>"
"<resource>"
" <object class=\"wxBitmap\" name=\"bitmap\">bitmap#1.png</object>"
"</resource>"
wxString::Format
(
"<?xml version=\"1.0\" ?>"
"<resource>"
" <object class=\"wxBitmap\" name=\"bad\">%s</object>"
" <object class=\"wxBitmap\" name=\"good\">%s</object>"
"</resource>",
filename,
url
)
);
CHECK( wxXmlResource::Get()->LoadBitmap("bitmap").IsOk() );
CHECK( wxXmlResource::Get()->LoadBitmap("good").IsOk() );
CHECK( !wxXmlResource::Get()->LoadBitmap("bad").IsOk() );
}
// This test is disabled by default as it requires the environment variable