Change wxRichTextParagraph::m_cachedLines data type to vector

Now wxRichTextParagraph::m_cachedLines is stored as a wxVector instead
of a wxList.

See #2523, closes #2577.
This commit is contained in:
Mehmet Soyturk
2021-11-02 10:15:13 +03:00
committed by Vadim Zeitlin
parent 151a9c5a63
commit 8aa5c55f61
5 changed files with 93 additions and 96 deletions

View File

@@ -139,6 +139,9 @@ Changes in behaviour not resulting in compilation errors
distinguishing them from the drive letters, even for single letter network distinguishing them from the drive letters, even for single letter network
share name. share name.
- wxRichTextParagraph::GetLines() now returns const wxVector<wxRichTextLine*>&
instead of wxList<wxRichTextLine*>&.
Changes in behaviour which may result in build errors Changes in behaviour which may result in build errors
----------------------------------------------------- -----------------------------------------------------

View File

@@ -4475,7 +4475,7 @@ protected:
#endif #endif
}; };
WX_DECLARE_LIST_WITH_DECL( wxRichTextLine, wxRichTextLineList , class WXDLLIMPEXP_RICHTEXT ); typedef wxVector<wxRichTextLine*> wxRichTextLineVector;
/** /**
@class wxRichTextParagraph @class wxRichTextParagraph
@@ -4528,7 +4528,7 @@ public:
/** /**
Returns the cached lines. Returns the cached lines.
*/ */
wxRichTextLineList& GetLines() { return m_cachedLines; } const wxRichTextLineVector& GetLines() const { return m_cachedLines; }
// Operations // Operations
@@ -4653,8 +4653,7 @@ public:
protected: protected:
// The lines that make up the wrapped paragraph // The lines that make up the wrapped paragraph
wxRichTextLineList m_cachedLines; wxRichTextLineVector m_cachedLines;
wxVector<wxRichTextLine*> m_cachedLinesVect;
// Whether the paragraph is impacted by floating objects from above // Whether the paragraph is impacted by floating objects from above
int m_impactedByFloatingObjects; int m_impactedByFloatingObjects;

View File

@@ -4305,7 +4305,7 @@ protected:
#endif #endif
}; };
class wxRichTextLineList; typedef wxVector<wxRichTextLine*> wxRichTextLineVector;
/** /**
@class wxRichTextParagraph @class wxRichTextParagraph
@@ -4357,7 +4357,7 @@ public:
/** /**
Returns the cached lines. Returns the cached lines.
*/ */
wxRichTextLineList& GetLines() { return m_cachedLines; } const wxRichTextLineVector& GetLines() const { return m_cachedLines; }
// Operations // Operations
@@ -4482,7 +4482,7 @@ public:
protected: protected:
// The lines that make up the wrapped paragraph // The lines that make up the wrapped paragraph
wxRichTextLineList m_cachedLines; wxRichTextLineVector m_cachedLines;
// Whether the paragraph is impacted by floating objects from above // Whether the paragraph is impacted by floating objects from above
int m_impactedByFloatingObjects; int m_impactedByFloatingObjects;

View File

