/***************************************************************************************************************
**
** CheckComboBox head file
**
** thanks jpn ()
**
*****************************************************************************************************************/
#ifndef CHECKCOMBOBOX_H
#define CHECKCOMBOBOX_H
#include
class CheckComboBox : public QComboBox
{
Q_OBJECT
public:
CheckComboBox( QWidget * parent = 0 , bool bHaveSelectAll=false);
~CheckComboBox();
int addItem(QString text, bool bCheck=false);
void setCheck(int nIndex, bool bCheck);
void SelectAll(bool bCheck);
bool isChecked(int nIndex);
void getSelStringList(QStringList &stSelectedList);
QString getSelString();
public slots:
void _itemCB(const QModelIndex &);
void _editTextChanged ();
private:
QMap _mapSelString;
bool _bHaveSelectAll;
};
#endif
/***************************************************/
#include "CheckComboBox.h"
// CheckView
class CheckView: public QListView
{
public:
CheckView(QWidget* parent = 0): QListView(parent)
{
}
bool eventFilter(QObject* object, QEvent* event)
{
if (event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* mouse = static_cast(event);
QModelIndex index = indexAt(mouse->pos());
if (index.isValid())
{
// check if the mouse was released over the checkbox
QStyleOptionButton option;
option.QStyleOption::operator=(viewOptions());
option.rect = visualRect(index);
QRect rect = style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &option);
if (rect.contains(mouse->pos()))
{
// mouse was release over a checkbox
// bypass combobox and deliver the event just for the listview
QListView::mouseReleaseEvent(mouse);
return true;
}
}
}
return false;
}
};
// CheckModel
class CheckModel: public QStandardItemModel
{
public:
CheckModel(QObject* parent = 0): QStandardItemModel(parent)
{
// a must
insertColumn(0);
}
Qt::ItemFlags flags(const QModelIndex& index) const
{
return QStandardItemModel::flags(index) | Qt::ItemIsUserCheckable;
}
};
// CheckComboBox
CheckComboBox::CheckComboBox (QWidget * parent , bool bHaveSelectAll/*=false*/) : QComboBox(parent)
{
setEditable(true);
lineEdit()->setReadOnly(true);
connect(lineEdit(), SIGNAL(textChanged(const QString &)), this, SLOT(_editTextChanged ()));
CheckModel* model = new CheckModel(this);
CheckView* view = new CheckView(this);
setModel(model);
setView(view);
// these 2 lines below are important and must be
// applied AFTER QComboBox::setView() because
// QComboBox installs it's own filter on the view
view->installEventFilter(view); // <--- !!!
view->viewport()->installEventFilter(view); // <--- !!!
setMinimumWidth(100);
connect(view, SIGNAL(clicked(const QModelIndex &)), this, SLOT(_itemCB(const QModelIndex &)));
_bHaveSelectAll = bHaveSelectAll;
if(bHaveSelectAll)
{
addItem(tr("Select All"));
}
}
CheckComboBox::~CheckComboBox()
{
_mapSelString.empty();
}
int CheckComboBox::addItem(QString text, bool bCheck/*=false*/)
{
QComboBox::addItem(text);
int nCount = count();
setCheck(nCount-1, bCheck);
return nCount-1;
}
void CheckComboBox::setCheck(int nIndex, bool bCheck)
{
int nCount = count();
if(nIndex<0 || nIndex>=nCount) return;
if(bCheck)
{
QComboBox::setItemData(nIndex, Qt::Checked, Qt::CheckStateRole);
if(_mapSelString.find(nIndex) == _mapSelString.end())
{
QString str = QComboBox::itemText(nIndex);
_mapSelString.insert(nIndex, str);
}
}
else
{
QComboBox::setItemData(nIndex, Qt::Unchecked, Qt::CheckStateRole);
if(_mapSelString.find(nIndex) != _mapSelString.end())
_mapSelString.remove(nIndex);
}
_editTextChanged ();
}
bool CheckComboBox::isChecked(int nIndex)
{
int nCount = count();
if(nIndex<0 || nIndex>=nCount) return false;
QVariant var = QComboBox::itemData(nIndex, Qt::CheckStateRole);
if(var == Qt::Checked)
return true;
else
return false;
}
void CheckComboBox::_itemCB(const QModelIndex & index)
{
int nIndex = index.row();
if(_bHaveSelectAll && nIndex == 0)
{
SelectAll(isChecked(nIndex));
}
else
{
QString str = this->itemText(nIndex);
if(isChecked(nIndex))
{
if(_mapSelString.find(nIndex) == _mapSelString.end())
_mapSelString.insert(nIndex, str);
}
else
{
if(_bHaveSelectAll)
{
setCheck(0, false);
}
if(_mapSelString.find(nIndex) != _mapSelString.end())
_mapSelString.remove(nIndex);
}
_editTextChanged();
}
}
void CheckComboBox::_editTextChanged ()
{
QString str;
int nStart = 0;
if(_bHaveSelectAll) nStart = 1;
for (int i=nStart; i< count(); i++)
{
if(_mapSelString.value(i)!="")
{
str += _mapSelString.value(i);
str += ";";
}
}
this->setEditText(str);
lineEdit()->setCursorPosition(0);
this->setToolTip(str);
}
void CheckComboBox::getSelStringList(QStringList &stSelectedList)
{
stSelectedList.empty();
int nStart = 0;
if(_bHaveSelectAll) nStart = 1;
for (int i=nStart; i< count(); i++)
{
if(_mapSelString.value(i)!="")
{
stSelectedList.append(_mapSelString.value(i));
}
}
}
QString CheckComboBox::getSelString()
{
QString str;
int nStart = 0;
if(_bHaveSelectAll) nStart = 1;
for (int i=nStart; i< count(); i++)
{
if(_mapSelString.value(i)!="")
{
str += _mapSelString.value(i);
str += ";";
}
}
return str;
}
void CheckComboBox::SelectAll(bool bCheck)
{
for(int i=0; i {
setCheck(i, bCheck);
}
}