mirror of
https://gitee.com/spark-store-project/spark-store
synced 2025-12-15 21:32:05 +08:00
update:允许用户忽略应用更新
This commit is contained in:
@@ -46,6 +46,9 @@ void AppDelegate::setModel(QAbstractItemModel *model) {
|
|||||||
void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
|
void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
|
// 检查是否为忽略状态
|
||||||
|
bool isIgnored = index.data(Qt::UserRole + 8).toBool();
|
||||||
|
|
||||||
if (option.state & QStyle::State_Selected)
|
if (option.state & QStyle::State_Selected)
|
||||||
painter->fillRect(option.rect, option.palette.highlight());
|
painter->fillRect(option.rect, option.palette.highlight());
|
||||||
else
|
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);
|
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->setBrush(Qt::NoBrush);
|
||||||
painter->drawRect(checkboxRect);
|
painter->drawRect(checkboxRect);
|
||||||
|
|
||||||
// 如果选中,绘制勾选标记
|
// 如果选中,绘制勾选标记
|
||||||
if (isSelected) {
|
if (isSelected && !isIgnored) {
|
||||||
painter->setPen(QPen(QColor("#2563EB"), 2));
|
painter->setPen(QPen(QColor("#2563EB"), 2));
|
||||||
painter->setBrush(QColor("#2563EB"));
|
painter->setBrush(QColor("#2563EB"));
|
||||||
painter->drawRect(checkboxRect.adjusted(4, 4, -4, -4));
|
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);
|
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 textX = iconRect.right() + margin;
|
||||||
int textWidth = rect.width() - textX - 100;
|
int textWidth = rect.width() - textX - 100;
|
||||||
|
|
||||||
QRect nameRect(textX, rect.top() + margin, textWidth, 20);
|
QRect nameRect(textX, rect.top() + margin, textWidth, 20);
|
||||||
painter->setFont(boldFont);
|
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);
|
painter->drawText(nameRect, Qt::AlignLeft | Qt::AlignVCenter, name);
|
||||||
|
|
||||||
QRect versionRect(textX, nameRect.bottom() + spacing, textWidth, 20);
|
QRect versionRect(textX, nameRect.bottom() + spacing, textWidth, 20);
|
||||||
painter->setFont(normalFont);
|
painter->setFont(normalFont);
|
||||||
painter->setPen(QColor("#888888"));
|
QColor versionColor = isIgnored ? QColor("#AAAAAA") : QColor("#888888");
|
||||||
|
painter->setPen(versionColor);
|
||||||
painter->drawText(versionRect, Qt::AlignLeft | Qt::AlignVCenter,
|
painter->drawText(versionRect, Qt::AlignLeft | Qt::AlignVCenter,
|
||||||
QString("当前版本: %1 → 新版本: %2").arg(currentVersion, newVersion));
|
QString("当前版本: %1 → 新版本: %2").arg(currentVersion, newVersion));
|
||||||
|
|
||||||
QRect descRect(textX, versionRect.bottom() + spacing, textWidth, 40);
|
QRect descRect(textX, versionRect.bottom() + spacing, textWidth, 40);
|
||||||
painter->setFont(normalFont);
|
painter->setFont(normalFont);
|
||||||
painter->setPen(QColor("#AAAAAA"));
|
QColor descColor = isIgnored ? QColor("#CCCCCC") : QColor("#AAAAAA");
|
||||||
|
painter->setPen(descColor);
|
||||||
painter->drawText(descRect, Qt::TextWordWrap,
|
painter->drawText(descRect, Qt::TextWordWrap,
|
||||||
QString("包大小:%1 MB").arg(QString::number(size.toDouble() / (1024 * 1024), 'f', 2)));
|
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 isInstalled = m_downloads.value(packageName).isInstalled;
|
||||||
bool isInstalling = m_downloads.value(packageName).isInstalling;
|
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);
|
QRect progressRect(rect.right() - 270, rect.top() + (rect.height() - 20) / 2, 150, 20);
|
||||||
QStyleOptionProgressBar progressBarOption;
|
QStyleOptionProgressBar progressBarOption;
|
||||||
progressBarOption.rect = progressRect;
|
progressBarOption.rect = progressRect;
|
||||||
@@ -188,6 +223,18 @@ bool AppDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
|||||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||||
QRect rect = option.rect;
|
QRect rect = option.rect;
|
||||||
QString packageName = index.data(Qt::UserRole + 1).toString();
|
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);
|
QRect checkboxRect(rect.left() + 10, rect.top() + (rect.height() - 20) / 2, 20, 20);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ signals:
|
|||||||
void updateDisplay(const QString &packageName);
|
void updateDisplay(const QString &packageName);
|
||||||
void updateFinished(bool success); //传递是否完成更新
|
void updateFinished(bool success); //传递是否完成更新
|
||||||
void ignoreApp(const QString &packageName, const QString &version); // 新增:忽略应用信号
|
void ignoreApp(const QString &packageName, const QString &version); // 新增:忽略应用信号
|
||||||
|
void unignoreApp(const QString &packageName); // 新增:取消忽略应用信号
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateSpinner(); // 新增槽函数
|
void updateSpinner(); // 新增槽函数
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ QVariant AppListModel::data(const QModelIndex &index, int role) const
|
|||||||
return map.value("description");
|
return map.value("description");
|
||||||
case Qt::UserRole + 7: // 下载 URL
|
case Qt::UserRole + 7: // 下载 URL
|
||||||
return map.value("download_url"); // 返回下载 URL
|
return map.value("download_url"); // 返回下载 URL
|
||||||
|
case Qt::UserRole + 8: // 忽略状态
|
||||||
|
return map.value("ignored");
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@@ -52,11 +54,21 @@ void AppListModel::setUpdateData(const QJsonArray &updateInfo)
|
|||||||
map["icon"] = obj["icon"].toString();
|
map["icon"] = obj["icon"].toString();
|
||||||
map["size"] = obj["size"].toString();
|
map["size"] = obj["size"].toString();
|
||||||
map["download_url"] = obj["download_url"].toString(); // 确保设置下载 URL
|
map["download_url"] = obj["download_url"].toString(); // 确保设置下载 URL
|
||||||
|
map["ignored"] = obj["ignored"].toBool(); // 设置忽略状态
|
||||||
m_data.append(map); // 添加到 QList<QVariantMap>
|
m_data.append(map); // 添加到 QList<QVariantMap>
|
||||||
|
|
||||||
qDebug() << "设置到模型的包名:" << map["package"].toString();
|
qDebug() << "设置到模型的包名:" << map["package"].toString() << "忽略状态:" << map["ignored"].toBool();
|
||||||
qDebug() << "设置到模型的下载 URL:" << map["download_url"].toString(); // 检查设置的数据
|
qDebug() << "设置到模型的下载 URL:" << map["download_url"].toString(); // 检查设置的数据
|
||||||
}
|
}
|
||||||
|
|
||||||
endResetModel();
|
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();
|
||||||
|
}
|
||||||
@@ -18,9 +18,12 @@ public:
|
|||||||
|
|
||||||
// 设置更新数据
|
// 设置更新数据
|
||||||
void setUpdateData(const QJsonArray &data);
|
void setUpdateData(const QJsonArray &data);
|
||||||
|
|
||||||
|
// 获取忽略状态
|
||||||
|
bool isAppIgnored(const QModelIndex &index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<QVariantMap> m_data; // 修改类型为 QList<QVariantMap>
|
QList<QVariantMap> m_data; // 修改类型为 QList<QVariantMap>
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // APPLISTMODEL_H
|
#endif // APPLISTMODEL_H
|
||||||
@@ -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, [=](){
|
connect(ui->updatePushButton, &QPushButton::clicked, this, [=](){
|
||||||
@@ -229,12 +230,42 @@ void MainWindow::checkUpdates()
|
|||||||
{
|
{
|
||||||
aptssUpdater updater;
|
aptssUpdater updater;
|
||||||
QJsonArray updateInfo = updater.getUpdateInfoAsJson();
|
QJsonArray updateInfo = updater.getUpdateInfoAsJson();
|
||||||
m_allApps = updateInfo; // 保存所有应用数据
|
|
||||||
m_model->setUpdateData(updateInfo);
|
// 分离正常应用和忽略应用
|
||||||
|
QJsonArray normalApps;
|
||||||
|
QJsonArray ignoredApps;
|
||||||
|
|
||||||
for (const auto &item : updateInfo) {
|
for (const auto &item : updateInfo) {
|
||||||
QJsonObject obj = item.toObject();
|
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(); // 检查模型数据
|
qDebug() << "模型设置的下载 URL:" << obj["download_url"].toString(); // 检查模型数据
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,7 +277,11 @@ void MainWindow::filterAppsByKeyword(const QString &keyword)
|
|||||||
m_model->setUpdateData(m_allApps);
|
m_model->setUpdateData(m_allApps);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QJsonArray filtered;
|
|
||||||
|
// 分离正常应用和忽略应用
|
||||||
|
QJsonArray normalApps;
|
||||||
|
QJsonArray ignoredApps;
|
||||||
|
|
||||||
for (const auto &item : m_allApps) {
|
for (const auto &item : m_allApps) {
|
||||||
QJsonObject obj = item.toObject();
|
QJsonObject obj = item.toObject();
|
||||||
// 可根据需要匹配更多字段
|
// 可根据需要匹配更多字段
|
||||||
@@ -254,9 +289,25 @@ void MainWindow::filterAppsByKeyword(const QString &keyword)
|
|||||||
QString package = obj.value("package").toString();
|
QString package = obj.value("package").toString();
|
||||||
if (name.contains(keyword, Qt::CaseInsensitive) ||
|
if (name.contains(keyword, Qt::CaseInsensitive) ||
|
||||||
package.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);
|
m_model->setUpdateData(filtered);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,14 +386,37 @@ void MainWindow::onIgnoreApp(const QString &packageName, const QString &version)
|
|||||||
// 将应用添加到忽略配置中
|
// 将应用添加到忽略配置中
|
||||||
m_ignoreConfig->addIgnoredApp(packageName, version);
|
m_ignoreConfig->addIgnoredApp(packageName, version);
|
||||||
|
|
||||||
// 从模型中移除被忽略的应用
|
// 更新模型中应用的状态,而不是移除
|
||||||
QJsonArray filteredApps;
|
QJsonArray updatedApps;
|
||||||
for (const auto &item : m_allApps) {
|
for (const auto &item : m_allApps) {
|
||||||
QJsonObject obj = item.toObject();
|
QJsonObject obj = item.toObject();
|
||||||
if (obj["package"].toString() != packageName) {
|
if (obj["package"].toString() == packageName) {
|
||||||
filteredApps.append(item);
|
obj["ignored"] = true; // 标记为忽略状态
|
||||||
}
|
}
|
||||||
|
updatedApps.append(obj);
|
||||||
}
|
}
|
||||||
m_allApps = filteredApps;
|
m_allApps = updatedApps;
|
||||||
m_model->setUpdateData(filteredApps);
|
|
||||||
|
// 重新排序:正常应用在前,忽略应用在后
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
@@ -43,5 +43,6 @@ private slots:
|
|||||||
void handleUpdateFinished(bool success); // 新增:处理更新完成的槽函数
|
void handleUpdateFinished(bool success); // 新增:处理更新完成的槽函数
|
||||||
void handleSelectionChanged(); // 新增:处理选择变化的槽函数
|
void handleSelectionChanged(); // 新增:处理选择变化的槽函数
|
||||||
void onIgnoreApp(const QString &packageName, const QString &version); // 新增:处理忽略应用的槽函数
|
void onIgnoreApp(const QString &packageName, const QString &version); // 新增:处理忽略应用的槽函数
|
||||||
|
void onUnignoreApp(const QString &packageName); // 新增:处理取消忽略应用
|
||||||
};
|
};
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
Reference in New Issue
Block a user