| ... |
... |
@@ -6934,234 +6934,257 @@ bool wxRichTextPlainText::Draw(wxDC& dc, wxRichTextDrawingContext& context, cons |
|
6934
|
6934
|
y = rect.y + (rect.height - charHeight - (descent - m_descent));
|
|
6935
|
6935
|
}
|
|
6936
|
6936
|
|
|
6937
|
|
- // TODO: new selection code
|
|
6938
|
|
-
|
|
6939
|
6937
|
// (a) All selected.
|
|
6940
|
6938
|
if (allSelected)
|
|
6941
|
6939
|
{
|
|
6942
|
|
- DrawTabbedString(dc, textAttr, rect, stringChunk, x, y, true);
|
|
|
6940
|
+ DrawTabbedString(dc, textAttr, rect, stringChunk, x, y, 0, stringChunk.length() - 1);
|
|
6943
|
6941
|
}
|
|
6944
|
6942
|
// (b) None selected.
|
|
6945
|
6943
|
else if (noneSelected)
|
|
6946
|
6944
|
{
|
|
6947
|
6945
|
// Draw all unselected
|
|
6948
|
|
- DrawTabbedString(dc, textAttr, rect, stringChunk, x, y, false);
|
|
|
6946
|
+ DrawTabbedString(dc, textAttr, rect, stringChunk, x, y, -1, -1);
|
|
6949
|
6947
|
}
|
|
6950
|
6948
|
else
|
|
6951
|
6949
|
{
|
|
6952
|
|
- // (c) Part selected, part not
|
|
6953
|
|
- // Let's draw unselected chunk, selected chunk, then unselected chunk.
|
|
6954
|
|
-
|
|
6955
|
|
- const wxString& str = stringWhole;
|
|
6956
|
|
-
|
|
6957
|
|
- dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
|
|
6958
|
|
-
|
|
6959
|
|
- // 1. Initial unselected chunk, if any, up until start of selection.
|
|
6960
|
|
- if (selectionRange.GetStart() > range.GetStart() && selectionRange.GetStart() <= range.GetEnd())
|
|
6961
|
|
- {
|
|
6962
|
|
- int r1 = range.GetStart();
|
|
6963
|
|
- int s1 = selectionRange.GetStart()-1;
|
|
6964
|
|
- int fragmentLen = s1 - r1 + 1;
|
|
6965
|
|
- if (fragmentLen < 0)
|
|
6966
|
|
- {
|
|
6967
|
|
- wxLogDebug(wxT("Mid(%d, %d"), (int)(r1 - offset), (int)fragmentLen);
|
|
6968
|
|
- }
|
|
6969
|
|
- wxString stringFragment = str.Mid(r1 - offset, fragmentLen);
|
|
6970
|
|
-
|
|
6971
|
|
- DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false);
|
|
6972
|
|
-
|
|
6973
|
|
-#if USE_KERNING_FIX
|
|
6974
|
|
- if (stringChunk.Find(wxT("\t")) == wxNOT_FOUND)
|
|
6975
|
|
- {
|
|
6976
|
|
- // Compensate for kerning difference
|
|
6977
|
|
- wxString stringFragment2(str.Mid(r1 - offset, fragmentLen+1));
|
|
6978
|
|
- wxString stringFragment3(str.Mid(r1 - offset + fragmentLen, 1));
|
|
|
6950
|
+ const int selStart = wxMax(selectionRange.GetStart(), range.GetStart()) - range.GetStart();
|
|
|
6951
|
+ const int selEnd = wxMin(selectionRange.GetEnd(), range.GetEnd()) - range.GetStart();
|
|
|
6952
|
+ DrawTabbedString(dc, textAttr, rect, stringChunk, x, y, selStart, selEnd);
|
|
|
6953
|
+ }
|
|
6979
|
6954
|
|
|
6980
|
|
- wxCoord w1, h1, w2, h2, w3, h3;
|
|
6981
|
|
- dc.GetTextExtent(stringFragment, & w1, & h1);
|
|
6982
|
|
- dc.GetTextExtent(stringFragment2, & w2, & h2);
|
|
6983
|
|
- dc.GetTextExtent(stringFragment3, & w3, & h3);
|
|
|
6955
|
+ return true;
|
|
|
6956
|
+}
|
|
6984
|
6957
|
|
|
6985
|
|
- int kerningDiff = (w1 + w3) - w2;
|
|
6986
|
|
- x = x - kerningDiff;
|
|
6987
|
|
- }
|
|
6988
|
|
-#endif
|
|
6989
|
|
- }
|
|
|
6958
|
+void wxRichTextPlainText::DrawTabbedString(wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect, wxString& str, wxCoord& x, wxCoord& y, ssize_t selStart, ssize_t selEnd)
|
|
|
6959
|
+{
|
|
|
6960
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
6961
|
+ // This function assumes str has uniform formatting (attr applies to //
|
|
|
6962
|
+ // the entire string). The calling code should split text into style //
|
|
|
6963
|
+ // runs before calling this function. //
|
|
|
6964
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
6965
|
+
|
|
|
6966
|
+ wxColour selClr = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
|
|
|
6967
|
+ wxColour txtForeClr = attr.HasTextColour() && attr.GetTextColour().IsOk()
|
|
|
6968
|
+ ? attr.GetTextColour()
|
|
|
6969
|
+ : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
|
|
6970
|
+ wxColour txtBackClr = attr.HasBackgroundColour() && attr.GetBackgroundColour().IsOk()
|
|
|
6971
|
+ ? attr.GetBackgroundColour()
|
|
|
6972
|
+ : wxTransparentColour;
|
|
|
6973
|
+ int txtBackMod = attr.HasBackgroundColour() && attr.GetBackgroundColour().IsOk()
|
|
|
6974
|
+ ? wxBRUSHSTYLE_SOLID
|
|
|
6975
|
+ : wxBRUSHSTYLE_TRANSPARENT;
|
|
|
6976
|
+ wxCoord originx = GetParent()->GetPosition().x;
|
|
|
6977
|
+ wxArrayInt startpos; // Character starting positions
|
|
|
6978
|
+ wxArrayInt endpos; // Character ending positions (cumulative widths)
|
|
|
6979
|
+ wxArrayInt tabstops; // Array of tab stop positions
|
|
|
6980
|
+
|
|
|
6981
|
+ const bool strikethrough = (attr.GetTextEffects() & wxTEXT_ATTR_EFFECT_STRIKETHROUGH) != 0;
|
|
|
6982
|
+ const int strikeheight = wxRound(0.5 * rect.GetHeight() + rect.y);
|
|
|
6983
|
+ size_t effectivetabstop;
|
|
|
6984
|
+ int posadjustment;
|
|
|
6985
|
+ size_t printstart;
|
|
|
6986
|
+ size_t i = 0; // initialization iterator
|
|
|
6987
|
+ size_t si = 0; // string iterator
|
|
|
6988
|
+ size_t ti = 0; // tabstop iterator
|
|
|
6989
|
+ size_t pi = 0; // position iterator
|
|
|
6990
|
+
|
|
|
6991
|
+
|
|
|
6992
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
6993
|
+ // Initial setup & early returns //
|
|
|
6994
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
6995
|
+
|
|
|
6996
|
+ if (str.empty())
|
|
|
6997
|
+ return;
|
|
6990
|
6998
|
|
|
6991
|
|
- // 2. Selected chunk, if any.
|
|
6992
|
|
- if (selectionRange.GetEnd() >= range.GetStart())
|
|
6993
|
|
- {
|
|
6994
|
|
- int s1 = wxMax(selectionRange.GetStart(), range.GetStart());
|
|
6995
|
|
- int s2 = wxMin(selectionRange.GetEnd(), range.GetEnd());
|
|
|
6999
|
+ // Get character ending positions
|
|
|
7000
|
+ dc.GetPartialTextExtents(str, endpos);
|
|
|
7001
|
+ startpos.SetCount(endpos.GetCount());
|
|
6996
|
7002
|
|
|
6997
|
|
- int fragmentLen = s2 - s1 + 1;
|
|
6998
|
|
- if (fragmentLen < 0)
|
|
6999
|
|
- {
|
|
7000
|
|
- wxLogDebug(wxT("Mid(%d, %d"), (int)(s1 - offset), (int)fragmentLen);
|
|
7001
|
|
- }
|
|
7002
|
|
- wxString stringFragment = str.Mid(s1 - offset, fragmentLen);
|
|
|
7003
|
+ startpos[0] = x;
|
|
|
7004
|
+ for (i = 0; i < endpos.GetCount() - 1; i++)
|
|
|
7005
|
+ {
|
|
|
7006
|
+ endpos[i] = x + endpos[i];
|
|
|
7007
|
+ startpos[i+1] = endpos[i];
|
|
|
7008
|
+ }
|
|
|
7009
|
+ endpos[i] = x + endpos[i];
|
|
7003
|
7010
|
|
|
7004
|
|
- DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, true);
|
|
|
7011
|
+ // Get all of the tabstops
|
|
|
7012
|
+ tabstops = attr.GetTabs().IsEmpty()
|
|
|
7013
|
+ ? wxRichTextParagraph::GetDefaultTabs()
|
|
|
7014
|
+ : attr.GetTabs();
|
|
|
7015
|
+ const size_t tabcount = tabstops.GetCount();
|
|
|
7016
|
+ for (i = 0; i < tabcount; i++)
|
|
|
7017
|
+ tabstops[i] = originx + ConvertTenthsMMToPixels(dc, tabstops[i]);
|
|
7005
|
7018
|
|
|
7006
|
|
-#if USE_KERNING_FIX
|
|
7007
|
|
- if (stringChunk.Find(wxT("\t")) == wxNOT_FOUND)
|
|
7008
|
|
- {
|
|
7009
|
|
- // Compensate for kerning difference
|
|
7010
|
|
- wxString stringFragment2(str.Mid(s1 - offset, fragmentLen+1));
|
|
7011
|
|
- wxString stringFragment3(str.Mid(s1 - offset + fragmentLen, 1));
|
|
7012
|
7019
|
|
|
7013
|
|
- wxCoord w1, h1, w2, h2, w3, h3;
|
|
7014
|
|
- dc.GetTextExtent(stringFragment, & w1, & h1);
|
|
7015
|
|
- dc.GetTextExtent(stringFragment2, & w2, & h2);
|
|
7016
|
|
- dc.GetTextExtent(stringFragment3, & w3, & h3);
|
|
|
7020
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
7021
|
+ // Tab stop position adjustments //
|
|
|
7022
|
+ //////////////////////////////////////////////////////////////////////////
|
|
7017
|
7023
|
|
|
7018
|
|
- int kerningDiff = (w1 + w3) - w2;
|
|
7019
|
|
- x = x - kerningDiff;
|
|
7020
|
|
- }
|
|
7021
|
|
-#endif
|
|
7022
|
|
- }
|
|
|
7024
|
+ // Adjust horizontal positions to account for tab stops.
|
|
|
7025
|
+ // Do this by looping through to find every tab character, calculate the
|
|
|
7026
|
+ // appropriate tab stop for it, measure the horizontal space difference,
|
|
|
7027
|
+ // and adjust the tab's ending position and the start/end positions of
|
|
|
7028
|
+ // every character after it.
|
|
|
7029
|
+ //
|
|
|
7030
|
+ // BL: Tab Char --> Tab Stop --> Pixel Adjustment --> New startpos/endpos
|
|
|
7031
|
+ //
|
|
|
7032
|
+ // NOTE: TODO: This almost certainly does not work for RTL languages
|
|
|
7033
|
+ // unless wxDC has some real x-flipping magic.
|
|
|
7034
|
+ for (si = 0; si < str.length(); si++)
|
|
|
7035
|
+ {
|
|
7023
|
7036
|
|
|
7024
|
|
- // 3. Remaining unselected chunk, if any
|
|
7025
|
|
- if (selectionRange.GetEnd() < range.GetEnd())
|
|
|
7037
|
+ if (str[si] == '\t')
|
|
7026
|
7038
|
{
|
|
7027
|
|
- int s2 = wxMin(selectionRange.GetEnd()+1, range.GetEnd());
|
|
7028
|
|
- int r2 = range.GetEnd();
|
|
|
7039
|
+ // We have a tab. Find the next tab stop AFTER this tab's start position.
|
|
|
7040
|
+ // NOTE: ti is monotonic.
|
|
|
7041
|
+ while (ti < tabcount && tabstops[ti] <= startpos[si])
|
|
|
7042
|
+ ti++;
|
|
7029
|
7043
|
|
|
7030
|
|
- int fragmentLen = r2 - s2 + 1;
|
|
7031
|
|
- if (fragmentLen < 0)
|
|
7032
|
|
- {
|
|
7033
|
|
- wxLogDebug(wxT("Mid(%d, %d"), (int)(s2 - offset), (int)fragmentLen);
|
|
7034
|
|
- }
|
|
7035
|
|
- wxString stringFragment = str.Mid(s2 - offset, fragmentLen);
|
|
7036
|
|
-
|
|
7037
|
|
- DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false);
|
|
7038
|
|
- }
|
|
7039
|
|
- }
|
|
|
7044
|
+ // If we found a valid tab stop before reaching the end of the list, use that.
|
|
|
7045
|
+ if (ti < tabcount)
|
|
|
7046
|
+ effectivetabstop = tabstops[ti];
|
|
7040
|
7047
|
|
|
7041
|
|
- return true;
|
|
7042
|
|
-}
|
|
7043
|
|
-
|
|
7044
|
|
-bool wxRichTextPlainText::DrawTabbedString(wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect,wxString& str, wxCoord& x, wxCoord& y, bool selected)
|
|
7045
|
|
-{
|
|
7046
|
|
- bool hasTabs = (str.Find(wxT('\t')) != wxNOT_FOUND);
|
|
|
7048
|
+ // Otherwise use the default tab width.
|
|
|
7049
|
+ else
|
|
|
7050
|
+ effectivetabstop = startpos[si] + ConvertTenthsMMToPixels(dc, WIDTH_FOR_DEFAULT_TABS);
|
|
|
7051
|
+
|
|
|
7052
|
+ // Adjust position calculations accordingly
|
|
|
7053
|
+ posadjustment = effectivetabstop - endpos[si];
|
|
|
7054
|
+ endpos[si] += posadjustment;
|
|
|
7055
|
+ for (pi = si + 1; pi < endpos.GetCount(); pi++)
|
|
|
7056
|
+ {
|
|
|
7057
|
+ startpos[pi] += posadjustment;
|
|
|
7058
|
+ endpos[pi] += posadjustment;
|
|
|
7059
|
+ }
|
|
|
7060
|
+ }
|
|
|
7061
|
+ }
|
|
|
7062
|
+
|
|
|
7063
|
+//////////////////////////////////////////////////////////////////////////////
|
|
|
7064
|
+// PLATFORM-SPECIFIC SELECTION HANDLING //
|
|
|
7065
|
+//////////////////////////////////////////////////////////////////////////////
|
|
|
7066
|
+// We face different challenges on different platforms:
|
|
|
7067
|
+// 1. On most platforms, the text foreground color changes when selected;
|
|
|
7068
|
+// as a result, we MUST make a separate DrawText() call for it or it
|
|
|
7069
|
+// won't render as expected.
|
|
|
7070
|
+// 2. On Mac, aggressive font-shaping means that breaking up DrawText()
|
|
|
7071
|
+// calls causes kerning-induced left-right jitter as text is selected
|
|
|
7072
|
+// (e.g., DrawText("AB") DrawText("CD") isn't the same canvas width as
|
|
|
7073
|
+// (DrawText("ABC") DrawText("D")). However, luckily, Mac does NOT use
|
|
|
7074
|
+// or need a different foreground color for text, so we don't NEED to
|
|
|
7075
|
+// break up the DrawText() calls.
|
|
|
7076
|
+// 3. However, caveat: selection highlights DO override the background
|
|
|
7077
|
+// color on Mac, so if we use DrawText() for the background color, we
|
|
|
7078
|
+// still need separate DrawText() calls on Mac. We address this by
|
|
|
7079
|
+// MANUALLY drawing text backgrounds on Mac (BEFORE drawing the
|
|
|
7080
|
+// selection highlight, so the selection highlight overwrites it),
|
|
|
7081
|
+// rather than using DrawText()'s background drawing capability.
|
|
|
7082
|
+#ifdef __WXMAC__
|
|
|
7083
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
7084
|
+ // Mac: Draw text background //
|
|
|
7085
|
+ //////////////////////////////////////////////////////////////////////////
|
|
7047
|
7086
|
|
|
7048
|
|
- wxArrayInt tabArray;
|
|
7049
|
|
- int tabCount;
|
|
7050
|
|
- if (hasTabs)
|
|
7051
|
7087
|
{
|
|
7052
|
|
- if (attr.GetTabs().IsEmpty())
|
|
7053
|
|
- tabArray = wxRichTextParagraph::GetDefaultTabs();
|
|
7054
|
|
- else
|
|
7055
|
|
- tabArray = attr.GetTabs();
|
|
7056
|
|
- tabCount = tabArray.GetCount();
|
|
7057
|
|
-
|
|
7058
|
|
- for (int i = 0; i < tabCount; ++i)
|
|
7059
|
|
- {
|
|
7060
|
|
- int pos = tabArray[i];
|
|
7061
|
|
- pos = ConvertTenthsMMToPixels(dc, pos);
|
|
7062
|
|
- tabArray[i] = pos;
|
|
7063
|
|
- }
|
|
|
7088
|
+ int backgroundWidth = endpos[endpos.GetCount() - 1] - startpos[0] + 1; // Avoid kerning gaps
|
|
|
7089
|
+ wxDCBrushChanger autobrush(dc, wxBrush(txtBackClr));
|
|
|
7090
|
+ wxDCPenChanger autopen(dc, wxPen(txtBackClr));
|
|
|
7091
|
+ dc.DrawRectangle(startpos[0], y, backgroundWidth, dc.GetTextExtent(str).y);
|
|
|
7092
|
+ txtBackMod = wxBRUSHSTYLE_TRANSPARENT;
|
|
7064
|
7093
|
}
|
|
7065
|
|
- else
|
|
7066
|
|
- tabCount = 0;
|
|
7067
|
7094
|
|
|
7068
|
|
- wxCoord w, h;
|
|
|
7095
|
+ ///////////////////////////////////////////////////////////////////////////
|
|
|
7096
|
+ // Mac: Draw selection rectangle //
|
|
|
7097
|
+ ///////////////////////////////////////////////////////////////////////////
|
|
7069
|
7098
|
|
|
7070
|
|
- if (selected)
|
|
|
7099
|
+ if (0 <= selStart && selStart <= selEnd && selEnd < endpos.GetCount())
|
|
7071
|
7100
|
{
|
|
7072
|
|
- wxColour highlightColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
|
|
7073
|
|
- wxColour highlightTextColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
|
|
7074
|
|
-
|
|
7075
|
|
- wxCheckSetBrush(dc, wxBrush(highlightColour));
|
|
7076
|
|
- wxCheckSetPen(dc, wxPen(highlightColour));
|
|
7077
|
|
- dc.SetTextForeground(highlightTextColour);
|
|
7078
|
|
- dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
|
|
|
7101
|
+ int selectionWidth = endpos[selEnd] - startpos[selStart] + 1; // Avoid kerning gaps
|
|
|
7102
|
+ wxDCBrushChanger autobrush(dc, wxBrush(selClr));
|
|
|
7103
|
+ wxDCPenChanger autopen(dc, wxPen(selClr));
|
|
|
7104
|
+ dc.DrawRectangle(startpos[selStart], rect.y, selectionWidth, rect.GetHeight());
|
|
7079
|
7105
|
}
|
|
7080
|
|
- else
|
|
|
7106
|
+#else
|
|
|
7107
|
+ // If str is entirely selected or not selected at all, we can print it
|
|
|
7108
|
+ // out in just one DrawText() call. However, if it's PARTIALLY selected,
|
|
|
7109
|
+ // we will need separate DrawText() calls. The easiest way to do this is
|
|
|
7110
|
+ // to call ourselves re-entrantly on (1) text before the selection,
|
|
|
7111
|
+ // (2) selected text, and (3) text after the selection.
|
|
|
7112
|
+ //
|
|
|
7113
|
+ // TODO: When dealing with combined LTR and RTL text there will be a
|
|
|
7114
|
+ // portion of selected text that is not contiguous with the rest, so we
|
|
|
7115
|
+ // will need to fix that eventually. E.g., if the first six characters of
|
|
|
7116
|
+ // "Yes, حبيبي, of course" are selected, then the selection rectangle(s)
|
|
|
7117
|
+ // will cover the underlined characters: Yes, حبيبي, of course
|
|
|
7118
|
+ // ----- -
|
|
|
7119
|
+ if (selStart == -1 && selEnd == -1)
|
|
7081
|
7120
|
{
|
|
7082
|
|
- dc.SetTextForeground(attr.GetTextColour());
|
|
|
7121
|
+ // Nothing is selected; leave existing setup in place.
|
|
|
7122
|
+ }
|
|
7083
|
7123
|
|
|
7084
|
|
- if (attr.HasFlag(wxTEXT_ATTR_BACKGROUND_COLOUR) && attr.GetBackgroundColour().IsOk())
|
|
7085
|
|
- {
|
|
7086
|
|
- dc.SetBackgroundMode(wxBRUSHSTYLE_SOLID);
|
|
7087
|
|
- dc.SetTextBackground(attr.GetBackgroundColour());
|
|
7088
|
|
- }
|
|
7089
|
|
- else
|
|
7090
|
|
- dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
|
|
|
7124
|
+ else if (selStart == 0 && selEnd == (static_cast<ssize_t>(str.length()) - 1))
|
|
|
7125
|
+ {
|
|
|
7126
|
+ // Everything is selected; change the colors we'll use to draw text.
|
|
|
7127
|
+ txtForeClr = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
|
|
|
7128
|
+ txtBackClr = selClr;
|
|
|
7129
|
+ txtBackMod = wxBRUSHSTYLE_SOLID;
|
|
7091
|
7130
|
}
|
|
7092
|
7131
|
|
|
7093
|
|
- wxCoord x_orig = GetParent()->GetPosition().x;
|
|
7094
|
|
- while (hasTabs)
|
|
|
7132
|
+ else
|
|
7095
|
7133
|
{
|
|
7096
|
|
- // the string has a tab
|
|
7097
|
|
- // break up the string at the Tab
|
|
7098
|
|
- wxString stringChunk = str.BeforeFirst(wxT('\t'));
|
|
7099
|
|
- str = str.AfterFirst(wxT('\t'));
|
|
7100
|
|
- dc.GetTextExtent(stringChunk, & w, & h);
|
|
7101
|
|
- int tabPos;
|
|
7102
|
|
- tabPos = x + w;
|
|
7103
|
|
- bool not_found = true;
|
|
7104
|
|
- for (int i = 0; i < tabCount && not_found; ++i)
|
|
7105
|
|
- {
|
|
7106
|
|
- int nextTabPos;
|
|
7107
|
|
- nextTabPos = tabArray.Item(i) + x_orig;
|
|
|
7134
|
+ // Partial selection; break it up into component parts.
|
|
|
7135
|
+ wxString selPrefix = str.Mid(0, selStart);
|
|
|
7136
|
+ wxString selString = str.Mid(selStart, selEnd - selStart + 1);
|
|
|
7137
|
+ wxString selSuffix = str.Mid(selEnd + 1);
|
|
7108
|
7138
|
|
|
7109
|
|
- // Find the next tab position.
|
|
7110
|
|
- // Even if we're at the end of the tab array, we must still draw the chunk.
|
|
|
7139
|
+ if (!selPrefix.empty())
|
|
|
7140
|
+ DrawTabbedString(dc, attr, rect, selPrefix, x, y, -1, -1);
|
|
7111
|
7141
|
|
|
7112
|
|
- if (nextTabPos > tabPos || (i == (tabCount - 1)))
|
|
7113
|
|
- {
|
|
7114
|
|
- if (nextTabPos <= tabPos)
|
|
7115
|
|
- {
|
|
7116
|
|
- int defaultTabWidth = ConvertTenthsMMToPixels(dc, WIDTH_FOR_DEFAULT_TABS);
|
|
7117
|
|
- nextTabPos = tabPos + defaultTabWidth;
|
|
7118
|
|
- }
|
|
|
7142
|
+ x = startpos[selStart];
|
|
7119
|
7143
|
|
|
7120
|
|
- not_found = false;
|
|
7121
|
|
- if (selected)
|
|
7122
|
|
- {
|
|
7123
|
|
- w = nextTabPos - x;
|
|
7124
|
|
- wxRect selRect(x, rect.y, w, rect.GetHeight());
|
|
7125
|
|
- dc.DrawRectangle(selRect);
|
|
7126
|
|
- }
|
|
7127
|
|
- dc.DrawText(stringChunk, x, y);
|
|
|
7144
|
+ if (!selString.empty())
|
|
|
7145
|
+ DrawTabbedString(dc, attr, rect, selString, x, y, 0, selString.length() - 1);
|
|
7128
|
7146
|
|
|
7129
|
|
- if (attr.HasTextEffects() && (attr.GetTextEffects() & wxTEXT_ATTR_EFFECT_STRIKETHROUGH))
|
|
7130
|
|
- {
|
|
7131
|
|
- wxPen oldPen = dc.GetPen();
|
|
7132
|
|
- wxCheckSetPen(dc, wxPen(attr.GetTextColour(), 1));
|
|
7133
|
|
- dc.DrawLine(x, (int) (y+(h/2)+0.5), x+w, (int) (y+(h/2)+0.5));
|
|
7134
|
|
- wxCheckSetPen(dc, oldPen);
|
|
7135
|
|
- }
|
|
|
7147
|
+ x = endpos[selEnd];
|
|
7136
|
7148
|
|
|
7137
|
|
- x = nextTabPos;
|
|
7138
|
|
- }
|
|
7139
|
|
- }
|
|
7140
|
|
- hasTabs = (str.Find(wxT('\t')) != wxNOT_FOUND);
|
|
|
7149
|
+ if (!selSuffix.empty())
|
|
|
7150
|
+ DrawTabbedString(dc, attr, rect, selSuffix, x, y, -1, -1);
|
|
|
7151
|
+
|
|
|
7152
|
+ return;
|
|
7141
|
7153
|
}
|
|
|
7154
|
+#endif
|
|
7142
|
7155
|
|
|
7143
|
|
- if (!str.IsEmpty())
|
|
7144
|
|
- {
|
|
7145
|
|
- dc.GetTextExtent(str, & w, & h);
|
|
7146
|
|
- if (selected)
|
|
7147
|
|
- {
|
|
7148
|
|
- wxRect selRect(x, rect.y, w, rect.GetHeight());
|
|
7149
|
|
- dc.DrawRectangle(selRect);
|
|
7150
|
|
- }
|
|
7151
|
|
- dc.DrawText(str, x, y);
|
|
|
7156
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
7157
|
+ // Draw text (and strikethrough) //
|
|
|
7158
|
+ //////////////////////////////////////////////////////////////////////////
|
|
7152
|
7159
|
|
|
7153
|
|
- if (attr.HasTextEffects() && (attr.GetTextEffects() & wxTEXT_ATTR_EFFECT_STRIKETHROUGH))
|
|
|
7160
|
+ printstart = 0;
|
|
|
7161
|
+ dc.SetBackgroundMode(txtBackMod);
|
|
|
7162
|
+ dc.SetTextBackground(txtBackClr);
|
|
|
7163
|
+ dc.SetTextForeground(txtForeClr);
|
|
|
7164
|
+ wxDCPenChanger penWithCleanup(dc, wxPen(txtForeClr)); // For strikethrough
|
|
|
7165
|
+ for (si = 0; si < str.length(); si++)
|
|
|
7166
|
+ {
|
|
|
7167
|
+ if (str[si] == '\t')
|
|
7154
|
7168
|
{
|
|
7155
|
|
- wxPen oldPen = dc.GetPen();
|
|
7156
|
|
- wxCheckSetPen(dc, wxPen(attr.GetTextColour(), 1));
|
|
7157
|
|
- dc.DrawLine(x, (int) (y+(h/2)+0.5), x+w, (int) (y+(h/2)+0.5));
|
|
7158
|
|
- wxCheckSetPen(dc, oldPen);
|
|
|
7169
|
+ if (si - printstart > 0)
|
|
|
7170
|
+ {
|
|
|
7171
|
+ dc.DrawText(str.Mid(printstart, si-printstart), startpos[printstart], y);
|
|
|
7172
|
+ if (strikethrough)
|
|
|
7173
|
+ dc.DrawLine(startpos[printstart], strikeheight, startpos[si], strikeheight);
|
|
|
7174
|
+ }
|
|
|
7175
|
+ // Match original behavior of only striking through SELECTED tabs.
|
|
|
7176
|
+ // TODO: Research and decide whether to keep doing this.
|
|
|
7177
|
+ if (selStart <= static_cast<ssize_t>(si) && static_cast<ssize_t>(si) <= selEnd && strikethrough)
|
|
|
7178
|
+ dc.DrawLine(startpos[si], strikeheight, endpos[si], strikeheight);
|
|
|
7179
|
+ printstart = si + 1;
|
|
7159
|
7180
|
}
|
|
7160
|
|
-
|
|
7161
|
|
- x += w;
|
|
7162
|
7181
|
}
|
|
7163
|
|
-
|
|
7164
|
|
- return true;
|
|
|
7182
|
+ if (printstart < str.length())
|
|
|
7183
|
+ {
|
|
|
7184
|
+ dc.DrawText(str.Mid(printstart), startpos[printstart], y);
|
|
|
7185
|
+ if (strikethrough)
|
|
|
7186
|
+ dc.DrawLine(startpos[printstart], strikeheight, endpos[endpos.GetCount()-1], strikeheight);
|
|
|
7187
|
+ }
|
|
7165
|
7188
|
}
|
|
7166
|
7189
|
|
|
7167
|
7190
|
/// Lay the item out
|