From 2df6eb22329eab7cfab68185c41ab2fac1076d8f Mon Sep 17 00:00:00 2001 From: Blake-Madden <66873089+Blake-Madden@users.noreply.github.com> Date: Wed, 19 Jun 2024 07:58:49 -0400 Subject: [PATCH] Add RTF support to wxTextCtrl under macOS Add function for setting and getting text control contents as RTF. For now this is only supported by wxOSX, but support for other platforms may be added in the future, so wxHAS_TEXTCTRL_RTF or IsRTFSupported() should be used to test (at compile- or run-time, respectively) whether RTF support is available. Closes #24626. --- docs/changes.txt | 5 ++ docs/doxygen/mainpages/const_cpp.h | 3 + include/wx/osx/cocoa/private/textimpl.h | 11 +++ include/wx/osx/core/private.h | 2 + include/wx/osx/iphone/private/textimpl.h | 4 ++ include/wx/osx/textctrl.h | 3 + include/wx/textctrl.h | 20 +++++- interface/wx/textctrl.h | 89 ++++++++++++++++++++++- samples/text/text.cpp | 69 +++++++++++++++++- src/common/textcmn.cpp | 91 ++++++++++++++++++++++-- src/osx/cocoa/textctrl.mm | 28 ++++++++ src/osx/iphone/textctrl.mm | 22 ++++++ src/osx/textctrl_osx.cpp | 10 +++ tests/controls/textctrltest.cpp | 24 +++++++ 14 files changed, 370 insertions(+), 11 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index a5a47c95f4..e3bb21ee47 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -99,6 +99,11 @@ Changes in behaviour not resulting in compilation errors - wxIMAGE_QUALITY_NEAREST has a different numeric value and is not the same as wxIMAGE_QUALITY_NORMAL any longer, see documentation for more details. +- wxTextCtrl::{Save,Load}File() will use RTF format when saving/loading files + with .rtf extension, and not plain text any longer, by default for the + platforms with RTF support. If you need to save/load plain text even for the + files with the .rtf extension, specify wxTEXT_TYPE_PLAIN explicitly. + Changes in behaviour which may result in build errors ----------------------------------------------------- diff --git a/docs/doxygen/mainpages/const_cpp.h b/docs/doxygen/mainpages/const_cpp.h index d9a6dc1a41..10a398fc9f 100644 --- a/docs/doxygen/mainpages/const_cpp.h +++ b/docs/doxygen/mainpages/const_cpp.h @@ -228,6 +228,9 @@ Currently the following symbols exist: symbol doesn't need to be tested any more.} @itemdef{wxHAS_SVG, Defined if SVG support (currently only via wxBitmapBundle::FromSVG()) is available.} @itemdef{wxHAS_TASK_BAR_ICON, Defined if wxTaskBarIcon is available on the current platform.} +@itemdef{wxHAS_TEXTCTRL_RTF, Defined if wxTextCtrl::SetRTFValue() and + wxTextCtrl::GetRTFValue() can be used. This constant, as well as RTF + support itself, is available since wxWidgets 3.3.0.} @itemdef{wxHAS_WINDOW_LABEL_IN_STATIC_BOX, Defined if wxStaticBox::Create() overload taking @c wxWindow* instead of the text label is available on the current platform.} @itemdef{wxHAS_MODE_T, Defined when wxWidgets defines @c mode_t typedef for the diff --git a/include/wx/osx/cocoa/private/textimpl.h b/include/wx/osx/cocoa/private/textimpl.h index c07fbedcd1..f318e852bd 100644 --- a/include/wx/osx/cocoa/private/textimpl.h +++ b/include/wx/osx/cocoa/private/textimpl.h @@ -60,6 +60,15 @@ public : virtual wxString GetStringValue() const override ; virtual void SetStringValue( const wxString &str) override ; + virtual wxString GetRTFValue() const override + { + wxFAIL_MSG("GetRTFValue() should only be used with multiline controls."); + return wxEmptyString; + } + virtual void SetRTFValue(const wxString& WXUNUSED(str)) override + { + wxFAIL_MSG("SetRTFValue() should only be used with multiline controls."); + } virtual void Copy() override ; virtual void Cut() override ; virtual void Paste() override ; @@ -110,6 +119,8 @@ public: virtual wxString GetStringValue() const override ; virtual void SetStringValue( const wxString &str) override ; + virtual wxString GetRTFValue() const override; + virtual void SetRTFValue(const wxString& str) override; virtual void Copy() override ; virtual void Cut() override ; virtual void Paste() override ; diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index f4c478497a..5eea1ad09d 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -709,6 +709,8 @@ public : virtual wxString GetStringValue() const = 0 ; virtual void SetStringValue( const wxString &val ) = 0 ; + virtual wxString GetRTFValue() const = 0; + virtual void SetRTFValue( const wxString& val ) = 0; virtual void SetSelection( long from, long to ) = 0 ; virtual void GetSelection( long* from, long* to ) const = 0 ; virtual void WriteText( const wxString& str ) = 0 ; diff --git a/include/wx/osx/iphone/private/textimpl.h b/include/wx/osx/iphone/private/textimpl.h index 3bb531192f..9466bab278 100644 --- a/include/wx/osx/iphone/private/textimpl.h +++ b/include/wx/osx/iphone/private/textimpl.h @@ -23,6 +23,8 @@ public : virtual wxString GetStringValue() const ; virtual void SetStringValue( const wxString &str) ; + virtual wxString GetRTFValue() const; + virtual void SetRTFValue(const wxString& WXUNUSED(str)); virtual void Copy() ; virtual void Cut() ; virtual void Paste() ; @@ -53,6 +55,8 @@ public: virtual wxString GetStringValue() const ; virtual void SetStringValue( const wxString &str) ; + virtual wxString GetRTFValue() const; + virtual void SetRTFValue(const wxString& WXUNUSED(str)); virtual void Copy() ; virtual void Cut() ; virtual void Paste() ; diff --git a/include/wx/osx/textctrl.h b/include/wx/osx/textctrl.h index cd5acb9d69..1dc6ea6031 100644 --- a/include/wx/osx/textctrl.h +++ b/include/wx/osx/textctrl.h @@ -109,6 +109,9 @@ public: virtual void SetWindowStyleFlag(long style) override; + virtual wxString GetRTFValue() const override; + virtual void SetRTFValue(const wxString& val) override; + // callbacks void OnDropFiles(wxDropFilesEvent& event); void OnChar(wxKeyEvent& event); // Process 'enter' if required diff --git a/include/wx/textctrl.h b/include/wx/textctrl.h index e55e5e1820..4e81eae4f7 100644 --- a/include/wx/textctrl.h +++ b/include/wx/textctrl.h @@ -103,7 +103,17 @@ const wxTextCoord wxInvalidTextCoord = -2; // wxTextCtrl file types // ---------------------------------------------------------------------------- -#define wxTEXT_TYPE_ANY 0 +// For now only wxOSX supports RTF in wxTextCtrl. +#ifdef __WXOSX__ + #define wxHAS_TEXTCTRL_RTF +#endif // __WXOSX__ + +enum wxTextCtrlFileType +{ + wxTEXT_TYPE_ANY, + wxTEXT_TYPE_PLAIN, + wxTEXT_TYPE_RTF +}; // ---------------------------------------------------------------------------- // wxTextCtrl::HitTest return values @@ -680,6 +690,14 @@ public: virtual wxString GetValue() const = 0; virtual void SetValue(const wxString& value) = 0; + // Returns whether the RTF-related functions below can be used. + static bool IsRTFSupported(); + + // Base class implementations simply assert, if IsRTFSupported() returns + // true, the port must override these functions to really implement them. + virtual wxString GetRTFValue() const; + virtual void SetRTFValue(const wxString& val); + protected: // implementation of loading/saving virtual bool DoLoadFile(const wxString& file, int fileType); diff --git a/interface/wx/textctrl.h b/interface/wx/textctrl.h index eba61160d0..c1d63a1c92 100644 --- a/interface/wx/textctrl.h +++ b/interface/wx/textctrl.h @@ -48,8 +48,40 @@ // wxTE_RICH controls - can be used together with or instead of wxTE_RICH #define wxTE_RICH2 0x8000 +/** + File types supported by wxTextCtrl::LoadFile() and wxTextCtrl::SaveFile(). -#define wxTEXT_TYPE_ANY 0 + @since 3.3.0 +*/ +enum wxTextCtrlFileType +{ + /** + Format determined by file extension when loading/saving the control's + content. + + The supported formats depend on the capabilities of the platform's + native control. + */ + wxTEXT_TYPE_ANY, + + /** + Plain Text Format. + + This format is supported under all platforms. + + @since 3.3.0 + */ + wxTEXT_TYPE_PLAIN, + + /** + Rich Text Format. + + This format is only supported under macOS currently. + + @since 3.3.0 + */ + wxTEXT_TYPE_RTF +}; /** @@ -1623,6 +1655,51 @@ public: */ virtual bool GetStyle(long position, wxTextAttr& style); + /** + Returns @c true if text controls support reading and writing RTF (Rich + Text Format). + + Currently this function only returns true in wxOSX, which is the only + port implementing RTF support in wxTextCtrl. + + @since 3.3.0 + + @see GetRTFValue(), SetRTFValue() + */ + static bool IsRTFSupported(); + + /** + Returns the content of a multiline text control as RTF (Rich Text + Formatted) text. + + Don't call this function unless IsRTFSupported() returns @true, as it + asserts if called in this case (and returns an empty string). + + @since 3.3.0 + + @see SetRTFValue() + */ + wxString GetRTFValue() const; + + /** + Sets the content of a multiline text control from an RTF (Rich Text + Formatted) buffer. + + This offers more granular control of content formatting, as well as a + significant performance benefit with larger content. This also provides + the ability to read an RTF file and move it directly into the control. + + Don't call this function unless IsRTFSupported() returns @true, as it + asserts if called in this case. + + @since 3.3.0 + + @see @ref page_samples_text for a usage example. + + @see GetRTFValue() + */ + void SetRTFValue(const wxString& val); + /** Finds the position of the character at the specified point. @@ -1723,7 +1800,10 @@ public: @param filename The filename of the file to load. @param fileType - The type of file to load. This is currently ignored in wxTextCtrl. + One of the values of wxTextCtrlFileType enum, specifying the type + of file to load. + Default value and plain text are supported on all platforms, while + ::wxTEXT_TYPE_RTF is only supported in wxOSX currently. @return @true if successful, @false otherwise. @@ -1802,7 +1882,10 @@ public: @param filename The name of the file in which to save the text. @param fileType - The type of file to save. This is currently ignored in wxTextCtrl. + One of the values of wxTextCtrlFileType enum, specifying the type + of file to save as. + Default value and plain text are supported on all platforms, while + ::wxTEXT_TYPE_RTF is only supported in wxOSX currently. @return @true if the operation was successful, @false otherwise. diff --git a/samples/text/text.cpp b/samples/text/text.cpp index 172128b090..53e9ddde7b 100644 --- a/samples/text/text.cpp +++ b/samples/text/text.cpp @@ -283,6 +283,8 @@ public: #endif // wxUSE_LOG void OnFileSave(wxCommandEvent& event); void OnFileLoad(wxCommandEvent& event); + void OnFileSaveRTF(wxCommandEvent& event); + void OnFileLoadRTF(wxCommandEvent& event); void OnRichTextTest(wxCommandEvent& event); void OnSetEditable(wxCommandEvent& event); @@ -323,6 +325,16 @@ public: m_panel->m_text->SetValue("Hello, world! (what else did you expect?)"); } + void OnSetRTF(wxCommandEvent& WXUNUSED(event)) + { + m_panel->m_textrich->SetRTFValue(R"({\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}} +{\colortbl ;\red79\green129\blue189;\red255\green0\blue0;\red192\green192\blue192;} +{\*\generator Riched20 10.0.22621}\viewkind4\uc1 + \pard\sa200\sl276\slmult1\cf1\b\i\f0\fs22\lang9 wxWidgets 3.3\cf0\b0\i0\par +\cf2 A \highlight3\ul cross-platform \highlight0\ulnone GUI library which uses \ul\b native\ulnone\b0 controls.\cf0\par +})"); + } + void OnChangeText(wxCommandEvent& WXUNUSED(event)) { m_panel->m_text->ChangeValue("Changed, not set: no event"); @@ -402,7 +414,9 @@ enum TEXT_QUIT = wxID_EXIT, TEXT_ABOUT = wxID_ABOUT, TEXT_LOAD = 101, + TEXT_LOAD_RTF, TEXT_SAVE, + TEXT_SAVE_RTF, TEXT_CLEAR, TEXT_RICH_TEXT_TEST, @@ -437,6 +451,7 @@ enum TEXT_REPLACE, TEXT_SELECT, TEXT_SET, + TEXT_SET_RTF, TEXT_CHANGE, // log menu @@ -463,6 +478,15 @@ bool MyApp::OnInit() "Save the text control contents to file"); file_menu->Append(TEXT_LOAD, "&Load file\tCtrl-O", "Load the sample file into text control"); + + if ( wxTextCtrl::IsRTFSupported() ) + { + file_menu->Append(TEXT_SAVE_RTF, "&Save file as RTF", + "Save the text control contents to file"); + file_menu->Append(TEXT_LOAD_RTF, "&Load RTF file", + "Load the sample file into text control"); + } + file_menu->AppendSeparator(); file_menu->Append(TEXT_RICH_TEXT_TEST, "Show Rich Text Editor"); file_menu->AppendSeparator(); @@ -510,6 +534,11 @@ bool MyApp::OnInit() menuText->Append(TEXT_SELECT, "&Select characters 4 to 8\tCtrl-I"); menuText->Append(TEXT_SET, "&Set the first text zone value\tCtrl-E"); menuText->Append(TEXT_CHANGE, "&Change the first text zone value\tShift-Ctrl-E"); + if ( wxTextCtrl::IsRTFSupported() ) + { + menuText->AppendSeparator(); + menuText->Append(TEXT_SET_RTF, "Set the rich text zone value from rich text formatted content"); + } menuText->AppendSeparator(); menuText->Append(TEXT_MOVE_ENDTEXT, "Move cursor to the end of &text"); menuText->Append(TEXT_MOVE_ENDENTRY, "Move cursor to the end of &entry"); @@ -1485,6 +1514,8 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(TEXT_ABOUT, MyFrame::OnAbout) EVT_MENU(TEXT_SAVE, MyFrame::OnFileSave) EVT_MENU(TEXT_LOAD, MyFrame::OnFileLoad) + EVT_MENU(TEXT_SAVE_RTF, MyFrame::OnFileSaveRTF) + EVT_MENU(TEXT_LOAD_RTF, MyFrame::OnFileLoadRTF) EVT_MENU(TEXT_RICH_TEXT_TEST, MyFrame::OnRichTextTest) EVT_MENU(TEXT_LOG_KEY, MyFrame::OnLogKey) @@ -1532,6 +1563,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(TEXT_GET_LINELENGTH, MyFrame::OnGetLineLength) EVT_MENU(TEXT_SET, MyFrame::OnSetText) + EVT_MENU(TEXT_SET_RTF, MyFrame::OnSetRTF) EVT_MENU(TEXT_CHANGE, MyFrame::OnChangeText) EVT_IDLE(MyFrame::OnIdle) @@ -1647,9 +1679,9 @@ void MyFrame::OnFileSave(wxCommandEvent& WXUNUSED(event)) // verify that the file length is correct wxFile file("dummy.txt"); wxLogStatus(this, - "Successfully saved file (text len = %lu, file size = %ld)", - (unsigned long)m_panel->m_textrich->GetValue().length(), - (long) file.Length()); + "Successfully saved file (text len = %zu, file size = %lld)", + m_panel->m_textrich->GetValue().length(), + file.Length()); #endif } else @@ -1668,6 +1700,37 @@ void MyFrame::OnFileLoad(wxCommandEvent& WXUNUSED(event)) } } +void MyFrame::OnFileSaveRTF(wxCommandEvent& WXUNUSED(event)) +{ + if ( m_panel->m_textrich->SaveFile("dummy.rtf", wxTEXT_TYPE_RTF) ) + { +#if wxUSE_FILE + // verify that the file length is correct + wxFile file("dummy.rtf"); + wxLogStatus(this, + "Successfully saved file (text len = %zu, file size = %lld)", + m_panel->m_textrich->GetValue().length(), + file.Length()); +#endif // wxUSE_FILE + } + else + { + wxLogStatus(this, "Couldn't save the file"); + } +} + +void MyFrame::OnFileLoadRTF(wxCommandEvent& WXUNUSED(event)) +{ + if ( m_panel->m_textrich->LoadFile("dummy.rtf", wxTEXT_TYPE_RTF) ) + { + wxLogStatus(this, "Successfully loaded file"); + } + else + { + wxLogStatus(this, "Couldn't load the file"); + } +} + void MyFrame::OnRichTextTest(wxCommandEvent& WXUNUSED(event)) { RichTextFrame* frame = new RichTextFrame(this, "Rich Text Editor"); diff --git a/src/common/textcmn.cpp b/src/common/textcmn.cpp index d87ff1ac2c..7ef11e3041 100644 --- a/src/common/textcmn.cpp +++ b/src/common/textcmn.cpp @@ -30,6 +30,10 @@ #include "wx/ffile.h" +#ifdef wxHAS_TEXTCTRL_RTF + #include "wx/filename.h" +#endif + extern WXDLLEXPORT_DATA(const char) wxTextCtrlNameStr[] = "text"; // ---------------------------------------------------------------------------- @@ -927,12 +931,41 @@ bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr& style) return true; } +// static +bool wxTextAreaBase::IsRTFSupported() +{ +#ifdef wxHAS_TEXTCTRL_RTF + return true; +#else + return false; +#endif +} + +wxString wxTextAreaBase::GetRTFValue() const +{ + wxFAIL_MSG("Not implemented for the current platform."); + + return wxEmptyString; +} + +void wxTextAreaBase::SetRTFValue(const wxString& WXUNUSED(val)) +{ + wxFAIL_MSG("Not implemented for the current platform."); +} + // ---------------------------------------------------------------------------- // file IO functions // ---------------------------------------------------------------------------- -bool wxTextAreaBase::DoLoadFile(const wxString& filename, int WXUNUSED(fileType)) +bool wxTextAreaBase::DoLoadFile(const wxString& filename, int fileType) { +#ifndef wxHAS_TEXTCTRL_RTF + wxASSERT_MSG(fileType != wxTEXT_TYPE_RTF, "RTF support is only available on macOS."); + if (fileType == wxTEXT_TYPE_RTF) + { + return false; + } +#endif #if wxUSE_FFILE wxFFile file(filename); if ( file.IsOpened() ) @@ -940,7 +973,30 @@ bool wxTextAreaBase::DoLoadFile(const wxString& filename, int WXUNUSED(fileType) wxString text; if ( file.ReadAll(&text) ) { - SetValue(text); + switch ( fileType ) + { + case wxTEXT_TYPE_RTF: +#ifdef wxHAS_TEXTCTRL_RTF + SetRTFValue(text); +#else // !wxHAS_TEXTCTRL_RTF + wxFAIL_MSG("RTF support not available under this platform"); +#endif // wxHAS_TEXTCTRL_RTF/!wxHAS_TEXTCTRL_RTF + break; + + case wxTEXT_TYPE_ANY: +#ifdef wxHAS_TEXTCTRL_RTF + if ( wxFileName(filename).GetExt().CmpNoCase("rtf") == 0 ) + { + SetRTFValue(text); + break; + } +#endif // wxHAS_TEXTCTRL_RTF + wxFALLTHROUGH; + + case wxTEXT_TYPE_PLAIN: + SetValue(text); + break; + } DiscardEdits(); m_filename = filename; @@ -957,11 +1013,38 @@ bool wxTextAreaBase::DoLoadFile(const wxString& filename, int WXUNUSED(fileType) return false; } -bool wxTextAreaBase::DoSaveFile(const wxString& filename, int WXUNUSED(fileType)) +bool wxTextAreaBase::DoSaveFile(const wxString& filename, int fileType) { #if wxUSE_FFILE wxFFile file(filename, wxT("w")); - if ( file.IsOpened() && file.Write(GetValue()) ) + + wxString value; + switch ( fileType ) + { + case wxTEXT_TYPE_RTF: +#ifdef wxHAS_TEXTCTRL_RTF + value = GetRTFValue(); +#else // !wxHAS_TEXTCTRL_RTF + wxFAIL_MSG("RTF support not available under this platform"); +#endif // wxHAS_TEXTCTRL_RTF/!wxHAS_TEXTCTRL_RTF + break; + + case wxTEXT_TYPE_ANY: +#ifdef wxHAS_TEXTCTRL_RTF + if ( wxFileName(filename).GetExt().CmpNoCase("rtf") == 0 ) + { + value = GetRTFValue(); + break; + } +#endif // wxHAS_TEXTCTRL_RTF + wxFALLTHROUGH; + + case wxTEXT_TYPE_PLAIN: + value = GetValue(); + break; + } + + if ( file.IsOpened() && file.Write(value) ) { // if it worked, save for future calls m_filename = filename; diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm index 7e1dc183eb..be363e6479 100644 --- a/src/osx/cocoa/textctrl.mm +++ b/src/osx/cocoa/textctrl.mm @@ -840,6 +840,34 @@ void wxNSTextViewControl::SetStringValue( const wxString &str) } } +wxString wxNSTextViewControl::GetRTFValue() const +{ + if (m_textView) + { + NSData* rtfData = [m_textView RTFFromRange:NSMakeRange(0, [[m_textView textStorage] length])]; + NSMutableString* rtfString = [[NSMutableString alloc] initWithData:rtfData encoding:NSASCIIStringEncoding]; + wxString result = wxMacConvertNewlines13To10(wxCFStringRef::AsString(rtfString)); + [rtfString release]; + return result; + } + return wxEmptyString; +} + +void wxNSTextViewControl::SetRTFValue(const wxString &str) +{ + wxString st = wxMacConvertNewlines10To13(str); + wxMacEditHelper helper(m_textView); + + if (m_textView) + { + [m_textView setString: wxCFStringRef( wxEmptyString ).AsNSString()]; + NSData* rtfData=[wxCFStringRef( st ).AsNSString() dataUsingEncoding:NSASCIIStringEncoding]; + [m_textView replaceCharactersInRange:NSMakeRange(0, 0) withRTF:rtfData]; + } + // Some text styles have to be updated manually. + DoUpdateTextStyle(); +} + void wxNSTextViewControl::Copy() { if (m_textView) diff --git a/src/osx/iphone/textctrl.mm b/src/osx/iphone/textctrl.mm index 695ef6353a..ba2037f52c 100644 --- a/src/osx/iphone/textctrl.mm +++ b/src/osx/iphone/textctrl.mm @@ -348,6 +348,17 @@ void wxUITextViewControl::SetStringValue( const wxString &str) } } +wxString wxUITextViewControl::GetRTFValue() const +{ + wxFAIL_MSG("GetRTFValue() should only be used with multiline controls."); + return wxEmptyString; +} + +void wxUITextViewControl::SetRTFValue(const wxString &str) +{ + wxFAIL_MSG("SetRTFValue() should only be used with multiline controls."); +} + void wxUITextViewControl::Copy() { if (m_textView) @@ -555,6 +566,17 @@ void wxUITextFieldControl::SetStringValue( const wxString &str) [m_textField setText: wxCFStringRef( str ).AsNSString()]; } +wxString wxUITextFieldControl::GetRTFValue() const +{ + wxFAIL_MSG("GetRTFValue() should only be used with multiline controls."); + return wxEmptyString; +} + +void wxUITextFieldControl::SetRTFValue(const wxString &str) +{ + wxFAIL_MSG("SetRTFValue() should only be used with multiline controls."); +} + wxSize wxUITextFieldControl::GetBestSize() const { wxRect r; diff --git a/src/osx/textctrl_osx.cpp b/src/osx/textctrl_osx.cpp index 5d41fcdc38..d4b788f582 100644 --- a/src/osx/textctrl_osx.cpp +++ b/src/osx/textctrl_osx.cpp @@ -149,6 +149,16 @@ void wxTextCtrl::OSXDisableAllSmartSubstitutions() OSXEnableAutomaticQuoteSubstitution(false); } +wxString wxTextCtrl::GetRTFValue() const +{ + return GetTextPeer()->GetRTFValue(); +} + +void wxTextCtrl::SetRTFValue(const wxString& val) +{ + GetTextPeer()->SetRTFValue(val); +} + bool wxTextCtrl::SetFont( const wxFont& font ) { if ( !wxTextCtrlBase::SetFont( font ) ) diff --git a/tests/controls/textctrltest.cpp b/tests/controls/textctrltest.cpp index 123e4f5fb6..a4bc72eb15 100644 --- a/tests/controls/textctrltest.cpp +++ b/tests/controls/textctrltest.cpp @@ -1463,6 +1463,30 @@ TEST_CASE("wxTextCtrl::EventsOnCreate", "[wxTextCtrl][event]") CHECK( updated.GetCount() == 1 ); } +#ifdef __WXOSX__ +TEST_CASE("wxTextCtrl::Get/SetRTFValue", "[wxTextCtrl][rtf]") +{ + wxWindow* const parent = wxTheApp->GetTopWindow(); + + std::unique_ptr text(new wxTextCtrl(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_RICH2 | wxTE_MULTILINE)); + + text->SetRTFValue(R"({\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}} +{\colortbl ;\red192\green80\blue77;} +{\*\generator Riched20 10.0.22621}\viewkind4\uc1 + \pard\sa200\sl276\slmult1\b\i\f0\fs22\lang9 wxWidg\'e9ts \cf1\i0 3.3\cf0\b0\par +})"); + // test getting the main text, including an extended ASCII character + wxString result = text->GetValue(); + CHECK(result.find(L"wxWidgéts") != wxString::npos); + CHECK(result.find(L"3.3") != wxString::npos); + + result = text->GetRTFValue(); + // 'é' will be encoded, just see if parts of the content are in there + CHECK(result.find(L"wxWidg") != wxString::npos); + CHECK(result.find(L"3.3") != wxString::npos); +} +#endif + TEST_CASE("wxTextCtrl::InitialCanUndo", "[wxTextCtrl][undo]") { long style = 0;