@@ -46,7 +46,6 @@
#include "wx/arrimpl.cpp" #include "wx/arrimpl.cpp"
WX_DEFINE_LIST(wxRichTextObjectList) WX_DEFINE_LIST(wxRichTextObjectList)
WX_DEFINE_LIST(wxRichTextLineList)
// Switch off if the platform doesn't like it for some reason // Switch off if the platform doesn't like it for some reason
#define wxRICHTEXT_USE_OPTIMIZED_DRAWING 1 #define wxRICHTEXT_USE_OPTIMIZED_DRAWING 1
@@ -2280,7 +2279,7 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, wxRichTextDrawingContext& co
// TODO: what if the child hasn't been laid out (e.g. involved in Undo) but still has 'old' lines // TODO: what if the child hasn't been laid out (e.g. involved in Undo) but still has 'old' lines
if ( !forceQuickLayout && if ( !forceQuickLayout &&
(layoutAll || (layoutAll ||
child->GetLines().IsEmpty() || child->GetLines().empty() ||
!child->GetRange().IsOutside(invalidRange)) ) !child->GetRange().IsOutside(invalidRange)) )
{ {
// Lays out the object first with a given amount of space, and then if no width was specified in attr, // Lays out the object first with a given amount of space, and then if no width was specified in attr,
@@ -2353,7 +2352,7 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, wxRichTextDrawingContext& co
wxRichTextParagraph* nodeChild = wxDynamicCast(node->GetData(), wxRichTextParagraph); wxRichTextParagraph* nodeChild = wxDynamicCast(node->GetData(), wxRichTextParagraph);
if (nodeChild) if (nodeChild)
{ {
if (nodeChild->GetLines().GetCount() == 0) if (nodeChild->GetLines().empty())
{ {
nodeChild->SetImpactedByFloatingObjects(-1); nodeChild->SetImpactedByFloatingObjects(-1);
@@ -2618,10 +2617,10 @@ wxRichTextLine* wxRichTextParagraphLayoutBox::GetLineAtPosition(long pos, bool c
if (child) if (child)
{ {
wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); wxRichTextLineVector::const_iterator it = child->GetLines().begin();
while (node2) while (it != child->GetLines().end())
{ {
wxRichTextLine* line = node2->GetData(); wxRichTextLine* line = *it;
wxRichTextRange range = line->GetAbsoluteRange(); wxRichTextRange range = line->GetAbsoluteRange();
@@ -2632,7 +2631,7 @@ wxRichTextLine* wxRichTextParagraphLayoutBox::GetLineAtPosition(long pos, bool c
((range.GetEnd() == child->GetRange().GetEnd()-1) && (pos == child->GetRange().GetEnd()))) ((range.GetEnd() == child->GetRange().GetEnd()-1) && (pos == child->GetRange().GetEnd())))
return line; return line;
node2 = node2->GetNext(); ++it;
} }
} }
} }
@@ -2658,17 +2657,17 @@ wxRichTextLine* wxRichTextParagraphLayoutBox::GetLineAtYPosition(int y) const
if (child) if (child)
{ {
wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); wxRichTextLineVector::const_iterator it = child->GetLines().begin();
while (node2) while (it != child->GetLines().end())
{ {
wxRichTextLine* line = node2->GetData(); wxRichTextLine* line = *it;
wxRect rect(line->GetRect()); wxRect rect(line->GetRect());
if (y <= rect.GetBottom()) if (y <= rect.GetBottom())
return line; return line;
node2 = node2->GetNext(); ++it;
} }
} }
@@ -2695,7 +2694,7 @@ int wxRichTextParagraphLayoutBox::GetLineCount() const
// wxASSERT (child != NULL); // wxASSERT (child != NULL);
if (child) if (child)
count += child->GetLines().GetCount(); count += child->GetLines().size();
node = node->GetNext(); node = node->GetNext();
} }
@@ -3160,10 +3159,10 @@ long wxRichTextParagraphLayoutBox::GetVisibleLineNumber(long pos, bool caretPosi
{ {
if (child->GetRange().Contains(pos)) if (child->GetRange().Contains(pos))
{ {
wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); wxRichTextLineVector::const_iterator it = child->GetLines().begin();
while (node2) while (it != child->GetLines().end())
{ {
wxRichTextLine* line = node2->GetData(); wxRichTextLine* line = *it;
wxRichTextRange lineRange = line->GetAbsoluteRange(); wxRichTextRange lineRange = line->GetAbsoluteRange();
if (lineRange.Contains(pos) || pos == lineRange.GetStart()) if (lineRange.Contains(pos) || pos == lineRange.GetStart())
@@ -3179,14 +3178,14 @@ long wxRichTextParagraphLayoutBox::GetVisibleLineNumber(long pos, bool caretPosi
lineCount ++; lineCount ++;
node2 = node2->GetNext(); ++it;
} }
// If we didn't find it in the lines, it must be // If we didn't find it in the lines, it must be
// the last position of the paragraph. So return the last line. // the last position of the paragraph. So return the last line.
return lineCount-1; return lineCount-1;
} }
else else
lineCount += child->GetLines().GetCount(); lineCount += child->GetLines().size();
} }
node = node->GetNext(); node = node->GetNext();
@@ -3209,23 +3208,23 @@ wxRichTextLine* wxRichTextParagraphLayoutBox::GetLineForVisibleLineNumber(long l
if (child) if (child)
{ {
if (lineNumber < (int) (child->GetLines().GetCount() + lineCount)) if (lineNumber < (int) (child->GetLines().size() + lineCount))
{ {
wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); wxRichTextLineVector::const_iterator it = child->GetLines().begin();
while (node2) while (it != child->GetLines().end())
{ {
wxRichTextLine* line = node2->GetData(); wxRichTextLine* line = *it;
if (lineCount == lineNumber) if (lineCount == lineNumber)
return line; return line;
lineCount ++; lineCount ++;
node2 = node2->GetNext(); ++it;
} }
} }
else else
lineCount += child->GetLines().GetCount(); lineCount += child->GetLines().size();
} }
node = node->GetNext(); node = node->GetNext();
@@ -4836,7 +4835,7 @@ bool wxRichTextParagraph::Draw(wxDC& dc, wxRichTextDrawingContext& context, cons
wxRichTextAttr bulletAttr(attr); wxRichTextAttr bulletAttr(attr);
// Get line height from first line, if any // Get line height from first line, if any
wxRichTextLine* line = m_cachedLines.GetFirst() ? (wxRichTextLine* ) m_cachedLines.GetFirst()->GetData() : NULL; wxRichTextLine* line = m_cachedLines.empty() ? NULL : m_cachedLines[0];
wxPoint linePos; wxPoint linePos;
int lineHeight wxDUMMY_INITIALIZE(0); int lineHeight wxDUMMY_INITIALIZE(0);
@@ -4884,10 +4883,10 @@ bool wxRichTextParagraph::Draw(wxDC& dc, wxRichTextDrawingContext& context, cons
// Draw the range for each line, one object at a time. // Draw the range for each line, one object at a time.
wxRichTextLineList::compatibility_iterator node = m_cachedLines.GetFirst(); wxRichTextLineVector::const_iterator it = m_cachedLines.begin();
while (node) while (it != m_cachedLines.end())
{ {
wxRichTextLine* line = node->GetData(); wxRichTextLine* line = *it;
wxRichTextRange lineRange = line->GetAbsoluteRange(); wxRichTextRange lineRange = line->GetAbsoluteRange();
// Lines are specified relative to the paragraph // Lines are specified relative to the paragraph
@@ -4950,7 +4949,7 @@ bool wxRichTextParagraph::Draw(wxDC& dc, wxRichTextDrawingContext& context, cons
} }
} }
node = node->GetNext(); ++it;
} }
return true; return true;
@@ -5696,8 +5695,10 @@ void wxRichTextParagraph::Copy(const wxRichTextParagraph& obj)
/// Clear the cached lines /// Clear the cached lines
void wxRichTextParagraph::ClearLines() void wxRichTextParagraph::ClearLines()
{ {
WX_CLEAR_LIST(wxRichTextLineList, m_cachedLines); size_t cachedLineCount = m_cachedLines.size();
m_cachedLinesVect.clear(); for (size_t i = 0; i < cachedLineCount; i++)
delete m_cachedLines[i];
m_cachedLines.clear();
} }
/// Get/set the object size for the given range. Returns false if the range /// Get/set the object size for the given range. Returns false if the range
@@ -5877,10 +5878,10 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
// (so we can assume that getting the unformatted size for a fragment // (so we can assume that getting the unformatted size for a fragment
// within a line is the actual size) // within a line is the actual size)
wxRichTextLineList::compatibility_iterator node = m_cachedLines.GetFirst(); wxRichTextLineVector::const_iterator it = m_cachedLines.begin();
while (node) while (it != m_cachedLines.end())
{ {
wxRichTextLine* line = node->GetData(); wxRichTextLine* line = *it;
wxRichTextRange lineRange = line->GetAbsoluteRange(); wxRichTextRange lineRange = line->GetAbsoluteRange();
if (!lineRange.IsOutside(range)) if (!lineRange.IsOutside(range))
{ {
@@ -5931,7 +5932,7 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
sz.y += maxLineHeight; sz.y += maxLineHeight;
sz.x = wxMax(sz.x, maxLineWidth); sz.x = wxMax(sz.x, maxLineWidth);
} }
node = node->GetNext(); ++it;
} }
size = sz; size = sz;
} }
@@ -5984,10 +5985,10 @@ bool wxRichTextParagraph::FindPosition(wxDC& dc, wxRichTextDrawingContext& conte
if (index < GetRange().GetStart() || index > GetRange().GetEnd()) if (index < GetRange().GetStart() || index > GetRange().GetEnd())
return false; return false;
wxRichTextLineList::compatibility_iterator node = m_cachedLines.GetFirst(); wxRichTextLineVector::const_iterator it = m_cachedLines.begin();
while (node) while (it != m_cachedLines.end())
{ {
wxRichTextLine* line = node->GetData(); wxRichTextLine* line = *it;
wxRichTextRange lineRange = line->GetAbsoluteRange(); wxRichTextRange lineRange = line->GetAbsoluteRange();
if (index >= lineRange.GetStart() && index <= lineRange.GetEnd()) if (index >= lineRange.GetStart() && index <= lineRange.GetEnd())
{ {
@@ -5996,9 +5997,12 @@ bool wxRichTextParagraph::FindPosition(wxDC& dc, wxRichTextDrawingContext& conte
// thing. // thing.
if (index == lineRange.GetEnd() && forceLineStart) if (index == lineRange.GetEnd() && forceLineStart)
{ {
if (node->GetNext()) wxRichTextLineVector::const_iterator itNext = it;
++itNext;
if (itNext != m_cachedLines.end())
{ {
wxRichTextLine* nextLine = node->GetNext()->GetData(); wxRichTextLine* nextLine = *itNext;
*height = nextLine->GetSize().y; *height = nextLine->GetSize().y;
pt = nextLine->GetAbsolutePosition(); pt = nextLine->GetAbsolutePosition();
return true; return true;
@@ -6025,7 +6029,7 @@ bool wxRichTextParagraph::FindPosition(wxDC& dc, wxRichTextDrawingContext& conte
} }
node = node->GetNext(); ++it;
} }
return false; return false;
@@ -6076,10 +6080,10 @@ int wxRichTextParagraph::HitTest(wxDC& dc, wxRichTextDrawingContext& context, co
wxPoint paraPos = GetPosition(); wxPoint paraPos = GetPosition();
wxRichTextLineList::compatibility_iterator node = m_cachedLines.GetFirst(); wxRichTextLineVector::const_iterator it = m_cachedLines.begin();
while (node) while (it != m_cachedLines.end())
{ {
wxRichTextLine* line = node->GetData(); wxRichTextLine* line = *it;
wxPoint linePos = paraPos + line->GetPosition(); wxPoint linePos = paraPos + line->GetPosition();
wxSize lineSize = line->GetSize(); wxSize lineSize = line->GetSize();
wxRichTextRange lineRange = line->GetAbsoluteRange(); wxRichTextRange lineRange = line->GetAbsoluteRange();
@@ -6177,7 +6181,7 @@ int wxRichTextParagraph::HitTest(wxDC& dc, wxRichTextDrawingContext& context, co
} }
} }
node = node->GetNext(); ++it;
} }
return wxRICHTEXT_HITTEST_NONE; return wxRICHTEXT_HITTEST_NONE;
@@ -6528,18 +6532,16 @@ wxString wxRichTextParagraph::GetBulletText()
/// Allocate or reuse a line object /// Allocate or reuse a line object
wxRichTextLine* wxRichTextParagraph::AllocateLine(int pos) wxRichTextLine* wxRichTextParagraph::AllocateLine(int pos)
{ {
if (pos < (int) m_cachedLines.GetCount()) if (pos < (int) m_cachedLines.size())
{ {
wxASSERT(m_cachedLinesVect.size() == m_cachedLines.GetCount()); wxRichTextLine* line = m_cachedLines[pos];
wxRichTextLine* line = m_cachedLinesVect[pos];
line->Init(this); line->Init(this);
return line; return line;
} }
else else
{ {
wxRichTextLine* line = new wxRichTextLine(this); wxRichTextLine* line = new wxRichTextLine(this);
m_cachedLines.Append(line); m_cachedLines.push_back(line);
m_cachedLinesVect.push_back(line);
return line; return line;
} }
} }
@@ -6547,18 +6549,14 @@ wxRichTextLine* wxRichTextParagraph::AllocateLine(int pos)
/// Clear remaining unused line objects, if any /// Clear remaining unused line objects, if any
bool wxRichTextParagraph::ClearUnusedLines(int lineCount) bool wxRichTextParagraph::ClearUnusedLines(int lineCount)
{ {
int cachedLineCount = m_cachedLines.GetCount(); size_t cachedLineCount = m_cachedLines.size();
if ((int) cachedLineCount > lineCount)
if ((size_t)lineCount < cachedLineCount)
{ {
for (int i = 0; i < (int) (cachedLineCount - lineCount); i ++) for (size_t i = lineCount; i < cachedLineCount; i++)
{ delete m_cachedLines[i];
wxRichTextLineList::compatibility_iterator node = m_cachedLines.GetLast(); m_cachedLines.resize(lineCount);
wxRichTextLine* line = node->GetData();
m_cachedLines.Erase(node);
delete line;
}
} }
m_cachedLinesVect.resize(lineCount);
return true; return true;
} }
@@ -11836,20 +11834,21 @@ void wxRichTextAction::CalculateRefreshOptimizations(wxArrayInt& optimizationLin
wxRichTextParagraph* para = container->GetParagraphAtPosition(GetRange().GetStart()); wxRichTextParagraph* para = container->GetParagraphAtPosition(GetRange().GetStart());
wxRichTextObjectList::compatibility_iterator firstNode = container->GetChildren().Find(para); wxRichTextObjectList::compatibility_iterator firstNode = container->GetChildren().Find(para);
wxRichTextObjectList::compatibility_iterator node = firstNode; wxRichTextObjectList::compatibility_iterator node = firstNode;
while (node) bool stop = false;
while (!stop && node)
{ {
wxRichTextParagraph* child = (wxRichTextParagraph*) node->GetData(); wxRichTextParagraph* child = (wxRichTextParagraph*) node->GetData();
wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); wxRichTextLineVector::const_iterator it = child->GetLines().begin();
while (node2) while (!stop && it != child->GetLines().end())
{ {
wxRichTextLine* line = node2->GetData(); wxRichTextLine* line = *it;
wxPoint pt = line->GetAbsolutePosition(); wxPoint pt = line->GetAbsolutePosition();
wxRichTextRange range = line->GetAbsoluteRange(); wxRichTextRange range = line->GetAbsoluteRange();
if (pt.y > lastY) if (pt.y > lastY)
{ {
node2 = wxRichTextLineList::compatibility_iterator(); stop = true;
node = wxRichTextObjectList::compatibility_iterator();
} }
else if (range.GetStart() > GetPosition() && pt.y >= firstVisiblePt.y) else if (range.GetStart() > GetPosition() && pt.y >= firstVisiblePt.y)
{ {
@@ -11857,12 +11856,10 @@ void wxRichTextAction::CalculateRefreshOptimizations(wxArrayInt& optimizationLin
optimizationLineYPositions.Add(pt.y); optimizationLineYPositions.Add(pt.y);
} }
if (node2) ++it;
node2 = node2->GetNext();
} }
if (node) node = node->GetNext();
node = node->GetNext();
} }
if (wxRichTextBuffer::GetFloatingLayoutMode() && container->GetFloatingObjectCount() > 0) if (wxRichTextBuffer::GetFloatingLayoutMode() && container->GetFloatingObjectCount() > 0)
@@ -12313,26 +12310,28 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent
wxRichTextObjectList::compatibility_iterator firstNode = container->GetChildren().Find(para); wxRichTextObjectList::compatibility_iterator firstNode = container->GetChildren().Find(para);
wxRichTextObjectList::compatibility_iterator node = firstNode; wxRichTextObjectList::compatibility_iterator node = firstNode;
wxRichTextObjectList::compatibility_iterator lastNode = wxRichTextObjectList::compatibility_iterator(); wxRichTextObjectList::compatibility_iterator lastNode = wxRichTextObjectList::compatibility_iterator();
while (node) bool stop = false;
while (!stop && node)
{ {
wxRichTextParagraph* child = (wxRichTextParagraph*) node->GetData(); wxRichTextParagraph* child = (wxRichTextParagraph*) node->GetData();
wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); wxRichTextLineVector::const_iterator it = child->GetLines().begin();
while (node2) while (!stop && it != child->GetLines().end())
{ {
wxRichTextLine* line = node2->GetData(); wxRichTextLine* line = *it;
wxPoint pt = line->GetAbsolutePosition(); wxPoint pt = line->GetAbsolutePosition();
wxRichTextRange range = line->GetAbsoluteRange(); wxRichTextRange range = line->GetAbsoluteRange();
const bool isLastLine = it + 1 == child->GetLines().end();
// we want to find the first line that is in the same position // 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. // 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 if (pt.y > lastY) // going past the end of the window, no more info
{ {
node2 = wxRichTextLineList::compatibility_iterator(); stop = true;
node = wxRichTextObjectList::compatibility_iterator();
} }
// Detect last line in the buffer // Detect last line in the buffer
else if (!node2->GetNext() && para->GetRange().Contains(container->GetOwnRange().GetEnd())) else if (isLastLine && para->GetRange().Contains(container->GetOwnRange().GetEnd()))
{ {
// If deleting text, make sure we refresh below as well as above // If deleting text, make sure we refresh below as well as above
if (positionOffset >= 0) if (positionOffset >= 0)
@@ -12343,8 +12342,7 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent
lastNode = node; lastNode = node;
node2 = wxRichTextLineList::compatibility_iterator(); stop = true;
node = wxRichTextObjectList::compatibility_iterator();
break; break;
} }
@@ -12363,20 +12361,17 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent
lastNode = node; lastNode = node;
node2 = wxRichTextLineList::compatibility_iterator(); stop = true;
node = wxRichTextObjectList::compatibility_iterator();
break; break;
} }
} }
} }
if (node2) ++it;
node2 = node2->GetNext();
} }
if (node) node = node->GetNext();
node = node->GetNext();
} }
firstY = wxMax(firstVisiblePt.y, firstY); firstY = wxMax(firstVisiblePt.y, firstY);

View File

@@ -80,13 +80,13 @@ void wxRichTextPrintout::OnPreparePrinting()
wxASSERT (child != NULL); wxASSERT (child != NULL);
if (child) if (child)
{ {
wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); wxRichTextLineVector::const_iterator it = child->GetLines().begin();
while (node2) while (it != child->GetLines().end())
{ {
wxRichTextLine* line = node2->GetData(); wxRichTextLine* line = *it;
int lineY = child->GetPosition().y + line->GetPosition().y - yOffset; int lineY = child->GetPosition().y + line->GetPosition().y - yOffset;
bool hasHardPageBreak = ((node2 == child->GetLines().GetFirst()) && child->GetAttributes().HasPageBreak()); bool hasHardPageBreak = ((it == child->GetLines().begin()) && child->GetAttributes().HasPageBreak());
// Break the page if either we're going off the bottom, or this paragraph specifies // Break the page if either we're going off the bottom, or this paragraph specifies
// an explicit page break // an explicit page break
@@ -134,7 +134,7 @@ void wxRichTextPrintout::OnPreparePrinting()
lastLine = line; lastLine = line;
node2 = node2->GetNext(); ++it;
} }
} }