diff --git a/build/cmake/setup.h.in b/build/cmake/setup.h.in index d052b2f03c..496fa988ee 100644 --- a/build/cmake/setup.h.in +++ b/build/cmake/setup.h.in @@ -216,6 +216,8 @@ #cmakedefine01 wxUSE_SECRETSTORE +#cmakedefine01 wxUSE_SPELLCHECK + #cmakedefine01 wxUSE_STDPATHS #cmakedefine01 wxUSE_TEXTBUFFER diff --git a/build/tools/before_install.sh b/build/tools/before_install.sh index 87b1fb0c94..373020c2e3 100755 --- a/build/tools/before_install.sh +++ b/build/tools/before_install.sh @@ -50,7 +50,7 @@ case $(uname -s) in *) case "$wxGTK_VERSION" in 3) libtoolkit_dev=libgtk-3-dev - extra_deps='libwebkit2gtk-4.0-dev libwebkitgtk-3.0-dev' + extra_deps='libwebkit2gtk-4.0-dev libwebkitgtk-3.0-dev libgtkspell3-3-dev' ;; 2) libtoolkit_dev=libgtk2.0-dev extra_deps='libwebkitgtk-dev' diff --git a/configure b/configure index 98dff2ffeb..e324f4c137 100755 --- a/configure +++ b/configure @@ -951,6 +951,8 @@ GTKPRINT_CFLAGS SDL_CONFIG SDL_LIBS SDL_CFLAGS +GTKSPELL_LIBS +GTKSPELL_CFLAGS LIBSECRET_LIBS LIBSECRET_CFLAGS GXX_VERSION @@ -1203,6 +1205,7 @@ enable_printfposparam enable_secretstore enable_snglinst enable_sound +enable_spellcheck enable_stdpaths enable_stopwatch enable_streams @@ -1431,6 +1434,8 @@ MesaGL_CFLAGS MesaGL_LIBS LIBSECRET_CFLAGS LIBSECRET_LIBS +GTKSPELL_CFLAGS +GTKSPELL_LIBS SDL_CFLAGS SDL_LIBS GTKPRINT_CFLAGS @@ -2171,6 +2176,7 @@ Optional Features: --enable-secretstore use wxSecretStore class --enable-snglinst use wxSingleInstanceChecker class --enable-sound use wxSound class + --enable-spellcheck enable spellchecking in wxTextCtrl class (MSW and GTK3 only) --enable-stdpaths use wxStandardPaths class --enable-stopwatch use wxStopWatch class --enable-streams use wxStream etc classes @@ -2469,6 +2475,10 @@ Some influential environment variables: C compiler flags for LIBSECRET, overriding pkg-config LIBSECRET_LIBS linker flags for LIBSECRET, overriding pkg-config + GTKSPELL_CFLAGS + C compiler flags for GTKSPELL, overriding pkg-config + GTKSPELL_LIBS + linker flags for GTKSPELL, overriding pkg-config SDL_CFLAGS C compiler flags for SDL, overriding pkg-config SDL_LIBS linker flags for SDL, overriding pkg-config GTKPRINT_CFLAGS @@ -7865,6 +7875,35 @@ fi eval "$wx_cv_use_sound" + enablestring= + defaultval=$wxUSE_ALL_FEATURES + if test -z "$defaultval"; then + if test x"$enablestring" = xdisable; then + defaultval=yes + else + defaultval=no + fi + fi + + # Check whether --enable-spellcheck was given. +if test "${enable_spellcheck+set}" = set; then : + enableval=$enable_spellcheck; + if test "$enableval" = yes; then + wx_cv_use_spellcheck='wxUSE_SPELLCHECK=yes' + else + wx_cv_use_spellcheck='wxUSE_SPELLCHECK=no' + fi + +else + + wx_cv_use_spellcheck='wxUSE_SPELLCHECK=${'DEFAULT_wxUSE_SPELLCHECK":-$defaultval}" + +fi + + + eval "$wx_cv_use_spellcheck" + + enablestring= defaultval=$wxUSE_ALL_FEATURES if test -z "$defaultval"; then @@ -33969,6 +34008,101 @@ fi fi + +if test "$wxUSE_SPELLCHECK" = "yes"; then + + if test "$WXGTK3" = 1; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTKSPELL" >&5 +$as_echo_n "checking for GTKSPELL... " >&6; } + +if test -n "$PKG_CONFIG"; then + if test -n "$GTKSPELL_CFLAGS"; then + pkg_cv_GTKSPELL_CFLAGS="$GTKSPELL_CFLAGS" + else + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtkspell3-3.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gtkspell3-3.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GTKSPELL_CFLAGS=`$PKG_CONFIG --cflags "gtkspell3-3.0" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi +if test -n "$PKG_CONFIG"; then + if test -n "$GTKSPELL_LIBS"; then + pkg_cv_GTKSPELL_LIBS="$GTKSPELL_LIBS" + else + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtkspell3-3.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gtkspell3-3.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GTKSPELL_LIBS=`$PKG_CONFIG --libs "gtkspell3-3.0" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GTKSPELL_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "gtkspell3-3.0"` + else + GTKSPELL_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "gtkspell3-3.0"` + fi + # Put the nasty error message in config.log where it belongs + echo "$GTKSPELL_PKG_ERRORS" >&5 + + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gtkspell3-3.0 not found, spell checking in wxTextCtrl won't be available" >&5 +$as_echo "$as_me: WARNING: gtkspell3-3.0 not found, spell checking in wxTextCtrl won't be available" >&2;} + wxUSE_SPELLCHECK=no + + +elif test $pkg_failed = untried; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gtkspell3-3.0 not found, spell checking in wxTextCtrl won't be available" >&5 +$as_echo "$as_me: WARNING: gtkspell3-3.0 not found, spell checking in wxTextCtrl won't be available" >&2;} + wxUSE_SPELLCHECK=no + + +else + GTKSPELL_CFLAGS=$pkg_cv_GTKSPELL_CFLAGS + GTKSPELL_LIBS=$pkg_cv_GTKSPELL_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + CXXFLAGS="$GTKSPELL_CFLAGS $CXXFLAGS" + LIBS="$GTKSPELL_LIBS $LIBS" + +fi + fi + + if test "$wxUSE_SPELLCHECK" = "yes"; then + $as_echo "#define wxUSE_SPELLCHECK 1" >>confdefs.h + + fi +fi + + if test "$wxUSE_STL" = "yes"; then $as_echo "#define wxUSE_STL 1" >>confdefs.h diff --git a/configure.in b/configure.in index 7a63cda1f3..18c10dd54e 100644 --- a/configure.in +++ b/configure.in @@ -766,6 +766,7 @@ WX_ARG_FEATURE(printfposparam,[ --enable-printfposparam use wxVsnprintf() which WX_ARG_FEATURE(secretstore, [ --enable-secretstore use wxSecretStore class], wxUSE_SECRETSTORE) WX_ARG_FEATURE(snglinst, [ --enable-snglinst use wxSingleInstanceChecker class], wxUSE_SNGLINST_CHECKER) WX_ARG_FEATURE(sound, [ --enable-sound use wxSound class], wxUSE_SOUND) +WX_ARG_FEATURE(spellcheck, [ --enable-spellcheck enable spellchecking in wxTextCtrl class (MSW and GTK3 only)], wxUSE_SPELLCHECK) WX_ARG_FEATURE(stdpaths, [ --enable-stdpaths use wxStandardPaths class], wxUSE_STDPATHS) WX_ARG_FEATURE(stopwatch, [ --enable-stopwatch use wxStopWatch class], wxUSE_STOPWATCH) WX_ARG_FEATURE(streams, [ --enable-streams use wxStream etc classes], wxUSE_STREAMS) @@ -5765,6 +5766,34 @@ if test "$wxUSE_SECRETSTORE" = "yes"; then fi fi + +dnl --------------------------------------------------------------------------- +dnl Spellchecking for wxTextCtrl +dnl --------------------------------------------------------------------------- + +if test "$wxUSE_SPELLCHECK" = "yes"; then + dnl The required APIs are always available under MSW and OS X and we don't + dnl implement support for spell checking in the other ports, but for GTK 3 + dnl we need to check for gtkspell library. + + if test "$WXGTK3" = 1; then + PKG_CHECK_MODULES(GTKSPELL, [gtkspell3-3.0], + [ + CXXFLAGS="$GTKSPELL_CFLAGS $CXXFLAGS" + LIBS="$GTKSPELL_LIBS $LIBS" + ], + [ + AC_MSG_WARN([gtkspell3-3.0 not found, spell checking in wxTextCtrl won't be available]) + wxUSE_SPELLCHECK=no + ] + ) + fi + + if test "$wxUSE_SPELLCHECK" = "yes"; then + AC_DEFINE(wxUSE_SPELLCHECK) + fi +fi + dnl --------------------------------------------------------------------------- dnl Register non-GUI class options for makefiles and setup.h dnl --------------------------------------------------------------------------- diff --git a/include/wx/android/setup.h b/include/wx/android/setup.h index 7d2516b3aa..03875c1dbf 100644 --- a/include/wx/android/setup.h +++ b/include/wx/android/setup.h @@ -447,6 +447,14 @@ // Recommended setting: 1 (but may be safely disabled if you don't use it) #define wxUSE_SECRETSTORE 1 +// Allow the use of the OS built-in spell checker in wxTextCtrl. +// +// Default is 1, the corresponding wxTextCtrl functions simply won't do +// anything if the functionality is not supported by the current platform. +// +// Recommended setting: 1 unless you want to save a tiny bit of code. +#define wxUSE_SPELLCHECK 1 + // Use wxStandardPaths class which allows to retrieve some standard locations // in the file system // diff --git a/include/wx/chkconf.h b/include/wx/chkconf.h index 4fa7561b9c..657baf4c81 100644 --- a/include/wx/chkconf.h +++ b/include/wx/chkconf.h @@ -282,6 +282,14 @@ # endif #endif /* !defined(wxUSE_SECRETSTORE) */ +#ifndef wxUSE_SPELLCHECK +# ifdef wxABORT_ON_CONFIG_ERROR +# error "wxUSE_SPELLCHECK must be defined, please read comment near the top of this file." +# else +# define wxUSE_SPELLCHECK 1 +# endif +#endif /* !defined(wxUSE_SPELLCHECK) */ + #ifndef wxUSE_STDPATHS # ifdef wxABORT_ON_CONFIG_ERROR # error "wxUSE_STDPATHS must be defined, please read comment near the top of this file." diff --git a/include/wx/gtk/setup.h b/include/wx/gtk/setup.h index da9678a222..85ffff1c21 100644 --- a/include/wx/gtk/setup.h +++ b/include/wx/gtk/setup.h @@ -448,6 +448,14 @@ // Recommended setting: 1 (but may be safely disabled if you don't use it) #define wxUSE_SECRETSTORE 1 +// Allow the use of the OS built-in spell checker in wxTextCtrl. +// +// Default is 1, the corresponding wxTextCtrl functions simply won't do +// anything if the functionality is not supported by the current platform. +// +// Recommended setting: 1 unless you want to save a tiny bit of code. +#define wxUSE_SPELLCHECK 1 + // Use wxStandardPaths class which allows to retrieve some standard locations // in the file system // diff --git a/include/wx/gtk/textctrl.h b/include/wx/gtk/textctrl.h index ebc2f02e0a..b4d6e6b595 100644 --- a/include/wx/gtk/textctrl.h +++ b/include/wx/gtk/textctrl.h @@ -96,6 +96,13 @@ public: // Overridden wxWindow methods virtual void SetWindowStyleFlag( long style ) wxOVERRIDE; +#if wxUSE_SPELLCHECK && defined(__WXGTK3__) + // Use native spelling and grammar checking functions. + virtual bool EnableProofCheck(const wxTextProofOptions& options + = wxTextProofOptions::Default()) wxOVERRIDE; + virtual wxTextProofOptions GetProofCheckOptions() const wxOVERRIDE; +#endif // wxUSE_SPELLCHECK && __WXGTK3__ + // Implementation from now on void OnDropFiles( wxDropFilesEvent &event ); void OnChar( wxKeyEvent &event ); diff --git a/include/wx/motif/setup.h b/include/wx/motif/setup.h index 9e1174e2ab..d6474006fb 100644 --- a/include/wx/motif/setup.h +++ b/include/wx/motif/setup.h @@ -448,6 +448,14 @@ // Recommended setting: 1 (but may be safely disabled if you don't use it) #define wxUSE_SECRETSTORE 1 +// Allow the use of the OS built-in spell checker in wxTextCtrl. +// +// Default is 1, the corresponding wxTextCtrl functions simply won't do +// anything if the functionality is not supported by the current platform. +// +// Recommended setting: 1 unless you want to save a tiny bit of code. +#define wxUSE_SPELLCHECK 1 + // Use wxStandardPaths class which allows to retrieve some standard locations // in the file system // diff --git a/include/wx/msw/setup.h b/include/wx/msw/setup.h index f87bcece45..3a9bceef80 100644 --- a/include/wx/msw/setup.h +++ b/include/wx/msw/setup.h @@ -448,6 +448,14 @@ // Recommended setting: 1 (but may be safely disabled if you don't use it) #define wxUSE_SECRETSTORE 1 +// Allow the use of the OS built-in spell checker in wxTextCtrl. +// +// Default is 1, the corresponding wxTextCtrl functions simply won't do +// anything if the functionality is not supported by the current platform. +// +// Recommended setting: 1 unless you want to save a tiny bit of code. +#define wxUSE_SPELLCHECK 1 + // Use wxStandardPaths class which allows to retrieve some standard locations // in the file system // diff --git a/include/wx/msw/textctrl.h b/include/wx/msw/textctrl.h index 4b85f69e3c..08ff22bbf4 100644 --- a/include/wx/msw/textctrl.h +++ b/include/wx/msw/textctrl.h @@ -111,6 +111,14 @@ public: bool ShowNativeCaret(bool show = true); bool HideNativeCaret() { return ShowNativeCaret(false); } +#if wxUSE_RICHEDIT && wxUSE_SPELLCHECK + // Use native spelling and grammar checking functions. + // This is only available in wxTE_RICH2 controls. + virtual bool EnableProofCheck(const wxTextProofOptions& options + = wxTextProofOptions::Default()) wxOVERRIDE; + virtual wxTextProofOptions GetProofCheckOptions() const wxOVERRIDE; +#endif // wxUSE_RICHEDIT && wxUSE_SPELLCHECK + // Implementation from now on // -------------------------- diff --git a/include/wx/osx/cocoa/private/textimpl.h b/include/wx/osx/cocoa/private/textimpl.h index c96cb52944..c6b57b5a6a 100644 --- a/include/wx/osx/cocoa/private/textimpl.h +++ b/include/wx/osx/cocoa/private/textimpl.h @@ -127,7 +127,10 @@ public: virtual bool HasOwnContextMenu() const wxOVERRIDE { return true; } - virtual void CheckSpelling(bool check) wxOVERRIDE; +#if wxUSE_SPELLCHECK + virtual void CheckSpelling(const wxTextProofOptions& options) wxOVERRIDE; + virtual wxTextProofOptions GetCheckingOptions() const wxOVERRIDE; +#endif // wxUSE_SPELLCHECK virtual void EnableAutomaticQuoteSubstitution(bool enable) wxOVERRIDE; virtual void EnableAutomaticDashSubstitution(bool enable) wxOVERRIDE; diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index d32434c800..db904c8207 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -77,6 +77,8 @@ WXDLLIMPEXP_BASE CFURLRef wxOSXCreateURLFromFileSystemPath( const wxString& path #include "wx/bitmap.h" #include "wx/window.h" +class wxTextProofOptions; + class WXDLLIMPEXP_CORE wxMacCGContextStateSaver { wxDECLARE_NO_COPY_CLASS(wxMacCGContextStateSaver); @@ -737,7 +739,10 @@ public : virtual void ShowPosition(long pos) ; virtual int GetLineLength(long lineNo) const ; virtual wxString GetLineText(long lineNo) const ; - virtual void CheckSpelling(bool WXUNUSED(check)) { } +#if wxUSE_SPELLCHECK + virtual void CheckSpelling(const wxTextProofOptions& WXUNUSED(options)) { } + virtual wxTextProofOptions GetCheckingOptions() const; +#endif // wxUSE_SPELLCHECK virtual void EnableAutomaticQuoteSubstitution(bool WXUNUSED(enable)) {} virtual void EnableAutomaticDashSubstitution(bool WXUNUSED(enable)) {} diff --git a/include/wx/osx/iphone/private/textimpl.h b/include/wx/osx/iphone/private/textimpl.h index 96b52e6d05..bdaa6c0c72 100644 --- a/include/wx/osx/iphone/private/textimpl.h +++ b/include/wx/osx/iphone/private/textimpl.h @@ -71,7 +71,6 @@ public: virtual bool HasOwnContextMenu() const { return true; } - virtual void CheckSpelling(bool check); virtual wxSize GetBestSize() const; protected: diff --git a/include/wx/osx/setup.h b/include/wx/osx/setup.h index e11ce81431..5254f4e6b2 100644 --- a/include/wx/osx/setup.h +++ b/include/wx/osx/setup.h @@ -454,6 +454,14 @@ // Recommended setting: 1 (but may be safely disabled if you don't use it) #define wxUSE_SECRETSTORE 1 +// Allow the use of the OS built-in spell checker in wxTextCtrl. +// +// Default is 1, the corresponding wxTextCtrl functions simply won't do +// anything if the functionality is not supported by the current platform. +// +// Recommended setting: 1 unless you want to save a tiny bit of code. +#define wxUSE_SPELLCHECK 1 + // Use wxStandardPaths class which allows to retrieve some standard locations // in the file system // diff --git a/include/wx/osx/textctrl.h b/include/wx/osx/textctrl.h index a784e39ac6..6e6a40817c 100644 --- a/include/wx/osx/textctrl.h +++ b/include/wx/osx/textctrl.h @@ -97,6 +97,13 @@ public: virtual void Cut() wxOVERRIDE; virtual void Paste() wxOVERRIDE; +#if wxUSE_SPELLCHECK + // Use native spelling and grammar checking functions (multiline only). + virtual bool EnableProofCheck(const wxTextProofOptions& options + = wxTextProofOptions::Default()) wxOVERRIDE; + virtual wxTextProofOptions GetProofCheckOptions() const wxOVERRIDE; +#endif // wxUSE_SPELLCHECK + // Implementation // -------------- virtual void Command(wxCommandEvent& event) wxOVERRIDE; @@ -130,7 +137,11 @@ public: virtual void MacVisibilityChanged() wxOVERRIDE; virtual void MacSuperChangedPosition() wxOVERRIDE; - virtual void MacCheckSpelling(bool check); + + // Use portable EnableProofCheck() instead now. +#if WXWIN_COMPATIBILITY_3_0 && wxUSE_SPELLCHECK + wxDEPRECATED( virtual void MacCheckSpelling(bool check) ); +#endif // WXWIN_COMPATIBILITY_3_0 && wxUSE_SPELLCHECK void OSXEnableAutomaticQuoteSubstitution(bool enable); void OSXEnableAutomaticDashSubstitution(bool enable); diff --git a/include/wx/setup_inc.h b/include/wx/setup_inc.h index 9a59af9816..52b1ca4d2c 100644 --- a/include/wx/setup_inc.h +++ b/include/wx/setup_inc.h @@ -444,6 +444,14 @@ // Recommended setting: 1 (but may be safely disabled if you don't use it) #define wxUSE_SECRETSTORE 1 +// Allow the use of the OS built-in spell checker in wxTextCtrl. +// +// Default is 1, the corresponding wxTextCtrl functions simply won't do +// anything if the functionality is not supported by the current platform. +// +// Recommended setting: 1 unless you want to save a tiny bit of code. +#define wxUSE_SPELLCHECK 1 + // Use wxStandardPaths class which allows to retrieve some standard locations // in the file system // diff --git a/include/wx/textctrl.h b/include/wx/textctrl.h index ac18c183e9..b2db92f48e 100644 --- a/include/wx/textctrl.h +++ b/include/wx/textctrl.h @@ -126,6 +126,76 @@ enum wxTextCtrlHitTestResult }; // ... the character returned +#if wxUSE_SPELLCHECK + +// ---------------------------------------------------------------------------- +// This object can be passed to wxTextCtrl::EnableProofCheck() to configure the +// proofing options for this control. +// ---------------------------------------------------------------------------- +class wxTextProofOptions +{ +public: + // Return the object corresponding to the default options: current + // language, spell checking enabled, grammar checking disabled. + static wxTextProofOptions Default() + { + wxTextProofOptions opts; + return opts.SpellCheck(true); + } + + // Return the object with all checks disabled. + static wxTextProofOptions Disable() + { + return wxTextProofOptions(); + } + + // Default copy ctor, assignment operator and dtor are ok + + // Methods that can be used to set the various options. + wxTextProofOptions& SpellCheck(bool enable = true) + { + m_EnableSpellCheck = enable; + return *this; + } + + wxTextProofOptions& GrammarCheck(bool enable = true) + { + m_EnableGrammarCheck = enable; + return *this; + } + + wxTextProofOptions& Language(const wxString& lang) + { + m_lang = lang; + return *this; + } + + // And the corresponding accessors. + bool IsSpellCheckEnabled() const { return m_EnableSpellCheck; } + bool IsGrammarCheckEnabled() const { return m_EnableGrammarCheck; } + const wxString& GetLang() const { return m_lang; } + + bool AnyChecksEnabled() const + { + return IsSpellCheckEnabled() || IsGrammarCheckEnabled(); + } + +private: + // Ctor is private, use static factory methods to create objects of this + // class. + wxTextProofOptions() + { + m_EnableSpellCheck = + m_EnableGrammarCheck = false; + } + + wxString m_lang; + bool m_EnableSpellCheck; + bool m_EnableGrammarCheck; +}; + +#endif // wxUSE_SPELLCHECK + // ---------------------------------------------------------------------------- // Types for wxTextAttr // ---------------------------------------------------------------------------- @@ -758,6 +828,19 @@ public: virtual const wxTextEntry* WXGetTextEntry() const wxOVERRIDE { return this; } +#if wxUSE_SPELLCHECK + // Use native spelling and grammar checking functions. + virtual bool EnableProofCheck(const wxTextProofOptions& WXUNUSED(options) + = wxTextProofOptions::Default()) + { + return false; + } + virtual wxTextProofOptions GetProofCheckOptions() const + { + return wxTextProofOptions::Disable(); + } +#endif // wxUSE_SPELLCHECK + protected: // Override wxEvtHandler method to check for a common problem of binding // wxEVT_TEXT_ENTER to a control without wxTE_PROCESS_ENTER style, which is diff --git a/include/wx/univ/setup.h b/include/wx/univ/setup.h index 010713e897..0b07bfbdfe 100644 --- a/include/wx/univ/setup.h +++ b/include/wx/univ/setup.h @@ -447,6 +447,14 @@ // Recommended setting: 1 (but may be safely disabled if you don't use it) #define wxUSE_SECRETSTORE 1 +// Allow the use of the OS built-in spell checker in wxTextCtrl. +// +// Default is 1, the corresponding wxTextCtrl functions simply won't do +// anything if the functionality is not supported by the current platform. +// +// Recommended setting: 1 unless you want to save a tiny bit of code. +#define wxUSE_SPELLCHECK 1 + // Use wxStandardPaths class which allows to retrieve some standard locations // in the file system // diff --git a/interface/wx/textctrl.h b/interface/wx/textctrl.h index d296d05c72..40d26da191 100644 --- a/interface/wx/textctrl.h +++ b/interface/wx/textctrl.h @@ -258,7 +258,6 @@ enum wxTextCtrlHitTestResult wxTE_HT_BEYOND }; - /** @class wxTextAttr @@ -979,6 +978,75 @@ public: void operator=(const wxTextAttr& attr); }; +/** + @class wxTextProofOptions + + This class provides a convenient means of passing multiple parameters to + wxTextCtrl::EnableProofCheck(). + + By default, i.e. when calling EnableProofCheck() without any parameters, + Default() proof options are used, which enable spelling (but not grammar) + checks for the current language. + + However it is also possible to customize the options: + + @code + textctrl->EnableProofCheck(wxTextProofOptions::Default().Language("fr").GrammarCheck()); + @endcode + + or disable the all checks entirely: + + @code + textctrl->EnableProofCheck(wxTextProofOptions::Disable()); + @endcode + + Note that this class has no public constructor, except for the copy + constructor, so its objects can only be created using the static factory + methods Default() or Disable(). + + @see wxTextCtrl::EnableProofCheck(), wxTextCtrl::GetProofCheckOptions(). + + @since 3.1.6 +*/ +class WXDLLIMPEXP_CORE wxTextProofOptions +{ + /** + Create an object corresponding to the default checks. + + The returned object enables spelling checks and disables grammar checks. + */ + static wxTextProofOptions Default() + + /** + Create an object disabling all checks. + + The returned object can be passed to wxTextCtrl::EnableProofCheck() to + disable all checks in the text control. + */ + static wxTextProofOptions Disable() + + /** + Enable / disable spell checking for this control. + */ + wxTextProofOptions& SpellCheck(bool enable = true) + + /** + Enable / disable grammar checking for this control. + + This option is currently only supported under macOS and is ignored under + the other platforms. + */ + wxTextProofOptions& GrammarCheck(bool enable = true) + + /// Return true if spell checking is enabled. + bool IsSpellCheckEnabled() const; + + /// Return true if grammar checking is enabled. + bool IsGrammarCheckEnabled() const; + + /// Returns true if any checks are enabled. + bool AnyChecksEnabled() const +}; /** @class wxTextCtrl @@ -1336,6 +1404,33 @@ public: */ virtual bool EmulateKeyPress(const wxKeyEvent& event); + /** + Enable or disable native spell checking on this text control if it is + available on the current platform. + + Currently this is supported in wxMSW (when running under Windows 8 or + later), wxGTK when using GTK 3 and wxOSX. In addition, wxMSW requires + that the text control has the wxTE_RICH2 style set. wxGTK3 and wxOSX + require that the control has the wxTE_MULTILINE style. + + @param options + A wxTextProofOptions object specifying the desired behaviour + of the proof checker (e.g. language to use, spell check, grammar + check, etc.) and whether the proof checks should be enabled at all. + By default, spelling checks for the current language are enabled. + Passing wxTextProofOptions::Disable() disables all the checks. + + @return + @true if proof checking has been successfully enabled or disabled, + @false otherwise (usually because the corresponding functionality + is not available under the current platform or for this type of + text control). + + @since 3.1.6 + */ + virtual bool EnableProofCheck(const wxTextProofOptions& options + = wxTextProofOptions::Default()); + /** Returns the style currently used for the new text. @@ -1477,6 +1572,18 @@ public: */ bool IsSingleLine() const; + /** + Returns the current text proofing options. + + This function is implemented for the same platforms as + EnableProofCheck() and returns wxTextProofOptions with all checks + disabled, i.e. such that wxTextProofOptions::AnyChecksEnabled() returns + @false. + + @since 3.1.6 + */ + virtual wxTextProofOptions GetProofCheckOptions(); + /** Loads and displays the named file, if it exists. diff --git a/samples/text/text.cpp b/samples/text/text.cpp index 892cd0ad36..44a680b125 100644 --- a/samples/text/text.cpp +++ b/samples/text/text.cpp @@ -1205,9 +1205,29 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h ) m_tab->SetClientData(const_cast(static_cast(wxS("tab")))); m_enter = new MyTextCtrl( this, 100, "Multiline, allow processing.", - wxPoint(180,170), wxSize(200,70), wxTE_MULTILINE | wxTE_PROCESS_ENTER ); + wxPoint(180,170), wxSize(200,70), wxTE_MULTILINE | wxTE_PROCESS_ENTER | wxTE_RICH2 ); m_enter->SetClientData(const_cast(static_cast(wxS("enter")))); +#if wxUSE_SPELLCHECK + (*m_enter) << "\n"; + + // Enable grammar check just for demonstration purposes (note that it's + // only supported under Mac, but spell checking will be enabled under the + // other platforms too, if supported). If we didn't want to enable it, we + // could omit the EnableProofCheck() argument entirely. + if ( !m_enter->EnableProofCheck(wxTextProofOptions::Default().GrammarCheck()) ) + { + (*m_enter) << "Spell checking is not available on this platform, sorry."; + } + else + { + // Break the string in several parts to avoid misspellings in the sources. + (*m_enter) << "Spell checking is enabled, mis" + "s" + "spelled words should be highlighted."; + } +#endif + m_textrich = new MyTextCtrl(this, wxID_ANY, "Allows more than 30Kb of text\n" "(on all Windows versions)\n" "and a very very very very very " diff --git a/setup.h.in b/setup.h.in index 673e540222..3e3f576193 100644 --- a/setup.h.in +++ b/setup.h.in @@ -216,6 +216,8 @@ #define wxUSE_SECRETSTORE 0 +#define wxUSE_SPELLCHECK 0 + #define wxUSE_STDPATHS 0 #define wxUSE_TEXTBUFFER 0 diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 86adcd3bd4..b279d1a817 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -32,6 +32,12 @@ #include "wx/gtk/private.h" #include "wx/gtk/private/gtk3-compat.h" +#if wxUSE_SPELLCHECK && defined(__WXGTK3__) +extern "C" { +#include +} +#endif // wxUSE_SPELLCHECK && __WXGTK3__ + // ---------------------------------------------------------------------------- // helpers // ---------------------------------------------------------------------------- @@ -1017,6 +1023,60 @@ void wxTextCtrl::GTKSetJustification() } } +#if wxUSE_SPELLCHECK && defined(__WXGTK3__) + +bool wxTextCtrl::EnableProofCheck(const wxTextProofOptions& options) +{ + wxCHECK_MSG( IsMultiLine(), false, + "Unable to enable spell check on control " + "which does not have wxTE_MULTILINE style" ); + + GtkTextView *textview = GTK_TEXT_VIEW(m_text); + wxCHECK_MSG( textview, false, wxS("wxTextCtrl is not a GtkTextView")); + + GtkSpellChecker *spell = gtk_spell_checker_get_from_text_view(textview); + + if ( options.IsSpellCheckEnabled() ) + { + if ( !spell ) + { + spell = gtk_spell_checker_new(); + gtk_spell_checker_attach(spell, textview); + } + + wxString lang = options.GetLang(); + + if ( !gtk_spell_checker_set_language(spell, + lang.empty() ? NULL : (const gchar *)lang.utf8_str(), + NULL) ) + return false; + } + else + { + if ( spell ) + gtk_spell_checker_detach(spell); + } + + return GetProofCheckOptions().IsSpellCheckEnabled(); +} + +wxTextProofOptions wxTextCtrl::GetProofCheckOptions() const +{ + wxTextProofOptions opts = wxTextProofOptions::Disable(); + + GtkTextView *textview = GTK_TEXT_VIEW(m_text); + + if ( IsMultiLine() && textview ) + { + if ( gtk_spell_checker_get_from_text_view(textview) ) + opts.SpellCheck(); + } + + return opts; +} + +#endif // wxUSE_SPELLCHECK && __WXGTK3__ + void wxTextCtrl::SetWindowStyleFlag(long style) { long styleOld = GetWindowStyleFlag(); diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 2819131b4d..4e06cff953 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -19,7 +19,6 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" - #if wxUSE_TEXTCTRL #ifndef WX_PRECOMP @@ -77,6 +76,27 @@ #include "wx/msw/ole/oleutils.h" #include "wx/msw/private/comptr.h" + + #if wxUSE_SPELLCHECK + #include "wx/msw/wrapwin.h" + + // Add defines that are missing in MinGW. + #ifndef IMF_SPELLCHECKING + #define IMF_SPELLCHECKING 0x0800 + #endif + #ifndef SES_USECTF + #define SES_USECTF 0x00010000 + #endif + #ifndef SES_CTFALLOWEMBED + #define SES_CTFALLOWEMBED 0x00200000 + #endif + #ifndef SES_CTFALLOWSMARTTAG + #define SES_CTFALLOWSMARTTAG 0x00400000 + #endif + #ifndef SES_CTFALLOWPROOFING + #define SES_CTFALLOWPROOFING 0x00800000 + #endif + #endif // wxUSE_SPELLCHECK #endif // wxUSE_RICHEDIT #if wxUSE_INKEDIT @@ -812,6 +832,44 @@ WXDWORD wxTextCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const return msStyle; } +#if wxUSE_RICHEDIT && wxUSE_SPELLCHECK + +bool wxTextCtrl::EnableProofCheck(const wxTextProofOptions& options) +{ + wxCHECK_MSG((m_windowStyle & wxTE_RICH2), false, + "Unable to enable proof checking on a control " + "that does not have wxTE_RICH2 style"); + + LPARAM editStyle = SES_USECTF | SES_CTFALLOWEMBED + | SES_CTFALLOWSMARTTAG | SES_CTFALLOWPROOFING; + ::SendMessage(GetHwnd(), EM_SETEDITSTYLE, editStyle, editStyle); + + LRESULT langOptions = ::SendMessage(GetHwnd(), EM_GETLANGOPTIONS, 0, 0); + + if ( options.IsSpellCheckEnabled() ) + langOptions |= IMF_SPELLCHECKING; + else + langOptions &= ~IMF_SPELLCHECKING; + + ::SendMessage(GetHwnd(), EM_SETLANGOPTIONS, 0, langOptions); + + return GetProofCheckOptions().IsSpellCheckEnabled(); +} + +wxTextProofOptions wxTextCtrl::GetProofCheckOptions() const +{ + wxTextProofOptions opts = wxTextProofOptions::Disable(); + + LRESULT langOptions = ::SendMessage(GetHwnd(), EM_GETLANGOPTIONS, 0, 0); + + if (langOptions & IMF_SPELLCHECKING) + opts.SpellCheck(); + + return opts; +} + +#endif // wxUSE_SPELLCHECK + void wxTextCtrl::SetWindowStyleFlag(long style) { // changing the alignment of the control dynamically works under Win2003 diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm index b8bab36b96..d756dc09d4 100644 --- a/src/osx/cocoa/textctrl.mm +++ b/src/osx/cocoa/textctrl.mm @@ -1277,12 +1277,30 @@ void wxNSTextViewControl::SetStyle(long start, } } -void wxNSTextViewControl::CheckSpelling(bool check) +#if wxUSE_SPELLCHECK + +void wxNSTextViewControl::CheckSpelling(const wxTextProofOptions& options) { - if (m_textView) - [m_textView setContinuousSpellCheckingEnabled: check]; + wxCHECK_RET( m_textView, "control must be created first" ); + + m_textView.continuousSpellCheckingEnabled = options.IsSpellCheckEnabled(); + m_textView.grammarCheckingEnabled = options.IsGrammarCheckEnabled(); } +wxTextProofOptions wxNSTextViewControl::GetCheckingOptions() const +{ + wxTextProofOptions opts = wxTextProofOptions::Disable(); + if ( m_textView ) + { + opts.SpellCheck(m_textView.continuousSpellCheckingEnabled); + opts.GrammarCheck(m_textView.grammarCheckingEnabled); + } + + return opts; +} + +#endif // wxUSE_SPELLCHECK + void wxNSTextViewControl::EnableAutomaticQuoteSubstitution(bool enable) { if (m_textView) diff --git a/src/osx/iphone/textctrl.mm b/src/osx/iphone/textctrl.mm index 7a1d785c64..147f8cb1d3 100644 --- a/src/osx/iphone/textctrl.mm +++ b/src/osx/iphone/textctrl.mm @@ -500,10 +500,6 @@ void wxUITextViewControl::SetStyle(long start, } } -void wxUITextViewControl::CheckSpelling(bool check) -{ -} - wxSize wxUITextViewControl::GetBestSize() const { wxRect r; diff --git a/src/osx/textctrl_osx.cpp b/src/osx/textctrl_osx.cpp index 31a3bcebcb..670e4859e2 100644 --- a/src/osx/textctrl_osx.cpp +++ b/src/osx/textctrl_osx.cpp @@ -124,10 +124,13 @@ void wxTextCtrl::MacVisibilityChanged() { } +#if WXWIN_COMPATIBILITY_3_0 && wxUSE_SPELLCHECK void wxTextCtrl::MacCheckSpelling(bool check) { - GetTextPeer()->CheckSpelling(check); + GetTextPeer()->CheckSpelling(check ? wxTextProofOptions::Default() + : wxTextProofOptions::Disable()); } +#endif // WXWIN_COMPATIBILITY_3_0 && wxUSE_SPELLCHECK void wxTextCtrl::OSXEnableAutomaticQuoteSubstitution(bool enable) { @@ -340,6 +343,22 @@ void wxTextCtrl::Paste() } } +#if wxUSE_SPELLCHECK + +bool wxTextCtrl::EnableProofCheck(const wxTextProofOptions& options) +{ + GetTextPeer()->CheckSpelling(options); + + return true; +} + +wxTextProofOptions wxTextCtrl::GetProofCheckOptions() const +{ + return GetTextPeer()->GetCheckingOptions(); +} + +#endif // wxUSE_SPELLCHECK + void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event) { // By default, load the first file into the text window. @@ -808,6 +827,15 @@ int wxTextWidgetImpl::GetLineLength(long lineNo) const return -1 ; } +#if wxUSE_SPELLCHECK + +wxTextProofOptions wxTextWidgetImpl::GetCheckingOptions() const +{ + return wxTextProofOptions::Disable(); +} + +#endif // wxUSE_SPELLCHECK + void wxTextWidgetImpl::SetJustification() { }