From 01d2a2f1d83e73c301a0d75efdb70385d68e0907 Mon Sep 17 00:00:00 2001 From: momen Date: Tue, 7 Oct 2025 16:52:56 +0800 Subject: [PATCH] =?UTF-8?q?update:=E5=85=81=E8=AE=B8=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E5=BA=94=E7=94=A8=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/appdelegate.cpp | 61 +++++++++++++++++++++++--- src/appdelegate.h | 1 + src/applistmodel.cpp | 14 +++++- src/applistmodel.h | 5 ++- src/mainwindow.cpp | 102 +++++++++++++++++++++++++++++++++++++------ src/mainwindow.h | 1 + 6 files changed, 161 insertions(+), 23 deletions(-) diff --git a/src/appdelegate.cpp b/src/appdelegate.cpp index e29ee8d..e51bff8 100644 --- a/src/appdelegate.cpp +++ b/src/appdelegate.cpp @@ -46,6 +46,9 @@ void AppDelegate::setModel(QAbstractItemModel *model) { void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { painter->save(); + // 检查是否为忽略状态 + bool isIgnored = index.data(Qt::UserRole + 8).toBool(); + if (option.state & QStyle::State_Selected) painter->fillRect(option.rect, option.palette.highlight()); else @@ -58,12 +61,13 @@ void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, c QRect checkboxRect(option.rect.left() + 10, option.rect.top() + (option.rect.height() - 20) / 2, 20, 20); // 绘制复选框边框 - painter->setPen(QColor("#888888")); + QColor checkboxColor = isIgnored ? QColor("#CCCCCC") : QColor("#888888"); + painter->setPen(checkboxColor); painter->setBrush(Qt::NoBrush); painter->drawRect(checkboxRect); // 如果选中,绘制勾选标记 - if (isSelected) { + if (isSelected && !isIgnored) { painter->setPen(QPen(QColor("#2563EB"), 2)); painter->setBrush(QColor("#2563EB")); painter->drawRect(checkboxRect.adjusted(4, 4, -4, -4)); @@ -85,25 +89,42 @@ void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, c // 调整图标位置,为复选框留出空间 QRect iconRect(rect.left() + 40, rect.top() + (rect.height() - iconSize) / 2, iconSize, iconSize); - QIcon(iconPath).paint(painter, iconRect); + + // 如果是忽略状态,绘制灰色图标 + if (isIgnored) { + // 创建灰度效果 + QPixmap originalPixmap = QIcon(iconPath).pixmap(iconSize, iconSize); + QPixmap grayPixmap(originalPixmap.size()); + grayPixmap.fill(Qt::transparent); + QPainter grayPainter(&grayPixmap); + grayPainter.setOpacity(0.3); // 设置透明度使其变灰 + grayPainter.drawPixmap(0, 0, originalPixmap); + grayPainter.end(); + painter->drawPixmap(iconRect, grayPixmap); + } else { + QIcon(iconPath).paint(painter, iconRect); + } int textX = iconRect.right() + margin; int textWidth = rect.width() - textX - 100; QRect nameRect(textX, rect.top() + margin, textWidth, 20); painter->setFont(boldFont); - painter->setPen(QColor("#333333")); + QColor nameColor = isIgnored ? QColor("#999999") : QColor("#333333"); + painter->setPen(nameColor); painter->drawText(nameRect, Qt::AlignLeft | Qt::AlignVCenter, name); QRect versionRect(textX, nameRect.bottom() + spacing, textWidth, 20); painter->setFont(normalFont); - painter->setPen(QColor("#888888")); + QColor versionColor = isIgnored ? QColor("#AAAAAA") : QColor("#888888"); + painter->setPen(versionColor); painter->drawText(versionRect, Qt::AlignLeft | Qt::AlignVCenter, QString("当前版本: %1 → 新版本: %2").arg(currentVersion, newVersion)); QRect descRect(textX, versionRect.bottom() + spacing, textWidth, 40); painter->setFont(normalFont); - painter->setPen(QColor("#AAAAAA")); + QColor descColor = isIgnored ? QColor("#CCCCCC") : QColor("#AAAAAA"); + painter->setPen(descColor); painter->drawText(descRect, Qt::TextWordWrap, QString("包大小:%1 MB").arg(QString::number(size.toDouble() / (1024 * 1024), 'f', 2))); @@ -112,7 +133,21 @@ void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, c bool isInstalled = m_downloads.value(packageName).isInstalled; bool isInstalling = m_downloads.value(packageName).isInstalling; - if (isDownloading) { + // 如果是忽略状态,显示"已忽略"文本和"取消忽略"按钮 + if (isIgnored) { + QRect ignoredTextRect(rect.right() - 170, rect.top() + (rect.height() - 30) / 2, 80, 30); + painter->setPen(QColor("#999999")); + painter->setFont(option.font); + painter->drawText(ignoredTextRect, Qt::AlignCenter, "已忽略"); + + // 绘制取消忽略按钮 + QRect unignoreButtonRect(rect.right() - 80, rect.top() + (rect.height() - 30) / 2, 70, 30); + painter->setPen(Qt::NoPen); + painter->setBrush(QColor("#F3F4F6")); + painter->drawRoundedRect(unignoreButtonRect, 4, 4); + painter->setPen(QColor("#6B7280")); + painter->drawText(unignoreButtonRect, Qt::AlignCenter, "取消忽略"); + } else if (isDownloading) { QRect progressRect(rect.right() - 270, rect.top() + (rect.height() - 20) / 2, 150, 20); QStyleOptionProgressBar progressBarOption; progressBarOption.rect = progressRect; @@ -188,6 +223,18 @@ bool AppDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, QMouseEvent *mouseEvent = static_cast(event); QRect rect = option.rect; QString packageName = index.data(Qt::UserRole + 1).toString(); + + // 检查是否为忽略状态,如果是则只允许取消忽略按钮的交互 + bool isIgnored = index.data(Qt::UserRole + 8).toBool(); + if (isIgnored) { + QRect unignoreButtonRect(option.rect.right() - 80, option.rect.top() + (option.rect.height() - 30) / 2, 70, 30); + if (unignoreButtonRect.contains(mouseEvent->pos())) { + // 发送取消忽略信号 + emit unignoreApp(packageName); + return true; + } + return true; // 消耗其他事件,不允许其他交互 + } // 检查是否点击了复选框 QRect checkboxRect(rect.left() + 10, rect.top() + (rect.height() - 20) / 2, 20, 20); diff --git a/src/appdelegate.h b/src/appdelegate.h index 15972c1..9385a33 100644 --- a/src/appdelegate.h +++ b/src/appdelegate.h @@ -39,6 +39,7 @@ signals: void updateDisplay(const QString &packageName); void updateFinished(bool success); //传递是否完成更新 void ignoreApp(const QString &packageName, const QString &version); // 新增:忽略应用信号 + void unignoreApp(const QString &packageName); // 新增:取消忽略应用信号 private slots: void updateSpinner(); // 新增槽函数 diff --git a/src/applistmodel.cpp b/src/applistmodel.cpp index 31e244a..9d7c83d 100644 --- a/src/applistmodel.cpp +++ b/src/applistmodel.cpp @@ -32,6 +32,8 @@ QVariant AppListModel::data(const QModelIndex &index, int role) const return map.value("description"); case Qt::UserRole + 7: // 下载 URL return map.value("download_url"); // 返回下载 URL + case Qt::UserRole + 8: // 忽略状态 + return map.value("ignored"); default: return QVariant(); } @@ -52,11 +54,21 @@ void AppListModel::setUpdateData(const QJsonArray &updateInfo) map["icon"] = obj["icon"].toString(); map["size"] = obj["size"].toString(); map["download_url"] = obj["download_url"].toString(); // 确保设置下载 URL + map["ignored"] = obj["ignored"].toBool(); // 设置忽略状态 m_data.append(map); // 添加到 QList - qDebug() << "设置到模型的包名:" << map["package"].toString(); + qDebug() << "设置到模型的包名:" << map["package"].toString() << "忽略状态:" << map["ignored"].toBool(); qDebug() << "设置到模型的下载 URL:" << map["download_url"].toString(); // 检查设置的数据 } endResetModel(); } + +bool AppListModel::isAppIgnored(const QModelIndex &index) const +{ + if (!index.isValid() || index.row() >= m_data.size()) + return false; + + const QVariantMap &map = m_data.at(index.row()); + return map.value("ignored").toBool(); +} \ No newline at end of file diff --git a/src/applistmodel.h b/src/applistmodel.h index 9e5e79a..d3f304d 100644 --- a/src/applistmodel.h +++ b/src/applistmodel.h @@ -18,9 +18,12 @@ public: // 设置更新数据 void setUpdateData(const QJsonArray &data); + + // 获取忽略状态 + bool isAppIgnored(const QModelIndex &index) const; private: QList m_data; // 修改类型为 QList }; -#endif // APPLISTMODEL_H +#endif // APPLISTMODEL_H \ No newline at end of file diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e2801ac..4e76371 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -55,8 +55,9 @@ MainWindow::MainWindow(QWidget *parent) } }); - // 连接忽略应用信号 - connect(m_delegate, &AppDelegate::ignoreApp, this, &MainWindow::onIgnoreApp); + // 连接应用委托的信号 + connect(m_delegate, &AppDelegate::ignoreApp, this, &MainWindow::onIgnoreApp); + connect(m_delegate, &AppDelegate::unignoreApp, this, &MainWindow::onUnignoreApp); // 新增:点击“更新全部”按钮批量下载 connect(ui->updatePushButton, &QPushButton::clicked, this, [=](){ @@ -229,12 +230,42 @@ void MainWindow::checkUpdates() { aptssUpdater updater; QJsonArray updateInfo = updater.getUpdateInfoAsJson(); - m_allApps = updateInfo; // 保存所有应用数据 - m_model->setUpdateData(updateInfo); - + + // 分离正常应用和忽略应用 + QJsonArray normalApps; + QJsonArray ignoredApps; + for (const auto &item : updateInfo) { QJsonObject obj = item.toObject(); - qDebug() << "模型设置的包名:" << obj["package"].toString(); + QString packageName = obj["package"].toString(); + QString currentVersion = obj["current_version"].toString(); + + // 检查应用是否被忽略 + if (m_ignoreConfig->isAppIgnored(packageName, currentVersion)) { + // 标记为忽略状态 + obj["ignored"] = true; + ignoredApps.append(obj); + } else { + obj["ignored"] = false; + normalApps.append(obj); + } + } + + // 合并数组:正常应用在前,忽略应用在后 + QJsonArray finalApps; + for (const auto &item : normalApps) { + finalApps.append(item); + } + for (const auto &item : ignoredApps) { + finalApps.append(item); + } + + m_allApps = finalApps; // 保存所有应用数据 + m_model->setUpdateData(finalApps); + + for (const auto &item : finalApps) { + QJsonObject obj = item.toObject(); + qDebug() << "模型设置的包名:" << obj["package"].toString() << "忽略状态:" << obj["ignored"].toBool(); qDebug() << "模型设置的下载 URL:" << obj["download_url"].toString(); // 检查模型数据 } } @@ -246,7 +277,11 @@ void MainWindow::filterAppsByKeyword(const QString &keyword) m_model->setUpdateData(m_allApps); return; } - QJsonArray filtered; + + // 分离正常应用和忽略应用 + QJsonArray normalApps; + QJsonArray ignoredApps; + for (const auto &item : m_allApps) { QJsonObject obj = item.toObject(); // 可根据需要匹配更多字段 @@ -254,9 +289,25 @@ void MainWindow::filterAppsByKeyword(const QString &keyword) QString package = obj.value("package").toString(); if (name.contains(keyword, Qt::CaseInsensitive) || package.contains(keyword, Qt::CaseInsensitive)) { - filtered.append(item); + + // 检查是否为忽略状态 + if (obj.value("ignored").toBool()) { + ignoredApps.append(item); + } else { + normalApps.append(item); + } } } + + // 合并数组:正常应用在前,忽略应用在后 + QJsonArray filtered; + for (const auto &item : normalApps) { + filtered.append(item); + } + for (const auto &item : ignoredApps) { + filtered.append(item); + } + m_model->setUpdateData(filtered); } @@ -335,14 +386,37 @@ void MainWindow::onIgnoreApp(const QString &packageName, const QString &version) // 将应用添加到忽略配置中 m_ignoreConfig->addIgnoredApp(packageName, version); - // 从模型中移除被忽略的应用 - QJsonArray filteredApps; + // 更新模型中应用的状态,而不是移除 + QJsonArray updatedApps; for (const auto &item : m_allApps) { QJsonObject obj = item.toObject(); - if (obj["package"].toString() != packageName) { - filteredApps.append(item); + if (obj["package"].toString() == packageName) { + obj["ignored"] = true; // 标记为忽略状态 } + updatedApps.append(obj); } - m_allApps = filteredApps; - m_model->setUpdateData(filteredApps); + m_allApps = updatedApps; + + // 重新排序:正常应用在前,忽略应用在后 + checkUpdates(); +} + +// 新增:处理取消忽略应用的槽函数 +void MainWindow::onUnignoreApp(const QString &packageName) { + // 从忽略配置中移除应用 + m_ignoreConfig->removeIgnoredApp(packageName); + + // 更新模型中应用的状态 + QJsonArray updatedApps; + for (const auto &item : m_allApps) { + QJsonObject obj = item.toObject(); + if (obj["package"].toString() == packageName) { + obj["ignored"] = false; // 标记为非忽略状态 + } + updatedApps.append(obj); + } + m_allApps = updatedApps; + + // 重新排序:正常应用在前,忽略应用在后 + checkUpdates(); } \ No newline at end of file diff --git a/src/mainwindow.h b/src/mainwindow.h index c00714b..5bf2f0a 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -43,5 +43,6 @@ private slots: void handleUpdateFinished(bool success); // 新增:处理更新完成的槽函数 void handleSelectionChanged(); // 新增:处理选择变化的槽函数 void onIgnoreApp(const QString &packageName, const QString &version); // 新增:处理忽略应用的槽函数 + void onUnignoreApp(const QString &packageName); // 新增:处理取消忽略应用 }; #endif // MAINWINDOW_H \ No newline at end of file