// Switch off if the platform doesn't like it for some reason
#define wxRICHTEXT_USE_OPTIMIZED_DRAWING 1
+const wxChar wxRichTextLineBreakChar = (wxChar) 29;
+
/*!
* wxRichTextObject
* This is the base for drawable objects.
m_range = obj.m_range;
m_attributes = obj.m_attributes;
m_descent = obj.m_descent;
-/*
- if (!m_attributes.GetFont().Ok())
- wxLogDebug(wxT("No font!"));
- if (!obj.m_attributes.GetFont().Ok())
- wxLogDebug(wxT("Parent has no font!"));
-*/
}
void wxRichTextObject::SetMargins(int margin)
/// Convenience function to add a paragraph of text
wxRichTextRange wxRichTextParagraphLayoutBox::AddParagraph(const wxString& text, wxTextAttrEx* paraStyle)
{
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
// Don't use the base style, just the default style, and the base style will
// be combined at display time.
// Divide into paragraph and character styles.
-
+
wxTextAttrEx defaultCharStyle;
wxTextAttrEx defaultParaStyle;
- wxRichTextSplitParaCharStyles(GetDefaultStyle(), defaultParaStyle, defaultCharStyle);
-#else
- wxTextAttrEx style(GetAttributes());
-
- // Apply default style. If the style has no attributes set,
- // then the attributes will remain the 'basic style' (i.e. the
- // layout box's style).
- wxRichTextApplyStyle(style, GetDefaultStyle());
- wxTextAttrEx defaultCharStyle = style;
- wxTextAttrEx defaultParaStyle = style;
-#endif
+ wxRichTextSplitParaCharStyles(GetDefaultStyle(), defaultParaStyle, defaultCharStyle);
wxTextAttrEx* pStyle = paraStyle ? paraStyle : (wxTextAttrEx*) & defaultParaStyle;
wxTextAttrEx* cStyle = & defaultCharStyle;
/// Adds multiple paragraphs, based on newlines.
wxRichTextRange wxRichTextParagraphLayoutBox::AddParagraphs(const wxString& text, wxTextAttrEx* paraStyle)
{
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
// Don't use the base style, just the default style, and the base style will
// be combined at display time.
// Divide into paragraph and character styles.
-
+
wxTextAttrEx defaultCharStyle;
wxTextAttrEx defaultParaStyle;
wxRichTextSplitParaCharStyles(GetDefaultStyle(), defaultParaStyle, defaultCharStyle);
-#else
- wxTextAttrEx style(GetAttributes());
-
- // Apply default style. If the style has no attributes set,
- // then the attributes will remain the 'basic style' (i.e. the
- // layout box's style).
- wxRichTextApplyStyle(style, GetDefaultStyle());
-
- wxTextAttrEx defaultCharStyle = style;
- wxTextAttrEx defaultParaStyle = style;
-#endif
wxTextAttrEx* pStyle = paraStyle ? paraStyle : (wxTextAttrEx*) & defaultParaStyle;
wxTextAttrEx* cStyle = & defaultCharStyle;
/// Convenience function to add an image
wxRichTextRange wxRichTextParagraphLayoutBox::AddImage(const wxImage& image, wxTextAttrEx* paraStyle)
{
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
// Don't use the base style, just the default style, and the base style will
// be combined at display time.
// Divide into paragraph and character styles.
-
+
wxTextAttrEx defaultCharStyle;
wxTextAttrEx defaultParaStyle;
wxRichTextSplitParaCharStyles(GetDefaultStyle(), defaultParaStyle, defaultCharStyle);
-#else
- wxTextAttrEx style(GetAttributes());
-
- // Apply default style. If the style has no attributes set,
- // then the attributes will remain the 'basic style' (i.e. the
- // layout box's style).
- wxRichTextApplyStyle(style, GetDefaultStyle());
-
- wxTextAttrEx defaultCharStyle = style;
- wxTextAttrEx defaultParaStyle = style;
-#endif
wxTextAttrEx* pStyle = paraStyle ? paraStyle : (wxTextAttrEx*) & defaultParaStyle;
wxTextAttrEx* cStyle = & defaultCharStyle;
wxRichTextObject* child = node->GetData();
if (!child->GetRange().IsOutside(range))
{
-// if (lineCount > 0)
-// text += wxT("\n");
wxRichTextRange childRange = range;
childRange.LimitTo(child->GetRange());
text += childText;
- if (childRange.GetEnd() == child->GetRange().GetEnd())
+ if ((childRange.GetEnd() == child->GetRange().GetEnd()) && node->GetNext())
text += wxT("\n");
lineCount ++;
bool parasOnly = ((flags & wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY) != 0);
bool charactersOnly = ((flags & wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY) != 0);
bool resetExistingStyle = ((flags & wxRICHTEXT_SETSTYLE_RESET) != 0);
+ bool removeStyle = ((flags & wxRICHTEXT_SETSTYLE_REMOVE) != 0);
// Apply paragraph style first, if any
wxRichTextAttr wholeStyle(style);
- if (wholeStyle.HasParagraphStyleName() && GetStyleSheet())
+ if (!removeStyle && wholeStyle.HasParagraphStyleName() && GetStyleSheet())
{
wxRichTextParagraphStyleDefinition* def = GetStyleSheet()->FindParagraphStyle(wholeStyle.GetParagraphStyleName());
if (def)
- wxRichTextApplyStyle(wholeStyle, def->GetStyle());
+ wxRichTextApplyStyle(wholeStyle, def->GetStyleMergedWithBase(GetStyleSheet()));
}
// Limit the attributes to be set to the content to only character attributes.
wxRichTextAttr characterAttributes(wholeStyle);
characterAttributes.SetFlags(characterAttributes.GetFlags() & (wxTEXT_ATTR_CHARACTER));
- if (characterAttributes.HasCharacterStyleName() && GetStyleSheet())
+ if (!removeStyle && characterAttributes.HasCharacterStyleName() && GetStyleSheet())
{
wxRichTextCharacterStyleDefinition* def = GetStyleSheet()->FindCharacterStyle(characterAttributes.GetCharacterStyleName());
if (def)
- wxRichTextApplyStyle(characterAttributes, def->GetStyle());
+ wxRichTextApplyStyle(characterAttributes, def->GetStyleMergedWithBase(GetStyleSheet()));
}
// If we are associated with a control, make undoable; otherwise, apply immediately
// to be included in the paragraph style
if ((paragraphStyle || parasOnly) && !charactersOnly)
{
- if (resetExistingStyle)
+ if (removeStyle)
+ {
+ // Removes the given style from the paragraph
+ wxRichTextRemoveStyle(newPara->GetAttributes(), style);
+ }
+ else if (resetExistingStyle)
newPara->GetAttributes() = wholeStyle;
else
{
}
}
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
- // If applying paragraph styles dynamically, don't change the text objects' attributes
+ // When applying paragraph styles dynamically, don't change the text objects' attributes
// since they will computed as needed. Only apply the character styling if it's _only_
// character styling. This policy is subject to change and might be put under user control.
// if (!paragraphStyle && characterStyle && range.GetStart() != newPara->GetRange().GetEnd())
if (!parasOnly && characterStyle && range.GetStart() != newPara->GetRange().GetEnd())
-#else
- if (characterStyle && range.GetStart() != newPara->GetRange().GetEnd())
-#endif
{
wxRichTextRange childRange(range);
childRange.LimitTo(newPara->GetRange());
{
wxRichTextObject* child = node2->GetData();
- if (resetExistingStyle)
+ if (removeStyle)
+ {
+ // Removes the given style from the paragraph
+ wxRichTextRemoveStyle(child->GetAttributes(), style);
+ }
+ else if (resetExistingStyle)
child->GetAttributes() = characterAttributes;
else
{
obj = GetParagraphAtPosition(position);
if (obj)
{
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
if (combineStyles)
{
// Start with the base style
}
else
style = obj->GetAttributes();
-#else
- style = obj->GetAttributes();
-#endif
+
return true;
}
}
obj = GetLeafObjectAtPosition(position);
if (obj)
{
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
if (combineStyles)
{
wxRichTextParagraph* para = wxDynamicCast(obj->GetParent(), wxRichTextParagraph);
}
else
style = obj->GetAttributes();
-#else
- style = obj->GetAttributes();
-#endif
+
return true;
}
}
{
if (style.HasFont())
{
- if (style.HasSize() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_SIZE))
+ if (style.HasFontSize() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_SIZE))
{
- if (currentStyle.GetFont().Ok() && currentStyle.HasSize())
+ if (currentStyle.GetFont().Ok() && currentStyle.HasFontSize())
{
if (currentStyle.GetFont().GetPointSize() != style.GetFont().GetPointSize())
{
}
}
- if (style.HasItalic() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_ITALIC))
+ if (style.HasFontItalic() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_ITALIC))
{
- if (currentStyle.GetFont().Ok() && currentStyle.HasItalic())
+ if (currentStyle.GetFont().Ok() && currentStyle.HasFontItalic())
{
if (currentStyle.GetFont().GetStyle() != style.GetFont().GetStyle())
{
}
}
- if (style.HasWeight() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_WEIGHT))
+ if (style.HasFontWeight() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_WEIGHT))
{
- if (currentStyle.GetFont().Ok() && currentStyle.HasWeight())
+ if (currentStyle.GetFont().Ok() && currentStyle.HasFontWeight())
{
if (currentStyle.GetFont().GetWeight() != style.GetFont().GetWeight())
{
}
}
- if (style.HasFaceName() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_FACE))
+ if (style.HasFontFaceName() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_FACE))
{
- if (currentStyle.GetFont().Ok() && currentStyle.HasFaceName())
+ if (currentStyle.GetFont().Ok() && currentStyle.HasFontFaceName())
{
wxString faceName1(currentStyle.GetFont().GetFaceName());
wxString faceName2(style.GetFont().GetFaceName());
}
}
- if (style.HasUnderlined() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_UNDERLINE))
+ if (style.HasFontUnderlined() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_UNDERLINE))
{
- if (currentStyle.GetFont().Ok() && currentStyle.HasUnderlined())
+ if (currentStyle.GetFont().Ok() && currentStyle.HasFontUnderlined())
{
if (currentStyle.GetFont().GetUnderlined() != style.GetFont().GetUnderlined())
{
{
// We need to find the bits in the new style that are different:
// just look at those bits that are specified by the new style.
-
+
int currentRelevantTextEffects = currentStyle.GetTextEffects() & style.GetTextEffectFlags();
int newRelevantTextEffects = style.GetTextEffects() & style.GetTextEffectFlags();
{
// Find the text effects that were different, using XOR
int differentEffects = currentRelevantTextEffects ^ newRelevantTextEffects;
-
+
// Clash of style - mark as such
multipleTextEffectAttributes |= differentEffects;
currentStyle.SetTextEffectFlags(currentStyle.GetTextEffectFlags() & ~differentEffects);
// The attributes that aren't valid because of multiple styles within the range
long multipleStyleAttributes = 0;
int multipleTextEffectAttributes = 0;
-
+
wxRichTextObjectList::compatibility_iterator node = GetChildren().GetFirst();
while (node)
{
if (!child->GetRange().IsOutside(range) && child->IsKindOf(CLASSINFO(wxRichTextPlainText)))
{
foundCount ++;
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
wxTextAttrEx textAttr = para->GetCombinedAttributes(child->GetAttributes());
-#else
- const wxTextAttrEx& textAttr = child->GetAttributes();
-#endif
+
if (wxTextAttrEqPartial(textAttr, style, style.GetFlags()))
matchingCount ++;
}
if (!para->GetRange().IsOutside(range))
{
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
wxTextAttrEx textAttr = GetAttributes();
// Apply the paragraph style
wxRichTextApplyStyle(textAttr, para->GetAttributes());
-#else
- const wxTextAttrEx& textAttr = para->GetAttributes();
-#endif
foundCount ++;
if (wxTextAttrEqPartial(textAttr, style, style.GetFlags()))
matchingCount ++;
Clear();
AddParagraph(wxEmptyString);
-
+
Invalidate(wxRICHTEXT_ALL);
}
wxRichTextListStyleDefinition* listDef = styleSheet->FindListStyle(para->GetAttributes().GetListStyleName());
if (paraDef && !listDef)
{
- para->GetAttributes() = paraDef->GetStyle();
+ para->GetAttributes() = paraDef->GetStyleMergedWithBase(styleSheet);
foundCount ++;
}
else if (listDef && !paraDef)
{
// Set overall style defined for the list style definition
- para->GetAttributes() = listDef->GetStyle();
+ para->GetAttributes() = listDef->GetStyleMergedWithBase(styleSheet);
// Apply the style for this level
wxRichTextApplyStyle(para->GetAttributes(), * listDef->GetLevelAttributes(listDef->FindLevelForIndent(currentIndent)));
else if (listDef && paraDef)
{
// Combines overall list style, style for level, and paragraph style
- para->GetAttributes() = listDef->CombineWithParagraphStyle(currentIndent, paraDef->GetStyle());
+ para->GetAttributes() = listDef->CombineWithParagraphStyle(currentIndent, paraDef->GetStyleMergedWithBase(styleSheet));
foundCount ++;
}
}
wxRichTextListStyleDefinition* listDef = styleSheet->FindListStyle(para->GetAttributes().GetListStyleName());
// Overall list definition style
- para->GetAttributes() = listDef->GetStyle();
+ para->GetAttributes() = listDef->GetStyleMergedWithBase(styleSheet);
// Style for this level
wxRichTextApplyStyle(para->GetAttributes(), * listDef->GetLevelAttributes(listDef->FindLevelForIndent(currentIndent)));
wxRichTextParagraphStyleDefinition* def = styleSheet->FindParagraphStyle(para->GetAttributes().GetParagraphStyleName());
if (def)
{
- para->GetAttributes() = def->GetStyle();
+ para->GetAttributes() = def->GetStyleMergedWithBase(styleSheet);
foundCount ++;
}
}
/// Set list style
bool wxRichTextParagraphLayoutBox::SetListStyle(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel)
{
+ wxRichTextStyleSheet* styleSheet = GetStyleSheet();
+
bool withUndo = ((flags & wxRICHTEXT_SETSTYLE_WITH_UNDO) != 0);
// bool applyMinimal = ((flags & wxRICHTEXT_SETSTYLE_OPTIMIZE) != 0);
bool specifyLevel = ((flags & wxRICHTEXT_SETSTYLE_SPECIFY_LEVEL) != 0);
// Renumbering will need to be done when we promote/demote a paragraph.
// Apply the overall list style, and item style for this level
- wxTextAttrEx listStyle(def->GetCombinedStyleForLevel(thisLevel));
+ wxTextAttrEx listStyle(def->GetCombinedStyleForLevel(thisLevel, styleSheet));
wxRichTextApplyStyle(newPara->GetAttributes(), listStyle);
// Now we need to do numbering
// Eliminate the main list-related attributes
newPara->GetAttributes().SetFlags(newPara->GetAttributes().GetFlags() & ~wxTEXT_ATTR_LEFT_INDENT & ~wxTEXT_ATTR_BULLET_STYLE & ~wxTEXT_ATTR_BULLET_NUMBER & ~wxTEXT_ATTR_BULLET_TEXT & wxTEXT_ATTR_LIST_STYLE_NAME);
- wxRichTextStyleSheet* styleSheet = GetStyleSheet();
if (styleSheet && !newPara->GetAttributes().GetParagraphStyleName().IsEmpty())
{
wxRichTextParagraphStyleDefinition* def = styleSheet->FindParagraphStyle(newPara->GetAttributes().GetParagraphStyleName());
if (def)
{
- newPara->GetAttributes() = def->GetStyle();
+ newPara->GetAttributes() = def->GetStyleMergedWithBase(styleSheet);
}
}
}
bool wxRichTextParagraphLayoutBox::DoNumberList(const wxRichTextRange& range, const wxRichTextRange& promotionRange, int promoteBy,
wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel)
{
+ wxRichTextStyleSheet* styleSheet = GetStyleSheet();
+
bool withUndo = ((flags & wxRICHTEXT_SETSTYLE_WITH_UNDO) != 0);
// bool applyMinimal = ((flags & wxRICHTEXT_SETSTYLE_OPTIMIZE) != 0);
#ifdef __WXDEBUG__
wxRichTextListStyleDefinition* defToUse = def;
if (!defToUse)
{
- wxRichTextStyleSheet* sheet = GetStyleSheet();
-
- if (sheet && !newPara->GetAttributes().GetListStyleName().IsEmpty())
- defToUse = sheet->FindListStyle(newPara->GetAttributes().GetListStyleName());
+ if (styleSheet && !newPara->GetAttributes().GetListStyleName().IsEmpty())
+ defToUse = styleSheet->FindListStyle(newPara->GetAttributes().GetListStyleName());
}
if (defToUse)
}
// Apply the overall list style, and item style for this level
- wxTextAttrEx listStyle(defToUse->GetCombinedStyleForLevel(thisLevel));
+ wxTextAttrEx listStyle(defToUse->GetCombinedStyleForLevel(thisLevel, styleSheet));
wxRichTextApplyStyle(newPara->GetAttributes(), listStyle);
// OK, we've (re)applied the style, now let's get the numbering right.
{
if (!previousParagraph->GetAttributes().HasFlag(wxTEXT_ATTR_BULLET_STYLE) || previousParagraph->GetAttributes().GetBulletStyle() == wxTEXT_ATTR_BULLET_STYLE_NONE)
return false;
-
- wxRichTextStyleSheet* sheet = GetStyleSheet();
- if (sheet && !previousParagraph->GetAttributes().GetListStyleName().IsEmpty())
+
+ wxRichTextStyleSheet* styleSheet = GetStyleSheet();
+ if (styleSheet && !previousParagraph->GetAttributes().GetListStyleName().IsEmpty())
{
- wxRichTextListStyleDefinition* def = sheet->FindListStyle(previousParagraph->GetAttributes().GetListStyleName());
+ wxRichTextListStyleDefinition* def = styleSheet->FindListStyle(previousParagraph->GetAttributes().GetListStyleName());
if (def)
{
// int thisIndent = previousParagraph->GetAttributes().GetLeftIndent();
// int thisLevel = def->FindLevelForIndent(thisIndent);
-
+
bool isOutline = (previousParagraph->GetAttributes().GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_OUTLINE) != 0;
attr.SetFlags(previousParagraph->GetAttributes().GetFlags() & (wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER|wxTEXT_ATTR_BULLET_TEXT|wxTEXT_ATTR_BULLET_NAME));
attr.SetBulletName(previousParagraph->GetAttributes().GetBulletName());
attr.SetBulletStyle(previousParagraph->GetAttributes().GetBulletStyle());
attr.SetListStyleName(previousParagraph->GetAttributes().GetListStyleName());
-
+
int nextNumber = previousParagraph->GetAttributes().GetBulletNumber() + 1;
attr.SetBulletNumber(nextNumber);
-
+
if (isOutline)
{
wxString text = previousParagraph->GetAttributes().GetBulletText();
attr.SetBulletText(text);
}
}
-
+
return true;
}
else
/// Draw the item
bool wxRichTextParagraph::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& WXUNUSED(rect), int WXUNUSED(descent), int style)
{
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
wxTextAttrEx attr = GetCombinedAttributes();
-#else
- const wxTextAttrEx& attr = GetAttributes();
-#endif
// Draw the bullet, if any
if (attr.GetBulletStyle() != wxTEXT_ATTR_BULLET_STYLE_NONE)
wxTextAttrEx bulletAttr(GetCombinedAttributes());
+ // Combine with the font of the first piece of content, if one is specified
+ if (GetChildren().GetCount() > 0)
+ {
+ wxRichTextObject* firstObj = (wxRichTextObject*) GetChildren().GetFirst()->GetData();
+ if (firstObj->GetAttributes().HasFont())
+ {
+ wxRichTextApplyStyle(bulletAttr, firstObj->GetAttributes());
+ }
+ }
+
// Get line height from first line, if any
wxRichTextLine* line = m_cachedLines.GetFirst() ? (wxRichTextLine* ) m_cachedLines.GetFirst()->GetData() : (wxRichTextLine*) NULL;
if (wxRichTextBuffer::GetRenderer())
wxRichTextBuffer::GetRenderer()->DrawBitmapBullet(this, dc, bulletAttr, bulletRect);
}
- else if (attr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_STANDARD)
- {
+ else if (attr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_STANDARD)
+ {
if (wxRichTextBuffer::GetRenderer())
wxRichTextBuffer::GetRenderer()->DrawStandardBullet(this, dc, bulletAttr, bulletRect);
}
else
{
wxString bulletText = GetBulletText();
-
+
if (!bulletText.empty() && wxRichTextBuffer::GetRenderer())
wxRichTextBuffer::GetRenderer()->DrawTextBullet(this, dc, bulletAttr, bulletRect, bulletText);
}
while (node2)
{
wxRichTextObject* child = node2->GetData();
-
+
if (!child->GetRange().IsOutside(lineRange) && !lineRange.IsOutside(range))
{
// Draw this part of the line at the correct position
/// Lay the item out
bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style)
{
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
wxTextAttrEx attr = GetCombinedAttributes();
-#else
- const wxTextAttrEx& attr = GetAttributes();
-#endif
// ClearLines();
int lineSpacing = 0;
// Let's assume line spacing of 10 is normal, 15 is 1.5, 20 is 2, etc.
- if (attr.GetLineSpacing() > 10 && attr.GetFont().Ok())
+ if (attr.GetLineSpacing() != 10 && attr.GetFont().Ok())
{
dc.SetFont(attr.GetFont());
lineSpacing = (ConvertTenthsMMToPixels(dc, dc.GetCharHeight()) * attr.GetLineSpacing())/10;
// can't tell the position until the size is determined. So possibly introduce
// another layout phase.
+ // TODO: can't this be called only once per child?
child->Layout(dc, rect, style);
// Available width depends on whether we're on the first or subsequent lines
// and found a suitable point some way into the child. So get the size for the fragment
// if necessary.
+ long nextBreakPos = GetFirstLineBreakPosition(lastEndPos+1);
+ long lastPosToUse = child->GetRange().GetEnd();
+ bool lineBreakInThisObject = (nextBreakPos > -1 && nextBreakPos <= child->GetRange().GetEnd());
+
+ if (lineBreakInThisObject)
+ lastPosToUse = nextBreakPos;
+
wxSize childSize;
int childDescent = 0;
- if (lastEndPos == child->GetRange().GetStart() - 1)
+
+ if ((nextBreakPos == -1) && (lastEndPos == child->GetRange().GetStart() - 1)) // i.e. we want to get the whole thing
{
childSize = child->GetCachedSize();
childDescent = child->GetDescent();
}
else
- GetRangeSize(wxRichTextRange(lastEndPos+1, child->GetRange().GetEnd()), childSize, childDescent, dc, wxRICHTEXT_UNFORMATTED,rect.GetPosition());
+ GetRangeSize(wxRichTextRange(lastEndPos+1, lastPosToUse), childSize, childDescent, dc, wxRICHTEXT_UNFORMATTED, rect.GetPosition());
+
+ // Cases:
+ // 1) There was a line break BEFORE the natural break
+ // 2) There was a line break AFTER the natural break
+ // 3) The child still fits (carry on)
- if (childSize.x + currentWidth > availableSpaceForText)
+ if ((lineBreakInThisObject && (childSize.x + currentWidth <= availableSpaceForText)) ||
+ (childSize.x + currentWidth > availableSpaceForText))
{
long wrapPosition = 0;
rangeToUse.LimitTo(child->GetRange());
int childDescent = 0;
- if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, position))
+ if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, wxPoint(position.x + sz.x, position.y)))
{
sz.y = wxMax(sz.y, childSize.y);
sz.x += childSize.x;
wxSize childSize;
int childDescent = 0;
- if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, position))
+ if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, wxPoint(position.x + sz.x, position.y)))
{
lineSize.y = wxMax(lineSize.y, childSize.y);
lineSize.x += childSize.x;
if (pt.x < linePos.x)
{
textPosition = lineRange.GetStart();
- return wxRICHTEXT_HITTEST_BEFORE;
+ return wxRICHTEXT_HITTEST_BEFORE|wxRICHTEXT_HITTEST_OUTSIDE;
}
else if (pt.x >= (linePos.x + lineSize.x))
{
textPosition = lineRange.GetEnd();
- return wxRICHTEXT_HITTEST_AFTER;
+ return wxRICHTEXT_HITTEST_AFTER|wxRICHTEXT_HITTEST_OUTSIDE;
}
else
{
wxString plainText;
if (GetContiguousPlainText(plainText, wxRichTextRange(range.GetStart(), breakPosition), false))
{
- int spacePos = plainText.Find(wxT(' '), true);
- if (spacePos != wxNOT_FOUND)
+ int newLinePos = plainText.Find(wxRichTextLineBreakChar);
+ if (newLinePos != wxNOT_FOUND)
+ {
+ breakPosition = wxMax(0, range.GetStart() + newLinePos);
+ }
+ else
{
- int positionsFromEndOfString = plainText.length() - spacePos - 1;
- breakPosition = breakPosition - positionsFromEndOfString;
+ int spacePos = plainText.Find(wxT(' '), true);
+ int tabPos = plainText.Find(wxT('\t'), true);
+ int pos = wxMax(spacePos, tabPos);
+ if (pos != wxNOT_FOUND)
+ {
+ int positionsFromEndOfString = plainText.length() - pos - 1;
+ breakPosition = breakPosition - positionsFromEndOfString;
+ }
}
}
{
text = GetAttributes().GetBulletText();
}
-
+
if (GetAttributes().GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_OUTLINE)
{
// The outline style relies on the text being computed statically,
sm_defaultTabs.Clear();
}
+/// Get the first position from pos that has a line break character.
+long wxRichTextParagraph::GetFirstLineBreakPosition(long pos)
+{
+ wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
+ while (node)
+ {
+ wxRichTextObject* obj = node->GetData();
+ if (pos >= obj->GetRange().GetStart() && pos <= obj->GetRange().GetEnd())
+ {
+ wxRichTextPlainText* textObj = wxDynamicCast(obj, wxRichTextPlainText);
+ if (textObj)
+ {
+ long breakPos = textObj->GetFirstLineBreakPosition(pos);
+ if (breakPos > -1)
+ return breakPos;
+ }
+ }
+ node = node->GetNext();
+ }
+ return -1;
+}
/*!
* wxRichTextLine
#define USE_KERNING_FIX 1
+// If insufficient tabs are defined, this is the tab width used
+#define WIDTH_FOR_DEFAULT_TABS 50
+
/// Draw the item
bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int WXUNUSED(style))
{
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
wxRichTextParagraph* para = wxDynamicCast(GetParent(), wxRichTextParagraph);
wxASSERT (para != NULL);
wxTextAttrEx textAttr(para ? para->GetCombinedAttributes(GetAttributes()) : GetAttributes());
-#else
- wxTextAttrEx textAttr(GetAttributes());
-#endif
int offset = GetRange().GetStart();
+ // Replace line break characters with spaces
+ wxString str = m_text;
+ wxString toRemove = wxRichTextLineBreakChar;
+ str.Replace(toRemove, wxT(" "));
+
long len = range.GetLength();
- wxString stringChunk = m_text.Mid(range.GetStart() - offset, (size_t) len);
+ wxString stringChunk = str.Mid(range.GetStart() - offset, (size_t) len);
if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS))
stringChunk.MakeUpper();
int fragmentLen = s1 - r1 + 1;
if (fragmentLen < 0)
wxLogDebug(wxT("Mid(%d, %d"), (int)(r1 - offset), (int)fragmentLen);
- wxString stringFragment = m_text.Mid(r1 - offset, fragmentLen);
+ wxString stringFragment = str.Mid(r1 - offset, fragmentLen);
DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false);
if (stringChunk.Find(wxT("\t")) == wxNOT_FOUND)
{
// Compensate for kerning difference
- wxString stringFragment2(m_text.Mid(r1 - offset, fragmentLen+1));
- wxString stringFragment3(m_text.Mid(r1 - offset + fragmentLen, 1));
+ wxString stringFragment2(str.Mid(r1 - offset, fragmentLen+1));
+ wxString stringFragment3(str.Mid(r1 - offset + fragmentLen, 1));
wxCoord w1, h1, w2, h2, w3, h3;
dc.GetTextExtent(stringFragment, & w1, & h1);
int fragmentLen = s2 - s1 + 1;
if (fragmentLen < 0)
wxLogDebug(wxT("Mid(%d, %d"), (int)(s1 - offset), (int)fragmentLen);
- wxString stringFragment = m_text.Mid(s1 - offset, fragmentLen);
+ wxString stringFragment = str.Mid(s1 - offset, fragmentLen);
DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, true);
if (stringChunk.Find(wxT("\t")) == wxNOT_FOUND)
{
// Compensate for kerning difference
- wxString stringFragment2(m_text.Mid(s1 - offset, fragmentLen+1));
- wxString stringFragment3(m_text.Mid(s1 - offset + fragmentLen, 1));
+ wxString stringFragment2(str.Mid(s1 - offset, fragmentLen+1));
+ wxString stringFragment3(str.Mid(s1 - offset + fragmentLen, 1));
wxCoord w1, h1, w2, h2, w3, h3;
dc.GetTextExtent(stringFragment, & w1, & h1);
int fragmentLen = r2 - s2 + 1;
if (fragmentLen < 0)
wxLogDebug(wxT("Mid(%d, %d"), (int)(s2 - offset), (int)fragmentLen);
- wxString stringFragment = m_text.Mid(s2 - offset, fragmentLen);
+ wxString stringFragment = str.Mid(s2 - offset, fragmentLen);
DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false);
}
else
{
dc.SetTextForeground(attr.GetTextColour());
- dc.SetBackgroundMode(wxTRANSPARENT);
+
+ if (attr.HasFlag(wxTEXT_ATTR_BACKGROUND_COLOUR) && attr.GetBackgroundColour().IsOk())
+ {
+ dc.SetBackgroundMode(wxSOLID);
+ dc.SetTextBackground(attr.GetBackgroundColour());
+ }
+ else
+ dc.SetBackgroundMode(wxTRANSPARENT);
}
while (hasTabs)
for (int i = 0; i < tabCount && not_found; ++i)
{
nextTabPos = tabArray.Item(i);
- if (nextTabPos > tabPos)
+
+ // Find the next tab position.
+ // Even if we're at the end of the tab array, we must still draw the chunk.
+
+ if (nextTabPos > tabPos || (i == (tabCount - 1)))
{
+ if (nextTabPos <= tabPos)
+ {
+ int defaultTabWidth = ConvertTenthsMMToPixels(dc, WIDTH_FOR_DEFAULT_TABS);
+ nextTabPos = tabPos + defaultTabWidth;
+ }
+
not_found = false;
if (selected)
{
/// Lay the item out
bool wxRichTextPlainText::Layout(wxDC& dc, const wxRect& WXUNUSED(rect), int WXUNUSED(style))
{
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
- wxRichTextParagraph* para = wxDynamicCast(GetParent(), wxRichTextParagraph);
- wxASSERT (para != NULL);
-
- wxTextAttrEx textAttr(para ? para->GetCombinedAttributes(GetAttributes()) : GetAttributes());
-#else
- wxTextAttrEx textAttr(GetAttributes());
-#endif
-
- if (textAttr.GetFont().Ok())
- dc.SetFont(textAttr.GetFont());
-
- wxString str = m_text;
- if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS))
- str.MakeUpper();
-
- wxCoord w, h;
- dc.GetTextExtent(str, & w, & h, & m_descent);
- m_size = wxSize(w, dc.GetCharHeight());
+ GetRangeSize(GetRange(), m_size, m_descent, dc, 0, wxPoint(0, 0));
return true;
}
if (!range.IsWithin(GetRange()))
return false;
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
wxRichTextParagraph* para = wxDynamicCast(GetParent(), wxRichTextParagraph);
wxASSERT (para != NULL);
wxTextAttrEx textAttr(para ? para->GetCombinedAttributes(GetAttributes()) : GetAttributes());
-#else
- wxTextAttrEx textAttr(GetAttributes());
-#endif
// 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
int startPos = range.GetStart() - GetRange().GetStart();
long len = range.GetLength();
- wxString stringChunk = m_text.Mid(startPos, (size_t) len);
+
+ wxString str(m_text);
+ wxString toReplace = wxRichTextLineBreakChar;
+ str.Replace(toReplace, wxT(" "));
+
+ wxString stringChunk = str.Mid(startPos, (size_t) len);
if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS))
stringChunk.MakeUpper();
dc.GetTextExtent(stringFragment, & w, & h);
width += w;
int absoluteWidth = width + position.x;
+
bool notFound = true;
for (int i = 0; i < tabCount && notFound; ++i)
{
nextTabPos = tabArray.Item(i);
- if (nextTabPos > absoluteWidth)
+
+ // Find the next tab position.
+ // Even if we're at the end of the tab array, we must still process the chunk.
+
+ if (nextTabPos > absoluteWidth || (i == (tabCount - 1)))
{
+ if (nextTabPos <= absoluteWidth)
+ {
+ int defaultTabWidth = ((wxRichTextPlainText*) this)->ConvertTenthsMMToPixels(dc, WIDTH_FOR_DEFAULT_TABS);
+ nextTabPos = absoluteWidth + defaultTabWidth;
+ }
+
notFound = false;
width = nextTabPos - position.x;
}
/// the first part in 'this'.
wxRichTextObject* wxRichTextPlainText::DoSplit(long pos)
{
- int index = pos - GetRange().GetStart();
+ long index = pos - GetRange().GetStart();
+
if (index < 0 || index >= (int) m_text.length())
return NULL;
stream << m_text << wxT("\n");
}
+/// Get the first position from pos that has a line break character.
+long wxRichTextPlainText::GetFirstLineBreakPosition(long pos)
+{
+ int i;
+ int len = m_text.length();
+ int startPos = pos - m_range.GetStart();
+ for (i = startPos; i < len; i++)
+ {
+ wxChar ch = m_text[i];
+ if (ch == wxRichTextLineBreakChar)
+ {
+ return i + m_range.GetStart();
+ }
+ }
+ return -1;
+}
+
/*!
* wxRichTextBuffer
* This is a kind of box, used to represent the whole buffer
void wxRichTextBuffer::ResetAndClearCommands()
{
Reset();
-
+
GetCommandProcessor()->ClearCommands();
Modify(false);
{
wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Text"), wxRICHTEXT_INSERT, this, ctrl, false);
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
wxTextAttrEx attr(GetDefaultStyle());
-#else
- wxTextAttrEx attr(GetBasicStyle());
- wxRichTextApplyStyle(attr, GetDefaultStyle());
-#endif
wxTextAttrEx* p = NULL;
wxTextAttrEx paraAttr;
wxTextAttrEx paraAttr;
if (flags & wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE)
{
- paraAttr = GetStyleForNewParagraph(pos);
+ // Get appropriate paragraph style
+ paraAttr = GetStyleForNewParagraph(pos, false, false);
if (!paraAttr.IsDefault())
p = & paraAttr;
}
length --;
action->GetNewParagraphs().SetPartialParagraph(true);
}
+ else if (text.length() > 0 && text.Last() == wxT('\n'))
+ length --;
action->SetPosition(pos);
wxTextAttrEx paraAttr;
if (flags & wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE)
{
- paraAttr = GetStyleForNewParagraph(pos);
+ paraAttr = GetStyleForNewParagraph(pos, false, true /* look for next paragraph style */);
if (!paraAttr.IsDefault())
p = & paraAttr;
}
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
wxTextAttrEx attr(GetDefaultStyle());
-#else
- wxTextAttrEx attr(GetBasicStyle());
- wxRichTextApplyStyle(attr, GetDefaultStyle());
-#endif
wxRichTextParagraph* newPara = new wxRichTextParagraph(wxEmptyString, this, & attr);
action->GetNewParagraphs().AppendChild(newPara);
p = & paraAttr;
}
-#if wxRICHTEXT_USE_DYNAMIC_STYLES
wxTextAttrEx attr(GetDefaultStyle());
-#else
- wxTextAttrEx attr(GetBasicStyle());
- wxRichTextApplyStyle(attr, GetDefaultStyle());
-#endif
wxRichTextParagraph* newPara = new wxRichTextParagraph(this, & attr);
if (p)
/// Get the style that is appropriate for a new paragraph at this position.
/// If the previous paragraph has a paragraph style name, look up the next-paragraph
/// style.
-wxRichTextAttr wxRichTextBuffer::GetStyleForNewParagraph(long pos, bool caretPosition) const
+wxRichTextAttr wxRichTextBuffer::GetStyleForNewParagraph(long pos, bool caretPosition, bool lookUpNewParaStyle) const
{
wxRichTextParagraph* para = GetParagraphAtPosition(pos, caretPosition);
if (para)
{
wxRichTextAttr attr;
bool foundAttributes = false;
-
+
// Look for a matching paragraph style
- if (!para->GetAttributes().GetParagraphStyleName().IsEmpty() && GetStyleSheet())
+ if (lookUpNewParaStyle && !para->GetAttributes().GetParagraphStyleName().IsEmpty() && GetStyleSheet())
{
wxRichTextParagraphStyleDefinition* paraDef = GetStyleSheet()->FindParagraphStyle(para->GetAttributes().GetParagraphStyleName());
if (paraDef)
if (nextParaDef)
{
foundAttributes = true;
- attr = nextParaDef->GetStyle();
+ attr = nextParaDef->GetStyleMergedWithBase(GetStyleSheet());
}
}
-
+
// If we didn't find the 'next style', use this style instead.
if (!foundAttributes)
{
foundAttributes = true;
- attr = paraDef->GetStyle();
+ attr = paraDef->GetStyleMergedWithBase(GetStyleSheet());
}
}
}
(~ wxTEXT_ATTR_BACKGROUND_COLOUR) );
attr.SetFlags(flags);
}
-
+
// Now see if we need to number the paragraph.
if (attr.HasBulletStyle())
{
}
/// Submit command to delete this range
-bool wxRichTextBuffer::DeleteRangeWithUndo(const wxRichTextRange& range, long initialCaretPosition, long WXUNUSED(newCaretPositon), wxRichTextCtrl* ctrl)
+bool wxRichTextBuffer::DeleteRangeWithUndo(const wxRichTextRange& range, wxRichTextCtrl* ctrl)
{
wxRichTextAction* action = new wxRichTextAction(NULL, _("Delete"), wxRICHTEXT_DELETE, this, ctrl);
- action->SetPosition(initialCaretPosition);
+ action->SetPosition(ctrl->GetCaretPosition());
// Set the range to delete
action->SetRange(range);
wxRichTextCharacterStyleDefinition* def = GetStyleSheet()->FindCharacterStyle(characterStyle);
if (def)
{
- wxTextAttrEx attr = def->GetStyle();
+ wxTextAttrEx attr = def->GetStyleMergedWithBase(GetStyleSheet());
return BeginStyle(attr);
}
}
wxRichTextParagraphStyleDefinition* def = GetStyleSheet()->FindParagraphStyle(paragraphStyle);
if (def)
{
- wxTextAttrEx attr = def->GetStyle();
+ wxTextAttrEx attr = def->GetStyleMergedWithBase(GetStyleSheet());
return BeginStyle(attr);
}
}
wxRichTextCharacterStyleDefinition* def = GetStyleSheet()->FindCharacterStyle(characterStyle);
if (def)
{
- attr = def->GetStyle();
+ attr = def->GetStyleMergedWithBase(GetStyleSheet());
}
}
attr.SetURL(url);
m_eventHandlers.Erase(node);
if (deleteHandler)
delete handler;
-
+
return true;
}
else
bool wxRichTextBuffer::SetStyleSheetAndNotify(wxRichTextStyleSheet* sheet)
{
wxRichTextStyleSheet* oldSheet = GetStyleSheet();
-
+
wxWindowID id = wxID_ANY;
if (GetRichTextCtrl())
id = GetRichTextCtrl()->GetId();
-
+
wxRichTextEvent event(wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACING, id);
event.SetEventObject(GetRichTextCtrl());
event.SetOldStyleSheet(oldSheet);
event.SetNewStyleSheet(sheet);
event.Allow();
-
+
if (SendEvent(event) && !event.IsAllowed())
{
if (sheet != oldSheet)
dc.SetFont(font);
int charHeight = dc.GetCharHeight();
-
+
int bulletWidth = (int) (((float) charHeight) * wxRichTextBuffer::GetBulletProportion());
int bulletHeight = bulletWidth;
int x = rect.x;
-
+
// Calculate the top position of the character (as opposed to the whole line height)
int y = rect.y + (rect.height - charHeight);
-
+
// Calculate where the bullet should be positioned
y = y + (charHeight+1)/2 - (bulletHeight+1)/2;
-
+
// The margin between a bullet and text.
int margin = paragraph->ConvertTenthsMMToPixels(dc, wxRichTextBuffer::GetBulletRightMargin());
-
+
if (bulletAttr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT)
x = rect.x + rect.width - bulletWidth - margin;
else if (bulletAttr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_ALIGN_CENTRE)
x = x + (rect.width)/2 - bulletWidth/2;
-
+
if (bulletAttr.GetBulletName() == wxT("standard/square"))
{
dc.DrawRectangle(x, y, bulletWidth, bulletHeight);
pts[1].x = x + bulletWidth/2; pts[1].y = y;
pts[2].x = x + bulletWidth; pts[2].y = y + bulletHeight/2;
pts[3].x = x + bulletWidth/2; pts[3].y = y + bulletHeight;
-
+
dc.DrawPolygon(4, pts);
}
else if (bulletAttr.GetBulletName() == wxT("standard/triangle"))
pts[0].x = x; pts[0].y = y;
pts[1].x = x + bulletWidth; pts[1].y = y + bulletHeight/2;
pts[2].x = x; pts[2].y = y + bulletHeight;
-
+
dc.DrawPolygon(3, pts);
}
else // "standard/circle", and catch-all
{
dc.DrawEllipse(x, y, bulletWidth, bulletHeight);
- }
-
+ }
+
return true;
}
int x = rect.x;
// Calculate the top position of the character (as opposed to the whole line height)
- int y = rect.y + (rect.height - charHeight);
+ int y = rect.y + (rect.height - charHeight);
// The margin between a bullet and text.
int margin = paragraph->ConvertTenthsMMToPixels(dc, wxRichTextBuffer::GetBulletRightMargin());
-
+
if (attr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT)
x = (rect.x + rect.width) - tw - margin;
else if (attr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_ALIGN_CENTRE)
x = x + (rect.width)/2 - tw/2;
dc.DrawText(text, x, y);
-
+
return true;
}
else
wxRichTextBuffer::InitStandardHandlers();
wxRichTextParagraph::InitDefaultTabs();
return true;
- };
+ }
void OnExit()
{
wxRichTextBuffer::CleanUpHandlers();
wxRichTextParagraph::ClearDefaultTabs();
wxRichTextCtrl::ClearAvailableFontNames();
wxRichTextBuffer::SetRenderer(NULL);
- };
+ }
};
IMPLEMENT_DYNAMIC_CLASS(wxRichTextModule, wxModule)
wxSize clientSize = m_ctrl->GetClientSize();
wxPoint firstVisiblePt = m_ctrl->GetFirstVisiblePoint();
int lastY = firstVisiblePt.y + clientSize.y;
-
+
wxRichTextParagraph* para = m_buffer->GetParagraphAtPosition(GetPosition());
wxRichTextObjectList::compatibility_iterator node = m_buffer->GetChildren().Find(para);
while (node)
wxRichTextLine* line = node2->GetData();
wxPoint pt = line->GetAbsolutePosition();
wxRichTextRange range = line->GetAbsoluteRange();
-
+
if (pt.y > lastY)
{
node2 = wxRichTextLineList::compatibility_iterator();
node = wxRichTextObjectList::compatibility_iterator();
}
else if (range.GetStart() > GetPosition() && pt.y >= firstVisiblePt.y)
- {
+ {
optimizationLineCharPositions.Add(range.GetStart());
optimizationLineYPositions.Add(pt.y);
}
if (node2)
node2 = node2->GetNext();
}
-
+
if (node)
node = node->GetNext();
}
- }
+ }
#endif
m_buffer->InsertFragment(GetPosition(), m_newParagraphs);
// Don't take into account the last newline
if (m_newParagraphs.GetPartialParagraph())
newCaretPosition --;
+ else
+ if (m_newParagraphs.GetChildren().GetCount() > 1)
+ {
+ wxRichTextObject* p = (wxRichTextObject*) m_newParagraphs.GetChildren().GetLast()->GetData();
+ if (p->GetRange().GetLength() == 1)
+ newCaretPosition --;
+ }
newCaretPosition = wxMin(newCaretPosition, (m_buffer->GetRange().GetEnd()-1));
-
if (optimizationLineCharPositions.GetCount() > 0)
UpdateAppearance(newCaretPosition, true /* send update event */, & optimizationLineCharPositions, & optimizationLineYPositions);
else
UpdateAppearance(newCaretPosition, true /* send update event */);
+ wxRichTextEvent cmdEvent(
+ wxEVT_COMMAND_RICHTEXT_CONTENT_INSERTED,
+ m_ctrl ? m_ctrl->GetId() : -1);
+ cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer);
+ cmdEvent.SetRange(GetRange());
+ cmdEvent.SetPosition(GetRange().GetStart());
+
+ m_buffer->SendEvent(cmdEvent);
+
break;
}
case wxRICHTEXT_DELETE:
UpdateAppearance(GetRange().GetStart()-1, true /* send update event */);
+ wxRichTextEvent cmdEvent(
+ wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED,
+ m_ctrl ? m_ctrl->GetId() : -1);
+ cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer);
+ cmdEvent.SetRange(GetRange());
+ cmdEvent.SetPosition(GetRange().GetStart());
+
+ m_buffer->SendEvent(cmdEvent);
+
break;
}
case wxRICHTEXT_CHANGE_STYLE:
UpdateAppearance(GetPosition());
+ wxRichTextEvent cmdEvent(
+ wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED,
+ m_ctrl ? m_ctrl->GetId() : -1);
+ cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer);
+ cmdEvent.SetRange(GetRange());
+ cmdEvent.SetPosition(GetRange().GetStart());
+
+ m_buffer->SendEvent(cmdEvent);
+
break;
}
default:
m_buffer->Invalidate(wxRichTextRange(GetRange().GetStart(), GetRange().GetStart()));
long newCaretPosition = GetPosition() - 1;
- // if (m_newParagraphs.GetPartialParagraph())
- // newCaretPosition --;
-
+
UpdateAppearance(newCaretPosition, true /* send update event */);
+ wxRichTextEvent cmdEvent(
+ wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED,
+ m_ctrl ? m_ctrl->GetId() : -1);
+ cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer);
+ cmdEvent.SetRange(GetRange());
+ cmdEvent.SetPosition(GetRange().GetStart());
+
+ m_buffer->SendEvent(cmdEvent);
+
break;
}
case wxRICHTEXT_DELETE:
UpdateAppearance(GetPosition(), true /* send update event */);
+ wxRichTextEvent cmdEvent(
+ wxEVT_COMMAND_RICHTEXT_CONTENT_INSERTED,
+ m_ctrl ? m_ctrl->GetId() : -1);
+ cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer);
+ cmdEvent.SetRange(GetRange());
+ cmdEvent.SetPosition(GetRange().GetStart());
+
+ m_buffer->SendEvent(cmdEvent);
+
break;
}
case wxRICHTEXT_CHANGE_STYLE:
UpdateAppearance(GetPosition());
+ wxRichTextEvent cmdEvent(
+ wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED,
+ m_ctrl ? m_ctrl->GetId() : -1);
+ cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer);
+ cmdEvent.SetRange(GetRange());
+ cmdEvent.SetPosition(GetRange().GetStart());
+
+ m_buffer->SendEvent(cmdEvent);
+
break;
}
default:
{
m_ctrl->LayoutContent();
m_ctrl->PositionCaret();
-
+
#if wxRICHTEXT_USE_OPTIMIZED_DRAWING
// Find refresh rectangle if we are in a position to optimise refresh
if (m_cmdId == wxRICHTEXT_INSERT && optimizationLineCharPositions && optimizationLineCharPositions->GetCount() > 0)
{
size_t i;
-
+
wxSize clientSize = m_ctrl->GetClientSize();
wxPoint firstVisiblePt = m_ctrl->GetFirstVisiblePoint();
-
+
// Start/end positions
int firstY = 0;
int lastY = firstVisiblePt.y + clientSize.y;
-
+
bool foundStart = false;
bool foundEnd = false;
-
+
// position offset - how many characters were inserted
int positionOffset = GetRange().GetLength();
// find the first line which is being drawn at the same position as it was
// before. Since we're talking about a simple insertion, we can assume
// that the rest of the window does not need to be redrawn.
-
+
wxRichTextParagraph* para = m_buffer->GetParagraphAtPosition(GetPosition());
wxRichTextObjectList::compatibility_iterator node = m_buffer->GetChildren().Find(para);
while (node)
wxRichTextLine* line = node2->GetData();
wxPoint pt = line->GetAbsolutePosition();
wxRichTextRange range = line->GetAbsoluteRange();
-
+
// we want to find the first line that is in the same position
// as before. This will mean we're at the end of the changed text.
-
+
if (pt.y > lastY) // going past the end of the window, no more info
{
node2 = wxRichTextLineList::compatibility_iterator();
foundStart = true;
}
- // search for this line being at the same position as before
+ // search for this line being at the same position as before
for (i = 0; i < optimizationLineCharPositions->GetCount(); i++)
{
if (((*optimizationLineCharPositions)[i] + positionOffset == range.GetStart()) &&
node = wxRichTextObjectList::compatibility_iterator();
break;
- }
+ }
}
}
if (node2)
node2 = node2->GetNext();
}
-
+
if (node)
node = node->GetNext();
}
-
+
if (!foundStart)
firstY = firstVisiblePt.y;
if (!foundEnd)
wxRect rect(firstVisiblePt.x, firstY, firstVisiblePt.x + clientSize.x, lastY - firstY);
m_ctrl->RefreshRect(rect);
-
+
// TODO: we need to make sure that lines are only drawn if in the update region. The rect
// passed to Draw is currently used in different ways (to pass the position the content should
// be drawn at as well as the relevant region).
}
- else
+ else
#endif
m_ctrl->Refresh(false);
int srcBits = style.GetTextEffects();
int srcFlags = style.GetTextEffectFlags();
-
+
wxRichTextCombineBitlists(destBits, srcBits, destFlags, srcFlags);
-
+
destStyle.SetTextEffects(destBits);
destStyle.SetTextEffectFlags(destFlags);
}
bool wxRichTextApplyStyle(wxRichTextAttr& destStyle, const wxRichTextAttr& style, wxRichTextAttr* compareWith)
{
- wxTextAttrEx attr(destStyle);
- wxRichTextApplyStyle(attr, style, compareWith);
- destStyle = attr;
+ destStyle = destStyle.Combine(style, compareWith);
return true;
}
if (style.GetFlags() & wxTEXT_ATTR_FONT_FACE)
{
- if (compareWith && compareWith->HasFaceName() && compareWith->GetFontFaceName() == style.GetFontFaceName())
+ if (compareWith && compareWith->HasFontFaceName() && compareWith->GetFontFaceName() == style.GetFontFaceName())
{
// The same as currently displayed, so don't set
}
if (style.GetFlags() & wxTEXT_ATTR_FONT_SIZE)
{
- if (compareWith && compareWith->HasSize() && compareWith->GetFontSize() == style.GetFontSize())
+ if (compareWith && compareWith->HasFontSize() && compareWith->GetFontSize() == style.GetFontSize())
{
// The same as currently displayed, so don't set
}
if (style.GetFlags() & wxTEXT_ATTR_FONT_ITALIC)
{
- if (compareWith && compareWith->HasItalic() && compareWith->GetFontStyle() == style.GetFontStyle())
+ if (compareWith && compareWith->HasFontItalic() && compareWith->GetFontStyle() == style.GetFontStyle())
{
// The same as currently displayed, so don't set
}
if (style.GetFlags() & wxTEXT_ATTR_FONT_WEIGHT)
{
- if (compareWith && compareWith->HasWeight() && compareWith->GetFontWeight() == style.GetFontWeight())
+ if (compareWith && compareWith->HasFontWeight() && compareWith->GetFontWeight() == style.GetFontWeight())
{
// The same as currently displayed, so don't set
}
if (style.GetFlags() & wxTEXT_ATTR_FONT_UNDERLINE)
{
- if (compareWith && compareWith->HasUnderlined() && compareWith->GetFontUnderlined() == style.GetFontUnderlined())
+ if (compareWith && compareWith->HasFontUnderlined() && compareWith->GetFontUnderlined() == style.GetFontUnderlined())
{
// The same as currently displayed, so don't set
}
int srcBits = style.GetTextEffects();
int srcFlags = style.GetTextEffectFlags();
-
+
wxRichTextCombineBitlists(destBits, srcBits, destFlags, srcFlags);
-
+
destStyle.SetTextEffects(destBits);
destStyle.SetTextEffectFlags(destFlags);
}
return true;
}
+// Remove attributes
+bool wxRichTextRemoveStyle(wxTextAttrEx& destStyle, const wxRichTextAttr& style)
+{
+ int flags = style.GetFlags();
+ int destFlags = destStyle.GetFlags();
+
+ destStyle.SetFlags(destFlags & ~flags);
+
+ return true;
+}
+
/// Combine two bitlists, specifying the bits of interest with separate flags.
bool wxRichTextCombineBitlists(int& valueA, int valueB, int& flagsA, int flagsB)
{
// We want to apply B's bits to A, taking into account each's flags which indicate which bits
// are to be taken into account. A zero in B's bits should reset that bit in A but only if B's flags
// indicate it.
-
+
// First, reset the 0 bits from B. We make a mask so we're only dealing with B's zero
// bits at this point, ignoring any 1 bits in B or 0 bits in B that are not relevant.
int valueA2 = ~(~valueB & flagsB) & valueA;
-
+
// Now combine the 1 bits.
int valueA3 = (valueB & flagsB) | valueA2;
-
+
valueA = valueA3;
flagsA = (flagsA | flagsB);
-
+
return true;
}
wxRichTextApplyStyle(charStyle, defaultCharStyle1);
wxRichTextApplyStyle(parStyle, defaultParaStyle1);
-
+
return true;
}
// operators
void wxRichTextAttr::operator= (const wxRichTextAttr& attr)
-{
+{
Copy(attr);
}
GetFontWeight() == attr.GetFontWeight() &&
GetFontUnderlined() == attr.GetFontUnderlined() &&
GetFontFaceName() == attr.GetFontFaceName() &&
-
+
GetURL() == attr.GetURL();
}
return true;
}
-wxRichTextAttr wxRichTextAttr::Combine(const wxRichTextAttr& attr,
- const wxRichTextAttr& attrDef,
- const wxTextCtrlBase *text)
+wxRichTextAttr wxRichTextAttr::Combine(const wxRichTextAttr& style, const wxRichTextAttr* compareWith) const
{
- wxColour colFg = attr.GetTextColour();
- if ( !colFg.Ok() )
- {
- colFg = attrDef.GetTextColour();
+ wxRichTextAttr destStyle = (*this);
+ destStyle.Apply(style, compareWith);
- if ( text && !colFg.Ok() )
- colFg = text->GetForegroundColour();
- }
+ return destStyle;
+}
- wxColour colBg = attr.GetBackgroundColour();
- if ( !colBg.Ok() )
+bool wxRichTextAttr::Apply(const wxRichTextAttr& style, const wxRichTextAttr* compareWith)
+{
+ wxRichTextAttr& destStyle = (*this);
+
+ if (style.HasFontWeight())
{
- colBg = attrDef.GetBackgroundColour();
+ if (!(compareWith && compareWith->HasFontWeight() && compareWith->GetFontWeight() == style.GetFontWeight()))
+ destStyle.SetFontWeight(style.GetFontWeight());
+ }
- if ( text && !colBg.Ok() )
- colBg = text->GetBackgroundColour();
+ if (style.HasFontSize())
+ {
+ if (!(compareWith && compareWith->HasFontSize() && compareWith->GetFontSize() == style.GetFontSize()))
+ destStyle.SetFontSize(style.GetFontSize());
}
- wxRichTextAttr newAttr(colFg, colBg);
+ if (style.HasFontItalic())
+ {
+ if (!(compareWith && compareWith->HasFontItalic() && compareWith->GetFontStyle() == style.GetFontStyle()))
+ destStyle.SetFontStyle(style.GetFontStyle());
+ }
- if (attr.HasWeight())
- newAttr.SetFontWeight(attr.GetFontWeight());
+ if (style.HasFontUnderlined())
+ {
+ if (!(compareWith && compareWith->HasFontUnderlined() && compareWith->GetFontUnderlined() == style.GetFontUnderlined()))
+ destStyle.SetFontUnderlined(style.GetFontUnderlined());
+ }
- if (attr.HasSize())
- newAttr.SetFontSize(attr.GetFontSize());
+ if (style.HasFontFaceName())
+ {
+ if (!(compareWith && compareWith->HasFontFaceName() && compareWith->GetFontFaceName() == style.GetFontFaceName()))
+ destStyle.SetFontFaceName(style.GetFontFaceName());
+ }
- if (attr.HasItalic())
- newAttr.SetFontStyle(attr.GetFontStyle());
+ if (style.GetTextColour().Ok() && style.HasTextColour())
+ {
+ if (!(compareWith && compareWith->HasTextColour() && compareWith->GetTextColour() == style.GetTextColour()))
+ destStyle.SetTextColour(style.GetTextColour());
+ }
- if (attr.HasUnderlined())
- newAttr.SetFontUnderlined(attr.GetFontUnderlined());
+ if (style.GetBackgroundColour().Ok() && style.HasBackgroundColour())
+ {
+ if (!(compareWith && compareWith->HasBackgroundColour() && compareWith->GetBackgroundColour() == style.GetBackgroundColour()))
+ destStyle.SetBackgroundColour(style.GetBackgroundColour());
+ }
- if (attr.HasFaceName())
- newAttr.SetFontFaceName(attr.GetFontFaceName());
+ if (style.HasAlignment())
+ {
+ if (!(compareWith && compareWith->HasAlignment() && compareWith->GetAlignment() == style.GetAlignment()))
+ destStyle.SetAlignment(style.GetAlignment());
+ }
- if (attr.HasAlignment())
- newAttr.SetAlignment(attr.GetAlignment());
- else if (attrDef.HasAlignment())
- newAttr.SetAlignment(attrDef.GetAlignment());
+ if (style.HasTabs())
+ {
+ if (!(compareWith && compareWith->HasTabs() && wxRichTextTabsEq(compareWith->GetTabs(), style.GetTabs())))
+ destStyle.SetTabs(style.GetTabs());
+ }
- if (attr.HasTabs())
- newAttr.SetTabs(attr.GetTabs());
- else if (attrDef.HasTabs())
- newAttr.SetTabs(attrDef.GetTabs());
+ if (style.HasLeftIndent())
+ {
+ if (!(compareWith && compareWith->HasLeftIndent() && compareWith->GetLeftIndent() == style.GetLeftIndent()
+ && compareWith->GetLeftSubIndent() == style.GetLeftSubIndent()))
+ destStyle.SetLeftIndent(style.GetLeftIndent(), style.GetLeftSubIndent());
+ }
- if (attr.HasLeftIndent())
- newAttr.SetLeftIndent(attr.GetLeftIndent(), attr.GetLeftSubIndent());
- else if (attrDef.HasLeftIndent())
- newAttr.SetLeftIndent(attrDef.GetLeftIndent(), attr.GetLeftSubIndent());
+ if (style.HasRightIndent())
+ {
+ if (!(compareWith && compareWith->HasRightIndent() && compareWith->GetRightIndent() == style.GetRightIndent()))
+ destStyle.SetRightIndent(style.GetRightIndent());
+ }
- if (attr.HasRightIndent())
- newAttr.SetRightIndent(attr.GetRightIndent());
- else if (attrDef.HasRightIndent())
- newAttr.SetRightIndent(attrDef.GetRightIndent());
+ if (style.HasParagraphSpacingAfter())
+ {
+ if (!(compareWith && compareWith->HasParagraphSpacingAfter() && compareWith->GetParagraphSpacingAfter() == style.GetParagraphSpacingAfter()))
+ destStyle.SetParagraphSpacingAfter(style.GetParagraphSpacingAfter());
+ }
- // NEW ATTRIBUTES
+ if (style.HasParagraphSpacingBefore())
+ {
+ if (!(compareWith && compareWith->HasParagraphSpacingBefore() && compareWith->GetParagraphSpacingBefore() == style.GetParagraphSpacingBefore()))
+ destStyle.SetParagraphSpacingBefore(style.GetParagraphSpacingBefore());
+ }
- if (attr.HasParagraphSpacingAfter())
- newAttr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter());
+ if (style.HasLineSpacing())
+ {
+ if (!(compareWith && compareWith->HasLineSpacing() && compareWith->GetLineSpacing() == style.GetLineSpacing()))
+ destStyle.SetLineSpacing(style.GetLineSpacing());
+ }
- if (attr.HasParagraphSpacingBefore())
- newAttr.SetParagraphSpacingBefore(attr.GetParagraphSpacingBefore());
+ if (style.HasCharacterStyleName())
+ {
+ if (!(compareWith && compareWith->HasCharacterStyleName() && compareWith->GetCharacterStyleName() == style.GetCharacterStyleName()))
+ destStyle.SetCharacterStyleName(style.GetCharacterStyleName());
+ }
- if (attr.HasLineSpacing())
- newAttr.SetLineSpacing(attr.GetLineSpacing());
+ if (style.HasParagraphStyleName())
+ {
+ if (!(compareWith && compareWith->HasParagraphStyleName() && compareWith->GetParagraphStyleName() == style.GetParagraphStyleName()))
+ destStyle.SetParagraphStyleName(style.GetParagraphStyleName());
+ }
- if (attr.HasCharacterStyleName())
- newAttr.SetCharacterStyleName(attr.GetCharacterStyleName());
+ if (style.HasListStyleName())
+ {
+ if (!(compareWith && compareWith->HasListStyleName() && compareWith->GetListStyleName() == style.GetListStyleName()))
+ destStyle.SetListStyleName(style.GetListStyleName());
+ }
- if (attr.HasParagraphStyleName())
- newAttr.SetParagraphStyleName(attr.GetParagraphStyleName());
+ if (style.HasBulletStyle())
+ {
+ if (!(compareWith && compareWith->HasBulletStyle() && compareWith->GetBulletStyle() == style.GetBulletStyle()))
+ destStyle.SetBulletStyle(style.GetBulletStyle());
+ }
- if (attr.HasListStyleName())
- newAttr.SetListStyleName(attr.GetListStyleName());
+ if (style.HasBulletText())
+ {
+ if (!(compareWith && compareWith->HasBulletText() && compareWith->GetBulletText() == style.GetBulletText()))
+ {
+ destStyle.SetBulletText(style.GetBulletText());
+ destStyle.SetBulletFont(style.GetBulletFont());
+ }
+ }
- if (attr.HasBulletStyle())
- newAttr.SetBulletStyle(attr.GetBulletStyle());
+ if (style.HasBulletNumber())
+ {
+ if (!(compareWith && compareWith->HasBulletNumber() && compareWith->GetBulletNumber() == style.GetBulletNumber()))
+ destStyle.SetBulletNumber(style.GetBulletNumber());
+ }
- if (attr.HasBulletNumber())
- newAttr.SetBulletNumber(attr.GetBulletNumber());
+ if (style.HasBulletName())
+ {
+ if (!(compareWith && compareWith->HasBulletName() && compareWith->GetBulletName() == style.GetBulletName()))
+ destStyle.SetBulletName(style.GetBulletName());
+ }
- if (attr.HasBulletName())
- newAttr.SetBulletName(attr.GetBulletName());
+ if (style.HasURL())
+ {
+ if (!(compareWith && compareWith->HasURL() && compareWith->GetURL() == style.GetURL()))
+ destStyle.SetURL(style.GetURL());
+ }
- if (attr.HasBulletText())
+ if (style.HasPageBreak())
{
- newAttr.SetBulletText(attr.GetBulletText());
- newAttr.SetBulletFont(attr.GetBulletFont());
+ if (!(compareWith && compareWith->HasPageBreak()))
+ destStyle.SetPageBreak();
}
- if (attr.HasURL())
- newAttr.SetURL(attr.GetURL());
+ if (style.HasTextEffects())
+ {
+ if (!(compareWith && compareWith->HasTextEffects() && compareWith->GetTextEffects() == style.GetTextEffects()))
+ {
+ int destBits = destStyle.GetTextEffects();
+ int destFlags = destStyle.GetTextEffectFlags();
- if (attr.HasPageBreak())
- newAttr.SetPageBreak();
+ int srcBits = style.GetTextEffects();
+ int srcFlags = style.GetTextEffectFlags();
- if (attr.HasTextEffects())
- {
- newAttr.SetTextEffects(attr.GetTextEffects());
- newAttr.SetTextEffectFlags(attr.GetTextEffectFlags());
+ wxRichTextCombineBitlists(destBits, srcBits, destFlags, srcFlags);
+
+ destStyle.SetTextEffects(destBits);
+ destStyle.SetTextEffectFlags(destFlags);
+ }
}
- if (attr.HasOutlineLevel())
- newAttr.SetOutlineLevel(attr.GetOutlineLevel());
+ if (style.HasOutlineLevel())
+ {
+ if (!(compareWith && compareWith->HasOutlineLevel() && compareWith->GetOutlineLevel() == style.GetOutlineLevel()))
+ destStyle.SetOutlineLevel(style.GetOutlineLevel());
+ }
- return newAttr;
+ return true;
}
/*!
// Otherwise, if there are font attributes in attr, apply them
if (attr.GetFlags() & wxTEXT_ATTR_FONT)
{
- if (attr.HasSize())
+ if (attr.HasFontSize())
{
flags |= wxTEXT_ATTR_FONT_SIZE;
font.SetPointSize(attr.GetFont().GetPointSize());
}
- if (attr.HasItalic())
+ if (attr.HasFontItalic())
{
flags |= wxTEXT_ATTR_FONT_ITALIC;;
font.SetStyle(attr.GetFont().GetStyle());
}
- if (attr.HasWeight())
+ if (attr.HasFontWeight())
{
flags |= wxTEXT_ATTR_FONT_WEIGHT;
font.SetWeight(attr.GetFont().GetWeight());
}
- if (attr.HasFaceName())
+ if (attr.HasFontFaceName())
{
flags |= wxTEXT_ATTR_FONT_FACE;
font.SetFaceName(attr.GetFont().GetFaceName());
}
- if (attr.HasUnderlined())
+ if (attr.HasFontUnderlined())
{
flags |= wxTEXT_ATTR_FONT_UNDERLINE;
font.SetUnderlined(attr.GetFont().GetUnderlined());
IMPLEMENT_CLASS(wxRichTextFileHandler, wxObject)
-#if wxUSE_STREAMS
+#if wxUSE_FFILE && wxUSE_STREAMS
bool wxRichTextFileHandler::LoadFile(wxRichTextBuffer *buffer, const wxString& filename)
{
wxFFileInputStream stream(filename);
return false;
}
-#endif // wxUSE_STREAMS
+#endif // wxUSE_FFILE && wxUSE_STREAMS
/// Can we handle this filename (if using files)? By default, checks the extension.
bool wxRichTextFileHandler::CanHandle(const wxString& filename) const
return false;
wxString text = buffer->GetText();
+
+ wxString newLine = wxRichTextLineBreakChar;
+ text.Replace(newLine, wxT("\n"));
+
wxCharBuffer buf = text.ToAscii();
stream.Write((const char*) buf, text.length());
// Write data in hex to a stream
bool wxRichTextImageBlock::WriteHex(wxOutputStream& stream)
{
- wxString hex;
- int i;
- for (i = 0; i < (int) m_dataSize; i++)
+ const int bufSize = 512;
+ char buf[bufSize+1];
+
+ int left = m_dataSize;
+ int n, i, j;
+ j = 0;
+ while (left > 0)
{
- hex = wxDecToHex(m_data[i]);
- wxCharBuffer buf = hex.ToAscii();
+ if (left*2 > bufSize)
+ {
+ n = bufSize; left -= (bufSize/2);
+ }
+ else
+ {
+ n = left*2; left = 0;
+ }
- stream.Write((const char*) buf, hex.length());
- }
+ char* b = buf;
+ for (i = 0; i < (n/2); i++)
+ {
+ wxDecToHex(m_data[j], b, b+1);
+ b += 2; j ++;
+ }
+ buf[n] = 0;
+ stream.Write((const char*) buf, n);
+ }
return true;
}
if (m_data)
delete[] m_data;
- wxString str(wxT(" "));
+ wxChar str[2];
m_data = new unsigned char[dataSize];
int i;
for (i = 0; i < dataSize; i ++)
{
- str[0] = stream.GetC();
- str[1] = stream.GetC();
+ str[0] = (char)stream.GetC();
+ str[1] = (char)stream.GetC();
m_data[i] = (unsigned char)wxHexToDec(str);
}