Fix wxComboBox implementation of wxTextEntry interface

Implement missing methods and send, or suppress, the expected events.
This commit is contained in:
Richard Smith
2019-01-17 12:00:01 +00:00
committed by Vadim Zeitlin
parent 1a7f9124b6
commit 3618356cf1
2 changed files with 123 additions and 7 deletions

View File

@@ -52,7 +52,7 @@ public:
const wxValidator& validator = wxDefaultValidator, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxComboBoxNameStr); const wxString& name = wxComboBoxNameStr);
virtual void SetSelection(int n) wxOVERRIDE { wxChoice::SetSelection(n); } virtual void SetSelection(int n) wxOVERRIDE;
virtual void SetSelection(long from, long to) wxOVERRIDE; virtual void SetSelection(long from, long to) wxOVERRIDE;
virtual int GetSelection() const wxOVERRIDE { return wxChoice::GetSelection(); } virtual int GetSelection() const wxOVERRIDE { return wxChoice::GetSelection(); }
@@ -70,6 +70,12 @@ public:
bool IsTextEmpty() const { return wxTextEntry::IsEmpty(); } bool IsTextEmpty() const { return wxTextEntry::IsEmpty(); }
virtual void SetValue(const wxString& value) wxOVERRIDE; virtual void SetValue(const wxString& value) wxOVERRIDE;
virtual void ChangeValue(const wxString& value) wxOVERRIDE;
virtual void AppendText(const wxString &value) wxOVERRIDE;
virtual void Replace(long from, long to, const wxString &value) wxOVERRIDE;
virtual void WriteText(const wxString &value) wxOVERRIDE;
virtual void SetInsertionPoint(long insertion) wxOVERRIDE;
virtual long GetInsertionPoint() const wxOVERRIDE;
virtual void Popup(); virtual void Popup();
virtual void Dismiss(); virtual void Dismiss();
@@ -80,6 +86,7 @@ protected:
virtual wxString DoGetValue() const wxOVERRIDE; virtual wxString DoGetValue() const wxOVERRIDE;
private: private:
void SetActualValue(const wxString& value);
// From wxTextEntry: // From wxTextEntry:
virtual wxWindow *GetEditableWindow() wxOVERRIDE { return this; } virtual wxWindow *GetEditableWindow() wxOVERRIDE { return this; }

View File

