Suppress clang-tidy warnings about freed memory in wxCharBuffer
These warnings seem bogus as clang-tidy provides the following
explanation for them:
include/wx/buffer.h:156:44: warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]
const CharType *data() const { return m_data->Get(); }
^
include/wx/buffer.h:127:9: note: Calling 'wxScopedCharTypeBuffer::DecRef'
DecRef();
^~~~~~~~
include/wx/buffer.h:194:14: note: Assuming the condition is false
if ( m_data == GetNullData() ) // exception, not ref-counted
^~~~~~~~~~~~~~~~~~~~~~~
include/wx/buffer.h:194:9: note: Taking false branch
if ( m_data == GetNullData() ) // exception, not ref-counted
^
include/wx/buffer.h:196:14: note: Assuming the condition is true
if ( --m_data->m_ref == 0 )
^~~~~~~~~~~~~~~~~~~~
include/wx/buffer.h:196:9: note: Taking true branch
if ( --m_data->m_ref == 0 )
^
include/wx/buffer.h:197:13: note: Memory is released
delete m_data;
^~~~~~~~~~~~~
include/wx/buffer.h:127:9: note: Returning; memory was released
DecRef();
^~~~~~~~
which assumes that the reference count became 0, and thus data was
freed, while it's still used, which means that the reference count is
non-zero.
Suppress the warnings to allow applications using clang-tidy to avoid
this warning whenever they use wxCharBuffer (possibly implicitly).
Improve wxWebView and wxWebViewChromium documentation Expand the description of wxWebView::GetNativeBackend(). Note that EVT_WEBVIEW_CREATED is available only since wxWidgets 3.3. Add references to relevant classes and methods. Improve wording and formatting. Mention that other versions of CEF may work. Closes #24752.
Add unit test for ellipse boundary pixels Add test verifying that the ellipse is drawn in the expected way, even if this is not really intuitive because it can overflow its bounding rectangle. Closes #24620.
Add RTF support to wxMSW wxTextCtrl too Make IsRTFSupported() non-static function as RTF is only supported by some (rich), but not all, wxTextCtrls under Windows. Closes #24718.
Fix wxDataViewCtrl border in dark mode under MSW Using wxBORDER_THEME for this control looked bad and was inconsistent with wxTreeCtrl, so stop doing it by overriding CanApplyThemeBorder() to return false for it, as it's already done for many standard controls in wxMSW. It might be better to remove CanApplyThemeBorder() entirely and stop using wxBORDER_THEME for windows by default in wxMSW, as it might be unnecessary with modern Windows versions, but for now make just this minimal change. Closes #24624.
| ... | ... | @@ -211,7 +211,17 @@ public: |
| 211 | 211 | DecRef();
|
| 212 | 212 | }
|
| 213 | 213 | |
| 214 | + // For some reasong clang-tidy gives a warning about using freed memory
|
|
| 215 | + // here even when this is not at all the case, seemingly because it doesn't
|
|
| 216 | + // follow reference counting logic, i.e. it assumes that it's possible to
|
|
| 217 | + // delete the data even when it's still referenced.
|
|
| 218 | + //
|
|
| 219 | + // Suppress the warning as it's extremely annoying to get it for every use
|
|
| 220 | + // of wxCharBuffer.
|
|
| 221 | + //
|
|
| 222 | + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDelete)
|
|
| 214 | 223 | CharType *data() { return m_data->Get(); }
|
| 224 | + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDelete)
|
|
| 215 | 225 | const CharType *data() const { return m_data->Get(); }
|
| 216 | 226 | operator const CharType *() const { return data(); }
|
| 217 | 227 | CharType operator[](size_t n) const { return data()[n]; }
|
| ... | ... | @@ -40,6 +40,12 @@ public: |
| 40 | 40 | virtual wxString GetValue() const override;
|
| 41 | 41 | virtual wxString GetRange(long from, long to) const override;
|
| 42 | 42 | |
| 43 | +#if wxUSE_RICHEDIT
|
|
| 44 | + virtual wxString GetRTFValue() const override;
|
|
| 45 | + virtual void SetRTFValue(const wxString& val) override;
|
|
| 46 | + virtual bool IsRTFSupported() override { return IsRich(); }
|
|
| 47 | +#endif // wxUSE_RICHEDIT
|
|
| 48 | + |
|
| 43 | 49 | virtual bool IsEmpty() const;
|
| 44 | 50 | |
| 45 | 51 | virtual void WriteText(const wxString& text) override;
|
| ... | ... | @@ -718,6 +718,8 @@ public : |
| 718 | 718 | virtual bool CanClipMaxLength() const { return false; }
|
| 719 | 719 | virtual void SetMaxLength(unsigned long WXUNUSED(len)) {}
|
| 720 | 720 | |
| 721 | + virtual bool IsRTFSupported() { return false; }
|
|
| 722 | + |
|
| 721 | 723 | virtual bool CanForceUpper() { return false; }
|
| 722 | 724 | virtual void ForceUpper() {}
|
| 723 | 725 |
| ... | ... | @@ -111,6 +111,7 @@ public: |
| 111 | 111 | |
| 112 | 112 | virtual wxString GetRTFValue() const override;
|
| 113 | 113 | virtual void SetRTFValue(const wxString& val) override;
|
| 114 | + virtual bool IsRTFSupported() override { return IsMultiLine(); }
|
|
| 114 | 115 | |
| 115 | 116 | // callbacks
|
| 116 | 117 | void OnDropFiles(wxDropFilesEvent& event);
|
| ... | ... | @@ -72,6 +72,9 @@ public: |
| 72 | 72 | DoEnableSystemTheme(enable, this);
|
| 73 | 73 | }
|
| 74 | 74 | |
| 75 | + // Using wxBORDER_THEME is unnecessary and looks bad for these controls.
|
|
| 76 | + virtual bool CanApplyThemeBorder() const override { return false; }
|
|
| 77 | + |
|
| 75 | 78 | protected:
|
| 76 | 79 | void EnableSystemThemeByDefault()
|
| 77 | 80 | {
|
| ... | ... | @@ -103,10 +103,10 @@ const wxTextCoord wxInvalidTextCoord = -2; |
| 103 | 103 | // wxTextCtrl file types
|
| 104 | 104 | // ----------------------------------------------------------------------------
|
| 105 | 105 | |
| 106 | -// For now only wxOSX supports RTF in wxTextCtrl.
|
|
| 107 | -#ifdef __WXOSX__
|
|
| 106 | +// wxOSX and wxMSW support RTF in wxTextCtrl.
|
|
| 107 | +#if defined(__WXOSX__) || (defined(__WXMSW__) && wxUSE_RICHEDIT)
|
|
| 108 | 108 | #define wxHAS_TEXTCTRL_RTF
|
| 109 | -#endif // __WXOSX__
|
|
| 109 | +#endif
|
|
| 110 | 110 | |
| 111 | 111 | enum wxTextCtrlFileType
|
| 112 | 112 | {
|
| ... | ... | @@ -691,7 +691,7 @@ public: |
| 691 | 691 | virtual void SetValue(const wxString& value) = 0;
|
| 692 | 692 | |
| 693 | 693 | // Returns whether the RTF-related functions below can be used.
|
| 694 | - static bool IsRTFSupported();
|
|
| 694 | + virtual bool IsRTFSupported() { return false; }
|
|
| 695 | 695 | |
| 696 | 696 | // Base class implementations simply assert, if IsRTFSupported() returns
|
| 697 | 697 | // true, the port must override these functions to really implement them.
|
| ... | ... | @@ -76,7 +76,7 @@ enum wxTextCtrlFileType |
| 76 | 76 | /**
|
| 77 | 77 | Rich Text Format.
|
| 78 | 78 | |
| 79 | - This format is only supported under macOS currently.
|
|
| 79 | + This format is only supported under macOS and MSW.
|
|
| 80 | 80 | |
| 81 | 81 | @since 3.3.0
|
| 82 | 82 | */
|
| ... | ... | @@ -1659,14 +1659,15 @@ public: |
| 1659 | 1659 | Returns @c true if text controls support reading and writing RTF (Rich
|
| 1660 | 1660 | Text Format).
|
| 1661 | 1661 | |
| 1662 | - Currently this function only returns true in wxOSX, which is the only
|
|
| 1663 | - port implementing RTF support in wxTextCtrl.
|
|
| 1662 | + This function only returns @true in wxOSX (for multiline contrls) and
|
|
| 1663 | + wxMSW (for rich controls), which are the only ports implementing
|
|
| 1664 | + RTF support in wxTextCtrl.
|
|
| 1664 | 1665 | |
| 1665 | 1666 | @since 3.3.0
|
| 1666 | 1667 | |
| 1667 | 1668 | @see GetRTFValue(), SetRTFValue()
|
| 1668 | 1669 | */
|
| 1669 | - static bool IsRTFSupported();
|
|
| 1670 | + bool IsRTFSupported();
|
|
| 1670 | 1671 | |
| 1671 | 1672 | /**
|
| 1672 | 1673 | Returns the content of a multiline text control as RTF (Rich Text
|
| ... | ... | @@ -176,7 +176,7 @@ enum wxWebViewIE_EmulationLevel |
| 176 | 176 | |
| 177 | 177 | Sample JavaScript opening a new window:
|
| 178 | 178 | @code
|
| 179 | - window.open("http://www.wxwidgets.org", "newWindow", "width=400,height=400");
|
|
| 179 | + window.open("https://www.wxwidgets.org", "newWindow", "width=400,height=400");
|
|
| 180 | 180 | @endcode
|
| 181 | 181 | |
| 182 | 182 | Sample C++ code handling a new window request:
|
| ... | ... | @@ -201,7 +201,7 @@ enum wxWebViewIE_EmulationLevel |
| 201 | 201 | wxWebView* childWebView = features->GetChildWebView();
|
| 202 | 202 | // Place the child web view into the window
|
| 203 | 203 | childWebView->Create(win, wxID_ANY);
|
| 204 | - sizer->Add(childWebView, 1, wxEXPAND);
|
|
| 204 | + sizer->Add(childWebView, wxSizerFlags().Proportion(1).Expand());
|
|
| 205 | 205 | }
|
| 206 | 206 | @endcode
|
| 207 | 207 | |
| ... | ... | @@ -274,7 +274,7 @@ class WXDLLIMPEXP_WEBVIEW wxWebViewConfiguration |
| 274 | 274 | {
|
| 275 | 275 | public:
|
| 276 | 276 | /**
|
| 277 | - Return the pointer to the native configuration used during creation of
|
|
| 277 | + Returns the pointer to the native configuration used during creation of
|
|
| 278 | 278 | a wxWebView.
|
| 279 | 279 | |
| 280 | 280 | When using two-step creation this method can be used to customize
|
| ... | ... | @@ -288,7 +288,7 @@ public: |
| 288 | 288 | wxWebView::New().
|
| 289 | 289 | |
| 290 | 290 | The return value needs to be down-casted to the appropriate type
|
| 291 | - depending on the platform:
|
|
| 291 | + depending on the backend:
|
|
| 292 | 292 | - macOS:
|
| 293 | 293 | <a href="https://developer.apple.com/documentation/webkit/wkwebviewconfiguration">WKWebViewConfiguration</a>
|
| 294 | 294 | pointer,
|
| ... | ... | @@ -304,7 +304,7 @@ public: |
| 304 | 304 | web view:
|
| 305 | 305 | @code
|
| 306 | 306 | #if defined(__WXMSW__)
|
| 307 | - #include "webview2EnvironmentOptions.h"
|
|
| 307 | + #include <webview2EnvironmentOptions.h>
|
|
| 308 | 308 | #elif defined(__WXOSX__)
|
| 309 | 309 | #import "WebKit/WebKit.h"
|
| 310 | 310 | #endif
|
| ... | ... | @@ -325,7 +325,7 @@ public: |
| 325 | 325 | webView->Create(this, wxID_ANY, "https://www.wxwidgets.org");
|
| 326 | 326 | @endcode
|
| 327 | 327 | */
|
| 328 | - virtual void* GetNativeConfiguration() const { return nullptr; }
|
|
| 328 | + virtual void* GetNativeConfiguration() const;
|
|
| 329 | 329 | |
| 330 | 330 | /**
|
| 331 | 331 | Returns the backend identifier for which this configuration was created.
|
| ... | ... | @@ -398,7 +398,7 @@ public: |
| 398 | 398 | @return The url of the request. Can be modified by the backend for
|
| 399 | 399 | compatibility.
|
| 400 | 400 | */
|
| 401 | - virtual wxString GetURI() const { return GetRawURI(); }
|
|
| 401 | + virtual wxString GetURI() const;
|
|
| 402 | 402 | |
| 403 | 403 | /**
|
| 404 | 404 | @return The body data of the request of @c null if nothing was posted.
|
| ... | ... | @@ -441,7 +441,7 @@ class WXDLLIMPEXP_WEBVIEW wxWebViewHandlerResponseData |
| 441 | 441 | {
|
| 442 | 442 | public:
|
| 443 | 443 | /**
|
| 444 | - @return returns pointer to the stream.
|
|
| 444 | + @return A pointer to the stream.
|
|
| 445 | 445 | |
| 446 | 446 | @see wxWebViewHandlerResponse::Finish()
|
| 447 | 447 | */
|
| ... | ... | @@ -575,7 +575,7 @@ public: |
| 575 | 575 | /**
|
| 576 | 576 | Function to create a new wxWebView with two-step creation,
|
| 577 | 577 | wxWebView::Create should be called on the returned object.
|
| 578 | - @return the created wxWebView
|
|
| 578 | + @return The created wxWebView.
|
|
| 579 | 579 | */
|
| 580 | 580 | virtual wxWebView* Create() = 0;
|
| 581 | 581 | |
| ... | ... | @@ -584,7 +584,7 @@ public: |
| 584 | 584 | with a wxWebViewConfiguration, wxWebView::Create should be
|
| 585 | 585 | called on the returned object.
|
| 586 | 586 | |
| 587 | - @return the created wxWebView
|
|
| 587 | + @return The created wxWebView.
|
|
| 588 | 588 | @since 3.3.0
|
| 589 | 589 | |
| 590 | 590 | @see CreateConfiguration()
|
| ... | ... | @@ -600,8 +600,8 @@ public: |
| 600 | 600 | @param size Size of the control
|
| 601 | 601 | @param style
|
| 602 | 602 | Window style. For generic window styles, please see wxWindow.
|
| 603 | - @param name Window name.
|
|
| 604 | - @return the created wxWebView
|
|
| 603 | + @param name Window name
|
|
| 604 | + @return The created wxWebView
|
|
| 605 | 605 | */
|
| 606 | 606 | virtual wxWebView* Create(wxWindow* parent,
|
| 607 | 607 | wxWindowID id,
|
| ... | ... | @@ -615,7 +615,7 @@ public: |
| 615 | 615 | wxWebView implementation can use this function to check all
|
| 616 | 616 | runtime requirements without trying to create a wxWebView.
|
| 617 | 617 | |
| 618 | - @return returns @true if the backend can be used or @false if it is
|
|
| 618 | + @return @true if the backend can be used or @false if it is
|
|
| 619 | 619 | not available during runtime.
|
| 620 | 620 | |
| 621 | 621 | @since 3.1.5
|
| ... | ... | @@ -890,11 +890,14 @@ public: |
| 890 | 890 | The predefined @c wxWebViewBackendWebKit constant contains the name of this
|
| 891 | 891 | backend.
|
| 892 | 892 | |
| 893 | - @par wxWEBVIEW_CHROMIUM (MSW, OSX, GTK)
|
|
| 893 | + @subsection wxWEBVIEW_CHROMIUM wxWEBVIEW_CHROMIUM (MSW, macOS, GTK)
|
|
| 894 | 894 | |
| 895 | 895 | The Chromium Embedded Framework backend has to be enabled when building wxWidgets,
|
| 896 | 896 | see wxWebViewChromium for additional usage and build instructions.
|
| 897 | 897 | |
| 898 | + The predefined @c wxWebViewBackendChromium constant contains the name of this
|
|
| 899 | + backend.
|
|
| 900 | + |
|
| 898 | 901 | @section async Asynchronous Notifications
|
| 899 | 902 | |
| 900 | 903 | Many of the methods in wxWebView are asynchronous, i.e. they return
|
| ... | ... | @@ -920,7 +923,7 @@ public: |
| 920 | 923 | |
| 921 | 924 | wxWebViewArchiveHandler is provided to allow the navigation of pages inside a zip
|
| 922 | 925 | archive. It supports paths of the form:
|
| 923 | - @c scheme:///C:/example/docs.zip;protocol=zip/main.htm
|
|
| 926 | + `scheme:///C:/example/docs.zip;protocol=zip/main.htm`
|
|
| 924 | 927 | |
| 925 | 928 | @beginEventEmissionTable{wxWebViewEvent}
|
| 926 | 929 | @event{EVT_WEBVIEW_CREATED(id, func)}
|
| ... | ... | @@ -928,6 +931,7 @@ public: |
| 928 | 931 | fully initialized. For the backends using asynchronous initialization,
|
| 929 | 932 | such as wxWebViewChromium, most of this class member functions can be
|
| 930 | 933 | only used once this event is received.
|
| 934 | + Available only in wxWidgets 3.3.0 or later.
|
|
| 931 | 935 | @event{EVT_WEBVIEW_NAVIGATING(id, func)}
|
| 932 | 936 | Process a @c wxEVT_WEBVIEW_NAVIGATING event, generated before trying
|
| 933 | 937 | to get a resource. This event may be vetoed to prevent navigating to this
|
| ... | ... | @@ -957,33 +961,33 @@ public: |
| 957 | 961 | Process a @c wxEVT_WEBVIEW_NEWWINDOW_FEATURES event, generated when
|
| 958 | 962 | window features are available for the new window. For usage
|
| 959 | 963 | details see wxWebViewWindowFeatures.
|
| 960 | - only available in wxWidgets 3.3.0 or later.
|
|
| 964 | + Available only in wxWidgets 3.3.0 or later.
|
|
| 961 | 965 | @event{EVT_WEBVIEW_WINDOW_CLOSE_REQUESTED(id, func)}
|
| 962 | 966 | Process a @c wxEVT_WEBVIEW_WINDOW_CLOSE_REQUESTED event, generated when
|
| 963 | 967 | a window is requested to be closed.
|
| 964 | - only available in wxWidgets 3.3.0 or later.
|
|
| 968 | + Available only in wxWidgets 3.3.0 or later.
|
|
| 965 | 969 | @event{EVT_WEBVIEW_TITLE_CHANGED(id, func)}
|
| 966 | 970 | Process a @c wxEVT_WEBVIEW_TITLE_CHANGED event, generated when
|
| 967 | 971 | the page title changes. Use GetString to get the title.
|
| 968 | 972 | @event{EVT_WEBVIEW_FULLSCREEN_CHANGED(id, func)}
|
| 969 | 973 | Process a @c wxEVT_WEBVIEW_FULLSCREEN_CHANGED event, generated when
|
| 970 | 974 | the page wants to enter or leave fullscreen. Use GetInt to get the status.
|
| 971 | - Not implemented for the IE backend
|
|
| 972 | - and is only available in wxWidgets 3.1.5 or later.
|
|
| 975 | + Not implemented for the IE backend.
|
|
| 976 | + Available only in wxWidgets 3.1.5 or later.
|
|
| 973 | 977 | @event{EVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED(id, func)}
|
| 974 | - Process a @c wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED event
|
|
| 975 | - only available in wxWidgets 3.1.5 or later. For usage details see
|
|
| 978 | + Process a @c wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED event.
|
|
| 979 | + Available only in wxWidgets 3.1.5 or later. For usage details see
|
|
| 976 | 980 | AddScriptMessageHandler().
|
| 977 | 981 | @event{EVT_WEBVIEW_SCRIPT_RESULT(id, func)}
|
| 978 | - Process a @c wxEVT_WEBVIEW_SCRIPT_RESULT event
|
|
| 979 | - only available in wxWidgets 3.1.6 or later. For usage details see
|
|
| 982 | + Process a @c wxEVT_WEBVIEW_SCRIPT_RESULT event.
|
|
| 983 | + Available only in wxWidgets 3.1.6 or later. For usage details see
|
|
| 980 | 984 | RunScriptAsync().
|
| 981 | 985 | @endEventTable
|
| 982 | 986 | |
| 983 | 987 | @since 2.9.3
|
| 984 | 988 | @library{wxwebview}
|
| 985 | 989 | @category{ctrl,webview}
|
| 986 | - @see wxWebViewHandler, wxWebViewEvent
|
|
| 990 | + @see wxWebViewEvent, wxWebViewConfiguration, wxWebViewHandler
|
|
| 987 | 991 | */
|
| 988 | 992 | class wxWebView : public wxControl
|
| 989 | 993 | {
|
| ... | ... | @@ -1010,9 +1014,7 @@ public: |
| 1010 | 1014 | Factory function to create a new wxWebView with two-step creation,
|
| 1011 | 1015 | wxWebView::Create should be called on the returned object.
|
| 1012 | 1016 | @param backend The backend web rendering engine to use.
|
| 1013 | - @c wxWebViewBackendDefault, @c wxWebViewBackendIE and
|
|
| 1014 | - @c wxWebViewBackendWebKit are predefined where appropriate.
|
|
| 1015 | - @return The created wxWebView
|
|
| 1017 | + @return The created wxWebView.
|
|
| 1016 | 1018 | @since 2.9.5
|
| 1017 | 1019 | */
|
| 1018 | 1020 | static wxWebView* New(const wxString& backend = wxWebViewBackendDefault);
|
| ... | ... | @@ -1113,9 +1115,39 @@ public: |
| 1113 | 1115 | |
| 1114 | 1116 | This method can be used to retrieve the pointer to the native rendering
|
| 1115 | 1117 | engine used by this control. The return value needs to be down-casted
|
| 1116 | - to the appropriate type depending on the platform: under Windows, it's
|
|
| 1117 | - a pointer to IWebBrowser2 interface, under macOS it's a WebView pointer
|
|
| 1118 | - and under GTK it's a WebKitWebView.
|
|
| 1118 | + to the appropriate type depending on the backend:
|
|
| 1119 | + <table>
|
|
| 1120 | + <tr>
|
|
| 1121 | + <th>Backend</th>
|
|
| 1122 | + <th>Platform</th>
|
|
| 1123 | + <th>Type</th>
|
|
| 1124 | + </tr>
|
|
| 1125 | + <tr>
|
|
| 1126 | + <td>wxWEBVIEW_BACKEND_IE</td>
|
|
| 1127 | + <td>MSW</td>
|
|
| 1128 | + <td><a href="https://learn.microsoft.com/windows/win32/api/exdisp/nn-exdisp-iwebbrowser2">IWebBrowser2</a></td>
|
|
| 1129 | + </tr>
|
|
| 1130 | + <tr>
|
|
| 1131 | + <td>wxWEBVIEW_BACKEND_EDGE</td>
|
|
| 1132 | + <td>MSW</td>
|
|
| 1133 | + <td><a href="https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2_2">ICoreWebView2_2</a></td>
|
|
| 1134 | + </tr>
|
|
| 1135 | + <tr>
|
|
| 1136 | + <td>wxWEBVIEW_WEBKIT2</td>
|
|
| 1137 | + <td>GTK3</td>
|
|
| 1138 | + <td><a href="https://webkitgtk.org/reference/webkitgtk/stable/class.WebView.html">WebKitWebView</a></td>
|
|
| 1139 | + </tr>
|
|
| 1140 | + <tr>
|
|
| 1141 | + <td>wxWEBVIEW_WEBKIT</td>
|
|
| 1142 | + <td>macOS</td>
|
|
| 1143 | + <td><a href="https://developer.apple.com/documentation/webkit/wkwebview">WKWebView</a></td>
|
|
| 1144 | + </tr>
|
|
| 1145 | + <tr>
|
|
| 1146 | + <td>wxWEBVIEW_CHROMIUM</td>
|
|
| 1147 | + <td>MSW, macOS, GTK</td>
|
|
| 1148 | + <td><a href="https://cef-builds.spotifycdn.com/docs/116.0/classCefBrowser.html">CefBrowser</a></td>
|
|
| 1149 | + </tr>
|
|
| 1150 | + </table>
|
|
| 1119 | 1151 | |
| 1120 | 1152 | For example, you could set the WebKit options using this method:
|
| 1121 | 1153 | @code
|
| ... | ... | @@ -1132,6 +1164,7 @@ public: |
| 1132 | 1164 | #endif
|
| 1133 | 1165 | @endcode
|
| 1134 | 1166 | |
| 1167 | + @see GetBackendVersionInfo()
|
|
| 1135 | 1168 | @since 2.9.5
|
| 1136 | 1169 | */
|
| 1137 | 1170 | virtual void* GetNativeBackend() const = 0;
|
| ... | ... | @@ -1379,7 +1412,7 @@ public: |
| 1379 | 1412 | Sample C++ code receiving a script message:
|
| 1380 | 1413 | @code
|
| 1381 | 1414 | // Install message handler with the name wx_msg
|
| 1382 | - m_webView->AddScriptMessageHandler('wx_msg');
|
|
| 1415 | + m_webView->AddScriptMessageHandler("wx_msg");
|
|
| 1383 | 1416 | // Bind handler
|
| 1384 | 1417 | m_webView->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, [](wxWebViewEvent& evt) {
|
| 1385 | 1418 | wxLogMessage("Script message received; value = %s, handler = %s", evt.GetString(), evt.GetMessageHandler());
|
| ... | ... | @@ -12,7 +12,8 @@ |
| 12 | 12 | Chromium Embedded Framework (CEF).
|
| 13 | 13 | |
| 14 | 14 | This backend is only available for Windows, Linux and macOS and currently
|
| 15 | - requires CEF version 116.
|
|
| 15 | + requires CEF version 116 (later, or even slightly earlier, versions may
|
|
| 16 | + work too, but compatibility with them is not guaranteed).
|
|
| 16 | 17 | |
| 17 | 18 | Using CEF also requires a compiler with C++14 support.
|
| 18 | 19 | |
| ... | ... | @@ -149,11 +150,11 @@ |
| 149 | 150 | know when it is usable.
|
| 150 | 151 | |
| 151 | 152 | |
| 152 | - __Mac OS X Platform__
|
|
| 153 | + __macOS Platform__
|
|
| 153 | 154 | |
| 154 | - OS X 10.13 or above is required.
|
|
| 155 | + macOS 10.13 or above is required.
|
|
| 155 | 156 | |
| 156 | - Due to the application bundle structure on OS X, wxWebviewChromium is a
|
|
| 157 | + Due to the application bundle structure on macOS, wxWebviewChromium is a
|
|
| 157 | 158 | little more complicated than on Windows/Linux platforms as extra helper
|
| 158 | 159 | applications for executing separate Chromium processes(renderer, plugin,
|
| 159 | 160 | etc) are required.
|
| ... | ... | @@ -479,13 +479,12 @@ bool MyApp::OnInit() |
| 479 | 479 | file_menu->Append(TEXT_LOAD, "&Load file\tCtrl-O",
|
| 480 | 480 | "Load the sample file into text control");
|
| 481 | 481 | |
| 482 | - if ( wxTextCtrl::IsRTFSupported() )
|
|
| 483 | - {
|
|
| 482 | +#ifdef wxHAS_TEXTCTRL_RTF
|
|
| 484 | 483 | file_menu->Append(TEXT_SAVE_RTF, "&Save file as RTF",
|
| 485 | 484 | "Save the text control contents to file");
|
| 486 | 485 | file_menu->Append(TEXT_LOAD_RTF, "&Load RTF file",
|
| 487 | 486 | "Load the sample file into text control");
|
| 488 | - }
|
|
| 487 | +#endif
|
|
| 489 | 488 | |
| 490 | 489 | file_menu->AppendSeparator();
|
| 491 | 490 | file_menu->Append(TEXT_RICH_TEXT_TEST, "Show Rich Text Editor");
|
| ... | ... | @@ -534,11 +533,10 @@ bool MyApp::OnInit() |
| 534 | 533 | menuText->Append(TEXT_SELECT, "&Select characters 4 to 8\tCtrl-I");
|
| 535 | 534 | menuText->Append(TEXT_SET, "&Set the first text zone value\tCtrl-E");
|
| 536 | 535 | menuText->Append(TEXT_CHANGE, "&Change the first text zone value\tShift-Ctrl-E");
|
| 537 | - if ( wxTextCtrl::IsRTFSupported() )
|
|
| 538 | - {
|
|
| 536 | +#ifdef wxHAS_TEXTCTRL_RTF
|
|
| 539 | 537 | menuText->AppendSeparator();
|
| 540 | 538 | menuText->Append(TEXT_SET_RTF, "Set the rich text zone value from rich text formatted content");
|
| 541 | - }
|
|
| 539 | +#endif
|
|
| 542 | 540 | menuText->AppendSeparator();
|
| 543 | 541 | menuText->Append(TEXT_MOVE_ENDTEXT, "Move cursor to the end of &text");
|
| 544 | 542 | menuText->Append(TEXT_MOVE_ENDENTRY, "Move cursor to the end of &entry");
|
| ... | ... | @@ -931,16 +931,6 @@ bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr& style) |
| 931 | 931 | return true;
|
| 932 | 932 | }
|
| 933 | 933 | |
| 934 | -// static
|
|
| 935 | -bool wxTextAreaBase::IsRTFSupported()
|
|
| 936 | -{
|
|
| 937 | -#ifdef wxHAS_TEXTCTRL_RTF
|
|
| 938 | - return true;
|
|
| 939 | -#else
|
|
| 940 | - return false;
|
|
| 941 | -#endif
|
|
| 942 | -}
|
|
| 943 | - |
|
| 944 | 934 | wxString wxTextAreaBase::GetRTFValue() const
|
| 945 | 935 | {
|
| 946 | 936 | wxFAIL_MSG("Not implemented for the current platform.");
|
| ... | ... | @@ -1114,6 +1114,92 @@ void wxTextCtrl::DoSetValue(const wxString& value, int flags) |
| 1114 | 1114 | }
|
| 1115 | 1115 | }
|
| 1116 | 1116 | |
| 1117 | +#if wxUSE_RICHEDIT
|
|
| 1118 | + |
|
| 1119 | +DWORD wxCALLBACK MSWEditStreamOutCallback(DWORD_PTR dwCookie, LPBYTE pbBuff,
|
|
| 1120 | + LONG cb, LONG* pcb)
|
|
| 1121 | +{
|
|
| 1122 | + // write the text
|
|
| 1123 | + std::string* psEntry = reinterpret_cast<std::string*>(dwCookie);
|
|
| 1124 | + psEntry->append(reinterpret_cast<const char*>(pbBuff), cb);
|
|
| 1125 | + *pcb = cb;
|
|
| 1126 | + |
|
| 1127 | + return 0;
|
|
| 1128 | +}
|
|
| 1129 | + |
|
| 1130 | +wxString wxTextCtrl::GetRTFValue() const
|
|
| 1131 | +{
|
|
| 1132 | + if ( !IsRich() )
|
|
| 1133 | + {
|
|
| 1134 | + wxFAIL_MSG("RTF support is only available for rich controls!");
|
|
| 1135 | + return wxEmptyString;
|
|
| 1136 | + }
|
|
| 1137 | + |
|
| 1138 | + // The Rich Edit control must write to a char buffer,
|
|
| 1139 | + // which we will later convert to a Unicode wxString using the current code page.
|
|
| 1140 | + //
|
|
| 1141 | + // We will reserve enough space assuming that the RTF will be twice as large
|
|
| 1142 | + // as the unencoded content.
|
|
| 1143 | + std::string buffer;
|
|
| 1144 | + buffer.reserve(GetLastPosition() * 2);
|
|
| 1145 | + |
|
| 1146 | + // Use a EDITSTREAMCALLBACK to stream text out from the control.
|
|
| 1147 | + EDITSTREAM es{ 0 };
|
|
| 1148 | + es.dwError = 0;
|
|
| 1149 | + es.pfnCallback = MSWEditStreamOutCallback;
|
|
| 1150 | + // our callback will write to a char buffer (i.e., std::string)
|
|
| 1151 | + es.dwCookie = reinterpret_cast<DWORD_PTR>(&buffer);
|
|
| 1152 | + |
|
| 1153 | + // Do NOT call with "(CP_UTF8 << 16) | SF_USECODEPAGE", as this will format the
|
|
| 1154 | + // output RTF to UTF-8 with a "urtf1" header (note the 'u').
|
|
| 1155 | + // Although this is a more modern format, few programs
|
|
| 1156 | + // (including Microsoft Wordpad) recognize it.
|
|
| 1157 | + //
|
|
| 1158 | + // Instead, write the content to an ANSI string using the current code page
|
|
| 1159 | + // (which will use a "rtf1" header). The control will encode any Unicode values
|
|
| 1160 | + // outside of the current code page with "\'[0-9A-F][0-9A-F]" syntax that most
|
|
| 1161 | + // parsers would support.
|
|
| 1162 | + //
|
|
| 1163 | + // Finally, use SFF_PLAINRTF so that the generated RTF is more portable between
|
|
| 1164 | + // RTF readers.
|
|
| 1165 | + ::SendMessage(GetHwnd(), EM_STREAMOUT,
|
|
| 1166 | + (WPARAM)(SF_RTF | SFF_PLAINRTF), (LPARAM)&es);
|
|
| 1167 | + |
|
| 1168 | + // Valid RTF is supposed to consist of 7-bit ASCII characters only,
|
|
| 1169 | + // anything else is escaped.
|
|
| 1170 | + return wxString::FromAscii(buffer.c_str(), buffer.length());
|
|
| 1171 | +}
|
|
| 1172 | + |
|
| 1173 | +void wxTextCtrl::SetRTFValue(const wxString& val)
|
|
| 1174 | +{
|
|
| 1175 | + wxCHECK_RET(IsRich(), "RTF support is only available for rich controls!");
|
|
| 1176 | + |
|
| 1177 | + SETTEXTEX textInfo{ 0 };
|
|
| 1178 | + textInfo.flags = ST_DEFAULT | ST_UNICODE;
|
|
| 1179 | + textInfo.codepage = 1200;
|
|
| 1180 | + |
|
| 1181 | + // Setting from Unicode will fail if control is read-only
|
|
| 1182 | + // (this is an undocumented "feature"), so we need to toggle that temporarily.
|
|
| 1183 | + const bool
|
|
| 1184 | + isReadOnly = (::GetWindowLong(GetHwnd(), GWL_STYLE) & ES_READONLY) != 0;
|
|
| 1185 | + if ( isReadOnly )
|
|
| 1186 | + {
|
|
| 1187 | + ::SendMessage(GetHwnd(), EM_SETREADONLY, FALSE, 0);
|
|
| 1188 | + }
|
|
| 1189 | + |
|
| 1190 | + ::SendMessage(GetHwnd(), EM_SETTEXTEX, (WPARAM)&textInfo,
|
|
| 1191 | + (LPARAM)static_cast<const wchar_t*>(val.wc_str()));
|
|
| 1192 | + |
|
| 1193 | + if ( isReadOnly )
|
|
| 1194 | + {
|
|
| 1195 | + ::SendMessage(GetHwnd(), EM_SETREADONLY, TRUE, 0);
|
|
| 1196 | + }
|
|
| 1197 | + |
|
| 1198 | + SetInsertionPoint(0);
|
|
| 1199 | +}
|
|
| 1200 | + |
|
| 1201 | +#endif // wxUSE_RICHEDIT
|
|
| 1202 | + |
|
| 1117 | 1203 | void wxTextCtrl::WriteText(const wxString& value)
|
| 1118 | 1204 | {
|
| 1119 | 1205 | DoWriteText(value);
|
| ... | ... | @@ -170,6 +170,7 @@ TEST_CASE("BitmapTestCase::ToImage", "[bitmap][image][convertto]") |
| 170 | 170 | }
|
| 171 | 171 | }
|
| 172 | 172 | |
| 173 | + // rectangle transparent pen test
|
|
| 173 | 174 | for ( int size = 4 ; size != 0 ; --size )
|
| 174 | 175 | {
|
| 175 | 176 | INFO("Red square size: " << size)
|
| ... | ... | @@ -215,6 +216,118 @@ TEST_CASE("BitmapTestCase::ToImage", "[bitmap][image][convertto]") |
| 215 | 216 | }
|
| 216 | 217 | }
|
| 217 | 218 | }
|
| 219 | + |
|
| 220 | + /* ellipse boundary test: on wxMSW, ellipse goes outside
|
|
| 221 | + rect on right and bottom */
|
|
| 222 | + {
|
|
| 223 | + wxBitmap bmp2 = bmp;
|
|
| 224 | + // verify bmp starts yellow
|
|
| 225 | + {
|
|
| 226 | + wxNativePixelData dataBmp(bmp2);
|
|
| 227 | + wxNativePixelData::Iterator rowStartBmp(dataBmp);
|
|
| 228 | + for ( int y = 0; y < bmp2.GetHeight(); ++y )
|
|
| 229 | + {
|
|
| 230 | + wxNativePixelData::Iterator iBmp = rowStartBmp;
|
|
| 231 | + for ( int x = 0; x < bmp2.GetWidth(); ++x, ++iBmp )
|
|
| 232 | + {
|
|
| 233 | + wxColour bmpc(iBmp.Red(), iBmp.Green(), iBmp.Blue());
|
|
| 234 | + CHECK_EQUAL_COLOUR_RGB(bmpc, (*wxYELLOW));
|
|
| 235 | + }
|
|
| 236 | + rowStartBmp.OffsetY(dataBmp, 1);
|
|
| 237 | + }
|
|
| 238 | + }
|
|
| 239 | + |
|
| 240 | + // change rectangle to red
|
|
| 241 | + wxRect rect(wxPoint(3, 3), wxSize(10, 5));
|
|
| 242 | + {
|
|
| 243 | + wxMemoryDC dc(bmp2);
|
|
| 244 | + dc.SetPen(*wxTRANSPARENT_PEN);
|
|
| 245 | + dc.SetBrush(*wxRED_BRUSH);
|
|
| 246 | + dc.DrawRectangle(rect);
|
|
| 247 | + }
|
|
| 248 | + |
|
| 249 | + // verify bitmap is still yellow, except rectangle is red
|
|
| 250 | + {
|
|
| 251 | + wxNativePixelData dataBmp(bmp2);
|
|
| 252 | + wxNativePixelData::Iterator rowStartBmp(dataBmp);
|
|
| 253 | + for ( int y = 0; y < bmp2.GetHeight(); ++y )
|
|
| 254 | + {
|
|
| 255 | + wxNativePixelData::Iterator iBmp = rowStartBmp;
|
|
| 256 | + for ( int x = 0; x < bmp2.GetWidth(); ++x, ++iBmp )
|
|
| 257 | + {
|
|
| 258 | + wxColour bmpc(iBmp.Red(), iBmp.Green(), iBmp.Blue());
|
|
| 259 | + CHECK_EQUAL_COLOUR_RGB(bmpc, (rect.Contains(x, y) ? *wxRED : *wxYELLOW));
|
|
| 260 | + }
|
|
| 261 | + rowStartBmp.OffsetY(dataBmp, 1);
|
|
| 262 | + }
|
|
| 263 | + }
|
|
| 264 | + |
|
| 265 | + // draw ellipse with rectangle bottomright moved in 1 (diagonal) pixel
|
|
| 266 | + {
|
|
| 267 | + wxMemoryDC dc(bmp2);
|
|
| 268 | + dc.SetPen(*wxRED_PEN);
|
|
| 269 | + dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
|
| 270 | + wxRect rect2(rect.GetTopLeft(), wxSize(rect.GetWidth() - 1, rect.GetHeight() - 1));
|
|
| 271 | + dc.DrawEllipse(rect2);
|
|
| 272 | + }
|
|
| 273 | + |
|
| 274 | + // verify bitmap is still yellow, except rectangle is red
|
|
| 275 | + {
|
|
| 276 | + wxNativePixelData dataBmp(bmp2);
|
|
| 277 | + wxNativePixelData::Iterator rowStartBmp(dataBmp);
|
|
| 278 | + for ( int y = 0; y < bmp2.GetHeight(); ++y )
|
|
| 279 | + {
|
|
| 280 | + wxNativePixelData::Iterator iBmp = rowStartBmp;
|
|
| 281 | + for ( int x = 0; x < bmp2.GetWidth(); ++x, ++iBmp )
|
|
| 282 | + {
|
|
| 283 | + wxColour bmpc(iBmp.Red(), iBmp.Green(), iBmp.Blue());
|
|
| 284 | + CHECK_EQUAL_COLOUR_RGB(bmpc, (rect.Contains(x, y) ? *wxRED : *wxYELLOW));
|
|
| 285 | + }
|
|
| 286 | + rowStartBmp.OffsetY(dataBmp, 1);
|
|
| 287 | + }
|
|
| 288 | + }
|
|
| 289 | + |
|
| 290 | + // draw ellipse with full rectangle
|
|
| 291 | + {
|
|
| 292 | + wxMemoryDC dc(bmp2);
|
|
| 293 | + dc.SetPen(*wxRED_PEN);
|
|
| 294 | + dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
|
| 295 | + dc.DrawEllipse(rect);
|
|
| 296 | + }
|
|
| 297 | + |
|
| 298 | + // verify that ellipse exceeded rect on bottom and right
|
|
| 299 | + {
|
|
| 300 | + bool pastBottom = false;
|
|
| 301 | + bool pastRight = false;
|
|
| 302 | + wxNativePixelData dataBmp(bmp2);
|
|
| 303 | + wxNativePixelData::Iterator rowStartBmp(dataBmp);
|
|
| 304 | + for ( int y = 0; y < bmp2.GetHeight(); ++y )
|
|
| 305 | + {
|
|
| 306 | + wxNativePixelData::Iterator iBmp = rowStartBmp;
|
|
| 307 | + for ( int x = 0; x < bmp2.GetWidth(); ++x, ++iBmp )
|
|
| 308 | + {
|
|
| 309 | + wxColour bmpc(iBmp.Red(), iBmp.Green(), iBmp.Blue());
|
|
| 310 | + if (bmpc != (rect.Contains(x, y) ? *wxRED : *wxYELLOW))
|
|
| 311 | + {
|
|
| 312 | + INFO("x,y: " << x << ", " << y);
|
|
| 313 | + if (y == rect.GetBottom() + 1)
|
|
| 314 | + {
|
|
| 315 | + pastBottom = true;
|
|
| 316 | + }
|
|
| 317 | + if (x == rect.GetRight() + 1)
|
|
| 318 | + {
|
|
| 319 | + pastRight = true;
|
|
| 320 | + }
|
|
| 321 | + }
|
|
| 322 | + CHECK((bmpc == (rect.Contains(x, y) ? *wxRED : *wxYELLOW) ||
|
|
| 323 | + y == rect.GetBottom() + 1 ||
|
|
| 324 | + x == rect.GetRight() + 1));
|
|
| 325 | + }
|
|
| 326 | + rowStartBmp.OffsetY(dataBmp, 1);
|
|
| 327 | + }
|
|
| 328 | + CHECK((pastBottom && pastRight));
|
|
| 329 | + }
|
|
| 330 | + }
|
|
| 218 | 331 | }
|
| 219 | 332 | |
| 220 | 333 | SECTION("RGB bitmap with mask")
|
—
View it on GitLab.
You're receiving this email because of your account on gitlab.com. Manage all notifications · Help