Use ACO_AUTOAPPEND option for text completion in wxMSW.
This option appends the first candidate completion value to the text control itself making it more user-friendly as it reduces the amount of typing needed to enter it. See #11465. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67513 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
1afe4f9b47
commit
b9a46ea5a2
@ -194,7 +194,7 @@ public:
|
|||||||
m_enumStrings = NULL;
|
m_enumStrings = NULL;
|
||||||
m_customCompleter = NULL;
|
m_customCompleter = NULL;
|
||||||
|
|
||||||
m_connectedTextChangedEvent = false;
|
m_connectedCharEvent = false;
|
||||||
|
|
||||||
// Create an object exposing IAutoComplete interface which we'll later
|
// Create an object exposing IAutoComplete interface which we'll later
|
||||||
// use to get IAutoComplete2 as the latter can't be created directly,
|
// use to get IAutoComplete2 as the latter can't be created directly,
|
||||||
@ -255,6 +255,7 @@ public:
|
|||||||
if ( SUCCEEDED(hr) )
|
if ( SUCCEEDED(hr) )
|
||||||
{
|
{
|
||||||
pAutoComplete2->SetOptions(ACO_AUTOSUGGEST |
|
pAutoComplete2->SetOptions(ACO_AUTOSUGGEST |
|
||||||
|
ACO_AUTOAPPEND |
|
||||||
ACO_UPDOWNKEYDROPSLIST);
|
ACO_UPDOWNKEYDROPSLIST);
|
||||||
pAutoComplete2->Release();
|
pAutoComplete2->Release();
|
||||||
}
|
}
|
||||||
@ -297,13 +298,25 @@ public:
|
|||||||
// We postpone connecting to this event until we really need to do
|
// We postpone connecting to this event until we really need to do
|
||||||
// it (however we don't disconnect from it when we don't need it
|
// it (however we don't disconnect from it when we don't need it
|
||||||
// any more because we don't have wxUNBIND_OR_DISCONNECT_HACK...).
|
// any more because we don't have wxUNBIND_OR_DISCONNECT_HACK...).
|
||||||
if ( !m_connectedTextChangedEvent )
|
if ( !m_connectedCharEvent )
|
||||||
{
|
{
|
||||||
m_connectedTextChangedEvent = true;
|
m_connectedCharEvent = true;
|
||||||
|
|
||||||
wxBIND_OR_CONNECT_HACK(m_win, wxEVT_COMMAND_TEXT_UPDATED,
|
// Use the special wxEVT_AFTER_CHAR and not the usual
|
||||||
wxCommandEventHandler,
|
// wxEVT_CHAR here because we need to have the updated value of
|
||||||
wxTextAutoCompleteData::OnTextChanged,
|
// the text control in this handler in order to provide
|
||||||
|
// completions for the correct prefix and unfortunately we
|
||||||
|
// don't have any way to let DefWindowProc() run from our
|
||||||
|
// wxEVT_CHAR handler (as we must also let the other handlers
|
||||||
|
// defined at wx level run first).
|
||||||
|
//
|
||||||
|
// Notice that we can't use wxEVT_COMMAND_TEXT_UPDATED here
|
||||||
|
// neither as, due to our use of ACO_AUTOAPPEND, we get
|
||||||
|
// EN_CHANGE notifications from the control every time
|
||||||
|
// IAutoComplete auto-appends something to it.
|
||||||
|
wxBIND_OR_CONNECT_HACK(m_win, wxEVT_AFTER_CHAR,
|
||||||
|
wxKeyEventHandler,
|
||||||
|
wxTextAutoCompleteData::OnAfterChar,
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,19 +361,32 @@ private:
|
|||||||
// the currently valid choices according to the custom completer.
|
// the currently valid choices according to the custom completer.
|
||||||
void UpdateStringsFromCustomCompleter()
|
void UpdateStringsFromCustomCompleter()
|
||||||
{
|
{
|
||||||
|
// As we use ACO_AUTOAPPEND, the selected part of the text is usually
|
||||||
|
// the one appended by us so don't consider it as part of the
|
||||||
|
// user-entered prefix.
|
||||||
|
long from, to;
|
||||||
|
m_entry->GetSelection(&from, &to);
|
||||||
|
|
||||||
|
if ( to == from )
|
||||||
|
from = m_entry->GetLastPosition(); // Take all if no selection.
|
||||||
|
|
||||||
|
const wxString prefix = m_entry->GetRange(0, from);
|
||||||
|
|
||||||
// For efficiency we access m_strings directly instead of creating
|
// For efficiency we access m_strings directly instead of creating
|
||||||
// another wxArrayString, normally this should save us an unnecessary
|
// another wxArrayString, normally this should save us an unnecessary
|
||||||
// memory allocation on the subsequent calls.
|
// memory allocation on the subsequent calls.
|
||||||
m_enumStrings->m_strings.clear();
|
m_enumStrings->m_strings.clear();
|
||||||
m_customCompleter->GetCompletions(m_entry->GetValue(),
|
m_customCompleter->GetCompletions(prefix, m_enumStrings->m_strings);
|
||||||
m_enumStrings->m_strings);
|
|
||||||
|
|
||||||
DoRefresh();
|
DoRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnTextChanged(wxCommandEvent& event)
|
void OnAfterChar(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
if ( m_customCompleter )
|
// Notice that we must not refresh the completions when the user
|
||||||
|
// presses Backspace as this would result in adding back the just
|
||||||
|
// erased character(s) because of ACO_AUTOAPPEND option we use.
|
||||||
|
if ( m_customCompleter && event.GetKeyCode() != WXK_BACK )
|
||||||
UpdateStringsFromCustomCompleter();
|
UpdateStringsFromCustomCompleter();
|
||||||
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
@ -386,7 +412,7 @@ private:
|
|||||||
wxTextCompleter *m_customCompleter;
|
wxTextCompleter *m_customCompleter;
|
||||||
|
|
||||||
// Initially false, set to true after connecting OnTextChanged() handler.
|
// Initially false, set to true after connecting OnTextChanged() handler.
|
||||||
bool m_connectedTextChangedEvent;
|
bool m_connectedCharEvent;
|
||||||
|
|
||||||
|
|
||||||
wxDECLARE_NO_COPY_CLASS(wxTextAutoCompleteData);
|
wxDECLARE_NO_COPY_CLASS(wxTextAutoCompleteData);
|
||||||
|
Loading…
Reference in New Issue
Block a user