#include "plancard.h" #include "ui_plancard.h" #include #include #include "UIStyleManager.h" #include "LHQLogAPI.h" PlanInfo::PlanInfo() { onWeekDay = enum_WeekDay::WeekDay_Mon; onDateTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss"); offWeekDay = enum_WeekDay::WeekDay_Mon; offDateTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss"); } PlanInfo::PlanInfo(const PlanInfo& info) { onWeekDay = info.onWeekDay; onDateTime = info.onDateTime; offWeekDay = info.offWeekDay; offDateTime = info.offDateTime; } PlanInfo& PlanInfo::operator=(const PlanInfo& info) { if(this != &info) { onWeekDay = info.onWeekDay; onDateTime = info.onDateTime; offWeekDay = info.offWeekDay; offDateTime = info.offDateTime; } return *this; } bool PlanInfo::operator==(const PlanInfo& info) const { if(onWeekDay == info.onWeekDay && onDateTime == info.onDateTime && offWeekDay == info.offWeekDay && offDateTime == info.offDateTime) { return true; } return false; } /* 重载比较函数 */ bool CSortModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { /* 先比较是正常日还是特殊日 */ auto leftDay = sourceModel()->data(left, UserRole_WeekDay).toInt(); auto rightDay = sourceModel()->data(right, UserRole_WeekDay).toInt(); if(leftDay != rightDay) { return leftDay < rightDay; /* 比较周几 */ } /* 日期类型相等,再比较时间 */ auto leftTime = sourceModel()->data(left, UserRole_Time).toDateTime(); auto rightTime = sourceModel()->data(right, UserRole_Time).toDateTime(); if(leftDay == static_cast(enum_WeekDay::WeekDay_Special)) { /* 特殊日,比较日期和时间 */ return leftTime < rightTime; }else { /* 正常日,只比较时间 */ return leftTime.time() < rightTime.time(); } } PlanCard::PlanCard(QWidget *parent) : QWidget(parent), ui(new Ui::PlanCard) { ui->setupUi(this); /* 设置最小宽度 */ this->setMinimumWidth(300); /* 初始化视图模型 */ m_model = new QStandardItemModel(this); m_model->setColumnCount(2); /* 两列 */ m_model->clear(); m_sortModel = new CSortModel(this); m_sortModel->setSourceModel(m_model); m_sortModel->sort(0, Qt::AscendingOrder); /* 默认升序 */ /* 设置排序数据 */ m_sortModel->setSortRole(QtUserRole::UserRole_Time); /* 设置排序角色 */ ui->tableView->setModel(m_sortModel); /* 设置每列的高度 */ ui->tableView->verticalHeader()->setDefaultSectionSize(34); /* 设置去掉标题 */ ui->tableView->horizontalHeader()->setVisible(false); /* 去掉列标题 */ ui->tableView->verticalHeader()->setVisible(false); /* 去掉网格线 */ ui->tableView->setShowGrid(false); /* 设置单元格不可编辑 */ ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); /* 设置空白图片和文字的位置 */ setSpaceImageAndTextRect(); /* 注册事件过滤器 */ // ui->tableView->installEventFilter(this); ui->tableView->viewport()->installEventFilter(this); /* 连接信号和槽 */ connect(&EPUIStyle, &UIStyleManager::signal_qssChanged, this, &PlanCard::do_setUIStyle); connect(ui->tableView, &QTableView::clicked, this, &PlanCard::do_tableView_clicked); /* 设置默认的皮肤 */ do_setUIStyle(); } PlanCard::~PlanCard() { delete ui; } /* 设置频率信息 */ void PlanCard::setChannelInfo(const ChannelInfo& info) { m_channelInfo = info; /* 设置标题 */ ui->label_title->setText(m_channelInfo.ChannelName); } /* 添加一项 */ void PlanCard::addPlanItem(const PlanInfo& info) { auto strStart = getDateString(info.onWeekDay, info.onDateTime); auto strEnd = getDateString(info.offWeekDay, info.offDateTime); /* 创建一个item */ QStandardItem* itemStart = new QStandardItem(); itemStart->setText(strStart); itemStart->setData(static_cast(info.onWeekDay), UserRole_WeekDay); /* 设置周几 */ itemStart->setData(info.onDateTime, UserRole_Time); /* 设置时间 */ QStandardItem* itemEnd = new QStandardItem(); itemEnd->setText(strEnd); itemEnd->setData(static_cast(info.offWeekDay), UserRole_WeekDay); /* 设置周几 */ itemEnd->setData(info.offDateTime, UserRole_Time); /* 设置时间 */ /* 添加一个项 */ m_model->appendRow(QList{itemStart, itemEnd}); m_isSpace = false; /* 有数据了 */ // LH_WRITE_LOG(QString("计划数目: %1").arg(m_model->rowCount())); // LH_WRITE_LOG(QString("UI: %1:%2").arg(ui->tableView->width()).arg(ui->tableView->height())); } /* 删除一项 */ void PlanCard::deletePlanItem(const enum_WeekDay weekDay, const QDateTime& time, const enum_OnOff onOff) { for(auto& it : m_model->findItems(QString(), Qt::MatchContains, 0)) { auto item = it->data(UserRole_WeekDay).toInt(); if(item == static_cast(weekDay) && it->data(UserRole_Time).toDateTime() == time) { /* 删除该行 */ m_model->removeRow(it->row()); break; } } /* 判断数据有没有空 */ if(m_model->rowCount() == 0) { m_isSpace = true; /* 没有数据了 */ } } /* 删除一项,传入行号 */ PlanInfo PlanCard::deletePlanItem(const int row) { if(row < 0 || row >= m_model->rowCount()) { return PlanInfo(); /* 没有选中行 */ } /* 获取原始模型的行号 */ auto sourceRow = m_sortModel->mapToSource(m_sortModel->index(row, 0)).row(); /* 获取该行计划 */ auto item1 = m_model->item(sourceRow, 0); auto item2 = m_model->item(sourceRow, 1); PlanInfo info; info.onWeekDay = static_cast(item1->data(UserRole_WeekDay).toInt()); info.onDateTime = item1->data(UserRole_Time).toDateTime(); info.offWeekDay = static_cast(item2->data(UserRole_WeekDay).toInt()); info.offDateTime = item2->data(UserRole_Time).toDateTime(); /* 删除该行 */ m_model->removeRow(sourceRow); /* 判断数据有没有空 */ if(m_model->rowCount() == 0) { m_isSpace = true; /* 没有数据了 */ } return info; /* 返回删除的计划 */ } /* 修改一项 */ PlanInfo PlanCard::modifyPlanItem(const int row, const PlanInfo& info) { if(row < 0 || row >= m_model->rowCount()) { return PlanInfo(); /* 没有选中行 */ } /* 获取原始模型的行号 */ auto sourceRow = m_sortModel->mapToSource(m_sortModel->index(row, 0)).row(); /* 获取该行计划 */ auto item1 = m_model->item(sourceRow, 0); auto item2 = m_model->item(sourceRow, 1); PlanInfo oldInfo; oldInfo.onWeekDay = static_cast(item1->data(UserRole_WeekDay).toInt()); oldInfo.onDateTime = item1->data(UserRole_Time).toDateTime(); oldInfo.offWeekDay = static_cast(item2->data(UserRole_WeekDay).toInt()); oldInfo.offDateTime = item2->data(UserRole_Time).toDateTime(); // LH_WRITE_LOG(QString("修改前的行: %1").arg(item1->row())); /* 修改该行 */ item1->setText(getDateString(info.onWeekDay, info.onDateTime)); item1->setData(static_cast(info.onWeekDay), UserRole_WeekDay); /* 设置周几 */ item1->setData(info.onDateTime, UserRole_Time); /* 设置时间 */ item2->setText(getDateString(info.offWeekDay, info.offDateTime)); item2->setData(static_cast(info.offWeekDay), UserRole_WeekDay); /* 设置周几 */ item2->setData(info.offDateTime, UserRole_Time); /* 设置时间 */ // LH_WRITE_LOG(QString("修改后的行: %1").arg(item1->row())); /* 依旧选中修改完成后的行 */ // ui->tableView->selectRow(item1->row()); return oldInfo; /* 返回修改前的计划 */ } /* 清空列表 */ void PlanCard::clearPlanItem() { for(auto& it : m_model->findItems(QString(), Qt::MatchContains, 0)) { m_model->removeRow(it->row()); } /* 判断数据有没有空 */ if(m_model->rowCount() == 0) { m_isSpace = true; /* 没有数据了 */ } } /* 取出所有的计划信息,用于给WebAPI发送数据 */ void PlanCard::getAllPlanInfo(QList& list) { int rowCount = m_model->rowCount(); for(int i = 0; i < rowCount; i++) { auto item1 = m_model->item(i, 0); auto item2 = m_model->item(i, 1); if(item1 == nullptr || item2 == nullptr) { continue; } OnePlanItemInfo info1; info1.ChannelID = m_channelInfo.ChannelID; info1.ChannelName = m_channelInfo.ChannelName; info1.onWeekDay = static_cast(item1->data(UserRole_WeekDay).toInt()); info1.onDateTime = item1->data(UserRole_Time).toDateTime(); info1.offWeekDay = static_cast(item2->data(UserRole_WeekDay).toInt()); info1.offDateTime = item2->data(UserRole_Time).toDateTime(); list.append(info1); } } /* 设置计划列表 */ void PlanCard::setPlanList(const QList& list) { /* 清空当前的计划列表 */ clearPlanItem(); for(const auto& it : list) { if(GInfo.isOnlineDB()) { if(it.ChannelID != m_channelInfo.ChannelID) { /* 不是当前频率的计划 */ LH_WRITE_ERROR(QString("频率ID不匹配,当前频率ID:%1, 计划频率ID:%2").arg(m_channelInfo.ChannelID).arg(it.ChannelID)); continue; } } /* 添加计划 */ PlanInfo info; info.onWeekDay = it.onWeekDay; info.onDateTime = it.onDateTime; info.offWeekDay = it.offWeekDay; info.offDateTime = it.offDateTime; addPlanItem(info); } } /* 获取计划列表,适用于PlanCard之间传输数据 */ void PlanCard::getPlanList(QList& list) { for(int i = 0; i < m_model->rowCount(); i++) { auto item1 = m_model->item(i, 0); auto item2 = m_model->item(i, 1); PlanInfo info; info.onWeekDay = static_cast(item1->data(UserRole_WeekDay).toInt()); info.onDateTime = item1->data(UserRole_Time).toDateTime(); info.offWeekDay = static_cast(item2->data(UserRole_WeekDay).toInt()); info.offDateTime = item2->data(UserRole_Time).toDateTime(); list.append(info); } } /* 设置计划列表,适用于PlanCard之间传输数据 */ void PlanCard::setPlanList(const QList& list) { /* 清空列表 */ clearPlanItem(); for(const auto& it : list) { addPlanItem(it); } } /** * @brief 获取选中的行 * * @return int */ int PlanCard::getSelectedRow() const { return ui->tableView->currentIndex().row(); } PlanInfo PlanCard::getSelectedPlan() { auto index = ui->tableView->currentIndex(); if(!index.isValid()) { return PlanInfo(); /* 没有选中行 */ } auto item1 = m_model->item(index.row(), 0); auto item2 = m_model->item(index.row(), 1); PlanInfo info; info.onWeekDay = static_cast(item1->data(UserRole_WeekDay).toInt()); info.onDateTime = item1->data(UserRole_Time).toDateTime(); info.offWeekDay = static_cast(item2->data(UserRole_WeekDay).toInt()); info.offDateTime = item2->data(UserRole_Time).toDateTime(); return info; } /* 设置自身被选中 */ void PlanCard::setSelected(bool isSelected) { if(isSelected) { ui->widget->setProperty("Selected", true); }else { ui->widget->setProperty("Selected", false); } ui->widget->style()->unpolish(ui->widget); ui->widget->style()->polish(ui->widget); } /* 自身被点击了,给外部调用,发送点击信号 */ void PlanCard::clickedCard() { emit signal_clickedCard(m_channelInfo.ChannelID); } /* 更改UI外观 */ void PlanCard::do_setUIStyle() { this->setStyleSheet(EPUIStyle.StrQSS_PlanCard); /* 打开图片 */ if(EPUIStyle.getUIStyle() == enum_UIStyle::UI_Light) { m_spaceImage = QPixmap(":/ICON/ICON/space_light.png"); }else { m_spaceImage = QPixmap(":/ICON/ICON/space_dark.png"); } } /* 点击了一个单元格,设置高亮一行 */ void PlanCard::do_tableView_clicked(const QModelIndex& index) { if(index.isValid()) { /* 设置高亮一行 */ ui->tableView->selectRow(index.row()); } /* 发送信号 */ auto item1 = m_model->item(index.row(), 0); auto item2 = m_model->item(index.row(), 1); PlanInfo info; info.onWeekDay = static_cast(item1->data(UserRole_WeekDay).toInt()); info.onDateTime = item1->data(UserRole_Time).toDateTime(); info.offWeekDay = static_cast(item2->data(UserRole_WeekDay).toInt()); info.offDateTime = item2->data(UserRole_Time).toDateTime(); emit signal_clickedItem(info); /* 发送信号 */ // emit signal_clickedCard(m_channelInfo.ChannelID); } /* 设置空白图片和文字的位置 */ void PlanCard::setSpaceImageAndTextRect() { /* 设置图片大小 */ m_rectSpaceImage.setSize(QSize(108, 87)); /* 设置文本区域大小 */ m_rectSpaceText.setSize(QSize(72, 19)); /* 设置空白图片位置 */ QPoint pointTable = ui->tableView->mapToParent(QPoint(0, 0)); /* 设置空白图片位置,居中显示 */ int x = pointTable.x() + (ui->tableView->width() - m_rectSpaceImage.width()) / 2; int y = pointTable.y() + (ui->tableView->height() - m_rectSpaceImage.height() - m_rectSpaceText.height() - 5) / 2; m_rectSpaceImage.moveTo(x, y); /* 设置空白文字位置 */ x = pointTable.x() + (ui->tableView->width() - m_rectSpaceText.width()) / 2; y = m_rectSpaceImage.y() + m_rectSpaceImage.height() + 5; m_rectSpaceText.moveTo(x, y); } /* 根据日期获取字符串 */ QString PlanCard::getDateString(const enum_WeekDay weekDay, const QDateTime& time) { QString strTime; switch(weekDay) { case enum_WeekDay::WeekDay_Mon: strTime = QString("星期一 %1").arg(time.toString("hh:mm:ss")); break; case enum_WeekDay::WeekDay_Tue: strTime = QString("星期二 %1").arg(time.toString("hh:mm:ss")); break; case enum_WeekDay::WeekDay_Wed: strTime = QString("星期三 %1").arg(time.toString("hh:mm:ss")); break; case enum_WeekDay::WeekDay_Thu: strTime = QString("星期四 %1").arg(time.toString("hh:mm:ss")); break; case enum_WeekDay::WeekDay_Fri: strTime = QString("星期五 %1").arg(time.toString("hh:mm:ss")); break; case enum_WeekDay::WeekDay_Sat: strTime = QString("星期六 %1").arg(time.toString("hh:mm:ss")); break; case enum_WeekDay::WeekDay_Sun: strTime = QString("星期天 %1").arg(time.toString("hh:mm:ss")); break; case enum_WeekDay::WeekDay_Special: strTime = QString("%1").arg(time.toString("yy-MM-dd hh:mm:ss")); break; default: strTime = QString("未知 %1").arg(time.toString("hh:mm:ss")); break; } return strTime; } /* 设置表格大小 */ void PlanCard::setTableViewSize() { /* 设置两列一样宽 */ auto horWidth = ui->tableView->width(); ui->tableView->horizontalHeader()->setDefaultSectionSize(horWidth / 2); // LH_WRITE_LOG(QString("表格大小: %1:%2").arg(ui->tableView->width()).arg(ui->tableView->height())); // LH_WRITE_LOG(QString("标题宽度: %1").arg(ui->widget_tableHeader->width())); } /* 绘制事件 */ void PlanCard::paintEvent(QPaintEvent *event) { if(m_isSpace) { QPainter painter(this); /* 绘制图片 */ painter.drawPixmap(m_rectSpaceImage, m_spaceImage); /* 绘制文字 */ QFont font = painter.font(); font.setPixelSize(12); painter.setFont(font); painter.drawText(m_rectSpaceText, Qt::AlignCenter, "暂无相关信息"); } QWidget::paintEvent(event); } /* 大小缩放事件 */ void PlanCard::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); /* 设置空白图片和文字的位置 */ setSpaceImageAndTextRect(); setTableViewSize(); } /* 显示事件,这里获取到的控件大小信息是正确的 */ void PlanCard::showEvent(QShowEvent *event) { QWidget::showEvent(event); /* 设置空白图片和文字的位置 */ setSpaceImageAndTextRect(); setTableViewSize(); } /* 鼠标点击事件 */ void PlanCard::mousePressEvent(QMouseEvent *event) { QWidget::mousePressEvent(event); /* 发送信号 */ emit signal_clickedCard(m_channelInfo.ChannelID); } /* 事件过滤器 */ bool PlanCard::eventFilter(QObject *watched, QEvent *event) { if(watched == ui->tableView->viewport()) { if(event->type() == QEvent::MouseButtonPress) { emit signal_clickedCard(m_channelInfo.ChannelID); } } return QWidget::eventFilter(watched, event); }