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
|
||||
{
|
||||
public:
|
||||
wxHtmlContainerCell(wxHtmlContainerCell *parent);
|
||||
explicit wxHtmlContainerCell(wxHtmlContainerCell *parent);
|
||||
virtual ~wxHtmlContainerCell();
|
||||
|
||||
virtual void Layout(int w) wxOVERRIDE;
|
||||
@@ -459,6 +459,11 @@ public:
|
||||
// insert cell at the end of m_Cells list
|
||||
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
|
||||
void SetAlignHor(int al) {m_AlignHor = al; m_LastLayout = -1;}
|
||||
int GetAlignHor() const {return m_AlignHor;}
|
||||
|
@@ -54,6 +54,11 @@ public:
|
||||
// (see wxFileSystem for detailed explanation)
|
||||
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).
|
||||
void SetFonts(const wxString& normal_face, const wxString& fixed_face, const int *sizes = NULL);
|
||||
|
||||
@@ -79,11 +84,14 @@ public:
|
||||
int GetTotalHeight() const;
|
||||
|
||||
private:
|
||||
void DoSetHtmlCell(wxHtmlContainerCell* cell);
|
||||
|
||||
wxDC *m_DC;
|
||||
wxHtmlWinParser *m_Parser;
|
||||
wxFileSystem *m_FS;
|
||||
wxFileSystem m_FS;
|
||||
wxHtmlWinParser m_Parser;
|
||||
wxHtmlContainerCell *m_Cells;
|
||||
int m_Width, m_Height;
|
||||
bool m_ownsCells;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxHtmlDCRenderer);
|
||||
};
|
||||
|
@@ -471,7 +471,21 @@ public:
|
||||
/**
|
||||
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.
|
||||
@@ -506,6 +520,9 @@ public:
|
||||
|
||||
/**
|
||||
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);
|
||||
|
||||
|
@@ -168,6 +168,19 @@ public:
|
||||
const wxString& basepath = wxEmptyString,
|
||||
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
|
||||
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)
|
||||
{
|
||||
wxString alg;
|
||||
|
@@ -70,9 +70,8 @@ wxHtmlDCRenderer::wxHtmlDCRenderer() : wxObject()
|
||||
m_DC = NULL;
|
||||
m_Width = m_Height = 0;
|
||||
m_Cells = NULL;
|
||||
m_Parser = new wxHtmlWinParser();
|
||||
m_FS = new wxFileSystem();
|
||||
m_Parser->SetFS(m_FS);
|
||||
m_ownsCells = false;
|
||||
m_Parser.SetFS(&m_FS);
|
||||
SetStandardFonts(DEFAULT_PRINT_FONT_SIZE);
|
||||
}
|
||||
|
||||
@@ -80,9 +79,8 @@ wxHtmlDCRenderer::wxHtmlDCRenderer() : wxObject()
|
||||
|
||||
wxHtmlDCRenderer::~wxHtmlDCRenderer()
|
||||
{
|
||||
if (m_Cells) delete m_Cells;
|
||||
if (m_Parser) delete m_Parser;
|
||||
if (m_FS) delete m_FS;
|
||||
if ( m_ownsCells )
|
||||
delete m_Cells;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +88,7 @@ wxHtmlDCRenderer::~wxHtmlDCRenderer()
|
||||
void wxHtmlDCRenderer::SetDC(wxDC *dc, double pixel_scale, double font_scale)
|
||||
{
|
||||
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_Width, "SetSize() must be called before SetHtmlText()" );
|
||||
|
||||
wxDELETE(m_Cells);
|
||||
m_FS.ChangePathTo(basepath, isdir);
|
||||
|
||||
m_FS->ChangePathTo(basepath, isdir);
|
||||
m_Cells = (wxHtmlContainerCell*) m_Parser->Parse(html);
|
||||
wxHtmlContainerCell* const cell = (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->Layout(m_Width);
|
||||
}
|
||||
|
||||
void wxHtmlDCRenderer::SetHtmlCell(wxHtmlContainerCell& cell)
|
||||
{
|
||||
DoSetHtmlCell(&cell);
|
||||
|
||||
m_ownsCells = false;
|
||||
}
|
||||
|
||||
|
||||
void wxHtmlDCRenderer::SetFonts(const wxString& normal_face, const wxString& fixed_face,
|
||||
const int *sizes)
|
||||
{
|
||||
m_Parser->SetFonts(normal_face, fixed_face, sizes);
|
||||
m_Parser.SetFonts(normal_face, fixed_face, sizes);
|
||||
|
||||
if ( m_Cells )
|
||||
m_Cells->Layout(m_Width);
|
||||
@@ -133,7 +150,7 @@ void wxHtmlDCRenderer::SetStandardFonts(int size,
|
||||
const wxString& normal_face,
|
||||
const wxString& fixed_face)
|
||||
{
|
||||
m_Parser->SetStandardFonts(size, normal_face, fixed_face);
|
||||
m_Parser.SetStandardFonts(size, normal_face, fixed_face);
|
||||
|
||||
if ( m_Cells )
|
||||
m_Cells->Layout(m_Width);
|
||||
|
@@ -24,37 +24,8 @@
|
||||
|
||||
#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.
|
||||
void HtmlParserTestCase::Invalid()
|
||||
TEST_CASE("wxHtmlParser::ParseInvalid", "[html][parser][error]")
|
||||
{
|
||||
class NullParser : public wxHtmlWinParser
|
||||
{
|
||||
@@ -75,4 +46,64 @@ void HtmlParserTestCase::Invalid()
|
||||
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
|
||||
|
Reference in New Issue
Block a user