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:
|
||||
|
||||
- Implement auto-completion support in wxTextEntry.
|
||||
- Implement switching to default video mode in wxDisplay (soren).
|
||||
|
||||
|
||||
|
@@ -32,12 +32,8 @@ class WXDLLIMPEXP_CORE wxTextEntry: public wxTextEntryBase
|
||||
{
|
||||
|
||||
public:
|
||||
wxTextEntry()
|
||||
: m_editable(true),
|
||||
m_maxLength(0)
|
||||
{ }
|
||||
|
||||
virtual ~wxTextEntry() {};
|
||||
wxTextEntry();
|
||||
virtual ~wxTextEntry();
|
||||
|
||||
virtual bool IsEditable() const;
|
||||
|
||||
@@ -88,10 +84,18 @@ public:
|
||||
// --------------
|
||||
|
||||
virtual wxTextWidgetImpl * GetTextPeer() const;
|
||||
wxTextCompleter *OSXGetCompleter() const { return m_completer; }
|
||||
|
||||
protected:
|
||||
|
||||
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;
|
||||
|
||||
// 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
|
||||
single-line text control using the given @a choices.
|
||||
|
||||
Notice that currently this function is only implemented in wxGTK2 and
|
||||
wxMSW ports and does nothing under the other platforms.
|
||||
Notice that currently this function is only implemented in wxGTK2,
|
||||
wxMSW and wxOSX/Cocoa ports and does nothing under the other platforms.
|
||||
|
||||
@since 2.9.0
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
Notice that you need to include @c wx/textcompleter.h in order to
|
||||
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
|
||||
|
||||
|
@@ -45,6 +45,7 @@
|
||||
#include "wx/filefn.h"
|
||||
#include "wx/sysopt.h"
|
||||
#include "wx/thread.h"
|
||||
#include "wx/textcompleter.h"
|
||||
|
||||
#include "wx/osx/private.h"
|
||||
#include "wx/osx/cocoa/private/textimpl.h"
|
||||
@@ -293,21 +294,49 @@ protected :
|
||||
forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int*)index
|
||||
{
|
||||
NSMutableArray* matches = NULL;
|
||||
NSString* partialString;
|
||||
|
||||
partialString = [[textView string] substringWithRange:charRange];
|
||||
wxTextWidgetImpl* impl = (wxNSTextFieldControl * ) wxWidgetImpl::FindFromWXWidget( self );
|
||||
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]
|
||||
);
|
||||
|
||||
matches = [NSMutableArray array];
|
||||
for ( ;; )
|
||||
{
|
||||
const wxString s = completer->GetNext();
|
||||
if ( s.empty() )
|
||||
break;
|
||||
|
||||
wxTextWidgetImpl* impl = (wxTextWidgetImpl* ) wxWidgetImpl::FindFromWXWidget( self );
|
||||
wxArrayString completions;
|
||||
|
||||
// adapt to whatever strategy we have for getting the strings
|
||||
// impl->GetTextEntry()->GetCompletions(wxCFStringRef::AsString(partialString), completions);
|
||||
|
||||
for (size_t i = 0; i < completions.GetCount(); ++i )
|
||||
[matches addObject: wxCFStringRef(completions[i]).AsNSString()];
|
||||
|
||||
// [matches sortUsingSelector:@selector(compare:)];
|
||||
// Normally the completer should return only the strings
|
||||
// starting with the prefix, but there could be exceptions
|
||||
// and, for compatibility with MSW which simply ignores all
|
||||
// entries that don't match the current text control contents,
|
||||
// we ignore them as well. Besides, our own wxTextCompleterFixed
|
||||
// doesn't respect this rule and, moreover, we need to extract
|
||||
// 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;
|
||||
}
|
||||
|
@@ -45,9 +45,22 @@
|
||||
#include "wx/filefn.h"
|
||||
#include "wx/sysopt.h"
|
||||
#include "wx/thread.h"
|
||||
#include "wx/textcompleter.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
|
||||
{
|
||||
return GetTextPeer()->GetStringValue() ;
|
||||
@@ -224,4 +237,23 @@ wxTextWidgetImpl * wxTextEntry::GetTextPeer() const
|
||||
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
|
||||
|
Reference in New Issue
Block a user