Don't make the combobox unconditionally editable, but only do this if wxCB_READONLY is not specified. Closes https://github.com/wxWidgets/wxWidgets/pull/1207
309 lines
7.8 KiB
C++
309 lines
7.8 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/qt/combobox.cpp
|
|
// Author: Peter Most, Mariano Reingart
|
|
// Copyright: (c) 2009 wxWidgets dev team
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#include "wx/combobox.h"
|
|
#include "wx/window.h"
|
|
#include "wx/qt/private/converter.h"
|
|
#include "wx/qt/private/winevent.h"
|
|
|
|
#include <QtWidgets/QComboBox>
|
|
#include <QtWidgets/QLineEdit>
|
|
|
|
class wxQtComboBox : public wxQtEventSignalHandler< QComboBox, wxComboBox >
|
|
{
|
|
public:
|
|
wxQtComboBox( wxWindow *parent, wxComboBox *handler );
|
|
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<wxQtComboBox*>(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 ),
|
|
m_textChangeIgnored( false )
|
|
{
|
|
connect(this, static_cast<void (QComboBox::*)(int index)>(&QComboBox::activated),
|
|
this, &wxQtComboBox::activated);
|
|
connect(this, &QComboBox::editTextChanged,
|
|
this, &wxQtComboBox::editTextChanged);
|
|
}
|
|
|
|
void wxQtComboBox::showPopup()
|
|
{
|
|
wxCommandEvent event( wxEVT_COMBOBOX_DROPDOWN, GetHandler()->GetId() );
|
|
EmitEvent( event );
|
|
QComboBox::showPopup();
|
|
}
|
|
|
|
void wxQtComboBox::hidePopup()
|
|
{
|
|
wxCommandEvent event( wxEVT_COMBOBOX_CLOSEUP, GetHandler()->GetId() );
|
|
EmitEvent( event );
|
|
QComboBox::hidePopup();
|
|
}
|
|
|
|
void wxQtComboBox::activated(int WXUNUSED(index))
|
|
{
|
|
wxComboBox *handler = GetHandler();
|
|
if ( handler )
|
|
handler->SendSelectionChangedEvent(wxEVT_COMBOBOX);
|
|
}
|
|
|
|
void wxQtComboBox::editTextChanged(const QString &text)
|
|
{
|
|
if ( m_textChangeIgnored )
|
|
return;
|
|
|
|
wxComboBox *handler = GetHandler();
|
|
if ( handler )
|
|
{
|
|
wxCommandEvent event( wxEVT_TEXT, handler->GetId() );
|
|
event.SetString( wxQtConvertString( text ) );
|
|
EmitEvent( event );
|
|
}
|
|
}
|
|
|
|
void wxComboBox::SetSelection( int n )
|
|
{
|
|
wxQtComboBox::IgnoreTextChange ignore( m_qtComboBox );
|
|
wxChoice::SetSelection( n );
|
|
}
|
|
|
|
wxComboBox::wxComboBox()
|
|
{
|
|
}
|
|
|
|
|
|
wxComboBox::wxComboBox(wxWindow *parent,
|
|
wxWindowID id,
|
|
const wxString& value,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
int n, const wxString choices[],
|
|
long style,
|
|
const wxValidator& validator,
|
|
const wxString& name )
|
|
{
|
|
Create( parent, id, value, pos, size, n, choices, style, validator, name );
|
|
}
|
|
|
|
|
|
wxComboBox::wxComboBox(wxWindow *parent, wxWindowID id,
|
|
const wxString& value,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
const wxArrayString& choices,
|
|
long style,
|
|
const wxValidator& validator,
|
|
const wxString& name )
|
|
{
|
|
Create( parent, id, value, pos, size, choices, style, validator, name );
|
|
}
|
|
|
|
|
|
bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
|
|
const wxString& value,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
const wxArrayString& choices,
|
|
long style,
|
|
const wxValidator& validator,
|
|
const wxString& name )
|
|
{
|
|
const wxString *pChoices = choices.size() ? &choices[ 0 ] : NULL;
|
|
return Create(parent, id, value, pos, size, choices.size(), pChoices,
|
|
style, validator, name );
|
|
}
|
|
|
|
|
|
bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
|
|
const wxString& value,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
int n, const wxString choices[],
|
|
long style,
|
|
const wxValidator& validator,
|
|
const wxString& name )
|
|
{
|
|
m_qtComboBox = new wxQtComboBox( parent, this );
|
|
m_qtComboBox->setEditable(!(style & wxCB_READONLY));
|
|
QtInitSort( m_qtComboBox );
|
|
|
|
while ( n-- > 0 )
|
|
m_qtComboBox->addItem( wxQtConvertString( *choices++ ));
|
|
m_qtComboBox->setEditText( wxQtConvertString( value ));
|
|
|
|
return QtCreateControl( parent, id, pos, size, style, validator, name );
|
|
}
|
|
|
|
void wxComboBox::SetActualValue(const wxString &value)
|
|
{
|
|
if ( HasFlag(wxCB_READONLY) )
|
|
{
|
|
SetStringSelection( value );
|
|
}
|
|
else
|
|
{
|
|
wxTextEntry::SetValue(value);
|
|
m_qtComboBox->setEditText( wxQtConvertString(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() );
|
|
}
|
|
|
|
void wxComboBox::Popup()
|
|
{
|
|
static_cast<QComboBox *>(GetHandle())->showPopup();
|
|
}
|
|
|
|
void wxComboBox::Dismiss()
|
|
{
|
|
static_cast<QComboBox *>(GetHandle())->hidePopup();
|
|
}
|
|
|
|
void wxComboBox::Clear()
|
|
{
|
|
wxTextEntry::Clear();
|
|
wxItemContainer::Clear();
|
|
}
|
|
|
|
void wxComboBox::SetSelection( long from, long to )
|
|
{
|
|
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 - 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
|
|
{
|
|
// use the inner text entry widget (note that can be null if not editable)
|
|
if ( m_qtComboBox->lineEdit() != NULL )
|
|
{
|
|
*from = m_qtComboBox->lineEdit()->selectionStart();
|
|
if ( *from >= 0 )
|
|
{
|
|
*to = *from + m_qtComboBox->lineEdit()->selectedText().length();
|
|
return;
|
|
}
|
|
}
|
|
// No selection or text control, call base for default behaviour:
|
|
wxTextEntry::GetSelection(from, to);
|
|
}
|