mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-06-15 04:52:33 -04:00
Add checklist widget
This commit is contained in:
parent
db9ccd9ca8
commit
13ecf0124e
@ -16,6 +16,7 @@ set(sdrgui_SOURCES
|
||||
gui/basicfeaturesettingsdialog.cpp
|
||||
gui/buttonswitch.cpp
|
||||
gui/channeladddialog.cpp
|
||||
gui/checklist.cpp
|
||||
gui/clickablelabel.cpp
|
||||
gui/colordialog.cpp
|
||||
gui/colormapper.cpp
|
||||
@ -146,6 +147,7 @@ set(sdrgui_HEADERS
|
||||
gui/basicfeaturesettingsdialog.h
|
||||
gui/buttonswitch.h
|
||||
gui/channeladddialog.h
|
||||
gui/checklist.h
|
||||
gui/colordialog.h
|
||||
gui/colormapper.h
|
||||
gui/commanditem.h
|
||||
|
172
sdrgui/gui/checklist.cpp
Normal file
172
sdrgui/gui/checklist.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
#include "checklist.h"
|
||||
|
||||
CheckList::CheckList(QWidget* parent) :
|
||||
QComboBox(parent)
|
||||
{
|
||||
m_model = new QStandardItemModel();
|
||||
setModel(m_model);
|
||||
|
||||
setEditable(true);
|
||||
lineEdit()->setReadOnly(true);
|
||||
lineEdit()->installEventFilter(this);
|
||||
setItemDelegate(new QCheckListStyledItemDelegate(this));
|
||||
|
||||
connect(lineEdit(), &QLineEdit::selectionChanged, lineEdit(), &QLineEdit::deselect);
|
||||
connect((QListView*) view(), SIGNAL(pressed(QModelIndex)), this, SLOT(on_itemPressed(QModelIndex)));
|
||||
connect(m_model, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector<int>)), this, SLOT(on_modelDataChanged()));
|
||||
}
|
||||
|
||||
CheckList::~CheckList()
|
||||
{
|
||||
delete m_model;
|
||||
}
|
||||
|
||||
void CheckList::setText(const QString &text)
|
||||
{
|
||||
m_text = text;
|
||||
updateText();
|
||||
}
|
||||
|
||||
void CheckList::setAllCheckedText(const QString &text)
|
||||
{
|
||||
m_allCheckedText = text;
|
||||
updateText();
|
||||
}
|
||||
|
||||
void CheckList::setNoneCheckedText(const QString &text)
|
||||
{
|
||||
m_noneCheckedText = text;
|
||||
updateText();
|
||||
}
|
||||
|
||||
void CheckList::setUnknownlyCheckedText(const QString &text)
|
||||
{
|
||||
m_unknownlyCheckedText = text;
|
||||
updateText();
|
||||
}
|
||||
|
||||
void CheckList::setSortRole(int role)
|
||||
{
|
||||
m_model->setSortRole(role);
|
||||
}
|
||||
|
||||
QStandardItem* CheckList::addCheckItem(const QString &label, const QVariant &data, const Qt::CheckState checkState)
|
||||
{
|
||||
QStandardItem* item = new QStandardItem(label);
|
||||
item->setCheckState(checkState);
|
||||
item->setData(data);
|
||||
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
|
||||
|
||||
m_model->appendRow(item);
|
||||
|
||||
updateText();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
int CheckList::globalCheckState()
|
||||
{
|
||||
int nbRows = m_model->rowCount(), nbChecked = 0, nbUnchecked = 0;
|
||||
|
||||
if (nbRows == 0)
|
||||
{
|
||||
return StateUnknown;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nbRows; i++)
|
||||
{
|
||||
if (m_model->item(i)->checkState() == Qt::Checked)
|
||||
{
|
||||
nbChecked++;
|
||||
}
|
||||
else if (m_model->item(i)->checkState() == Qt::Unchecked)
|
||||
{
|
||||
nbUnchecked++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return StateUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
return nbChecked == nbRows ? Qt::Checked : nbUnchecked == nbRows ? Qt::Unchecked : Qt::PartiallyChecked;
|
||||
}
|
||||
|
||||
bool CheckList::eventFilter(QObject* _object, QEvent* _event)
|
||||
{
|
||||
if (_object == lineEdit() && _event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
showPopup();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CheckList::updateText()
|
||||
{
|
||||
QString text;
|
||||
|
||||
if (m_text.isEmpty())
|
||||
{
|
||||
switch (globalCheckState())
|
||||
{
|
||||
case Qt::Checked:
|
||||
text = m_allCheckedText;
|
||||
break;
|
||||
|
||||
case Qt::Unchecked:
|
||||
text = m_noneCheckedText;
|
||||
break;
|
||||
|
||||
case Qt::PartiallyChecked:
|
||||
for (int i = 0; i < m_model->rowCount(); i++)
|
||||
{
|
||||
if (m_model->item(i)->checkState() == Qt::Checked)
|
||||
{
|
||||
if (!text.isEmpty())
|
||||
{
|
||||
text+= ", ";
|
||||
}
|
||||
|
||||
text+= m_model->item(i)->text();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
text = m_unknownlyCheckedText;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text = m_text;
|
||||
}
|
||||
|
||||
lineEdit()->setText(text);
|
||||
}
|
||||
|
||||
void CheckList::on_modelDataChanged()
|
||||
{
|
||||
updateText();
|
||||
emit globalCheckStateChanged(globalCheckState());
|
||||
}
|
||||
|
||||
void CheckList::on_itemPressed(const QModelIndex &index)
|
||||
{
|
||||
QStandardItem* item = m_model->itemFromIndex(index);
|
||||
|
||||
if (item->checkState() == Qt::Checked)
|
||||
{
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
else
|
||||
{
|
||||
item->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckList::isChecked(int index) const
|
||||
{
|
||||
return m_model->item(index)->checkState() == Qt::Checked;
|
||||
}
|
105
sdrgui/gui/checklist.h
Normal file
105
sdrgui/gui/checklist.h
Normal file
@ -0,0 +1,105 @@
|
||||
#ifndef CHECKLIST
|
||||
#define CHECKLIST
|
||||
|
||||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
#include <QStandardItemModel>
|
||||
#include <QLineEdit>
|
||||
#include <QEvent>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QListView>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
/**
|
||||
* @brief QComboBox with support of checkboxes
|
||||
* http://stackoverflow.com/questions/8422760/combobox-of-checkboxes
|
||||
*/
|
||||
class SDRGUI_API CheckList : public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Additional value to Qt::CheckState when some checkboxes are Qt::PartiallyChecked
|
||||
*/
|
||||
static const int StateUnknown = 3;
|
||||
|
||||
private:
|
||||
QStandardItemModel* m_model;
|
||||
/**
|
||||
* @brief Text to display regardless of what is checked
|
||||
*/
|
||||
QString m_text;
|
||||
/**
|
||||
* @brief Text displayed when no item is checked
|
||||
*/
|
||||
QString m_noneCheckedText;
|
||||
/**
|
||||
* @brief Text displayed when all items are checked
|
||||
*/
|
||||
QString m_allCheckedText;
|
||||
/**
|
||||
* @brief Text displayed when some items are partially checked
|
||||
*/
|
||||
QString m_unknownlyCheckedText;
|
||||
|
||||
signals:
|
||||
void globalCheckStateChanged(int);
|
||||
|
||||
public:
|
||||
CheckList(QWidget* parent = nullptr);
|
||||
~CheckList();
|
||||
|
||||
void setText(const QString &text);
|
||||
void setAllCheckedText(const QString &text);
|
||||
void setNoneCheckedText(const QString &text);
|
||||
void setUnknownlyCheckedText(const QString &text);
|
||||
|
||||
bool isChecked(int index) const;
|
||||
|
||||
void setSortRole(int role);
|
||||
|
||||
/**
|
||||
* @brief Adds a item to the checklist
|
||||
* @return the new QStandardItem
|
||||
*/
|
||||
QStandardItem* addCheckItem(const QString &label, const QVariant &data, const Qt::CheckState checkState);
|
||||
|
||||
/**
|
||||
* @brief Computes the global state of the checklist :
|
||||
* - if there is no item: StateUnknown
|
||||
* - if there is at least one item partially checked: StateUnknown
|
||||
* - if all items are checked: Qt::Checked
|
||||
* - if no item is checked: Qt::Unchecked
|
||||
* - else: Qt::PartiallyChecked
|
||||
*/
|
||||
int globalCheckState();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* _object, QEvent* _event);
|
||||
|
||||
private:
|
||||
void updateText();
|
||||
|
||||
private slots:
|
||||
void on_modelDataChanged();
|
||||
|
||||
void on_itemPressed(const QModelIndex &index);
|
||||
|
||||
public:
|
||||
class QCheckListStyledItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
QCheckListStyledItemDelegate(QObject* parent = 0) : QStyledItemDelegate(parent) {}
|
||||
|
||||
void paint(QPainter * painter_, const QStyleOptionViewItem & option_, const QModelIndex & index_) const
|
||||
{
|
||||
QStyleOptionViewItem & refToNonConstOption = const_cast<QStyleOptionViewItem &>(option_);
|
||||
refToNonConstOption.showDecorationSelected = false;
|
||||
QStyledItemDelegate::paint(painter_, refToNonConstOption, index_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user