This repository has been archived on 2020-09-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
libs/qad/widgets/ecombobox.cpp
2020-05-25 16:59:19 +03:00

117 lines
3.4 KiB
C++

#include <QStandardItemModel>
#include <QApplication>
#include <QDebug>
#include <QHeaderView>
#include "ecombobox.h"
#include "qad_types.h"
class EModel: public QStandardItemModel {
public:
EModel(QObject * parent = 0): QStandardItemModel(parent) {
#if QT_VERSION < 0x050000
setSupportedDragActions(Qt::MoveAction);
#endif
}
protected:
virtual Qt::ItemFlags flags(const QModelIndex & index) const {
Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
if (!index.isValid()) f |= Qt::ItemIsDropEnabled;
return f;
}
#if QT_VERSION >= 0x050000
Qt::DropActions supportedDragActions() const {return Qt::MoveAction;}
#endif
};
EComboBox::EComboBox(QWidget * parent): QComboBox(parent) {
setView(&iv);
setModel(new EModel());
iv.setTextElideMode(Qt::ElideMiddle);
iv.setRootIsDecorated(false);
iv.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
iv.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
iv.setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
iv.setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
iv.setMinimumHeight(100);
icon.setPixmap(QPixmap(":/icons/edit-find.png"));
icon.setScaledContents(true);
icon.setFixedSize(preferredIconSize(1.2, this));
ifont = nfont = font();
ifont.setItalic(true);
#if QT_VERSION >= 0x040700
filter.setPlaceholderText(tr("Filter"));
filter.setFont(ifont);
#endif
header.setAutoFillBackground(true);
header.setLayout(new QBoxLayout(QBoxLayout::LeftToRight));
header.layout()->setSpacing(2);
header.layout()->setContentsMargins(2, 0, 0, 0);
header.layout()->addWidget(&icon);
header.layout()->addWidget(&filter);
header.setParent(iv.header());
connect(&filter, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
}
QSize EComboBox::sizeHint() const {
QSize s = QComboBox::sizeHint();
s.setWidth(s.width() + 16);
return s;
}
void EComboBox::showPopup() {
iv.setDragDropMode(isEditable() ? QAbstractItemView::InternalMove : QAbstractItemView::NoDragDrop);
filterChanged(filter.text(), true);
QComboBox::showPopup();
QRect r = iv.header()->rect();
header.setGeometry(r.x(), r.y(), r.width(), r.height() - 1);
filter.setFocus();
}
void EComboBox::changeEvent(QEvent * e) {
QComboBox::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
#if QT_VERSION >= 0x040700
filter.setPlaceholderText(tr("Filter"));
#endif
break;
default:
break;
}
}
void EComboBox::filterChanged(const QString & text, bool first) {
if (filter.text().isEmpty()) filter.setFont(ifont);
else filter.setFont(nfont);
iv.hide();
QModelIndex pi = iv.rootIndex();
if (text.isEmpty()) {
for (int i = 0; i < iv.model()->rowCount(); ++i) {
iv.setRowHidden(i, pi, false);
iv.model()->setData(iv.model()->index(i, 0), iv.model()->index(i, 0, pi).data().toString(), Qt::ToolTipRole);
}
iv.show();
if (first) return;
hidePopup();
showPopup();
qApp->processEvents();
QRect r = iv.header()->rect();
header.setGeometry(r.x(), r.y(), r.width(), r.height() - 1);
return;
}
for (int i = 0; i < iv.model()->rowCount(); ++i) {
iv.setRowHidden(i, pi, !iv.model()->index(i, 0, pi).data().toString().contains(QRegExp(text, Qt::CaseInsensitive)));
iv.model()->setData(iv.model()->index(i, 0), iv.model()->index(i, 0, pi).data().toString(), Qt::ToolTipRole);
}
iv.show();
qApp->processEvents();
QRect r = iv.header()->rect();
header.setGeometry(r.x(), r.y(), r.width(), r.height() - 1);
}