213 lines
6.6 KiB
C++
213 lines
6.6 KiB
C++
/**
|
||
* @file PaiTreeItemDelegate.h
|
||
* @brief PAI系统中常见的数据树节点ItemDelegate类
|
||
* @date 2011-09-29
|
||
*/
|
||
#include <QPainter>
|
||
#include <QPen>
|
||
#include <QBrush>
|
||
#include <QLinearGradient>
|
||
#include <QStyleOptionViewItemV4>
|
||
#include <QStyleFactory>
|
||
#include <QApplication>
|
||
|
||
#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);
|
||
}
|
||
}
|