PowerModeler/source/attributeTableDelegate.cpp

283 lines
9.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "attributeTableDelegate.h"
#include "attributeTableModel.h"
#include "attributeNamespace.h"
#include "sqlQueryExecutor.h"
#include "ui_textEditWidget.h"
#include <QSpinBox>
#include <QComboBox>
#include <QLineEdit>
#include <QPainter>
#include <QRegularExpressionValidator>
TextEditWidget::TextEditWidget(QWidget* parent)
: QWidget(parent), ui(new Ui::TextEditWidget)
{
ui->setupUi(this);
setWindowFlags(Qt::FramelessWindowHint);
//不设置焦点策略点击按钮后会触发tableView的Tab键原因尚不清楚
ui->btnConfirm->setFocusPolicy(Qt::NoFocus);
ui->btnCancle->setFocusPolicy(Qt::NoFocus);
m_promptString = "";
m_patternString = "";
connect(ui->plainTextEdit, &QPlainTextEdit::textChanged, this, &TextEditWidget::onTextChanged);
connect(ui->btnConfirm, &QPushButton::clicked, this, &TextEditWidget::onBtnClicked_confirm);
connect(ui->btnCancle, &QPushButton::clicked, this, &TextEditWidget::onBtnClicked_cancle);
}
TextEditWidget::~TextEditWidget()
{
delete ui;
}
// bool TextEditWidget::eventFilter(QObject* obj, QEvent* event)
// {
// if (event->type() == QEvent::KeyPress)
// {
// QKeyEvent* pKeyEvent = static_cast<QKeyEvent*>(event);
// if (pKeyEvent->key() == Qt::Key_Tab)
// {
// qDebug() << "Key_Tab";
// return true;
// }
// }
// return QWidget::eventFilter(obj, event);
// }
QString TextEditWidget::editText()
{
return ui->plainTextEdit->toPlainText();
}
void TextEditWidget::setEditText(const QString& text)
{
ui->plainTextEdit->setPlainText(text);
}
void TextEditWidget::setPrompt(const QString& prompt)
{
m_promptString = prompt;
ui->label->setText(m_promptString);
}
void TextEditWidget::setRegularExpression(const QString& pattern)
{
//QPlainTextEidt没有setValidator方法所以需要在textChanged槽函数中进行处理
/*QRegularExpression regExp(pattern);
QRegularExpressionValidator* validator = new QRegularExpressionValidator(regExp, this);
ui->plainTextEdit->setValidator(validator);*/
m_patternString = pattern;
m_regExp.setPattern(m_patternString.replace(1, 0 , "^"));
}
void TextEditWidget::setErrorInfo(const QString& errorInfo)
{
ui->label->setText(errorInfo);
}
void TextEditWidget::onTextChanged()
{
ui->label->setText(m_promptString);
if(m_patternString.isEmpty())
return;
QString text = ui->plainTextEdit->toPlainText();
QString filtered = text;
filtered.replace(m_regExp, "");
//qDebug() << text << " " << m_regExp.pattern() << " " << filtered;
if (filtered != text)
{
// 保存光标位置,避免替换后光标跳转
QTextCursor cursor = ui->plainTextEdit->textCursor();
int pos = cursor.position();
ui->plainTextEdit->setPlainText(filtered);
cursor.setPosition(pos - (text.length() - filtered.length()));
ui->plainTextEdit->setTextCursor(cursor);
}
}
void TextEditWidget::onBtnClicked_confirm()
{
emit confirm();
}
void TextEditWidget::onBtnClicked_cancle()
{
emit cancle();
}
AttributeTableDelegate::AttributeTableDelegate(QTableView* view, const QString& connection, QObject *parent)
: QStyledItemDelegate(parent)
, m_tableView(view)
, m_connection(connection)
{
}
AttributeTableDelegate::~AttributeTableDelegate()
{}
void AttributeTableDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
//根据行号设置交替色
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
if ((index.row() + 1) % 2 == 0)
{
//opt.backgroundBrush = QBrush(QColor(243, 245, 249));
painter->fillRect(opt.rect, QColor(240, 248, 255));
}
//处理加粗字体逻辑
if(/*index.column() == 0 || */index.data(Qt::UserRole + AttributeEidt::EditStatus).toBool())
{
opt.font.setBold(true);
//opt.palette.setColor(QPalette::Text, Qt::red);
}
//先执行默认绘制(包括背景、文本等基础元素)
QStyledItemDelegate::paint(painter, opt, index);
//最后绘制删除线(确保位于最顶层)
if(m_tableView && m_tableView->model())
{
QModelIndex numberIndex = m_tableView->model()->index(index.row(), 0);
QString text = numberIndex.data(Qt::DisplayRole).toString();
if(text.contains("-"))
{
QRect rect = m_tableView->visualRect(index);
painter->save();
painter->setPen(Qt::red);
painter->drawLine(rect.left(), rect.y() + rect.height()*0.5, rect.right(), rect.y() + rect.height()*0.5); //painter属于view所以要以view的坐标系为标准
painter->restore();
}
}
}
QWidget* AttributeTableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const
{
int dataCol = index.column() - 1;
if(dataCol == 0) //属性类型
{
TextEditWidget* textEditor = new TextEditWidget(parent);
textEditor->setPrompt(QString::fromWCharArray(L"类型为英文"));
textEditor->setRegularExpression("[A-Za-z0-9]");
connect(textEditor, &TextEditWidget::confirm, this, [=]{
QString strText = textEditor->editText();
bool exists = SqlQueryExecutor::instance().attributeTypeExistsInDB(m_connection, strText);
if(exists)
textEditor->setErrorInfo(QString::fromWCharArray(L"该类型已存在"));
else
{
emit const_cast<AttributeTableDelegate*>(this)->commitData(textEditor);
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
}
});
connect(textEditor, &TextEditWidget::cancle, this, [=]{
//createEditor为const成员函数而closeEditor是QAbstractItemDelegate的非const信号在const成员函数中不能直接调用需要转换为非const指针
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
});
return textEditor;
}
else if(dataCol == 1 || dataCol == 4) //1-数据名称、4-默认值
{
TextEditWidget* textEditor = new TextEditWidget(parent);
connect(textEditor, &TextEditWidget::confirm, this, [=]{
emit const_cast<AttributeTableDelegate*>(this)->commitData(textEditor);
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
});
connect(textEditor, &TextEditWidget::cancle, this, [=]{
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
});
return textEditor;
}
else if(dataCol == 2) //数据类型
{
if(m_tableView)
{
auto* model = qobject_cast<AttributeTableModel*>(m_tableView->model());
if(model)
{
QMap<int, AttributeTableModel::DataType> dataTypes = model->getDataTypes();
QComboBox* comboBox = new QComboBox(parent);
for(auto dataType : dataTypes)
comboBox->addItem(dataType.type);
return comboBox;
}
}
}
else if(dataCol == 3) //数据长度
{
QSpinBox* spinBox = new QSpinBox(parent);
spinBox->setRange(-1, 999);
spinBox->setValue(0);
return spinBox;
}
return QStyledItemDelegate::createEditor(parent, option, index);
}
// void AttributeTableDelegate::destroyEditor(QWidget* editor, const QModelIndex& index) const
// {
// emit const_cast<AttributeTableDelegate*>(this)->closeEditor(editor, QAbstractItemDelegate::NoHint);
// }
void AttributeTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if(TextEditWidget* textEditor = qobject_cast<TextEditWidget*>(editor))
textEditor->setEditText(index.data(Qt::DisplayRole).toString());
else
QStyledItemDelegate::setEditorData(editor, index);
}
void AttributeTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QVariant newValue;
if(TextEditWidget* textEditor = qobject_cast<TextEditWidget*>(editor))
newValue = textEditor->editText();
else if(QLineEdit* lineEdit = qobject_cast<QLineEdit*>(editor))
newValue = lineEdit->text();
else if(QComboBox* comboBox = qobject_cast<QComboBox*>(editor))
newValue = comboBox->currentText();
else if(QSpinBox* spinBox = qobject_cast<QSpinBox*>(editor))
newValue = spinBox->value();
else
{
QStyledItemDelegate::setModelData(editor, model, index);
return;
}
QVariant oldValue = index.data(Qt::EditRole);
//qDebug() << "newValue: " << newValue.toString() << "oldValue: " << oldValue.toString();
if (newValue == oldValue)
return;
model->setData(index, newValue, Qt::EditRole);
}
void AttributeTableDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(TextEditWidget* textEditor = qobject_cast<TextEditWidget*>(editor))
{
QSize editorSize = textEditor->size();
QRect optRect = option.rect;
QWidget* parentWidget = textEditor->parentWidget();
int nX = optRect.x();
if(parentWidget && (nX + editorSize.width()) > parentWidget->width())
nX = parentWidget->width() - editorSize.width();
int nY = optRect.bottom() - editorSize.height();
if(nY < 0)
nY = 0;
textEditor->setGeometry(nX, nY, editorSize.width(), editorSize.height());
}
else
editor->setGeometry(option.rect);
}
bool AttributeTableDelegate::isEnumType(const QModelIndex& index) const
{
return index.data(Qt::UserRole + AttributeEidt::DataType).toInt() == AttributeEidt::ENUM;
}