@@ -23,13 +23,37 @@ public:
virtual void showPopup() wxOVERRIDE; virtual void showPopup() wxOVERRIDE;
virtual void hidePopup() wxOVERRIDE; virtual void hidePopup() wxOVERRIDE;
class IgnoreTextChange
{
public:
// Note that wxComboBox inherits its QComboBox pointer from wxChoice,
// where it can't be stored as wxQtComboBox, but its dynamic type is
// nevertheless always wxQtComboBox, so the cast below is safe.
explicit IgnoreTextChange(QComboBox *combo)
: m_combo(static_cast<wxQtComboBox*>(combo))
{
m_combo->m_textChangeIgnored = true;
}
~IgnoreTextChange()
{
m_combo->m_textChangeIgnored = false;
}
private:
wxQtComboBox* m_combo;
};
private: private:
void activated(int index); void activated(int index);
void editTextChanged(const QString &text); void editTextChanged(const QString &text);
bool m_textChangeIgnored;
}; };
wxQtComboBox::wxQtComboBox( wxWindow *parent, wxComboBox *handler ) wxQtComboBox::wxQtComboBox( wxWindow *parent, wxComboBox *handler )
: wxQtEventSignalHandler< QComboBox, wxComboBox >( parent, handler ) : wxQtEventSignalHandler< QComboBox, wxComboBox >( parent, handler ),
m_textChangeIgnored( false )
{ {
setEditable( true ); setEditable( true );
connect(this, static_cast<void (QComboBox::*)(int index)>(&QComboBox::activated), connect(this, static_cast<void (QComboBox::*)(int index)>(&QComboBox::activated),
@@ -61,6 +85,9 @@ void wxQtComboBox::activated(int WXUNUSED(index))
void wxQtComboBox::editTextChanged(const QString &text) void wxQtComboBox::editTextChanged(const QString &text)
{ {
if ( m_textChangeIgnored )
return;
wxComboBox *handler = GetHandler(); wxComboBox *handler = GetHandler();
if ( handler ) if ( handler )
{ {
@@ -70,6 +97,11 @@ void wxQtComboBox::editTextChanged(const QString &text)
} }
} }
void wxComboBox::SetSelection( int n )
{
wxQtComboBox::IgnoreTextChange ignore( m_qtComboBox );
wxChoice::SetSelection( n );
}
wxComboBox::wxComboBox() wxComboBox::wxComboBox()
{ {
@@ -137,10 +169,12 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
return QtCreateControl( parent, id, pos, size, style, validator, name ); return QtCreateControl( parent, id, pos, size, style, validator, name );
} }
void wxComboBox::SetValue(const wxString& value) void wxComboBox::SetActualValue(const wxString &value)
{ {
if ( HasFlag(wxCB_READONLY) ) if ( HasFlag(wxCB_READONLY) )
SetStringSelection(value); {
SetStringSelection( value );
}
else else
{ {
wxTextEntry::SetValue(value); wxTextEntry::SetValue(value);
@@ -148,6 +182,56 @@ void wxComboBox::SetValue(const wxString& value)
} }
} }
void wxComboBox::SetValue(const wxString& value)
{
SetActualValue( value );
SetInsertionPoint( 0 );
}
void wxComboBox::ChangeValue(const wxString &value)
{
wxQtComboBox::IgnoreTextChange ignore( m_qtComboBox );
SetValue( value );
}
void wxComboBox::AppendText(const wxString &value)
{
SetActualValue( GetValue() + value );
}
void wxComboBox::Replace(long from, long to, const wxString &value)
{
const wxString original( GetValue() );
if ( to < 0 )
{
to = original.length();
}
if ( from == 0 )
{
SetActualValue( value + original.substr(to, original.length()) );
}
wxString front = original.substr( 0, from ) + value;
long iPoint = front.length();
if ( front.length() <= original.length() )
{
SetActualValue( front + original.substr(to, original.length()) );
}
else
{
SetActualValue( front );
}
SetInsertionPoint( iPoint );
}
void wxComboBox::WriteText(const wxString &value)
{
m_qtComboBox->lineEdit()->insert( wxQtConvertString( value ) );
}
wxString wxComboBox::DoGetValue() const wxString wxComboBox::DoGetValue() const
{ {
return wxQtConvertString( m_qtComboBox->currentText() ); return wxQtConvertString( m_qtComboBox->currentText() );
@@ -171,15 +255,40 @@ void wxComboBox::Clear()
void wxComboBox::SetSelection( long from, long to ) void wxComboBox::SetSelection( long from, long to )
{ {
// SelectAll uses -1 to -1, adjust for qt: if ( from == -1 )
if (from == -1 && to == -1)
{ {
from = 0; from = 0;
}
if ( to == -1 )
{
to = GetValue().length(); to = GetValue().length();
} }
SetInsertionPoint( from );
// use the inner text entry widget (note that can be null if not editable) // use the inner text entry widget (note that can be null if not editable)
if ( m_qtComboBox->lineEdit() != NULL ) if ( m_qtComboBox->lineEdit() != NULL )
m_qtComboBox->lineEdit()->setSelection(from, to); {
m_qtComboBox->lineEdit()->setSelection( from, to - from );
}
}
void wxComboBox::SetInsertionPoint( long pos )
{
// check if pos indicates end of text:
if ( pos == -1 )
m_qtComboBox->lineEdit()->end( false );
else
m_qtComboBox->lineEdit()->setCursorPosition( pos );
}
long wxComboBox::GetInsertionPoint() const
{
long selectionStart = m_qtComboBox->lineEdit()->selectionStart();
if ( selectionStart >= 0 )
return selectionStart;
return m_qtComboBox->lineEdit()->cursorPosition();
} }
void wxComboBox::GetSelection(long* from, long* to) const void wxComboBox::GetSelection(long* from, long* to) const