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);
|
|||
|
|
}
|
|||
|
|
}
|