diff --git a/include/wx/qt/combobox.h b/include/wx/qt/combobox.h index 490e2cb117..bc0222d5cb 100644 --- a/include/wx/qt/combobox.h +++ b/include/wx/qt/combobox.h @@ -52,7 +52,7 @@ public: const wxValidator& validator = wxDefaultValidator, 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 int GetSelection() const wxOVERRIDE { return wxChoice::GetSelection(); } @@ -70,6 +70,12 @@ public: bool IsTextEmpty() const { return wxTextEntry::IsEmpty(); } 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 Dismiss(); @@ -80,6 +86,7 @@ protected: virtual wxString DoGetValue() const wxOVERRIDE; private: + void SetActualValue(const wxString& value); // From wxTextEntry: virtual wxWindow *GetEditableWindow() wxOVERRIDE { return this; } diff --git a/src/qt/combobox.cpp b/src/qt/combobox.cpp index 3ca015a019..36685b1954 100644 --- a/src/qt/combobox.cpp +++ b/src/qt/combobox.cpp @@ -23,13 +23,37 @@ public: virtual void showPopup() 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(combo)) + { + m_combo->m_textChangeIgnored = true; + } + + ~IgnoreTextChange() + { + m_combo->m_textChangeIgnored = false; + } + + private: + wxQtComboBox* m_combo; + }; + private: void activated(int index); void editTextChanged(const QString &text); + + bool m_textChangeIgnored; }; wxQtComboBox::wxQtComboBox( wxWindow *parent, wxComboBox *handler ) - : wxQtEventSignalHandler< QComboBox, wxComboBox >( parent, handler ) + : wxQtEventSignalHandler< QComboBox, wxComboBox >( parent, handler ), + m_textChangeIgnored( false ) { setEditable( true ); connect(this, static_cast(&QComboBox::activated), @@ -61,6 +85,9 @@ void wxQtComboBox::activated(int WXUNUSED(index)) void wxQtComboBox::editTextChanged(const QString &text) { + if ( m_textChangeIgnored ) + return; + wxComboBox *handler = GetHandler(); 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() { @@ -137,10 +169,12 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id, 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) ) - SetStringSelection(value); + { + SetStringSelection( value ); + } else { 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 { return wxQtConvertString( m_qtComboBox->currentText() ); @@ -171,15 +255,40 @@ void wxComboBox::Clear() void wxComboBox::SetSelection( long from, long to ) { - // SelectAll uses -1 to -1, adjust for qt: - if (from == -1 && to == -1) + if ( from == -1 ) { from = 0; + } + if ( to == -1 ) + { to = GetValue().length(); } + + SetInsertionPoint( from ); // use the inner text entry widget (note that can be null if not editable) 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