266 lines
6.7 KiB
C++
266 lines
6.7 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/qt/choice.cpp
|
|
// Author: Peter Most, Mariano Reingart
|
|
// Copyright: (c) 2010 wxWidgets dev team
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#include "wx/choice.h"
|
|
#include "wx/qt/private/winevent.h"
|
|
|
|
#include <QtWidgets/QComboBox>
|
|
#include <QtCore/QSortFilterProxyModel>
|
|
|
|
namespace
|
|
{
|
|
|
|
class LexicalSortProxyModel : public QSortFilterProxyModel
|
|
{
|
|
public:
|
|
explicit LexicalSortProxyModel(QObject* owner) : QSortFilterProxyModel(owner) {}
|
|
|
|
bool lessThan( const QModelIndex &left, const QModelIndex &right ) const wxOVERRIDE
|
|
{
|
|
const QVariant leftData = sourceModel()->data( left );
|
|
const QVariant rightData = sourceModel()->data( right );
|
|
|
|
if ( leftData.type() != QVariant::String )
|
|
return false;
|
|
|
|
int insensitiveResult = QString::compare(
|
|
leftData.value<QString>(),
|
|
rightData.value<QString>(),
|
|
Qt::CaseInsensitive );
|
|
|
|
if ( insensitiveResult == 0 )
|
|
{
|
|
return QString::compare( leftData.value<QString>(),
|
|
rightData.value<QString>() ) < 0;
|
|
}
|
|
|
|
return insensitiveResult < 0;
|
|
}
|
|
};
|
|
|
|
class wxQtChoice : public wxQtEventSignalHandler< QComboBox, wxChoice >
|
|
{
|
|
public:
|
|
wxQtChoice( wxWindow *parent, wxChoice *handler );
|
|
|
|
private:
|
|
void activated(int index);
|
|
};
|
|
|
|
wxQtChoice::wxQtChoice( wxWindow *parent, wxChoice *handler )
|
|
: wxQtEventSignalHandler< QComboBox, wxChoice >( parent, handler )
|
|
{
|
|
// the activated signal is overloaded, the following explicit cast is needed:
|
|
connect(this, static_cast<void (QComboBox::*)(int index)>(&QComboBox::activated),
|
|
this, &wxQtChoice::activated);
|
|
}
|
|
|
|
void wxQtChoice::activated(int WXUNUSED(index))
|
|
{
|
|
wxChoice *handler = GetHandler();
|
|
if ( handler )
|
|
handler->SendSelectionChangedEvent(wxEVT_CHOICE);
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
wxChoice::wxChoice() :
|
|
m_qtComboBox(NULL)
|
|
{
|
|
}
|
|
|
|
void wxChoice::QtInitSort( QComboBox *combo )
|
|
{
|
|
QSortFilterProxyModel *proxyModel = new LexicalSortProxyModel(combo);
|
|
proxyModel->setSourceModel(combo->model());
|
|
combo->model()->setParent(proxyModel);
|
|
combo->setModel(proxyModel);
|
|
}
|
|
|
|
|
|
wxChoice::wxChoice( wxWindow *parent, wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
int n, const wxString choices[],
|
|
long style,
|
|
const wxValidator& validator,
|
|
const wxString& name )
|
|
{
|
|
Create( parent, id, pos, size, n, choices, style, validator, name );
|
|
}
|
|
|
|
|
|
wxChoice::wxChoice( wxWindow *parent, wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
const wxArrayString& choices,
|
|
long style,
|
|
const wxValidator& validator,
|
|
const wxString& name )
|
|
{
|
|
Create( parent, id, pos, size, choices, style, validator, name );
|
|
}
|
|
|
|
|
|
bool wxChoice::Create( wxWindow *parent, wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
const wxArrayString& choices,
|
|
long style,
|
|
const wxValidator& validator,
|
|
const wxString& name )
|
|
{
|
|
return Create( parent, id, pos, size, choices.size(), choices.size() ? &choices[ 0 ] : NULL, style,
|
|
validator, name );
|
|
}
|
|
|
|
|
|
bool wxChoice::Create( wxWindow *parent, wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
int n, const wxString choices[],
|
|
long style,
|
|
const wxValidator& validator,
|
|
const wxString& name )
|
|
{
|
|
m_qtComboBox = new wxQtChoice( parent, this );
|
|
|
|
QtInitSort( m_qtComboBox );
|
|
|
|
while ( n-- > 0 )
|
|
m_qtComboBox->addItem( wxQtConvertString( *choices++ ));
|
|
|
|
return QtCreateControl( parent, id, pos, size, style, validator, name );
|
|
}
|
|
|
|
wxSize wxChoice::DoGetBestSize() const
|
|
{
|
|
wxSize basesize = wxChoiceBase::DoGetBestSize();
|
|
wxSize size = wxControl::DoGetBestSize();
|
|
// mix calculated size by wx base prioritizing qt hint (max):
|
|
if (size.GetWidth() < basesize.GetWidth())
|
|
size.SetWidth(basesize.GetWidth());
|
|
if (size.GetHeight() < basesize.GetHeight())
|
|
size.SetHeight(basesize.GetHeight());
|
|
return size;
|
|
}
|
|
|
|
|
|
unsigned wxChoice::GetCount() const
|
|
{
|
|
return m_qtComboBox->count();
|
|
}
|
|
|
|
wxString wxChoice::GetString(unsigned int n) const
|
|
{
|
|
return wxQtConvertString( m_qtComboBox->itemText(n) );
|
|
}
|
|
|
|
void wxChoice::SetString(unsigned int n, const wxString& s)
|
|
{
|
|
m_qtComboBox->setItemText(n, wxQtConvertString(s));
|
|
}
|
|
|
|
|
|
void wxChoice::SetSelection(int n)
|
|
{
|
|
m_qtComboBox->blockSignals(true);
|
|
m_qtComboBox->setCurrentIndex(n);
|
|
m_qtComboBox->blockSignals(false);
|
|
}
|
|
|
|
int wxChoice::GetSelection() const
|
|
{
|
|
return m_qtComboBox->currentIndex();
|
|
}
|
|
|
|
|
|
int wxChoice::DoInsertItems(const wxArrayStringsAdapter & items,
|
|
unsigned int pos,
|
|
void **clientData,
|
|
wxClientDataType type)
|
|
{
|
|
InvalidateBestSize();
|
|
|
|
// Hack: to avoid resorting the model many times in DoInsertOneItem(),
|
|
// which will be called for each item from DoInsertItemsInLoop(), reset the
|
|
// wxCB_SORT style if we have it temporarily and only sort once at the end.
|
|
bool wasSorted = false;
|
|
if ( IsSorted() )
|
|
{
|
|
wasSorted = true;
|
|
ToggleWindowStyle(wxCB_SORT);
|
|
}
|
|
|
|
int n = DoInsertItemsInLoop(items, pos, clientData, type);
|
|
|
|
if ( wasSorted )
|
|
{
|
|
// Restore the flag turned off above.
|
|
ToggleWindowStyle(wxCB_SORT);
|
|
|
|
// And actually sort items now.
|
|
m_qtComboBox->model()->sort(0);
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
int wxChoice::DoInsertOneItem(const wxString& item, unsigned int pos)
|
|
{
|
|
// Maintain unselected state
|
|
const bool unselected = m_qtComboBox->currentIndex() == -1;
|
|
|
|
m_qtComboBox->insertItem(pos, wxQtConvertString(item));
|
|
|
|
if ( IsSorted() )
|
|
m_qtComboBox->model()->sort(0);
|
|
|
|
if ( unselected )
|
|
m_qtComboBox->setCurrentIndex(-1);
|
|
|
|
return pos;
|
|
}
|
|
|
|
void wxChoice::DoSetItemClientData(unsigned int n, void *clientData)
|
|
{
|
|
QVariant variant = qVariantFromValue(clientData);
|
|
m_qtComboBox->setItemData(n, variant);
|
|
}
|
|
|
|
void *wxChoice::DoGetItemClientData(unsigned int n) const
|
|
{
|
|
QVariant variant = m_qtComboBox->itemData(n);
|
|
return variant.value<void *>();
|
|
}
|
|
|
|
|
|
void wxChoice::DoClear()
|
|
{
|
|
m_qtComboBox->clear();
|
|
}
|
|
|
|
void wxChoice::DoDeleteOneItem(unsigned int pos)
|
|
{
|
|
const int selection = GetSelection();
|
|
|
|
if ( selection >= 0 && static_cast<unsigned int>(selection) == pos )
|
|
{
|
|
SetSelection( wxNOT_FOUND );
|
|
}
|
|
m_qtComboBox->removeItem(pos);
|
|
}
|
|
|
|
QWidget *wxChoice::GetHandle() const
|
|
{
|
|
return m_qtComboBox;
|
|
}
|