/** * @file PaiTreeItemDelegate.h * @brief PAI系统中常见的数据树节点ItemDelegate类 * @date 2011-09-29 */ #include #include #include #include #include #include #include #include "PaiTreeItemDelegate.h" #include "GlobalUtility.h" #include "PaiLineEdit.h" using namespace pai::gui; QStyle *g_Style = QStyleFactory::create("motif"); PaiTreeItemDelegate::PaiTreeItemDelegate(QObject *pParent) : QStyledItemDelegate(pParent) { } QSize PaiTreeItemDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { return QStyledItemDelegate::sizeHint(option, index); } void PaiTreeItemDelegate::paint(QPainter *pPainter, const QStyleOptionViewItem & option, const QModelIndex & index) const { QStyleOptionViewItemV4 opt = option; initStyleOption(&opt, index); bool bSelected = opt.state & QStyle::State_Selected; if(!bSelected) { QVariant varIndexHilightData = index.data(pai::gui::HilightRole); if(varIndexHilightData.isValid() && (varIndexHilightData.type() == QVariant::Bool) && varIndexHilightData.toBool()) { opt.state |= QStyle::State_Selected; } } // 在disable状态下,如果单击disable的节点,其它选中的节点不会被取消选中,但selectable可以做到这一点 // 利用这一点,可以用selectable代替disable的部分功能 // 将不可选择状态绘制为不可用状态的的样式 if(!(index.flags() & Qt::ItemIsSelectable)) { QStyle::State f = QStyle::State_Enabled; f = ~f; opt.state &= f; } QStyledItemDelegate::paint(pPainter, opt, index); } /////////////////////////////////////////////////////////////////////////////// PaiCagegoryTreeItemDelegate::PaiCagegoryTreeItemDelegate(QObject *pParent) : QStyledItemDelegate(pParent), m_RowHeight(40) { } void PaiCagegoryTreeItemDelegate::SetRowHeight(int height) { if(height <= 0) { return; } m_RowHeight = height; } void PaiCagegoryTreeItemDelegate::paint(QPainter *pPainter, const QStyleOptionViewItem & option, const QModelIndex & index) const { QStyleOptionViewItemV4 opt = option; initStyleOption(&opt, index); bool bSelected = opt.state & QStyle::State_Selected; bool bHover = opt.state & QStyle::State_MouseOver; QPointF startPoint(0, 0); QPointF finalPoint(0, opt.rect.height()); QLinearGradient linearGrad(startPoint, finalPoint); QPen pen; if(index.child(0, 0).isValid()) { if(bSelected) { linearGrad.setColorAt(0, QColor("#F6FDFF")); linearGrad.setColorAt(1, QColor("#DAF3FD")); } else if(bHover) { linearGrad.setColorAt(0, QColor("#EAF9FE")); linearGrad.setColorAt(1, QColor("#D5E4F2")); } else { linearGrad.setColorAt(0, QColor("#E7F1F8")); linearGrad.setColorAt(1, QColor("#DAF3FD")); } opt.backgroundBrush = QBrush(linearGrad); pen = QPen(QBrush(QColor("#A8BBC6")), 1, Qt::SolidLine); } else { if(bSelected) { linearGrad.setColorAt(0, QColor("#F6FDFF")); linearGrad.setColorAt(1, QColor("#F6FDFF")); } pen = QPen(QBrush(QColor("#C9D5DC")), 1, Qt::DashLine); } const QWidget *pWidget = opt.widget; if(pWidget == NULL) { return; } QStyle *pStyle = pWidget ? pWidget->style() : QApplication::style(); pStyle->drawControl(QStyle::CE_ItemViewItem, &opt, pPainter, pWidget); QPen oldPen(pPainter->pen()); pPainter->setPen(pen); pPainter->drawLine(opt.rect.bottomLeft(), opt.rect.bottomRight()); pPainter->setPen(oldPen); if(index.data(Qt::BackgroundRole).isValid()) { if(index.data(Qt::BackgroundRole).value< QBrush > () != Qt::NoBrush) { pPainter->fillRect(opt.rect.adjusted(1, 10, -1, -10), index.data(Qt::BackgroundRole).value< QBrush > ()); } } } QSize PaiCagegoryTreeItemDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { QSize sz = QStyledItemDelegate::sizeHint(option, index); sz.setHeight(m_RowHeight); return sz; } ///////////////////////////////////////////////////////////////////////////// PaiNameLimitedTreeItemDelegate::PaiNameLimitedTreeItemDelegate(QWidget *pParent) : PaiTreeItemDelegate(pParent) { // 数据树重命名时,只接受输入字母、数字、汉字以及'_'、'-'和'.',并且长度不能超过100个字符 // 不接受以'.'开始的输入 m_RegExp = QRegExp("([\u4e00-\u9fa50-9a-zA-Z_\\-\\.]){1,100}"); } PaiNameLimitedTreeItemDelegate::PaiNameLimitedTreeItemDelegate(const QRegExp & regExp, QWidget *pParent) : PaiTreeItemDelegate(pParent) { m_RegExp = regExp; } QWidget* PaiNameLimitedTreeItemDelegate::createEditor(QWidget *pParent, const QStyleOptionViewItem & /*option*/, const QModelIndex & /*index*/) const { PaiLineEdit *pLineEdit = new PaiLineEdit(pParent); // 设置限定范围 pLineEdit->setValidator(new QRegExpValidator(m_RegExp, pParent)); return pLineEdit; } void PaiNameLimitedTreeItemDelegate::setEditorData(QWidget *pEditor, const QModelIndex & index) const { PaiLineEdit *pEdit = dynamic_cast< PaiLineEdit* > (pEditor); if(pEdit) { pEdit->setText(index.model()->data(index, Qt::EditRole).toString()); } } void PaiNameLimitedTreeItemDelegate::setModelData(QWidget *pEditor, QAbstractItemModel *pModel, const QModelIndex & index) const { PaiLineEdit *pEdit = dynamic_cast< PaiLineEdit* > (pEditor); if(pEdit) { if(m_RegExp.exactMatch(pEdit->text())) { pModel->setData(index, pEdit->text(), Qt::EditRole); emit ModelDataChanged(index); } else { pEdit->setText(index.model()->data(index, Qt::EditRole).toString()); } } } void PaiNameLimitedTreeItemDelegate::updateEditorGeometry(QWidget *pEditor, const QStyleOptionViewItem & option, const QModelIndex & /*index*/) const { if(pEditor) { pEditor->setGeometry(option.rect); } }