Merge branch 'html-set-cell'
Make wxHTML API more flexible by allowing to operate on individual wxHtmlContainerCell instead of only the entire HTML document text. See https://github.com/wxWidgets/wxWidgets/pull/899
This commit is contained in:
@@ -445,7 +445,7 @@ protected:
|
|||||||
class WXDLLIMPEXP_HTML wxHtmlContainerCell : public wxHtmlCell
|
class WXDLLIMPEXP_HTML wxHtmlContainerCell : public wxHtmlCell
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxHtmlContainerCell(wxHtmlContainerCell *parent);
|
explicit wxHtmlContainerCell(wxHtmlContainerCell *parent);
|
||||||
virtual ~wxHtmlContainerCell();
|
virtual ~wxHtmlContainerCell();
|
||||||
|
|
||||||
virtual void Layout(int w) wxOVERRIDE;
|
virtual void Layout(int w) wxOVERRIDE;
|
||||||
@@ -459,6 +459,11 @@ public:
|
|||||||
// insert cell at the end of m_Cells list
|
// insert cell at the end of m_Cells list
|
||||||
void InsertCell(wxHtmlCell *cell);
|
void InsertCell(wxHtmlCell *cell);
|
||||||
|
|
||||||
|
// Detach a child cell. After calling this method, it's the caller
|
||||||
|
// responsibility to destroy this cell (possibly by calling InsertCell()
|
||||||
|
// with it to attach it elsewhere).
|
||||||
|
void Detach(wxHtmlCell *cell);
|
||||||
|
|
||||||
// sets horizontal/vertical alignment
|
// sets horizontal/vertical alignment
|
||||||
void SetAlignHor(int al) {m_AlignHor = al; m_LastLayout = -1;}
|
void SetAlignHor(int al) {m_AlignHor = al; m_LastLayout = -1;}
|
||||||
int GetAlignHor() const {return m_AlignHor;}
|
int GetAlignHor() const {return m_AlignHor;}
|
||||||
|
@@ -54,6 +54,11 @@ public:
|
|||||||
// (see wxFileSystem for detailed explanation)
|
// (see wxFileSystem for detailed explanation)
|
||||||
void SetHtmlText(const wxString& html, const wxString& basepath = wxEmptyString, bool isdir = true);
|
void SetHtmlText(const wxString& html, const wxString& basepath = wxEmptyString, bool isdir = true);
|
||||||
|
|
||||||
|
// Sets the HTML cell that will be rendered: this is more efficient than
|
||||||
|
// using text as it allows to parse it only once. Note that the cell will
|
||||||
|
// be modified by this call.
|
||||||
|
void SetHtmlCell(wxHtmlContainerCell& cell);
|
||||||
|
|
||||||
// Sets fonts to be used when displaying HTML page. (if size null then default sizes used).
|
// Sets fonts to be used when displaying HTML page. (if size null then default sizes used).
|
||||||
void SetFonts(const wxString& normal_face, const wxString& fixed_face, const int *sizes = NULL);
|
void SetFonts(const wxString& normal_face, const wxString& fixed_face, const int *sizes = NULL);
|
||||||
|
|
||||||
@@ -79,11 +84,14 @@ public:
|
|||||||
int GetTotalHeight() const;
|
int GetTotalHeight() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void DoSetHtmlCell(wxHtmlContainerCell* cell);
|
||||||
|
|
||||||
wxDC *m_DC;
|
wxDC *m_DC;
|
||||||
wxHtmlWinParser *m_Parser;
|
wxFileSystem m_FS;
|
||||||
wxFileSystem *m_FS;
|
wxHtmlWinParser m_Parser;
|
||||||
wxHtmlContainerCell *m_Cells;
|
wxHtmlContainerCell *m_Cells;
|
||||||
int m_Width, m_Height;
|
int m_Width, m_Height;
|
||||||
|
bool m_ownsCells;
|
||||||
|
|
||||||
wxDECLARE_NO_COPY_CLASS(wxHtmlDCRenderer);
|
wxDECLARE_NO_COPY_CLASS(wxHtmlDCRenderer);
|
||||||
};
|
};
|
||||||
|
@@ -471,7 +471,21 @@ public:
|
|||||||
/**
|
/**
|
||||||
Constructor. @a parent is pointer to parent container or @NULL.
|
Constructor. @a parent is pointer to parent container or @NULL.
|
||||||
*/
|
*/
|
||||||
wxHtmlContainerCell(wxHtmlContainerCell* parent);
|
explicit wxHtmlContainerCell(wxHtmlContainerCell* parent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Detach a child cell.
|
||||||
|
|
||||||
|
Detaching a cell removes it from this container and allows to reattach
|
||||||
|
it to another one by using InsertCell(). Alternatively, this method can
|
||||||
|
be used to selectively remove some elements of the HTML document tree
|
||||||
|
by deleting the cell after calling it.
|
||||||
|
|
||||||
|
@param cell Must be non-null and an immediate child of this cell.
|
||||||
|
|
||||||
|
@since 3.1.2
|
||||||
|
*/
|
||||||
|
void Detach(wxHtmlCell* cell);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns container's horizontal alignment.
|
Returns container's horizontal alignment.
|
||||||
@@ -506,6 +520,9 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Inserts a new cell into the container.
|
Inserts a new cell into the container.
|
||||||
|
|
||||||
|
Note that the container takes ownership of the cell and will delete it
|
||||||
|
when it itself is destroyed.
|
||||||
*/
|
*/
|
||||||
void InsertCell(wxHtmlCell* cell);
|
void InsertCell(wxHtmlCell* cell);
|
||||||
|
|
||||||
|
@@ -168,6 +168,19 @@ public:
|
|||||||
const wxString& basepath = wxEmptyString,
|
const wxString& basepath = wxEmptyString,
|
||||||
bool isdir = true);
|
bool isdir = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Associate the given HTML contents to the renderer.
|
||||||
|
|
||||||
|
This is similar to SetHtmlText(), but is more efficient as the text can
|
||||||
|
be parsed only once, using wxHtmlParser::Parse(), and then passed to
|
||||||
|
wxHtmlDCRenderer multiple times or already reused for other purposes.
|
||||||
|
|
||||||
|
Note that @a cell will be modified (e.g. laid out) by this function.
|
||||||
|
|
||||||
|
@since 3.1.2
|
||||||
|
*/
|
||||||
|
void SetHtmlCell(wxHtmlContainerCell& cell);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set size of output rectangle, in pixels. Note that you @b can't change
|
Set size of output rectangle, in pixels. Note that you @b can't change
|
||||||
width of the rectangle between calls to Render() !
|
width of the rectangle between calls to Render() !
|
||||||
|
@@ -1159,6 +1159,43 @@ void wxHtmlContainerCell::InsertCell(wxHtmlCell *f)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void wxHtmlContainerCell::Detach(wxHtmlCell *cell)
|
||||||
|
{
|
||||||
|
wxHtmlCell* const firstChild = GetFirstChild();
|
||||||
|
if ( cell == firstChild )
|
||||||
|
{
|
||||||
|
m_Cells = cell->GetNext();
|
||||||
|
if ( m_LastCell == cell )
|
||||||
|
m_LastCell = NULL;
|
||||||
|
}
|
||||||
|
else // Not the first child.
|
||||||
|
{
|
||||||
|
for ( wxHtmlCell* prev = firstChild;; )
|
||||||
|
{
|
||||||
|
wxHtmlCell* const next = prev->GetNext();
|
||||||
|
|
||||||
|
// We can't reach the end of the children list without finding this
|
||||||
|
// cell, normally.
|
||||||
|
wxCHECK_RET( next, "Detaching cell which is not our child" );
|
||||||
|
|
||||||
|
if ( cell == next )
|
||||||
|
{
|
||||||
|
prev->SetNext(cell->GetNext());
|
||||||
|
if ( m_LastCell == cell )
|
||||||
|
m_LastCell = prev;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cell->SetParent(NULL);
|
||||||
|
cell->SetNext(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void wxHtmlContainerCell::SetAlign(const wxHtmlTag& tag)
|
void wxHtmlContainerCell::SetAlign(const wxHtmlTag& tag)
|
||||||
{
|
{
|
||||||
wxString alg;
|
wxString alg;
|
||||||
|
@@ -70,9 +70,8 @@ wxHtmlDCRenderer::wxHtmlDCRenderer() : wxObject()
|
|||||||
m_DC = NULL;
|
m_DC = NULL;
|
||||||
m_Width = m_Height = 0;
|
m_Width = m_Height = 0;
|
||||||
m_Cells = NULL;
|
m_Cells = NULL;
|
||||||
m_Parser = new wxHtmlWinParser();
|
m_ownsCells = false;
|
||||||
m_FS = new wxFileSystem();
|
m_Parser.SetFS(&m_FS);
|
||||||
m_Parser->SetFS(m_FS);
|
|
||||||
SetStandardFonts(DEFAULT_PRINT_FONT_SIZE);
|
SetStandardFonts(DEFAULT_PRINT_FONT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,9 +79,8 @@ wxHtmlDCRenderer::wxHtmlDCRenderer() : wxObject()
|
|||||||
|
|
||||||
wxHtmlDCRenderer::~wxHtmlDCRenderer()
|
wxHtmlDCRenderer::~wxHtmlDCRenderer()
|
||||||
{
|
{
|
||||||
if (m_Cells) delete m_Cells;
|
if ( m_ownsCells )
|
||||||
if (m_Parser) delete m_Parser;
|
delete m_Cells;
|
||||||
if (m_FS) delete m_FS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -90,7 +88,7 @@ wxHtmlDCRenderer::~wxHtmlDCRenderer()
|
|||||||
void wxHtmlDCRenderer::SetDC(wxDC *dc, double pixel_scale, double font_scale)
|
void wxHtmlDCRenderer::SetDC(wxDC *dc, double pixel_scale, double font_scale)
|
||||||
{
|
{
|
||||||
m_DC = dc;
|
m_DC = dc;
|
||||||
m_Parser->SetDC(m_DC, pixel_scale, font_scale);
|
m_Parser.SetDC(m_DC, pixel_scale, font_scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -110,19 +108,38 @@ void wxHtmlDCRenderer::SetHtmlText(const wxString& html, const wxString& basepat
|
|||||||
wxCHECK_RET( m_DC, "SetDC() must be called before SetHtmlText()" );
|
wxCHECK_RET( m_DC, "SetDC() must be called before SetHtmlText()" );
|
||||||
wxCHECK_RET( m_Width, "SetSize() must be called before SetHtmlText()" );
|
wxCHECK_RET( m_Width, "SetSize() must be called before SetHtmlText()" );
|
||||||
|
|
||||||
wxDELETE(m_Cells);
|
m_FS.ChangePathTo(basepath, isdir);
|
||||||
|
|
||||||
m_FS->ChangePathTo(basepath, isdir);
|
wxHtmlContainerCell* const cell = (wxHtmlContainerCell*) m_Parser.Parse(html);
|
||||||
m_Cells = (wxHtmlContainerCell*) m_Parser->Parse(html);
|
wxCHECK_RET( cell, "Failed to parse HTML" );
|
||||||
|
|
||||||
|
DoSetHtmlCell(cell);
|
||||||
|
|
||||||
|
m_ownsCells = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxHtmlDCRenderer::DoSetHtmlCell(wxHtmlContainerCell* cell)
|
||||||
|
{
|
||||||
|
if ( m_ownsCells )
|
||||||
|
delete m_Cells;
|
||||||
|
|
||||||
|
m_Cells = cell;
|
||||||
m_Cells->SetIndent(0, wxHTML_INDENT_ALL, wxHTML_UNITS_PIXELS);
|
m_Cells->SetIndent(0, wxHTML_INDENT_ALL, wxHTML_UNITS_PIXELS);
|
||||||
m_Cells->Layout(m_Width);
|
m_Cells->Layout(m_Width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxHtmlDCRenderer::SetHtmlCell(wxHtmlContainerCell& cell)
|
||||||
|
{
|
||||||
|
DoSetHtmlCell(&cell);
|
||||||
|
|
||||||
|
m_ownsCells = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void wxHtmlDCRenderer::SetFonts(const wxString& normal_face, const wxString& fixed_face,
|
void wxHtmlDCRenderer::SetFonts(const wxString& normal_face, const wxString& fixed_face,
|
||||||
const int *sizes)
|
const int *sizes)
|
||||||
{
|
{
|
||||||
m_Parser->SetFonts(normal_face, fixed_face, sizes);
|
m_Parser.SetFonts(normal_face, fixed_face, sizes);
|
||||||
|
|
||||||
if ( m_Cells )
|
if ( m_Cells )
|
||||||
m_Cells->Layout(m_Width);
|
m_Cells->Layout(m_Width);
|
||||||
@@ -133,7 +150,7 @@ void wxHtmlDCRenderer::SetStandardFonts(int size,
|
|||||||
const wxString& normal_face,
|
const wxString& normal_face,
|
||||||
const wxString& fixed_face)
|
const wxString& fixed_face)
|
||||||
{
|
{
|
||||||
m_Parser->SetStandardFonts(size, normal_face, fixed_face);
|
m_Parser.SetStandardFonts(size, normal_face, fixed_face);
|
||||||
|
|
||||||
if ( m_Cells )
|
if ( m_Cells )
|
||||||
m_Cells->Layout(m_Width);
|
m_Cells->Layout(m_Width);
|
||||||
|
@@ -24,37 +24,8 @@
|
|||||||
|
|
||||||
#include "wx/html/winpars.h"
|
#include "wx/html/winpars.h"
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// test class
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class HtmlParserTestCase : public CppUnit::TestCase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
HtmlParserTestCase() { }
|
|
||||||
|
|
||||||
private:
|
|
||||||
CPPUNIT_TEST_SUITE( HtmlParserTestCase );
|
|
||||||
CPPUNIT_TEST( Invalid );
|
|
||||||
CPPUNIT_TEST_SUITE_END();
|
|
||||||
|
|
||||||
void Invalid();
|
|
||||||
|
|
||||||
wxDECLARE_NO_COPY_CLASS(HtmlParserTestCase);
|
|
||||||
};
|
|
||||||
|
|
||||||
// register in the unnamed registry so that these tests are run by default
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION( HtmlParserTestCase );
|
|
||||||
|
|
||||||
// also include in its own registry so that these tests can be run alone
|
|
||||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( HtmlParserTestCase, "HtmlParserTestCase" );
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// tests themselves
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Test that parsing invalid HTML simply fails but doesn't crash for example.
|
// Test that parsing invalid HTML simply fails but doesn't crash for example.
|
||||||
void HtmlParserTestCase::Invalid()
|
TEST_CASE("wxHtmlParser::ParseInvalid", "[html][parser][error]")
|
||||||
{
|
{
|
||||||
class NullParser : public wxHtmlWinParser
|
class NullParser : public wxHtmlWinParser
|
||||||
{
|
{
|
||||||
@@ -75,4 +46,64 @@ void HtmlParserTestCase::Invalid()
|
|||||||
p.Parse("<!---");
|
p.Parse("<!---");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("wxHtmlCell::Detach", "[html][cell]")
|
||||||
|
{
|
||||||
|
wxMemoryDC dc;
|
||||||
|
|
||||||
|
wxHtmlContainerCell* const top = new wxHtmlContainerCell(NULL);
|
||||||
|
wxHtmlContainerCell* const cont = new wxHtmlContainerCell(NULL);
|
||||||
|
wxHtmlCell* const cell1 = new wxHtmlWordCell("Hello", dc);
|
||||||
|
wxHtmlCell* const cell2 = new wxHtmlColourCell(*wxRED);
|
||||||
|
wxHtmlCell* const cell3 = new wxHtmlWordCell("world", dc);
|
||||||
|
|
||||||
|
cont->InsertCell(cell1);
|
||||||
|
cont->InsertCell(cell2);
|
||||||
|
cont->InsertCell(cell3);
|
||||||
|
top->InsertCell(cont);
|
||||||
|
|
||||||
|
SECTION("container")
|
||||||
|
{
|
||||||
|
top->Detach(cont);
|
||||||
|
CHECK( top->GetFirstChild() == NULL );
|
||||||
|
|
||||||
|
delete cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("first-child")
|
||||||
|
{
|
||||||
|
cont->Detach(cell1);
|
||||||
|
CHECK( cont->GetFirstChild() == cell2 );
|
||||||
|
|
||||||
|
delete cell1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("middle-child")
|
||||||
|
{
|
||||||
|
cont->Detach(cell2);
|
||||||
|
CHECK( cont->GetFirstChild() == cell1 );
|
||||||
|
CHECK( cell1->GetNext() == cell3 );
|
||||||
|
|
||||||
|
delete cell2;
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("last-child")
|
||||||
|
{
|
||||||
|
cont->Detach(cell3);
|
||||||
|
CHECK( cont->GetFirstChild() == cell1 );
|
||||||
|
CHECK( cell1->GetNext() == cell2 );
|
||||||
|
CHECK( cell2->GetNext() == NULL );
|
||||||
|
|
||||||
|
delete cell3;
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("invalid")
|
||||||
|
{
|
||||||
|
WX_ASSERT_FAILS_WITH_ASSERT_MESSAGE
|
||||||
|
(
|
||||||
|
"Expected assertion for detaching non-child",
|
||||||
|
top->Detach(cell1);
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif //wxUSE_HTML
|
#endif //wxUSE_HTML
|
||||||
|
Reference in New Issue
Block a user