diff --git a/include/wx/richtext/richtextbuffer.h b/include/wx/richtext/richtextbuffer.h index 14fa4d437e..8768321344 100644 --- a/include/wx/richtext/richtextbuffer.h +++ b/include/wx/richtext/richtextbuffer.h @@ -1195,12 +1195,12 @@ public: bool HasClearMode() const { return HasFlag(wxTEXT_BOX_ATTR_CLEAR); } /** - Returns the collapse mode - whether to collapse borders. Currently unimplemented. + Returns the collapse mode - whether to collapse borders. */ wxTextBoxAttrCollapseMode GetCollapseBorders() const { return m_collapseMode; } /** - Sets the collapse mode - whether to collapse borders. Currently unimplemented. + Sets the collapse mode - whether to collapse borders. */ void SetCollapseBorders(wxTextBoxAttrCollapseMode collapse) { m_collapseMode = collapse; m_flags |= wxTEXT_BOX_ATTR_COLLAPSE_BORDERS; } @@ -2583,6 +2583,11 @@ public: const wxRichTextAttr& parentAttr, const wxRichTextAttr& attr, const wxRect& availableParentSpace, const wxRect& availableContainerSpace, int style); + /** + Adjusts the attributes for virtual attribute provision, collapsed borders, etc. + */ + virtual bool AdjustAttributes(wxRichTextAttr& attr, wxRichTextDrawingContext& context); + /** Sets the object's attributes. */ @@ -5578,6 +5583,8 @@ public: virtual int HitTest(wxDC& dc, wxRichTextDrawingContext& context, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags = 0); + virtual bool AdjustAttributes(wxRichTextAttr& attr, wxRichTextDrawingContext& context); + virtual wxString GetXMLNodeName() const { return wxT("cell"); } virtual bool CanEditProperties() const { return true; } @@ -5639,6 +5646,8 @@ public: virtual int HitTest(wxDC& dc, wxRichTextDrawingContext& context, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags = 0); + virtual bool AdjustAttributes(wxRichTextAttr& attr, wxRichTextDrawingContext& context); + virtual wxString GetXMLNodeName() const { return wxT("table"); } virtual bool Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style); diff --git a/interface/wx/richtext/richtextbuffer.h b/interface/wx/richtext/richtextbuffer.h index 7857043e98..a1218b5985 100644 --- a/interface/wx/richtext/richtextbuffer.h +++ b/interface/wx/richtext/richtextbuffer.h @@ -1074,12 +1074,12 @@ public: bool HasClearMode() const { return HasFlag(wxTEXT_BOX_ATTR_CLEAR); } /** - Returns the collapse mode - whether to collapse borders. Currently unimplemented. + Returns the collapse mode - whether to collapse borders. */ wxTextBoxAttrCollapseMode GetCollapseBorders() const { return m_collapseMode; } /** - Sets the collapse mode - whether to collapse borders. Currently unimplemented. + Sets the collapse mode - whether to collapse borders. */ void SetCollapseBorders(wxTextBoxAttrCollapseMode collapse) { m_collapseMode = collapse; m_flags |= wxTEXT_BOX_ATTR_COLLAPSE_BORDERS; } @@ -2456,6 +2456,11 @@ public: const wxRichTextAttr& parentAttr, const wxRichTextAttr& attr, const wxRect& availableParentSpace, const wxRect& availableContainerSpace, int style); + /** + Adjusts the attributes for virtual attribute provision, collapsed borders, etc. + */ + virtual bool AdjustAttributes(wxRichTextAttr& attr, wxRichTextDrawingContext& context); + /** Sets the object's attributes. */ diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index c3d22f6306..24599790f7 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -588,7 +588,7 @@ wxRect wxRichTextObject::GetAvailableContentArea(wxDC& dc, wxRichTextDrawingCont wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; marginRect = outerRect; wxRichTextAttr attr(GetAttributes()); - context.ApplyVirtualAttributes(attr, (wxRichTextObject*) this); + ((wxRichTextObject*)this)->AdjustAttributes(attr, context); GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect); return contentRect; } @@ -1115,13 +1115,20 @@ bool wxRichTextObject::LayoutToBestSize(wxDC& dc, wxRichTextDrawingContext& cont return true; } +// Adjusts the attributes for virtual attribute provision, collapsed borders, etc. +bool wxRichTextObject::AdjustAttributes(wxRichTextAttr& attr, wxRichTextDrawingContext& context) +{ + context.ApplyVirtualAttributes(attr, this); + + return true; +} + // Move the object recursively, by adding the offset from old to new void wxRichTextObject::Move(const wxPoint& pt) { SetPosition(pt); } - /*! * wxRichTextCompositeObject * This is the base for drawable objects. @@ -1849,7 +1856,7 @@ bool wxRichTextParagraphLayoutBox::Draw(wxDC& dc, wxRichTextDrawingContext& cont wxRect thisRect(GetPosition(), GetCachedSize()); wxRichTextAttr attr(GetAttributes()); - context.ApplyVirtualAttributes(attr, this); + AdjustAttributes(attr, context); int flags = style; if (selection.IsValid() && GetParentContainer() != this && selection.GetContainer() == this && selection.WithinSelection(GetRange().GetStart(), GetParentContainer())) @@ -1908,7 +1915,7 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, wxRichTextDrawingContext& co bool formatRect = (style & wxRICHTEXT_LAYOUT_SPECIFIED_RECT) == wxRICHTEXT_LAYOUT_SPECIFIED_RECT; wxRichTextAttr attr(GetAttributes()); - context.ApplyVirtualAttributes(attr, this); + AdjustAttributes(attr, context); // If only laying out a specific area, the passed rect has a different meaning: // the visible part of the buffer. This is used in wxRichTextCtrl::OnSize, @@ -4503,9 +4510,9 @@ bool wxRichTextParagraph::Draw(wxDC& dc, wxRichTextDrawingContext& context, cons // different for different objects. wxRect paraRect = GetRect(); wxRichTextAttr attr = GetCombinedAttributes(); - context.ApplyVirtualAttributes(attr, this); + AdjustAttributes(attr, context); - DrawBoxAttributes(dc, GetBuffer(), attr, paraRect); + DrawBoxAttributes(dc, GetBuffer(), attr, paraRect, 0); // Draw the bullet, if any if ((attr.GetBulletStyle() == wxTEXT_ATTR_BULLET_STYLE_NONE) == 0 && (attr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_CONTINUATION) == 0) @@ -4684,7 +4691,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co } wxRichTextAttr attr = GetCombinedAttributes(); - context.ApplyVirtualAttributes(attr, this); + AdjustAttributes(attr, context); // ClearLines(); @@ -6281,7 +6288,7 @@ void wxRichTextParagraph::LayoutFloat(wxDC& dc, wxRichTextDrawingContext& contex { int x = 0; wxRichTextAttr parentAttr(GetAttributes()); - context.ApplyVirtualAttributes(parentAttr, this); + AdjustAttributes(parentAttr, context); #if 1 // 27-09-2012 wxRect availableSpace = GetParent()->GetAvailableContentArea(dc, context, rect); @@ -6431,7 +6438,7 @@ bool wxRichTextPlainText::Draw(wxDC& dc, wxRichTextDrawingContext& context, cons wxASSERT (para != NULL); wxRichTextAttr textAttr(para ? para->GetCombinedAttributes(GetAttributes(), false /* no box attributes */) : GetAttributes()); - context.ApplyVirtualAttributes(textAttr, this); + AdjustAttributes(textAttr, context); // Let's make the assumption for now that for content in a paragraph, including // text, we never have a discontinuous selection. So we only deal with a @@ -6794,7 +6801,7 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz int relativeX = position.x - GetParent()->GetPosition().x; wxRichTextAttr textAttr(para ? para->GetCombinedAttributes(GetAttributes()) : GetAttributes()); - context.ApplyVirtualAttributes(textAttr, (wxRichTextObject*) this); + ((wxRichTextObject*) this)->AdjustAttributes(textAttr, context); // Always assume unformatted text, since at this level we have no knowledge // of line breaks - and we don't need it, since we'll calculate size within @@ -9298,6 +9305,80 @@ int wxRichTextCell::HitTest(wxDC& dc, wxRichTextDrawingContext& context, const w } } +// Adjusts the attributes for virtual attribute provision, collapsed borders, etc. +bool wxRichTextCell::AdjustAttributes(wxRichTextAttr& attr, wxRichTextDrawingContext& context) +{ + wxRichTextObject::AdjustAttributes(attr, context); + + wxRichTextTable* table = wxDynamicCast(GetParent(), wxRichTextTable); + if (table && table->GetAttributes().GetTextBoxAttr().HasCollapseBorders() && + table->GetAttributes().GetTextBoxAttr().GetCollapseBorders() == wxTEXT_BOX_ATTR_COLLAPSE_FULL) + { + // Collapse borders: + // (1) Reset left and top for all cells; + // (2) for bottom and right, ignore if at edge of table, otherwise + // use this cell's border if present, otherwise adjacent border if not. + // Takes into account spanning by checking if adjacent cells are shown. + int row, col; + if (table->GetCellRowColumnPosition(GetRange().GetStart(), row, col)) + { + attr.GetTextBoxAttr().GetBorder().GetLeft().Reset(); + attr.GetTextBoxAttr().GetBorder().GetTop().Reset(); + + // Compute right border + wxRichTextCell* adjacentCellRight = NULL; + int i; + for (i = col+1; i < table->GetColumnCount(); i++) + { + wxRichTextCell* cell = table->GetCell(row, i); + if (cell->IsShown()) + { + adjacentCellRight = cell; + break; + } + } + // If no adjacent cell (either because they were hidden or at the edge of the table) + // then we must reset the border + if (!adjacentCellRight) + attr.GetTextBoxAttr().GetBorder().GetRight().Reset(); + else + { + if (!attr.GetTextBoxAttr().GetBorder().GetRight().IsValid() || + attr.GetTextBoxAttr().GetBorder().GetRight().GetWidth().GetValue() == 0) + { + attr.GetTextBoxAttr().GetBorder().GetRight() = adjacentCellRight->GetAttributes().GetTextBoxAttr().GetBorder().GetLeft(); + } + } + + // Compute bottom border + wxRichTextCell* adjacentCellBelow = NULL; + for (i = row+1; i < table->GetRowCount(); i++) + { + wxRichTextCell* cell = table->GetCell(i, col); + if (cell->IsShown()) + { + adjacentCellBelow = cell; + break; + } + } + // If no adjacent cell (either because they were hidden or at the edge of the table) + // then we must reset the border + if (!adjacentCellBelow) + attr.GetTextBoxAttr().GetBorder().GetBottom().Reset(); + else + { + if (!attr.GetTextBoxAttr().GetBorder().GetBottom().IsValid() || + attr.GetTextBoxAttr().GetBorder().GetBottom().GetWidth().GetValue() == 0) + { + attr.GetTextBoxAttr().GetBorder().GetBottom() = adjacentCellBelow->GetAttributes().GetTextBoxAttr().GetBorder().GetTop(); + } + } + } + } + + return true; +} + /// Copy void wxRichTextCell::Copy(const wxRichTextCell& obj) { @@ -9418,37 +9499,45 @@ bool wxRichTextTable::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wx { wxRichTextBox::Draw(dc, context, range, selection, rect, descent, style); - int colCount = GetColumnCount(); - int rowCount = GetRowCount(); - int col, row; - for (col = 0; col < colCount; col++) + // If the table is not collapsed (in which case the outer table box provides the border), + // draw the overall border again using cell borders in case it has been overwritten by + // adjacent cell borders of different colours. + if (!GetAttributes().GetTextBoxAttr().HasCollapseBorders() || + GetAttributes().GetTextBoxAttr().GetCollapseBorders() != wxTEXT_BOX_ATTR_COLLAPSE_FULL) { - for (row = 0; row < rowCount; row++) + int colCount = GetColumnCount(); + int rowCount = GetRowCount(); + int col, row; + for (col = 0; col < colCount; col++) { - if (row == 0 || row == (rowCount-1) || col == 0 || col == (colCount-1)) + for (row = 0; row < rowCount; row++) { - wxRichTextCell* cell = GetCell(row, col); - if (cell && cell->IsShown() && !cell->GetRange().IsOutside(range)) + if (row == 0 || row == (rowCount-1) || col == 0 || col == (colCount-1)) { - wxRect childRect(cell->GetPosition(), cell->GetCachedSize()); - wxRichTextAttr attr(cell->GetAttributes()); - if (row != 0) - attr.GetTextBoxAttr().GetBorder().GetTop().Reset(); - if (row != (rowCount-1)) - attr.GetTextBoxAttr().GetBorder().GetBottom().Reset(); - if (col != 0) - attr.GetTextBoxAttr().GetBorder().GetLeft().Reset(); - if (col != (colCount-1)) - attr.GetTextBoxAttr().GetBorder().GetRight().Reset(); - - if (attr.GetTextBoxAttr().GetBorder().IsValid()) + wxRichTextCell* cell = GetCell(row, col); + if (cell && cell->IsShown() && !cell->GetRange().IsOutside(range)) { - wxRect boxRect(cell->GetPosition(), cell->GetCachedSize()); - wxRect marginRect = boxRect; - wxRect contentRect, borderRect, paddingRect, outlineRect; + wxRect childRect(cell->GetPosition(), cell->GetCachedSize()); + wxRichTextAttr attr(cell->GetAttributes()); + cell->AdjustAttributes(attr, context); + if (row != 0) + attr.GetTextBoxAttr().GetBorder().GetTop().Reset(); + if (row != (rowCount-1)) + attr.GetTextBoxAttr().GetBorder().GetBottom().Reset(); + if (col != 0) + attr.GetTextBoxAttr().GetBorder().GetLeft().Reset(); + if (col != (colCount-1)) + attr.GetTextBoxAttr().GetBorder().GetRight().Reset(); - cell->GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect); - cell->DrawBorder(dc, GetBuffer(), attr.GetTextBoxAttr().GetBorder(), borderRect); + if (attr.GetTextBoxAttr().GetBorder().IsValid()) + { + wxRect boxRect(cell->GetPosition(), cell->GetCachedSize()); + wxRect marginRect = boxRect; + wxRect contentRect, borderRect, paddingRect, outlineRect; + + cell->GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect); + cell->DrawBorder(dc, GetBuffer(), attr.GetTextBoxAttr().GetBorder(), borderRect); + } } } } @@ -9629,7 +9718,7 @@ bool wxRichTextTable::Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxTextAttrDimensionConverter converter(dc, scale, availableSpace.GetSize()); wxRichTextAttr attr(GetAttributes()); - context.ApplyVirtualAttributes(attr, this); + AdjustAttributes(attr, context); bool tableHasPercentWidth = (attr.GetTextBoxAttr().GetWidth().GetUnits() == wxTEXT_ATTR_UNITS_PERCENTAGE); // If we have no fixed table size, and assuming we're not pushed for @@ -9809,7 +9898,9 @@ bool wxRichTextTable::Layout(wxDC& dc, wxRichTextDrawingContext& context, const if (cell->IsShown()) { int cellTotalLeftMargin = 0, cellTotalRightMargin = 0, cellTotalTopMargin = 0, cellTotalBottomMargin = 0; - GetTotalMargin(dc, buffer, cell->GetAttributes(), cellTotalLeftMargin, cellTotalRightMargin, cellTotalTopMargin, cellTotalBottomMargin); + wxRichTextAttr cellAttr(cell->GetAttributes()); + cell->AdjustAttributes(cellAttr, context); + GetTotalMargin(dc, buffer, cellAttr, cellTotalLeftMargin, cellTotalRightMargin, cellTotalTopMargin, cellTotalBottomMargin); overallRowContentMargin += (cellTotalLeftMargin + cellTotalRightMargin); visibleCellCount ++; @@ -9934,7 +10025,9 @@ bool wxRichTextTable::Layout(wxDC& dc, wxRichTextDrawingContext& context, const if (cell->IsShown()) { int cellTotalLeftMargin = 0, cellTotalRightMargin = 0, cellTotalTopMargin = 0, cellTotalBottomMargin = 0; - GetTotalMargin(dc, buffer, cell->GetAttributes(), cellTotalLeftMargin, cellTotalRightMargin, cellTotalTopMargin, cellTotalBottomMargin); + wxRichTextAttr cellAttr(cell->GetAttributes()); + cell->AdjustAttributes(cellAttr, context); + GetTotalMargin(dc, buffer, cellAttr, cellTotalLeftMargin, cellTotalRightMargin, cellTotalTopMargin, cellTotalBottomMargin); overallRowContentMargin += (cellTotalLeftMargin + cellTotalRightMargin); visibleCellCount ++; @@ -10232,6 +10325,22 @@ bool wxRichTextTable::Layout(wxDC& dc, wxRichTextDrawingContext& context, const return true; } +// Adjusts the attributes for virtual attribute provision, collapsed borders, etc. +bool wxRichTextTable::AdjustAttributes(wxRichTextAttr& attr, wxRichTextDrawingContext& context) +{ + wxRichTextObject::AdjustAttributes(attr, context); + + if (attr.GetTextBoxAttr().HasCollapseBorders() && + attr.GetTextBoxAttr().GetCollapseBorders() == wxTEXT_BOX_ATTR_COLLAPSE_FULL) + { + // Padding between the table border and the table cells no longer + // applies in collapsed mode. + attr.GetTextBoxAttr().GetPadding().Reset(); + } + + return true; +} + // Finds the absolute position and row height for the given character position bool wxRichTextTable::FindPosition(wxDC& dc, wxRichTextDrawingContext& context, long index, wxPoint& pt, int* height, bool forceLineStart) { @@ -11226,7 +11335,7 @@ bool wxRichTextAction::Do() else container->InvalidateHierarchy(GetRange()); - UpdateAppearance(GetPosition()); + UpdateAppearance(GetPosition(), true); wxRichTextEvent cmdEvent( wxEVT_RICHTEXT_STYLE_CHANGED, @@ -11829,7 +11938,7 @@ bool wxRichTextImage::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wx return false; wxRichTextAttr attr(GetAttributes()); - context.ApplyVirtualAttributes(attr, this); + AdjustAttributes(attr, context); DrawBoxAttributes(dc, GetBuffer(), attr, wxRect(rect.GetPosition(), GetCachedSize())); @@ -11863,7 +11972,7 @@ bool wxRichTextImage::Layout(wxDC& dc, wxRichTextDrawingContext& context, const contentRect = wxRect(wxPoint(0,0), imageSize); wxRichTextAttr attr(GetAttributes()); - context.ApplyVirtualAttributes(attr, this); + AdjustAttributes(attr, context); GetBoxRects(dc, GetBuffer(), attr, marginRect, borderRect, contentRect, paddingRect, outlineRect); @@ -11893,7 +12002,7 @@ bool wxRichTextImage::GetRangeSize(const wxRichTextRange& range, wxSize& size, i } wxRichTextAttr attr(GetAttributes()); - context.ApplyVirtualAttributes(attr, (wxRichTextObject*) this); + ((wxRichTextObject*)this)->AdjustAttributes(attr, context); wxSize imageSize(m_imageCache.GetWidth(), m_imageCache.GetHeight()); wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect;