diff --git a/include/wx/textctrl.h b/include/wx/textctrl.h
index 341409530e..22792af375 100644
--- a/include/wx/textctrl.h
+++ b/include/wx/textctrl.h
@@ -270,6 +270,14 @@ enum wxTextAttrLineSpacing
wxTEXT_ATTR_LINE_SPACING_TWICE = 20
};
+enum wxTextAttrUnderlineType
+{
+ wxTEXT_ATTR_UNDERLINE_NONE,
+ wxTEXT_ATTR_UNDERLINE_SOLID,
+ wxTEXT_ATTR_UNDERLINE_DOUBLE,
+ wxTEXT_ATTR_UNDERLINE_SPECIAL
+};
+
// ----------------------------------------------------------------------------
// wxTextAttr: a structure containing the visual attributes of a text
// ----------------------------------------------------------------------------
@@ -320,7 +328,13 @@ public:
void SetFontStyle(wxFontStyle fontStyle) { m_fontStyle = fontStyle; m_flags |= wxTEXT_ATTR_FONT_ITALIC; }
void SetFontWeight(wxFontWeight fontWeight) { m_fontWeight = fontWeight; m_flags |= wxTEXT_ATTR_FONT_WEIGHT; }
void SetFontFaceName(const wxString& faceName) { m_fontFaceName = faceName; m_flags |= wxTEXT_ATTR_FONT_FACE; }
- void SetFontUnderlined(bool underlined) { m_fontUnderlined = underlined; m_flags |= wxTEXT_ATTR_FONT_UNDERLINE; }
+ void SetFontUnderlined(bool underlined) { SetFontUnderlined(underlined ? wxTEXT_ATTR_UNDERLINE_SOLID : wxTEXT_ATTR_UNDERLINE_NONE); }
+ void SetFontUnderlined(wxTextAttrUnderlineType type, const wxColour& colour = wxNullColour)
+ {
+ m_flags |= wxTEXT_ATTR_FONT_UNDERLINE;
+ m_fontUnderlineType = type;
+ m_colUnderline = colour;
+ }
void SetFontStrikethrough(bool strikethrough) { m_fontStrikethrough = strikethrough; m_flags |= wxTEXT_ATTR_FONT_STRIKETHROUGH; }
void SetFontEncoding(wxFontEncoding encoding) { m_fontEncoding = encoding; m_flags |= wxTEXT_ATTR_FONT_ENCODING; }
void SetFontFamily(wxFontFamily family) { m_fontFamily = family; m_flags |= wxTEXT_ATTR_FONT_FAMILY; }
@@ -359,7 +373,9 @@ public:
int GetFontSize() const { return m_fontSize; }
wxFontStyle GetFontStyle() const { return m_fontStyle; }
wxFontWeight GetFontWeight() const { return m_fontWeight; }
- bool GetFontUnderlined() const { return m_fontUnderlined; }
+ bool GetFontUnderlined() const { return m_fontUnderlineType != wxTEXT_ATTR_UNDERLINE_NONE; }
+ wxTextAttrUnderlineType GetUnderlineType() const { return m_fontUnderlineType; }
+ const wxColour& GetUnderlineColour() const { return m_colUnderline; }
bool GetFontStrikethrough() const { return m_fontStrikethrough; }
const wxString& GetFontFaceName() const { return m_fontFaceName; }
wxFontEncoding GetFontEncoding() const { return m_fontEncoding; }
@@ -508,7 +524,8 @@ private:
wxFontStyle m_fontStyle;
wxFontWeight m_fontWeight;
wxFontFamily m_fontFamily;
- bool m_fontUnderlined;
+ wxTextAttrUnderlineType m_fontUnderlineType;
+ wxColour m_colUnderline;
bool m_fontStrikethrough;
wxString m_fontFaceName;
diff --git a/interface/wx/textctrl.h b/interface/wx/textctrl.h
index 3bf15e7e5e..7ebd41d347 100644
--- a/interface/wx/textctrl.h
+++ b/interface/wx/textctrl.h
@@ -219,6 +219,19 @@ enum wxTextAttrLineSpacing
};
+/**
+ Underline types that can be used in wxTextAttr::SetFontUnderline().
+
+ @since 3.1.3
+*/
+enum wxTextAttrUnderlineType
+{
+ wxTEXT_ATTR_UNDERLINE_NONE,
+ wxTEXT_ATTR_UNDERLINE_SOLID,
+ wxTEXT_ATTR_UNDERLINE_DOUBLE,
+ wxTEXT_ATTR_UNDERLINE_SPECIAL
+};
+
/**
Describes the possible return values of wxTextCtrl::HitTest().
@@ -422,6 +435,20 @@ public:
*/
bool GetFontUnderlined() const;
+ /**
+ Returns the underline type, which is one of the @wxTextAttrUnderlineType values.
+
+ @since 3.1.3
+ */
+ wxTextAttrUnderlineType GetUnderlineType() const;
+
+ /**
+ Returns the underline color used. wxNullColour when the text colour is used.
+
+ @since 3.1.3
+ */
+ const wxColour& GetUnderlineColour() const;
+
/**
Returns the font weight.
*/
@@ -803,10 +830,34 @@ public:
void SetFontStyle(wxFontStyle fontStyle);
/**
- Sets the font underlining.
+ Sets the font underlining (solid line, text colour).
*/
void SetFontUnderlined(bool underlined);
+ /**
+ Sets the font underlining.
+
+ @param type Type of underline.
+
+ @param colour Colour to use for underlining, text colour is used by
+ default.
+
+ @note On wxMSW, wxTEXT_ATTR_UNDERLINE_DOUBLE is shown as
+ wxTEXT_ATTR_UNDERLINE_SOLID. There is only a limited number of colours
+ supported, the RGB values are listed
+ here.
+ wxTEXT_ATTR_UNDERLINE_SPECIAL is shown as a waved line.
+
+ @note On wxGTK, underline colour is only supported by wxGTK3.
+ wxTEXT_ATTR_UNDERLINE_SPECIAL is shown as a waved line. GTK might
+ overrule the colour of wxTEXT_ATTR_UNDERLINE_SPECIAL.
+
+ @note On wxOSX, wxTEXT_ATTR_UNDERLINE_SPECIAL is shown as a dotted line.
+
+ @since 3.1.3
+ */
+ void SetFontUnderlined(wxTextAttrUnderlineType type, const wxColour& colour = wxNullColour);
+
/**
Sets the font weight.
*/
diff --git a/samples/text/text.cpp b/samples/text/text.cpp
index 7e5256b0b9..f4ee6f9038 100644
--- a/samples/text/text.cpp
+++ b/samples/text/text.cpp
@@ -1228,8 +1228,24 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
m_textrich->AppendText("This text should be cyan on blue\n");
m_textrich->SetDefaultStyle(wxTextAttr(*wxBLUE, *wxWHITE));
m_textrich->AppendText("And this should be in blue and the text you "
- "type should be in blue as well");
-
+ "type should be in blue as well.\n");
+ m_textrich->SetDefaultStyle(wxTextAttr());
+ wxTextAttr attr = m_textrich->GetDefaultStyle();
+ attr.SetFontUnderlined(true);
+ m_textrich->SetDefaultStyle(attr);
+ m_textrich->AppendText("\nAnd there");
+ attr.SetFontUnderlined(false);
+ m_textrich->SetDefaultStyle(attr);
+ m_textrich->AppendText(" is a ");
+ attr.SetFontUnderlined(wxTEXT_ATTR_UNDERLINE_SPECIAL, *wxRED);
+ m_textrich->SetDefaultStyle(attr);
+ m_textrich->AppendText("mispeled");
+ attr.SetFontUnderlined(false);
+ m_textrich->SetDefaultStyle(attr);
+ m_textrich->AppendText(" word.");
+ attr.SetFontUnderlined(wxTEXT_ATTR_UNDERLINE_DOUBLE, *wxGREEN);
+ const long endPos = m_textrich->GetLastPosition();
+ m_textrich->SetStyle(endPos - 4, endPos - 2, attr);
// lay out the controls
wxBoxSizer *column1 = new wxBoxSizer(wxVERTICAL);
diff --git a/src/common/textcmn.cpp b/src/common/textcmn.cpp
index 2774635bbe..9f8de569bd 100644
--- a/src/common/textcmn.cpp
+++ b/src/common/textcmn.cpp
@@ -162,7 +162,7 @@ void wxTextAttr::Init()
m_fontSize = 12;
m_fontStyle = wxFONTSTYLE_NORMAL;
m_fontWeight = wxFONTWEIGHT_NORMAL;
- m_fontUnderlined = false;
+ m_fontUnderlineType = wxTEXT_ATTR_UNDERLINE_NONE;
m_fontStrikethrough = false;
m_fontEncoding = wxFONTENCODING_DEFAULT;
m_fontFamily = wxFONTFAMILY_DEFAULT;
@@ -175,6 +175,7 @@ void wxTextAttr::Init()
m_textEffectFlags = wxTEXT_ATTR_EFFECT_NONE;
m_outlineLevel = 0;
m_bulletNumber = 0;
+ m_colUnderline = wxNullColour;
}
// Copy
@@ -192,7 +193,8 @@ void wxTextAttr::Copy(const wxTextAttr& attr)
m_fontSize = attr.m_fontSize;
m_fontStyle = attr.m_fontStyle;
m_fontWeight = attr.m_fontWeight;
- m_fontUnderlined = attr.m_fontUnderlined;
+ m_fontUnderlineType = attr.m_fontUnderlineType;
+ m_colUnderline = attr.m_colUnderline;
m_fontStrikethrough = attr.m_fontStrikethrough;
m_fontFaceName = attr.m_fontFaceName;
m_fontEncoding = attr.m_fontEncoding;
@@ -257,7 +259,7 @@ bool wxTextAttr::operator== (const wxTextAttr& attr) const
(!HasFontSize() || (GetFontSize() == attr.GetFontSize())) &&
(!HasFontItalic() || (GetFontStyle() == attr.GetFontStyle())) &&
(!HasFontWeight() || (GetFontWeight() == attr.GetFontWeight())) &&
- (!HasFontUnderlined() || (GetFontUnderlined() == attr.GetFontUnderlined())) &&
+ (!HasFontUnderlined() || ((GetUnderlineType() == attr.GetUnderlineType()) && (GetUnderlineColour() == attr.GetUnderlineColour()) )) &&
(!HasFontStrikethrough() || (GetFontStrikethrough() == attr.GetFontStrikethrough())) &&
(!HasFontFaceName() || (GetFontFaceName() == attr.GetFontFaceName())) &&
(!HasFontEncoding() || (GetFontEncoding() == attr.GetFontEncoding())) &&
@@ -327,7 +329,8 @@ bool wxTextAttr::EqPartial(const wxTextAttr& attr, bool weakTest) const
if (HasFontItalic() && attr.HasFontItalic() && GetFontStyle() != attr.GetFontStyle())
return false;
- if (HasFontUnderlined() && attr.HasFontUnderlined() && GetFontUnderlined() != attr.GetFontUnderlined())
+ if (HasFontUnderlined() && attr.HasFontUnderlined() &&
+ ( (GetUnderlineType() != attr.GetUnderlineType()) || (GetUnderlineColour() != attr.GetUnderlineColour()) ))
return false;
if (HasFontStrikethrough() && attr.HasFontStrikethrough() && GetFontStrikethrough() != attr.GetFontStrikethrough())
@@ -502,7 +505,7 @@ bool wxTextAttr::GetFontAttributes(const wxFont& font, int flags)
m_fontWeight = font.GetWeight();
if (flags & wxTEXT_ATTR_FONT_UNDERLINE)
- m_fontUnderlined = font.GetUnderlined();
+ m_fontUnderlineType = font.GetUnderlined() ? wxTEXT_ATTR_UNDERLINE_SOLID : wxTEXT_ATTR_UNDERLINE_NONE;
if (flags & wxTEXT_ATTR_FONT_STRIKETHROUGH)
m_fontStrikethrough = font.GetStrikethrough();
@@ -571,8 +574,10 @@ bool wxTextAttr::Apply(const wxTextAttr& style, const wxTextAttr* compareWith)
if (style.HasFontUnderlined())
{
- if (!(compareWith && compareWith->HasFontUnderlined() && compareWith->GetFontUnderlined() == style.GetFontUnderlined()))
- destStyle.SetFontUnderlined(style.GetFontUnderlined());
+ if (!(compareWith && compareWith->HasFontUnderlined() &&
+ compareWith->GetUnderlineType() == style.GetUnderlineType() &&
+ compareWith->GetUnderlineColour() == style.GetUnderlineColour()))
+ destStyle.SetFontUnderlined(style.GetUnderlineType(), style.GetUnderlineColour());
}
if (style.HasFontStrikethrough())
@@ -791,6 +796,8 @@ wxTextAttr wxTextAttr::Combine(const wxTextAttr& attr,
}
wxTextAttr newAttr(colFg, colBg, font);
+ if (attr.HasFontUnderlined())
+ newAttr.SetFontUnderlined(attr.GetUnderlineType(), attr.GetUnderlineColour());
if (attr.HasAlignment())
newAttr.SetAlignment(attr.GetAlignment());
diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp
index b19a3f5367..9a7e12f5e3 100644
--- a/src/gtk/textctrl.cpp
+++ b/src/gtk/textctrl.cpp
@@ -124,6 +124,57 @@ static void wxGtkTextApplyTagsFromAttr(GtkWidget *text,
}
}
+ if ( attr.HasFontUnderlined() )
+ {
+ PangoUnderline pangoUnderlineStyle = PANGO_UNDERLINE_NONE;
+ switch ( attr.GetUnderlineType() )
+ {
+ case wxTEXT_ATTR_UNDERLINE_SOLID:
+ pangoUnderlineStyle = PANGO_UNDERLINE_SINGLE;
+ break;
+ case wxTEXT_ATTR_UNDERLINE_DOUBLE:
+ pangoUnderlineStyle = PANGO_UNDERLINE_DOUBLE;
+ break;
+ case wxTEXT_ATTR_UNDERLINE_SPECIAL:
+ pangoUnderlineStyle = PANGO_UNDERLINE_ERROR;
+ break;
+ default:
+ pangoUnderlineStyle = PANGO_UNDERLINE_NONE;
+ break;
+ }
+
+ g_snprintf(buf, sizeof(buf), "WXFONTUNDERLINESTYLE %u",
+ (unsigned)pangoUnderlineStyle);
+ tag = gtk_text_tag_table_lookup( gtk_text_buffer_get_tag_table( text_buffer ),
+ buf );
+ if (!tag)
+ tag = gtk_text_buffer_create_tag( text_buffer, buf,
+ "underline-set", TRUE,
+ "underline", pangoUnderlineStyle,
+ NULL );
+ gtk_text_buffer_apply_tag (text_buffer, tag, start, end);
+
+#ifdef __WXGTK3__
+ if ( wx_is_at_least_gtk3(16) )
+ {
+ wxColour colour = attr.GetUnderlineColour();
+ if ( colour.IsOk() )
+ {
+ g_snprintf(buf, sizeof(buf), "WXFONTUNDERLINECOLOUR %u %u %u %u",
+ colour.Red(), colour.Green(), colour.Blue(), colour.Alpha());
+ tag = gtk_text_tag_table_lookup( gtk_text_buffer_get_tag_table( text_buffer ),
+ buf );
+ if (!tag)
+ tag = gtk_text_buffer_create_tag( text_buffer, buf,
+ "underline-rgba-set", TRUE,
+ "underline-rgba", static_cast(colour),
+ NULL );
+ gtk_text_buffer_apply_tag (text_buffer, tag, start, end);
+ }
+ }
+#endif
+ }
+
if (attr.HasTextColour())
{
wxGtkTextRemoveTagsWithPrefix(text_buffer, "WXFORECOLOR", start, end);
@@ -1845,8 +1896,48 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style)
if ( font.SetNativeFontInfo(wxString(pangoFontString)) )
style.SetFont(font);
- if ( pattr->appearance.underline != PANGO_UNDERLINE_NONE )
- style.SetFontUnderlined(true);
+ wxTextAttrUnderlineType underlineType = wxTEXT_ATTR_UNDERLINE_NONE;
+ switch ( pattr->appearance.underline )
+ {
+ case PANGO_UNDERLINE_SINGLE:
+ underlineType = wxTEXT_ATTR_UNDERLINE_SOLID;
+ break;
+ case PANGO_UNDERLINE_DOUBLE:
+ underlineType = wxTEXT_ATTR_UNDERLINE_DOUBLE;
+ break;
+ case PANGO_UNDERLINE_ERROR:
+ underlineType = wxTEXT_ATTR_UNDERLINE_SPECIAL;
+ break;
+ default:
+ underlineType = wxTEXT_ATTR_UNDERLINE_NONE;
+ break;
+ }
+
+ wxColour underlineColour = wxNullColour;
+#ifdef __WXGTK3__
+ GSList* tags = gtk_text_iter_get_tags(&positioni);
+ for ( GSList* tagp = tags; tagp != NULL; tagp = tagp->next )
+ {
+ GtkTextTag* tag = static_cast(tagp->data);
+ gboolean underlineSet = FALSE;
+ g_object_get(tag, "underline-rgba-set", &underlineSet, NULL);
+ if ( underlineSet )
+ {
+ GdkRGBA* gdkColour = NULL;
+ g_object_get(tag, "underline-rgba", &gdkColour, NULL);
+ if ( gdkColour )
+ underlineColour = wxColour(*gdkColour);
+ gdk_rgba_free(gdkColour);
+ break;
+ }
+ }
+ if ( tags )
+ g_slist_free(tags);
+#endif
+
+ if ( underlineType != wxTEXT_ATTR_UNDERLINE_NONE )
+ style.SetFontUnderlined(underlineType, underlineColour);
+
if ( pattr->appearance.strikethrough )
style.SetFontStrikethrough(true);
diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp
index 9044420c46..2110fb4d6a 100644
--- a/src/msw/textctrl.cpp
+++ b/src/msw/textctrl.cpp
@@ -81,6 +81,27 @@
#define CFE_AUTOBACKCOLOR 0x04000000
#endif
+// missing defines for MinGW build
+#ifndef CFM_UNDERLINETYPE
+ #define CFM_UNDERLINETYPE 0x00800000
+#endif
+
+#ifndef CFU_UNDERLINENONE
+ #define CFU_UNDERLINENONE 0
+#endif
+
+#ifndef CFU_UNDERLINE
+ #define CFU_UNDERLINE 1
+#endif
+
+#ifndef CFU_UNDERLINEDOUBLE
+ #define CFU_UNDERLINEDOUBLE 3
+#endif
+
+#ifndef CFU_UNDERLINEWAVE
+ #define CFU_UNDERLINEWAVE 8
+#endif
+
#if wxUSE_DRAG_AND_DROP && wxUSE_RICHEDIT
// dummy value used for m_dropTarget, different from any valid pointer value
@@ -2795,6 +2816,30 @@ bool wxTextCtrl::SetFont(const wxFont& font)
// styling support for rich edit controls
// ----------------------------------------------------------------------------
+#if _RICHEDIT_VER >= 0x0800
+static const wxColour gs_underlineColourMap[] =
+{
+ // The colours are coming from https://docs.microsoft.com/en-us/windows/desktop/api/tom/nf-tom-itextdocument2-geteffectcolor.
+ wxNullColour, // text colour
+ wxColour(0, 0, 0 ), // black
+ wxColour(0, 0, 255), // blue
+ wxColour(0, 255, 255), // cyan
+ wxColour(0, 255, 0 ), // green
+ wxColour(255, 0, 255), // magenta
+ wxColour(255, 0, 0 ), // red
+ wxColour(255, 255, 0 ), // yellow
+ wxColour(255, 255, 255), // white
+ wxColour(0, 0, 128), // navy
+ wxColour(0, 128, 128), // teal
+ wxColour(0, 128, 0 ), // light green
+ wxColour(128, 0, 128), // purple
+ wxColour(128, 0, 0 ), // maroon
+ wxColour(128, 128, 0 ), // olive
+ wxColour(128, 128, 128), // grey
+ wxColour(192, 192, 192), // light grey
+};
+#endif
+
bool wxTextCtrl::MSWSetCharFormat(const wxTextAttr& style, long start, long end)
{
// initialize CHARFORMAT struct
@@ -2865,6 +2910,42 @@ bool wxTextCtrl::MSWSetCharFormat(const wxTextAttr& style, long start, long end)
}
}
+ if ( style.HasFontUnderlined() )
+ {
+ cf.dwMask |= CFM_UNDERLINETYPE;
+ BYTE underlineType = CFU_UNDERLINENONE;
+ switch ( style.GetUnderlineType() )
+ {
+ case wxTEXT_ATTR_UNDERLINE_SOLID:
+ underlineType = CFU_UNDERLINE;
+ break;
+ case wxTEXT_ATTR_UNDERLINE_DOUBLE:
+ underlineType = CFU_UNDERLINEDOUBLE;
+ break;
+ case wxTEXT_ATTR_UNDERLINE_SPECIAL:
+ underlineType = CFU_UNDERLINEWAVE;
+ break;
+ default:
+ underlineType = CFU_UNDERLINENONE;
+ break;
+ }
+ cf.bUnderlineType = underlineType;
+
+#if _RICHEDIT_VER >= 0x0800
+ BYTE colour = 0;
+ const wxColour& col = style.GetUnderlineColour();
+ for ( size_t c = 0; c < WXSIZEOF(gs_underlineColourMap); ++c )
+ {
+ if ( col == gs_underlineColourMap[c] )
+ {
+ colour = static_cast(c);
+ break;
+ }
+ }
+ cf.bUnderlineColor = colour;
+#endif
+ }
+
if ( style.HasTextColour() )
{
cf.dwMask |= CFM_COLOR;
@@ -3028,7 +3109,7 @@ bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
// even try to do anything if it's the only thing we want to change
if ( m_verRichEdit == 1 && !style.HasFont() && !style.HasTextColour() &&
!style.HasLeftIndent() && !style.HasRightIndent() && !style.HasAlignment() &&
- !style.HasTabs() )
+ !style.HasTabs() && !style.GetFontUnderlined() )
{
// nothing to do: return true if there was really nothing to do and
// false if we failed to set bg colour
@@ -3181,6 +3262,32 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style)
}
#endif // wxUSE_RICHEDIT2
+ wxTextAttrUnderlineType underlineType = wxTEXT_ATTR_UNDERLINE_NONE;
+ switch ( cf.bUnderlineType )
+ {
+ case CFU_UNDERLINE:
+ underlineType = wxTEXT_ATTR_UNDERLINE_SOLID;
+ break;
+ case CFU_UNDERLINEDOUBLE:
+ underlineType = wxTEXT_ATTR_UNDERLINE_DOUBLE;
+ break;
+ case CFU_UNDERLINEWAVE:
+ underlineType = wxTEXT_ATTR_UNDERLINE_SPECIAL;
+ break;
+ default:
+ underlineType = wxTEXT_ATTR_UNDERLINE_NONE;
+ break;
+ }
+
+ wxColour underlineColour;
+#if _RICHEDIT_VER >= 0x0800
+ if ( cf.bUnderlineColor < WXSIZEOF(gs_underlineColourMap) )
+ underlineColour = gs_underlineColourMap[cf.bUnderlineColor];
+#endif
+
+ if ( underlineType != wxTEXT_ATTR_UNDERLINE_NONE )
+ style.SetFontUnderlined(underlineType, underlineColour);
+
// now get the paragraph formatting
PARAFORMAT2 pf;
wxZeroMemory(pf);
diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm
index 089a1eef7c..27581dae19 100644
--- a/src/osx/cocoa/textctrl.mm
+++ b/src/osx/cocoa/textctrl.mm
@@ -128,7 +128,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil;
@implementation wxTextEntryFormatter
-- (id)init
+- (id)init
{
if ( self = [super init] )
{
@@ -138,7 +138,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil;
return self;
}
-- (void) setMaxLength:(int) maxlen
+- (void) setMaxLength:(int) maxlen
{
maxLength = maxlen;
}
@@ -155,13 +155,13 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil;
return [NSString stringWithString:anObject];
}
-- (BOOL)getObjectValue:(id *)obj forString:(NSString *)string errorDescription:(NSString **)error
+- (BOOL)getObjectValue:(id *)obj forString:(NSString *)string errorDescription:(NSString **)error
{
*obj = [NSString stringWithString:string];
return YES;
}
-- (BOOL)isPartialStringValid:(NSString **)partialStringPtr proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
+- (BOOL)isPartialStringValid:(NSString **)partialStringPtr proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
originalString:(NSString *)origString originalSelectedRange:(NSRange)origSelRange errorDescription:(NSString **)error
{
if ( maxLength > 0 )
@@ -226,9 +226,9 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil;
- (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector
{
wxUnusedVar(textView);
-
+
BOOL handled = NO;
-
+
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( control );
if ( impl )
{
@@ -322,7 +322,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil;
}
}
}
-
+
return handled;
}
@@ -406,7 +406,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil;
BOOL r = [super becomeFirstResponder];
if ( impl != NULL && r )
impl->DoNotifyFocusSet();
-
+
return r;
}
@@ -653,11 +653,11 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil;
{
wxUnusedVar(textView);
wxUnusedVar(control);
-
+
BOOL handled = NO;
// send back key events wx' common code knows how to handle
-
+
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
if ( impl )
{
@@ -681,7 +681,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil;
}
}
}
-
+
return handled;
}
@@ -740,7 +740,7 @@ wxNSTextViewControl::wxNSTextViewControl( wxTextCtrl *wxPeer, WXWidget w, long s
[tv setVerticallyResizable:YES];
[tv setHorizontallyResizable:hasHScroll];
[tv setAutoresizingMask:NSViewWidthSizable];
-
+
if ( hasHScroll )
{
[[tv textContainer] setContainerSize:NSMakeSize(MAX_WIDTH, MAX_WIDTH)];
@@ -1036,19 +1036,23 @@ void wxNSTextViewControl::SetFont( const wxFont & font , const wxColour& WXUNUSE
bool wxNSTextViewControl::GetStyle(long position, wxTextAttr& style)
{
if (m_textView && position >=0)
- {
+ {
NSFont* font = NULL;
NSColor* bgcolor = NULL;
NSColor* fgcolor = NULL;
+ NSNumber* ultype = NULL;
+ NSColor* ulcolor = NULL;
// NOTE: It appears that other platforms accept GetStyle with the position == length
// but that NSTextStorage does not accept length as a valid position.
// Therefore we return the default control style in that case.
- if (position < (long) [[m_textView string] length])
+ if (position < (long) [[m_textView string] length])
{
NSTextStorage* storage = [m_textView textStorage];
font = [storage attribute:NSFontAttributeName atIndex:position effectiveRange:NULL];
bgcolor = [storage attribute:NSBackgroundColorAttributeName atIndex:position effectiveRange:NULL];
fgcolor = [storage attribute:NSForegroundColorAttributeName atIndex:position effectiveRange:NULL];
+ ultype = [storage attribute:NSUnderlineStyleAttributeName atIndex:position effectiveRange:NULL];
+ ulcolor = [storage attribute:NSUnderlineColorAttributeName atIndex:position effectiveRange:NULL];
}
else
{
@@ -1056,16 +1060,47 @@ bool wxNSTextViewControl::GetStyle(long position, wxTextAttr& style)
font = [attrs objectForKey:NSFontAttributeName];
bgcolor = [attrs objectForKey:NSBackgroundColorAttributeName];
fgcolor = [attrs objectForKey:NSForegroundColorAttributeName];
+ ultype = [attrs objectForKey:NSUnderlineStyleAttributeName];
+ ulcolor = [attrs objectForKey:NSUnderlineColorAttributeName];
}
-
+
if (font)
style.SetFont(wxFont(font));
-
+
if (bgcolor)
style.SetBackgroundColour(wxColour(bgcolor));
-
+
if (fgcolor)
style.SetTextColour(wxColour(fgcolor));
+
+ wxTextAttrUnderlineType underlineType = wxTEXT_ATTR_UNDERLINE_NONE;
+ if ( ultype )
+ {
+ NSInteger ulval = [ultype integerValue];
+ switch ( ulval )
+ {
+ case NSUnderlineStyleSingle:
+ underlineType = wxTEXT_ATTR_UNDERLINE_SOLID;
+ break;
+ case NSUnderlineStyleDouble:
+ underlineType = wxTEXT_ATTR_UNDERLINE_DOUBLE;
+ break;
+ case NSUnderlineStyleSingle | NSUnderlinePatternDot:
+ underlineType = wxTEXT_ATTR_UNDERLINE_SPECIAL;
+ break;
+ default:
+ underlineType = wxTEXT_ATTR_UNDERLINE_NONE;
+ break;
+ }
+ }
+
+ wxColour underlineColour;
+ if ( ulcolor )
+ underlineColour = wxColour(ulcolor);
+
+ if ( underlineType != wxTEXT_ATTR_UNDERLINE_NONE )
+ style.SetFontUnderlined(underlineType, underlineColour);
+
return true;
}
@@ -1082,14 +1117,38 @@ void wxNSTextViewControl::SetStyle(long start,
if ( start == -1 && end == -1 )
{
NSMutableDictionary* const
- attrs = [NSMutableDictionary dictionaryWithCapacity:3];
+ attrs = [NSMutableDictionary dictionaryWithCapacity:5];
if ( style.HasFont() )
[attrs setValue:style.GetFont().OSXGetNSFont() forKey:NSFontAttributeName];
if ( style.HasBackgroundColour() )
[attrs setValue:style.GetBackgroundColour().OSXGetNSColor() forKey:NSBackgroundColorAttributeName];
if ( style.HasTextColour() )
[attrs setValue:style.GetTextColour().OSXGetNSColor() forKey:NSForegroundColorAttributeName];
-
+ if ( style.HasFontUnderlined() )
+ {
+ int underlineStyle = NSUnderlineStyleNone;
+ switch ( style.GetUnderlineType() )
+ {
+ case wxTEXT_ATTR_UNDERLINE_SOLID:
+ underlineStyle = NSUnderlineStyleSingle;
+ break;
+ case wxTEXT_ATTR_UNDERLINE_DOUBLE:
+ underlineStyle = NSUnderlineStyleDouble;
+ break;
+ case wxTEXT_ATTR_UNDERLINE_SPECIAL:
+ underlineStyle = NSUnderlineStyleSingle | NSUnderlinePatternDot;
+ break;
+ default:
+ underlineStyle = NSUnderlineStyleNone;
+ break;
+ }
+ [attrs setObject:[NSNumber numberWithInt:( underlineStyle )] forKey:NSUnderlineStyleAttributeName];
+ wxColour colour = style.GetUnderlineColour();
+ if ( colour.IsOk() )
+ {
+ [attrs setValue:colour.OSXGetNSColor() forKey:NSUnderlineColorAttributeName];
+ }
+ }
[m_textView setTypingAttributes:attrs];
}
else // Set the attributes just for this range.
@@ -1105,8 +1164,37 @@ void wxNSTextViewControl::SetStyle(long start,
if ( style.HasTextColour() )
[storage addAttribute:NSForegroundColorAttributeName value:style.GetTextColour().OSXGetNSColor() range:range];
+
+ if( style.HasFontUnderlined() )
+ {
+ NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
+ int underlineStyle = NSUnderlineStyleNone;
+ switch ( style.GetUnderlineType() )
+ {
+ case wxTEXT_ATTR_UNDERLINE_SOLID:
+ underlineStyle = NSUnderlineStyleSingle;
+ break;
+ case wxTEXT_ATTR_UNDERLINE_DOUBLE:
+ underlineStyle = NSUnderlineStyleDouble;
+ break;
+ case wxTEXT_ATTR_UNDERLINE_SPECIAL:
+ underlineStyle = NSUnderlineStyleSingle | NSUnderlinePatternDot;
+ break;
+ default:
+ underlineStyle = NSUnderlineStyleNone;
+ break;
+ }
+ [dict setObject:[NSNumber numberWithInt:( underlineStyle )] forKey:NSUnderlineStyleAttributeName];
+ wxColour colour = style.GetUnderlineColour();
+ if ( colour.IsOk() )
+ {
+ [dict setValue:colour.OSXGetNSColor() forKey:NSUnderlineColorAttributeName];
+ }
+ [storage addAttributes:dict range:range];
+ [dict release];
+ }
}
-
+
if ( style.HasAlignment() )
{
switch ( style.GetAlignment() )
@@ -1510,7 +1598,7 @@ wxWidgetImplType* wxWidgetImpl::CreateTextControl( wxTextCtrl* wxpeer,
{
[v setAlignment:NSCenterTextAlignment];
}
-
+
NSTextFieldCell* cell = [v cell];
[cell setWraps:NO];
[cell setScrollable:YES];