From e8872b335cb9780e228f219d6d7a2e2b79a43ac4 Mon Sep 17 00:00:00 2001 From: Tobias Fleischer Date: Sat, 26 Mar 2022 13:56:31 +0100 Subject: [PATCH] Allow using multiple lines in single line wxTextCtrl under Mac Add new OSX specific OSXEnableNewLineReplacement(bool enable) function to control if new lines should be replaced with spaces (which is still done by default) in a single-line wxTextCtrl. Closes #22245. --- include/wx/osx/cocoa/private/textimpl.h | 4 +++ include/wx/osx/core/private.h | 2 ++ include/wx/osx/textctrl.h | 1 + interface/wx/textctrl.h | 29 ++++++++++++++++++++++ src/osx/cocoa/textctrl.mm | 33 ++++++++++++++++++++++++- src/osx/textctrl_osx.cpp | 7 +++++- 6 files changed, 74 insertions(+), 2 deletions(-) diff --git a/include/wx/osx/cocoa/private/textimpl.h b/include/wx/osx/cocoa/private/textimpl.h index c6b57b5a6a..bc1112f1c3 100644 --- a/include/wx/osx/cocoa/private/textimpl.h +++ b/include/wx/osx/cocoa/private/textimpl.h @@ -81,6 +81,8 @@ public : virtual bool becomeFirstResponder(WXWidget slf, void *_cmd) wxOVERRIDE; virtual bool resignFirstResponder(WXWidget slf, void *_cmd) wxOVERRIDE; + virtual void EnableNewLineReplacement(bool enable) wxOVERRIDE; + virtual bool GetNewLineReplacement() wxOVERRIDE; virtual void SetInternalSelection( long from , long to ); virtual void UpdateInternalSelectionFromEditor( wxNSTextFieldEditor* editor); protected : @@ -133,6 +135,8 @@ public: #endif // wxUSE_SPELLCHECK virtual void EnableAutomaticQuoteSubstitution(bool enable) wxOVERRIDE; virtual void EnableAutomaticDashSubstitution(bool enable) wxOVERRIDE; + virtual void EnableNewLineReplacement(bool enable) wxOVERRIDE; + virtual bool GetNewLineReplacement() wxOVERRIDE; virtual wxSize GetBestSize() const wxOVERRIDE; virtual void SetJustification() wxOVERRIDE; diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index 4b5c3fe5ae..8d380bd56d 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -750,6 +750,8 @@ public : virtual void EnableAutomaticQuoteSubstitution(bool WXUNUSED(enable)) {} virtual void EnableAutomaticDashSubstitution(bool WXUNUSED(enable)) {} + virtual void EnableNewLineReplacement(bool WXUNUSED(enable)) {} + virtual bool GetNewLineReplacement() { return true; } virtual wxSize GetBestSize() const { return wxDefaultSize; } virtual bool SetHint(const wxString& WXUNUSED(hint)) { return false; } diff --git a/include/wx/osx/textctrl.h b/include/wx/osx/textctrl.h index 6e6a40817c..bde361ab28 100644 --- a/include/wx/osx/textctrl.h +++ b/include/wx/osx/textctrl.h @@ -143,6 +143,7 @@ public: wxDEPRECATED( virtual void MacCheckSpelling(bool check) ); #endif // WXWIN_COMPATIBILITY_3_0 && wxUSE_SPELLCHECK + void OSXEnableNewLineReplacement(bool enable); void OSXEnableAutomaticQuoteSubstitution(bool enable); void OSXEnableAutomaticDashSubstitution(bool enable); void OSXDisableAllSmartSubstitutions(); diff --git a/interface/wx/textctrl.h b/interface/wx/textctrl.h index aab53d978b..fdb1ffd8ee 100644 --- a/interface/wx/textctrl.h +++ b/interface/wx/textctrl.h @@ -1761,6 +1761,35 @@ public: */ virtual long XYToPosition(long x, long y) const; + /** + @name Mac-specific functions + */ + //@{ + + /** + Enable the automatic replacement of new lines characters in a + single-line text field with spaces under macOS. + + This feature is enabled by default and will replace any new line (`\n`) + character entered into a single-line text field with the space + character. Usually single-line text fields are not expected to hold + multiple lines of text (that is what wxTE_MULTILINE is for, after all) + and it is impossible to have multiple lines of text in them under + non-Mac platforms. However, under macOS/Cocoa, a single-line text + control can still show multiple lines and this function allows to lift + the restriction preventing multiple lines from being entered unless + wxTE_MULTILINE is specified. + + @note This function is only available for macOS/Cocoa. It also has no + effect if the wxTE_MULTILINE flag is set on a text control. + + @onlyfor{wxosx} + @since 3.1.6 + */ + virtual void OSXEnableNewLineReplacement(bool enable); + + //@} + //@{ /** Operator definitions for appending to a text control. diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm index 20beb2521c..763e43287f 100644 --- a/src/osx/cocoa/textctrl.mm +++ b/src/osx/cocoa/textctrl.mm @@ -118,6 +118,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; int maxLength; wxTextEntry* field; bool forceUpper; + bool replaceNewLine; } @end @@ -130,6 +131,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; { maxLength = 0; forceUpper = false; + replaceNewLine = true; } return self; } @@ -139,6 +141,16 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; maxLength = maxlen; } +- (void) replaceNewLine:(bool) enable +{ + replaceNewLine = enable; +} + +- (bool) getReplaceNewLine +{ + return replaceNewLine; +} + - (void) forceUpper { forceUpper = true; @@ -177,7 +189,7 @@ NSView* wxMacEditHelper::ms_viewCurrentlyEdited = nil; // wxTextEntryFormatter is always associated with single-line text entry (through wxNSTextFieldControl) // so all new line characters should be replaced with spaces (like it is done in single-line NSCell). - NSString* lineStr = [*partialStringPtr stringByReplacingOccurrencesOfString: @"\n" withString: @" "]; + NSString* lineStr = replaceNewLine ? [*partialStringPtr stringByReplacingOccurrencesOfString: @"\n" withString: @" "] : *partialStringPtr; NSString* newStr = forceUpper ? [lineStr uppercaseString] : lineStr; @@ -1327,6 +1339,15 @@ void wxNSTextViewControl::EnableAutomaticDashSubstitution(bool enable) [m_textView setAutomaticDashSubstitutionEnabled:enable]; } +void wxNSTextViewControl::EnableNewLineReplacement(bool enable) +{ +} + +bool wxNSTextViewControl::GetNewLineReplacement() +{ + return false; +} + wxSize wxNSTextViewControl::GetBestSize() const { wxSize size; @@ -1443,6 +1464,16 @@ void wxNSTextFieldControl::SetMaxLength(unsigned long len) [GetFormatter() setMaxLength:len]; } +void wxNSTextFieldControl::EnableNewLineReplacement(bool enable) +{ + [GetFormatter() replaceNewLine:enable]; +} + +bool wxNSTextFieldControl::GetNewLineReplacement() +{ + return [GetFormatter() getReplaceNewLine]; +} + void wxNSTextFieldControl::ForceUpper() { [GetFormatter() forceUpper]; diff --git a/src/osx/textctrl_osx.cpp b/src/osx/textctrl_osx.cpp index 670e4859e2..327ee21195 100644 --- a/src/osx/textctrl_osx.cpp +++ b/src/osx/textctrl_osx.cpp @@ -132,6 +132,11 @@ void wxTextCtrl::MacCheckSpelling(bool check) } #endif // WXWIN_COMPATIBILITY_3_0 && wxUSE_SPELLCHECK +void wxTextCtrl::OSXEnableNewLineReplacement(bool enable) +{ + GetTextPeer()->EnableNewLineReplacement(enable); +} + void wxTextCtrl::OSXEnableAutomaticQuoteSubstitution(bool enable) { GetTextPeer()->EnableAutomaticQuoteSubstitution(enable); @@ -458,7 +463,7 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) return; } - if ( !(m_windowStyle & wxTE_MULTILINE) ) + if ( GetTextPeer()->GetNewLineReplacement() ) { wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow); if ( tlw && tlw->GetDefaultItem() )