PowerModeler/source/attributeTableDelegate.cpp

283 lines
9.8 KiB
C++
Raw Normal View History

#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
{
2025-04-01 18:10:48 +08:00
//根据行号设置交替色
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));
}
2025-03-27 21:01:25 +08:00
2025-04-01 18:10:48 +08:00
//处理加粗字体逻辑
if(/*index.column() == 0 || */index.data(Qt::UserRole + AttributeEidt::EditStatus).toBool())
{
opt.font.setBold(true);
2025-03-27 21:01:25 +08:00
//opt.palette.setColor(QPalette::Text, Qt::red);
}
2025-03-27 21:01:25 +08:00
2025-04-01 18:10:48 +08:00
//先执行默认绘制(包括背景、文本等基础元素)
QStyledItemDelegate::paint(painter, opt, index);
2025-03-27 21:01:25 +08:00
//最后绘制删除线(确保位于最顶层)
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);
}
2025-03-27 21:01:25 +08:00
// 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;
}