new wxHtmlWindow::OnOpeningURL API
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13854 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
d2b0092bed
commit
6cc4e6b81a
@ -134,6 +134,40 @@ Returns pointer to the source being parsed.
|
||||
Setups the parser for parsing the {\it source} string. (Should be overridden
|
||||
in derived class)
|
||||
|
||||
\membersection{wxHtmlParser::OpenURL}\label{wxhtmlparseropenurl}
|
||||
|
||||
\func{virtual wxFSFile*}{OpenURL}{\param{wxHtmlURLType }{type}, \param{const wxString\& }{url}}
|
||||
|
||||
Opens given URL and returns {\tt wxFSFile} object that can be used to read data
|
||||
from it. This method may return NULL in one of two cases: either the URL doesn't
|
||||
point to any valid resource or the URL is blocked by overriden implementation
|
||||
of {\it OpenURL} in derived class.
|
||||
|
||||
\wxheading{Parameters}
|
||||
|
||||
\docparam{type}{Indicates type of the resource. Is one of
|
||||
\begin{twocollist}\itemsep=0pt
|
||||
\twocolitem{{\bf wxHTML\_URL\_PAGE}}{Opening a HTML page.}
|
||||
\twocolitem{{\bf wxHTML\_URL\_IMAGE}}{Opening an image.}
|
||||
\twocolitem{{\bf wxHTML\_URL\_OTHER}}{Opening a resource that doesn't fall into
|
||||
any other category.}
|
||||
\end{twocollist}}
|
||||
|
||||
\docparam{url}{URL being opened.}
|
||||
|
||||
\wxheading{Notes}
|
||||
|
||||
Always use this method in tag handlers instead of {\tt GetFS()->OpenFile()}
|
||||
because it can block the URL and is thus more secure.
|
||||
|
||||
Default behaviour is to call \helpref{wxHtmlWindow::OnOpeningURL}{wxhtmlwindowonopeningurl}
|
||||
of the associated wxHtmlWindow object (which may decide to block the URL or
|
||||
redirect it to another one),if there's any, and always open the URL if the
|
||||
parser is not used with wxHtmlWindow.
|
||||
|
||||
Returned {\tt wxFSFile} object is not guaranteed to point to {\it url}, it might
|
||||
have been redirected!
|
||||
|
||||
\membersection{wxHtmlParser::Parse}\label{wxhtmlparserparse}
|
||||
|
||||
\func{wxObject*}{Parse}{\param{const wxString\& }{source}}
|
||||
|
@ -200,13 +200,39 @@ Also see \helpref{wxHtmlLinkInfo}{wxhtmllinkinfo}.
|
||||
|
||||
\membersection{wxHtmlWindow::OnOpeningURL}\label{wxhtmlwindowonopeningurl}
|
||||
|
||||
\func{virtual bool}{OnOpeningURL}{\param{const wxString\& }{url}}
|
||||
\func{virtual wxHtmlOpeningStatus}{OnOpeningURL}{\param{wxHtmlURLType }{type},\param{const wxString\& }{url}, \param{wxString *}{redirect}}
|
||||
|
||||
Called when an URL is being opened (either when the user clicks on a link or
|
||||
an image is loaded). If the function returns FALSE, the URL won't be fetched.
|
||||
Default behaviour is to return TRUE.
|
||||
an image is loaded). The URL will be opened only if OnOpeningURL returns
|
||||
{\tt wxHTML\_OPEN}. This method is called by
|
||||
\helpref{wxHtmlParser::OpenURL}{wxhtmlparseropenurl}.
|
||||
You can override OnOpeningURL to selectively block some
|
||||
URLs (e.g. for security reasons) or to redirect them elsewhere. Default
|
||||
behaviour is to always return {\tt wxHTML\_OPEN}.
|
||||
|
||||
Also see \helpref{wxHtmlWinParser::CanOpenURL}{wxhtmlwinparsercanopenurl}.
|
||||
\wxheading{Parameters}
|
||||
|
||||
\docparam{type}{Indicates type of the resource. Is one of
|
||||
\begin{twocollist}\itemsep=0pt
|
||||
\twocolitem{{\bf wxHTML\_URL\_PAGE}}{Opening a HTML page.}
|
||||
\twocolitem{{\bf wxHTML\_URL\_IMAGE}}{Opening an image.}
|
||||
\twocolitem{{\bf wxHTML\_URL\_OTHER}}{Opening a resource that doesn't fall into
|
||||
any other category.}
|
||||
\end{twocollist}}
|
||||
|
||||
\docparam{url}{URL being opened.}
|
||||
|
||||
\docparam{redirect}{Pointer to wxString variable that must be filled with an
|
||||
URL if OnOpeningURL returns {\tt wxHTML\_REDIRECT}.}
|
||||
|
||||
\wxheading{Return value}
|
||||
\begin{twocollist}\itemsep=0pt
|
||||
\twocolitem{{\bf wxHTML\_OPEN}}{Open the URL.}
|
||||
\twocolitem{{\bf wxHTML\_BLOCK}}{Deny access to the URL, \helpref{wxHtmlParser::OpenURL}{wxhtmlparseropenurl} will return NULL.}
|
||||
\twocolitem{{\bf wxHTML\_REDIRECT}}{Don't open {\it url}, redirect to another
|
||||
URL. OnOpeningURL must fill {\it *redirect} with the new URL. OnOpeningURL will
|
||||
be called again on returned URL.}
|
||||
\end{twocollist}
|
||||
|
||||
\membersection{wxHtmlWindow::OnSetTitle}\label{wxhtmlwindowonsettitle}
|
||||
|
||||
|
@ -43,14 +43,6 @@ Constructor. Don't use the default one, use constructor with
|
||||
|
||||
Adds \helpref{module}{handlers} to the list of wxHtmlWinParser tag handler.
|
||||
|
||||
\membersection{wxHtmlWinParser::CanOpenURL}\label{wxhtmlwinparsercanopenurl}
|
||||
|
||||
\func{virtual bool}{CanOpenURL}{\param{const wxString\& }{url}}
|
||||
|
||||
Call this function to determine whether you are allowed to open given URL.
|
||||
Default behaviour is to call \helpref{wxHtmlWindow::OnOpeningURL}{wxhtmlwindowonopeningurl}
|
||||
of the associated wxHtmlWindow object.
|
||||
|
||||
\membersection{wxHtmlWinParser::CloseContainer}\label{wxhtmlwinparserclosecontainer}
|
||||
|
||||
\func{wxHtmlContainerCell*}{CloseContainer}{\void}
|
||||
|
@ -31,6 +31,14 @@ class WXDLLEXPORT wxHtmlEntitiesParser;
|
||||
class wxHtmlTextPieces;
|
||||
class wxHtmlParserState;
|
||||
|
||||
|
||||
enum wxHtmlURLType
|
||||
{
|
||||
wxHTML_URL_PAGE,
|
||||
wxHTML_URL_IMAGE,
|
||||
wxHTML_URL_OTHER
|
||||
};
|
||||
|
||||
// This class handles generic parsing of HTML document : it scans
|
||||
// the document and divide it into blocks of tags (where one block
|
||||
// consists of starting and ending tag and of text between these
|
||||
@ -48,9 +56,9 @@ public:
|
||||
|
||||
wxFileSystem* GetFS() const { return m_FS; }
|
||||
|
||||
// Returns TRUE if the parser is allowed to open given URL (may be forbidden
|
||||
// Opens file if the parser is allowed to open given URL (may be forbidden
|
||||
// for security reasons)
|
||||
virtual bool CanOpenURL(const wxString& url) const { return TRUE; }
|
||||
virtual wxFSFile *OpenURL(wxHtmlURLType type, const wxString& url) const;
|
||||
|
||||
// You can simply call this method when you need parsed output.
|
||||
// This method does these things:
|
||||
|
@ -32,6 +32,19 @@ class wxHtmlWinModule;
|
||||
class wxHtmlHistoryArray;
|
||||
class wxHtmlProcessorList;
|
||||
|
||||
|
||||
// wxHtmlWindow flags:
|
||||
#define wxHW_SCROLLBAR_NEVER 0x0002
|
||||
#define wxHW_SCROLLBAR_AUTO 0x0004
|
||||
|
||||
// enums for wxHtmlWindow::OnOpeningURL
|
||||
enum wxHtmlOpeningStatus
|
||||
{
|
||||
wxHTML_OPEN,
|
||||
wxHTML_BLOCK,
|
||||
wxHTML_REDIRECT
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// wxHtmlWindow
|
||||
// (This is probably the only class you will directly use.)
|
||||
@ -106,10 +119,6 @@ public:
|
||||
// Sets fonts to be used when displaying HTML page.
|
||||
void SetFonts(wxString normal_face, wxString fixed_face, const int *sizes);
|
||||
|
||||
// Sets the title of the window
|
||||
// (depending on the information passed to SetRelatedFrame() method)
|
||||
virtual void OnSetTitle(const wxString& title);
|
||||
|
||||
// Sets space between text and window borders.
|
||||
void SetBorders(int b) {m_Borders = b;}
|
||||
|
||||
@ -136,8 +145,24 @@ public:
|
||||
// Adds input filter
|
||||
static void AddFilter(wxHtmlFilter *filter);
|
||||
|
||||
// Returns a pointer to the parser.
|
||||
wxHtmlWinParser *GetParser() const { return m_Parser; }
|
||||
|
||||
// Adds HTML processor to this instance of wxHtmlWindow:
|
||||
void AddProcessor(wxHtmlProcessor *processor);
|
||||
// Adds HTML processor to wxHtmlWindow class as whole:
|
||||
static void AddGlobalProcessor(wxHtmlProcessor *processor);
|
||||
|
||||
// what would we do with it?
|
||||
virtual bool AcceptsFocusFromKeyboard() const { return FALSE; }
|
||||
|
||||
// -- Callbacks --
|
||||
|
||||
// Sets the title of the window
|
||||
// (depending on the information passed to SetRelatedFrame() method)
|
||||
virtual void OnSetTitle(const wxString& title);
|
||||
|
||||
// Called when the mouse hovers over a cell: (x, y) are logical coords
|
||||
//
|
||||
// Default behaviour is to do nothing at all
|
||||
virtual void OnCellMouseHover(wxHtmlCell *cell, wxCoord x, wxCoord y);
|
||||
|
||||
@ -151,21 +176,14 @@ public:
|
||||
// call LoadPage(loc)
|
||||
virtual void OnLinkClicked(const wxHtmlLinkInfo& link);
|
||||
|
||||
// Called when wxHtmlWindow wants to fetch data from an URL (e.g. when loading
|
||||
// a page or loading an image). The data are downloaded if and only if
|
||||
// OnOpeningURL returns TRUE.
|
||||
virtual bool OnOpeningURL(const wxString& url) const { return TRUE; }
|
||||
|
||||
// Returns a pointer to the parser.
|
||||
wxHtmlWinParser *GetParser() const { return m_Parser; }
|
||||
|
||||
// Adds HTML processor to this instance of wxHtmlWindow:
|
||||
void AddProcessor(wxHtmlProcessor *processor);
|
||||
// Adds HTML processor to wxHtmlWindow class as whole:
|
||||
static void AddGlobalProcessor(wxHtmlProcessor *processor);
|
||||
|
||||
// what would we do with it?
|
||||
virtual bool AcceptsFocusFromKeyboard() const { return FALSE; }
|
||||
// Called when wxHtmlWindow wants to fetch data from an URL (e.g. when
|
||||
// loading a page or loading an image). The data are downloaded if and only if
|
||||
// OnOpeningURL returns TRUE. If OnOpeningURL returns wxHTML_REDIRECT,
|
||||
// it must set *redirect to the new URL
|
||||
virtual wxHtmlOpeningStatus OnOpeningURL(wxHtmlURLType type,
|
||||
const wxString& url,
|
||||
wxString *redirect) const
|
||||
{ return wxHTML_OPEN; }
|
||||
|
||||
protected:
|
||||
void Init();
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
virtual void DoneParser();
|
||||
virtual wxObject* GetProduct();
|
||||
|
||||
virtual bool CanOpenURL(const wxString& url) const;
|
||||
virtual wxFSFile *OpenURL(wxHtmlURLType type, const wxString& url) const;
|
||||
|
||||
// Set's the DC used for parsing. If SetDC() is not called,
|
||||
// parsing won't proceed
|
||||
|
@ -812,4 +812,10 @@ wxChar wxHtmlEntitiesParser::GetEntityChar(const wxString& entity)
|
||||
return GetCharForCode(code);
|
||||
}
|
||||
|
||||
wxFSFile *wxHtmlParser::OpenURL(wxHtmlURLType WXUNUSED(type),
|
||||
const wxString& url) const
|
||||
{
|
||||
return GetFS()->OpenFile(url);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -263,13 +263,7 @@ bool wxHtmlWindow::LoadPage(const wxString& location)
|
||||
Refresh(FALSE);
|
||||
}
|
||||
|
||||
if ( !m_Parser->CanOpenURL(location) )
|
||||
{
|
||||
wxLogError(_("Access denied to document '%s'!"), location.c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
f = m_FS->OpenFile(location);
|
||||
f = m_Parser->OpenURL(wxHTML_URL_PAGE, location);
|
||||
|
||||
if (f == NULL)
|
||||
{
|
||||
|
@ -292,6 +292,7 @@ public:
|
||||
private:
|
||||
wxBitmap *m_bitmap;
|
||||
int m_bmpW, m_bmpH;
|
||||
bool m_showFrame:1;
|
||||
wxScrolledWindow *m_window;
|
||||
#if wxUSE_GIF && wxUSE_TIMER
|
||||
wxGIFDecoder *m_gifDecoder;
|
||||
@ -323,12 +324,55 @@ class wxGIFTimer : public wxTimer
|
||||
// wxHtmlImageCell
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
/* XPM */
|
||||
static const char * broken_image_xpm[] = {
|
||||
"29 31 7 1",
|
||||
" c None",
|
||||
". c #808080",
|
||||
"+ c #FFFFFF",
|
||||
"@ c #C0C0C0",
|
||||
"# c #000000",
|
||||
"$ c #333366",
|
||||
"% c #B2B2B2",
|
||||
"..................... ",
|
||||
".+++++++++++++++++++.. ",
|
||||
".+++++++++++++++++++.@. ",
|
||||
".++@@@@@@@@@@@@@@@@@.+@. ",
|
||||
".++@@@@@@@@@@@@@@@@@.++@. ",
|
||||
".++@@@@@.@@@@.@@@@@@.+++@. ",
|
||||
".++@@@@@@@@@@@@@@@@@.++++@. ",
|
||||
".++@@@@@@@@@@@@@@@@@.+++++@. ",
|
||||
".++@@.@@@@@@@@@@.@@@######## ",
|
||||
".++@@@@@@@@@@@@@@@@@@$$$$$$#.",
|
||||
".######@@@@@@@@@@@@@@@.....#.",
|
||||
" ###@@@@@@@@@@@@@@@++#.",
|
||||
" #####@@@@@@@@@@++#.",
|
||||
" #@.@@@@@@@@++#.",
|
||||
".. ###@@@@@@@++#.",
|
||||
".+.... #@@@@@@++#.",
|
||||
".++@@@... ####@@++#.",
|
||||
".++@@@@@@.. #####.",
|
||||
".++@@@@@@@@... ",
|
||||
".++@@@@@@%%%%@. ",
|
||||
".++@@@@@@%%%%@@.... ",
|
||||
".++@@@@@@%%%%@@@@@@.... ",
|
||||
".++@@@@@@%%%%@@@@@@@@@@.... ",
|
||||
".++@@@@@@@@@@@@@@@@@@@@@@++#.",
|
||||
".++@@@@@@@@@@@@@@@@@@@@@@++#.",
|
||||
".++@@@@@@@@@@@@@@@@@@@@@@++#.",
|
||||
".++@@@@@@@@@@@@@@@@@@@@@@++#.",
|
||||
".++@@@@@@@@@@@@@@@@@@@@@@++#.",
|
||||
".++++++++++++++++++++++++++#.",
|
||||
".++++++++++++++++++++++++++#.",
|
||||
"############################."};
|
||||
|
||||
wxHtmlImageCell::wxHtmlImageCell(wxWindow *window, wxFSFile *input,
|
||||
int w, int h, double scale, int align,
|
||||
const wxString& mapname) : wxHtmlCell()
|
||||
{
|
||||
m_window = window ? wxStaticCast(window, wxScrolledWindow) : NULL;
|
||||
m_scale = scale;
|
||||
m_showFrame = FALSE;
|
||||
m_bitmap = NULL;
|
||||
m_bmpW = w;
|
||||
m_bmpH = h;
|
||||
@ -341,46 +385,63 @@ wxHtmlImageCell::wxHtmlImageCell(wxWindow *window, wxFSFile *input,
|
||||
m_physX = m_physY = -1;
|
||||
#endif
|
||||
|
||||
wxInputStream *s = input->GetStream();
|
||||
|
||||
if ( s )
|
||||
if ( input )
|
||||
{
|
||||
bool readImg = TRUE;
|
||||
|
||||
#if wxUSE_GIF && wxUSE_TIMER
|
||||
if ( (input->GetLocation().Matches(wxT("*.gif")) ||
|
||||
input->GetLocation().Matches(wxT("*.GIF"))) && m_window )
|
||||
wxInputStream *s = input->GetStream();
|
||||
|
||||
if ( s )
|
||||
{
|
||||
m_gifDecoder = new wxGIFDecoder(s, TRUE);
|
||||
if ( m_gifDecoder->ReadGIF() == wxGIF_OK )
|
||||
bool readImg = TRUE;
|
||||
|
||||
#if wxUSE_GIF && wxUSE_TIMER
|
||||
if ( (input->GetLocation().Matches(wxT("*.gif")) ||
|
||||
input->GetLocation().Matches(wxT("*.GIF"))) && m_window )
|
||||
{
|
||||
wxImage img;
|
||||
if ( m_gifDecoder->ConvertToImage(&img) )
|
||||
SetImage(img);
|
||||
|
||||
readImg = FALSE;
|
||||
|
||||
if ( m_gifDecoder->IsAnimation() )
|
||||
m_gifDecoder = new wxGIFDecoder(s, TRUE);
|
||||
if ( m_gifDecoder->ReadGIF() == wxGIF_OK )
|
||||
{
|
||||
m_gifTimer = new wxGIFTimer(this);
|
||||
m_gifTimer->Start(m_gifDecoder->GetDelay(), TRUE);
|
||||
wxImage img;
|
||||
if ( m_gifDecoder->ConvertToImage(&img) )
|
||||
SetImage(img);
|
||||
|
||||
readImg = FALSE;
|
||||
|
||||
if ( m_gifDecoder->IsAnimation() )
|
||||
{
|
||||
m_gifTimer = new wxGIFTimer(this);
|
||||
m_gifTimer->Start(m_gifDecoder->GetDelay(), TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxDELETE(m_gifDecoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxDELETE(m_gifDecoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if ( readImg )
|
||||
#endif
|
||||
{
|
||||
wxDELETE(m_gifDecoder);
|
||||
SetImage(wxImage(*s, wxBITMAP_TYPE_ANY));
|
||||
}
|
||||
}
|
||||
|
||||
if ( readImg )
|
||||
#endif
|
||||
}
|
||||
else // input==NULL, use "broken image" bitmap
|
||||
{
|
||||
if ( m_bmpW == -1 && m_bmpH == -1 )
|
||||
{
|
||||
SetImage(wxImage(*s, wxBITMAP_TYPE_ANY));
|
||||
m_bmpW == 29, m_bmpH = 31;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_showFrame = TRUE;
|
||||
if ( m_bmpW == -1 ) m_bmpW = 31;
|
||||
if ( m_bmpH == -1 ) m_bmpH = 33;
|
||||
}
|
||||
m_bitmap = new wxBitmap(broken_image_xpm);
|
||||
}
|
||||
|
||||
m_Width = (int)(scale * (double)m_bmpW);
|
||||
@ -487,7 +548,14 @@ wxHtmlImageCell::~wxHtmlImageCell()
|
||||
|
||||
void wxHtmlImageCell::Draw(wxDC& dc, int x, int y, int WXUNUSED(view_y1), int WXUNUSED(view_y2))
|
||||
{
|
||||
if (m_bitmap)
|
||||
if ( m_showFrame )
|
||||
{
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.SetPen(*wxBLACK_PEN);
|
||||
dc.DrawRectangle(x + m_PosX, y + m_PosY, m_Width, m_Height);
|
||||
x++, y++;
|
||||
}
|
||||
if ( m_bitmap )
|
||||
{
|
||||
double us_x, us_y;
|
||||
dc.GetUserScale(&us_x, &us_y);
|
||||
@ -549,10 +617,8 @@ TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA")
|
||||
wxString tmp = tag.GetParam(wxT("SRC"));
|
||||
wxString mn = wxEmptyString;
|
||||
|
||||
if ( !m_WParser->CanOpenURL(tmp) )
|
||||
return FALSE;
|
||||
|
||||
str = m_WParser->GetFS()->OpenFile(tmp);
|
||||
str = m_WParser->OpenURL(wxHTML_URL_IMAGE, tmp);
|
||||
|
||||
if (tag.HasParam(wxT("WIDTH")))
|
||||
tag.GetParamAsInt(wxT("WIDTH"), &w);
|
||||
if (tag.HasParam(wxT("HEIGHT")))
|
||||
@ -575,18 +641,16 @@ TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA")
|
||||
mn = mn.Mid( 1 );
|
||||
}
|
||||
}
|
||||
wxHtmlImageCell *cel = NULL;
|
||||
wxHtmlImageCell *cel = new wxHtmlImageCell(
|
||||
m_WParser->GetWindow(),
|
||||
str, w, h,
|
||||
m_WParser->GetPixelScale(),
|
||||
al, mn);
|
||||
cel->SetLink(m_WParser->GetLink());
|
||||
cel->SetId(tag.GetParam(wxT("id"))); // may be empty
|
||||
m_WParser->GetContainer()->InsertCell(cel);
|
||||
if (str)
|
||||
{
|
||||
cel = new wxHtmlImageCell(m_WParser->GetWindow(),
|
||||
str, w, h,
|
||||
m_WParser->GetPixelScale(),
|
||||
al, mn);
|
||||
cel->SetLink(m_WParser->GetLink());
|
||||
cel->SetId(tag.GetParam(wxT("id"))); // may be empty
|
||||
m_WParser->GetContainer()->InsertCell(cel);
|
||||
delete str;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tag.GetName() == wxT("MAP"))
|
||||
|
@ -180,14 +180,31 @@ wxObject* wxHtmlWinParser::GetProduct()
|
||||
return top;
|
||||
}
|
||||
|
||||
bool wxHtmlWinParser::CanOpenURL(const wxString& url) const
|
||||
wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type,
|
||||
const wxString& url) const
|
||||
{
|
||||
// FIXME - normalize the URL to full path before passing to
|
||||
// OnOpeningURL!!
|
||||
if ( m_Window )
|
||||
return m_Window->OnOpeningURL(url);
|
||||
{
|
||||
wxString redirect;
|
||||
wxString myurl(url);
|
||||
wxHtmlOpeningStatus status;
|
||||
for (;;)
|
||||
{
|
||||
if ( m_Window->OnOpeningURL(type, myurl, &redirect) == wxHTML_REDIRECT )
|
||||
myurl = redirect;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if ( status == wxHTML_BLOCK )
|
||||
return NULL;
|
||||
else
|
||||
return GetFS()->OpenFile(myurl);
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
return wxHtmlParser::OpenURL(type, url);
|
||||
}
|
||||
|
||||
void wxHtmlWinParser::AddText(const wxChar* txt)
|
||||
|
Loading…
Reference in New Issue
Block a user