Implement auto-completion support for wxTextEntry in wxOSX/Cocoa.
Both completing a set of fixed strings and dynamic completion using a custom completer are supported, although completing the file names remains MSW-only for now. Note that, unlike under MSW, auto-completion under Mac is not automatic and has to be triggered manually by calling complete: method. This is done by pressing F5 key by default. In the future we should call it automatically on a timer event to make it more obviously discoverable. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67526 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -525,6 +525,7 @@ MSW:
|
|||||||
|
|
||||||
OSX:
|
OSX:
|
||||||
|
|
||||||
|
- Implement auto-completion support in wxTextEntry.
|
||||||
- Implement switching to default video mode in wxDisplay (soren).
|
- Implement switching to default video mode in wxDisplay (soren).
|
||||||
|
|
||||||
|
|
||||||
|
@@ -32,12 +32,8 @@ class WXDLLIMPEXP_CORE wxTextEntry: public wxTextEntryBase
|
|||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
wxTextEntry()
|
wxTextEntry();
|
||||||
: m_editable(true),
|
virtual ~wxTextEntry();
|
||||||
m_maxLength(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual ~wxTextEntry() {};
|
|
||||||
|
|
||||||
virtual bool IsEditable() const;
|
virtual bool IsEditable() const;
|
||||||
|
|
||||||
@@ -88,10 +84,18 @@ public:
|
|||||||
// --------------
|
// --------------
|
||||||
|
|
||||||
virtual wxTextWidgetImpl * GetTextPeer() const;
|
virtual wxTextWidgetImpl * GetTextPeer() const;
|
||||||
|
wxTextCompleter *OSXGetCompleter() const { return m_completer; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual wxString DoGetValue() const;
|
virtual wxString DoGetValue() const;
|
||||||
|
|
||||||
|
virtual bool DoAutoCompleteStrings(const wxArrayString& choices);
|
||||||
|
virtual bool DoAutoCompleteCustom(wxTextCompleter *completer);
|
||||||
|
|
||||||
|
// The object providing auto-completions or NULL if none.
|
||||||
|
wxTextCompleter *m_completer;
|
||||||
|
|
||||||
bool m_editable;
|
bool m_editable;
|
||||||
|
|
||||||
// need to make this public because of the current implementation via callbacks
|
// need to make this public because of the current implementation via callbacks
|
||||||
|
@@ -46,8 +46,8 @@ public:
|
|||||||
Call this function to enable auto-completion of the text typed in a
|
Call this function to enable auto-completion of the text typed in a
|
||||||
single-line text control using the given @a choices.
|
single-line text control using the given @a choices.
|
||||||
|
|
||||||
Notice that currently this function is only implemented in wxGTK2 and
|
Notice that currently this function is only implemented in wxGTK2,
|
||||||
wxMSW ports and does nothing under the other platforms.
|
wxMSW and wxOSX/Cocoa ports and does nothing under the other platforms.
|
||||||
|
|
||||||
@since 2.9.0
|
@since 2.9.0
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
Notice that you need to include @c wx/textcompleter.h in order to
|
Notice that you need to include @c wx/textcompleter.h in order to
|
||||||
define your class inheriting from wxTextCompleter.
|
define your class inheriting from wxTextCompleter.
|
||||||
|
|
||||||
Currently this method is only implemented in wxMSW port.
|
Currently this method is only implemented in wxMSW and wxOSX/Cocoa.
|
||||||
|
|
||||||
@since 2.9.2
|
@since 2.9.2
|
||||||
|
|
||||||
|
@@ -45,6 +45,7 @@
|
|||||||
#include "wx/filefn.h"
|
#include "wx/filefn.h"
|
||||||
#include "wx/sysopt.h"
|
#include "wx/sysopt.h"
|
||||||
#include "wx/thread.h"
|
#include "wx/thread.h"
|
||||||
|
#include "wx/textcompleter.h"
|
||||||
|
|
||||||
#include "wx/osx/private.h"
|
#include "wx/osx/private.h"
|
||||||
#include "wx/osx/cocoa/private/textimpl.h"
|
#include "wx/osx/cocoa/private/textimpl.h"
|
||||||
@@ -293,21 +294,49 @@ protected :
|
|||||||
forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int*)index
|
forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int*)index
|
||||||
{
|
{
|
||||||
NSMutableArray* matches = NULL;
|
NSMutableArray* matches = NULL;
|
||||||
NSString* partialString;
|
|
||||||
|
|
||||||
partialString = [[textView string] substringWithRange:charRange];
|
wxTextWidgetImpl* impl = (wxNSTextFieldControl * ) wxWidgetImpl::FindFromWXWidget( self );
|
||||||
matches = [NSMutableArray array];
|
wxTextEntry * const entry = impl->GetTextEntry();
|
||||||
|
wxTextCompleter * const completer = entry->OSXGetCompleter();
|
||||||
|
if ( completer )
|
||||||
|
{
|
||||||
|
const wxString prefix = entry->GetValue();
|
||||||
|
if ( completer->Start(prefix) )
|
||||||
|
{
|
||||||
|
const wxString
|
||||||
|
wordStart = wxCFStringRef::AsString(
|
||||||
|
[[textView string] substringWithRange:charRange]
|
||||||
|
);
|
||||||
|
|
||||||
wxTextWidgetImpl* impl = (wxTextWidgetImpl* ) wxWidgetImpl::FindFromWXWidget( self );
|
matches = [NSMutableArray array];
|
||||||
wxArrayString completions;
|
for ( ;; )
|
||||||
|
{
|
||||||
|
const wxString s = completer->GetNext();
|
||||||
|
if ( s.empty() )
|
||||||
|
break;
|
||||||
|
|
||||||
// adapt to whatever strategy we have for getting the strings
|
// Normally the completer should return only the strings
|
||||||
// impl->GetTextEntry()->GetCompletions(wxCFStringRef::AsString(partialString), completions);
|
// starting with the prefix, but there could be exceptions
|
||||||
|
// and, for compatibility with MSW which simply ignores all
|
||||||
for (size_t i = 0; i < completions.GetCount(); ++i )
|
// entries that don't match the current text control contents,
|
||||||
[matches addObject: wxCFStringRef(completions[i]).AsNSString()];
|
// we ignore them as well. Besides, our own wxTextCompleterFixed
|
||||||
|
// doesn't respect this rule and, moreover, we need to extract
|
||||||
// [matches sortUsingSelector:@selector(compare:)];
|
// just the rest of the string anyhow.
|
||||||
|
wxString completion;
|
||||||
|
if ( s.StartsWith(prefix, &completion) )
|
||||||
|
{
|
||||||
|
// We discarded the entire prefix above but actually we
|
||||||
|
// should include the part of it that consists of the
|
||||||
|
// beginning of the current word, otherwise it would be
|
||||||
|
// lost when completion is accepted as OS X supposes that
|
||||||
|
// our matches do start with the "partial word range"
|
||||||
|
// passed to us.
|
||||||
|
const wxCFStringRef fullWord(wordStart + completion);
|
||||||
|
[matches addObject: fullWord.AsNSString()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
@@ -45,9 +45,22 @@
|
|||||||
#include "wx/filefn.h"
|
#include "wx/filefn.h"
|
||||||
#include "wx/sysopt.h"
|
#include "wx/sysopt.h"
|
||||||
#include "wx/thread.h"
|
#include "wx/thread.h"
|
||||||
|
#include "wx/textcompleter.h"
|
||||||
|
|
||||||
#include "wx/osx/private.h"
|
#include "wx/osx/private.h"
|
||||||
|
|
||||||
|
wxTextEntry::wxTextEntry()
|
||||||
|
{
|
||||||
|
m_completer = NULL;
|
||||||
|
m_editable = true;
|
||||||
|
m_maxLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxTextEntry::~wxTextEntry()
|
||||||
|
{
|
||||||
|
delete m_completer;
|
||||||
|
}
|
||||||
|
|
||||||
wxString wxTextEntry::DoGetValue() const
|
wxString wxTextEntry::DoGetValue() const
|
||||||
{
|
{
|
||||||
return GetTextPeer()->GetStringValue() ;
|
return GetTextPeer()->GetStringValue() ;
|
||||||
@@ -224,4 +237,23 @@ wxTextWidgetImpl * wxTextEntry::GetTextPeer() const
|
|||||||
return win ? dynamic_cast<wxTextWidgetImpl *>(win->GetPeer()) : NULL;
|
return win ? dynamic_cast<wxTextWidgetImpl *>(win->GetPeer()) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Auto-completion
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxTextEntry::DoAutoCompleteStrings(const wxArrayString& choices)
|
||||||
|
{
|
||||||
|
wxTextCompleterFixed * const completer = new wxTextCompleterFixed;
|
||||||
|
completer->SetCompletions(choices);
|
||||||
|
|
||||||
|
return DoAutoCompleteCustom(completer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTextEntry::DoAutoCompleteCustom(wxTextCompleter *completer)
|
||||||
|
{
|
||||||
|
m_completer = completer;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_TEXTCTRL
|
#endif // wxUSE_TEXTCTRL
|
||||||
|
Reference in New Issue
Block a user