mirror of
https://gitee.com/spark-store-project/spark-store
synced 2025-12-20 03:01:36 +08:00
chore:完成ssinstall更新
This commit is contained in:
@@ -9,14 +9,16 @@
|
|||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
|
||||||
AppDelegate::AppDelegate(QObject *parent)
|
AppDelegate::AppDelegate(QObject *parent)
|
||||||
: QStyledItemDelegate(parent), m_downloadManager(new DownloadManager(this)) {
|
: QStyledItemDelegate(parent), m_downloadManager(new DownloadManager(this)), m_installProcess(nullptr) {
|
||||||
|
|
||||||
connect(m_downloadManager, &DownloadManager::downloadFinished, this,
|
connect(m_downloadManager, &DownloadManager::downloadFinished, this,
|
||||||
[this](const QString &packageName, bool success) {
|
[this](const QString &packageName, bool success) {
|
||||||
if (m_downloads.contains(packageName)) {
|
if (m_downloads.contains(packageName)) {
|
||||||
m_downloads[packageName].isDownloading = false;
|
m_downloads[packageName].isDownloading = false;
|
||||||
emit updateDisplay(packageName);
|
emit updateDisplay(packageName);
|
||||||
qDebug() << (success ? "下载完成:" : "下载失败:") << packageName;
|
qDebug() << (success ? "下载完成:" : "下载失败:") << packageName;
|
||||||
|
if (success) {
|
||||||
|
enqueueInstall(packageName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -28,6 +30,7 @@ AppDelegate::AppDelegate(QObject *parent)
|
|||||||
emit updateDisplay(packageName); // 实时刷新进度条
|
emit updateDisplay(packageName); // 实时刷新进度条
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
m_spinnerTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppDelegate::setModel(QAbstractItemModel *model) {
|
void AppDelegate::setModel(QAbstractItemModel *model) {
|
||||||
@@ -82,6 +85,8 @@ void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, c
|
|||||||
QString packageName = index.data(Qt::UserRole + 1).toString();
|
QString packageName = index.data(Qt::UserRole + 1).toString();
|
||||||
bool isDownloading = m_downloads.contains(packageName) && m_downloads[packageName].isDownloading;
|
bool isDownloading = m_downloads.contains(packageName) && m_downloads[packageName].isDownloading;
|
||||||
int progress = m_downloads.value(packageName, DownloadInfo{0, false}).progress;
|
int progress = m_downloads.value(packageName, DownloadInfo{0, false}).progress;
|
||||||
|
bool isInstalled = m_downloads.value(packageName).isInstalled;
|
||||||
|
bool isInstalling = m_downloads.value(packageName).isInstalling;
|
||||||
|
|
||||||
if (isDownloading) {
|
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);
|
||||||
@@ -103,24 +108,37 @@ void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, c
|
|||||||
painter->setPen(Qt::white); // 白色文字
|
painter->setPen(Qt::white); // 白色文字
|
||||||
painter->setFont(option.font);
|
painter->setFont(option.font);
|
||||||
painter->drawText(buttonRect, Qt::AlignCenter, "取消");
|
painter->drawText(buttonRect, Qt::AlignCenter, "取消");
|
||||||
|
} else if (isInstalling) {
|
||||||
|
// 安装中:显示转圈和文字
|
||||||
|
QRect spinnerRect(option.rect.right() - 80, option.rect.top() + (option.rect.height() - 30) / 2, 30, 30);
|
||||||
|
int angle = (m_spinnerTimer.elapsed() / 10) % 360;
|
||||||
|
QPen pen(QColor("#2563EB"), 3);
|
||||||
|
painter->setPen(pen);
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
QRectF arcRect = spinnerRect.adjusted(3, 3, -3, -3);
|
||||||
|
painter->drawArc(arcRect, angle * 16, 120 * 16); // 120度弧
|
||||||
|
|
||||||
|
QRect textRect(option.rect.right() - 120, option.rect.top() + (option.rect.height() - 30) / 2, 110, 30);
|
||||||
|
painter->setPen(QColor("#2563EB"));
|
||||||
|
painter->setFont(option.font);
|
||||||
|
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, "正在安装中");
|
||||||
} else {
|
} else {
|
||||||
QString packageName = index.data(Qt::UserRole + 1).toString();
|
QRect buttonRect(option.rect.right() - 80, option.rect.top() + (option.rect.height() - 30) / 2, 70, 30);
|
||||||
bool isDownloaded = m_downloads.contains(packageName) && !m_downloads[packageName].isDownloading;
|
|
||||||
|
|
||||||
QRect buttonRect(rect.right() - 80, rect.top() + (rect.height() - 30) / 2, 70, 30);
|
|
||||||
painter->setPen(Qt::NoPen);
|
painter->setPen(Qt::NoPen);
|
||||||
|
if (isInstalled) {
|
||||||
if (isDownloaded) {
|
painter->setBrush(QColor("#10B981"));
|
||||||
// 下载完成状态
|
painter->drawRoundedRect(buttonRect, 4, 4);
|
||||||
painter->setBrush(QColor("#10B981")); // 绿色背景
|
painter->setPen(Qt::white);
|
||||||
|
painter->drawText(buttonRect, Qt::AlignCenter, "已安装");
|
||||||
|
} else if (m_downloads.contains(packageName) && !m_downloads[packageName].isDownloading) {
|
||||||
|
painter->setBrush(QColor("#10B981"));
|
||||||
painter->drawRoundedRect(buttonRect, 4, 4);
|
painter->drawRoundedRect(buttonRect, 4, 4);
|
||||||
painter->setPen(Qt::white);
|
painter->setPen(Qt::white);
|
||||||
painter->drawText(buttonRect, Qt::AlignCenter, "下载完成");
|
painter->drawText(buttonRect, Qt::AlignCenter, "下载完成");
|
||||||
} else {
|
} else {
|
||||||
// 更新按钮状态
|
painter->setBrush(QColor("#e9effd"));
|
||||||
painter->setBrush(QColor("#e9effd")); // 背景色
|
|
||||||
painter->drawRoundedRect(buttonRect, 4, 4);
|
painter->drawRoundedRect(buttonRect, 4, 4);
|
||||||
painter->setPen(QColor("#2563EB")); // 文字颜色
|
painter->setPen(QColor("#2563EB"));
|
||||||
painter->drawText(buttonRect, Qt::AlignCenter, "更新");
|
painter->drawText(buttonRect, Qt::AlignCenter, "更新");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,12 +187,89 @@ void AppDelegate::startDownloadForAll() {
|
|||||||
for (int row = 0; row < m_model->rowCount(); ++row) {
|
for (int row = 0; row < m_model->rowCount(); ++row) {
|
||||||
QModelIndex index = m_model->index(row, 0);
|
QModelIndex index = m_model->index(row, 0);
|
||||||
QString packageName = index.data(Qt::UserRole + 1).toString();
|
QString packageName = index.data(Qt::UserRole + 1).toString();
|
||||||
if (m_downloads.contains(packageName) && m_downloads[packageName].isDownloading)
|
if (m_downloads.contains(packageName) && (m_downloads[packageName].isDownloading || m_downloads[packageName].isInstalled))
|
||||||
continue; // 跳过正在下载的
|
continue; // 跳过正在下载或已安装的
|
||||||
QString downloadUrl = index.data(Qt::UserRole + 7).toString();
|
QString downloadUrl = index.data(Qt::UserRole + 7).toString();
|
||||||
QString outputPath = QString("%1/%2.metalink").arg(QDir::tempPath(), packageName);
|
QString outputPath = QString("%1/%2.metalink").arg(QDir::tempPath(), packageName);
|
||||||
m_downloads[packageName] = {0, true};
|
m_downloads[packageName] = {0, true, false};
|
||||||
m_downloadManager->startDownload(packageName, downloadUrl, outputPath);
|
m_downloadManager->startDownload(packageName, downloadUrl, outputPath);
|
||||||
emit updateDisplay(packageName);
|
emit updateDisplay(packageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增:安装队列相关实现
|
||||||
|
void AppDelegate::enqueueInstall(const QString &packageName) {
|
||||||
|
m_installQueue.enqueue(packageName);
|
||||||
|
if (!m_isInstalling) {
|
||||||
|
startNextInstall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppDelegate::startNextInstall() {
|
||||||
|
if (m_installQueue.isEmpty()) {
|
||||||
|
m_isInstalling = false;
|
||||||
|
m_installingPackage.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_isInstalling = true;
|
||||||
|
QString packageName = m_installQueue.dequeue();
|
||||||
|
m_installingPackage = packageName;
|
||||||
|
m_downloads[packageName].isInstalling = true;
|
||||||
|
emit updateDisplay(packageName);
|
||||||
|
|
||||||
|
// 查找 /tmp 下以包名开头的 .deb 文件
|
||||||
|
QDir tempDir(QDir::tempPath());
|
||||||
|
QStringList debs = tempDir.entryList(QStringList() << QString("%1_*.deb").arg(packageName), QDir::Files);
|
||||||
|
QString debPath;
|
||||||
|
if (!debs.isEmpty()) {
|
||||||
|
debPath = tempDir.absoluteFilePath(debs.first());
|
||||||
|
} else {
|
||||||
|
debs = tempDir.entryList(QStringList() << QString("%1*.deb").arg(packageName), QDir::Files);
|
||||||
|
if (!debs.isEmpty()) {
|
||||||
|
debPath = tempDir.absoluteFilePath(debs.first());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debPath.isEmpty()) {
|
||||||
|
qWarning() << "未找到deb文件,包名:" << packageName;
|
||||||
|
m_downloads[packageName].isInstalling = false;
|
||||||
|
emit updateDisplay(packageName);
|
||||||
|
m_installingPackage.clear();
|
||||||
|
startNextInstall();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_installProcess = new QProcess(this);
|
||||||
|
connect(m_installProcess, &QProcess::readyReadStandardOutput, this, [this, packageName]() {
|
||||||
|
QByteArray out = m_installProcess->readAllStandardOutput();
|
||||||
|
QString text = QString::fromLocal8Bit(out);
|
||||||
|
qDebug().noquote() << text;
|
||||||
|
// 检查“软件包已安装”关键字
|
||||||
|
if (text.contains(QStringLiteral("软件包已安装"))) {
|
||||||
|
m_downloads[packageName].isInstalling = false;
|
||||||
|
m_downloads[packageName].isInstalled = true;
|
||||||
|
emit updateDisplay(packageName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(m_installProcess, &QProcess::readyReadStandardError, this, [this]() {
|
||||||
|
QByteArray err = m_installProcess->readAllStandardError();
|
||||||
|
qDebug().noquote() << QString::fromLocal8Bit(err);
|
||||||
|
});
|
||||||
|
connect(m_installProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
||||||
|
this, [this, packageName](int /*exitCode*/, QProcess::ExitStatus /*status*/) {
|
||||||
|
// 若未检测到“软件包已安装”,此处兜底
|
||||||
|
if (!m_downloads[packageName].isInstalled) {
|
||||||
|
m_downloads[packageName].isInstalling = false;
|
||||||
|
}
|
||||||
|
emit updateDisplay(packageName);
|
||||||
|
m_installProcess->deleteLater();
|
||||||
|
m_installProcess = nullptr;
|
||||||
|
m_installingPackage.clear();
|
||||||
|
startNextInstall();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 注意参数顺序:deb路径在前,--no-create-desktop-entry在后
|
||||||
|
QStringList args;
|
||||||
|
args << debPath << "--no-create-desktop-entry";
|
||||||
|
m_installProcess->start("ssinstall", args);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,11 +2,16 @@
|
|||||||
|
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include <QQueue>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QElapsedTimer>
|
||||||
#include "downloadmanager.h"
|
#include "downloadmanager.h"
|
||||||
|
|
||||||
struct DownloadInfo {
|
struct DownloadInfo {
|
||||||
int progress = 0;
|
int progress = 0;
|
||||||
bool isDownloading = false;
|
bool isDownloading = false;
|
||||||
|
bool isInstalled = false;
|
||||||
|
bool isInstalling = false; // 新增:标记是否正在安装
|
||||||
};
|
};
|
||||||
|
|
||||||
class AppDelegate : public QStyledItemDelegate {
|
class AppDelegate : public QStyledItemDelegate {
|
||||||
@@ -20,7 +25,7 @@ public:
|
|||||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
bool editorEvent(QEvent *event, QAbstractItemModel *model,
|
bool editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||||
const QStyleOptionViewItem &option, const QModelIndex &index) override;
|
const QStyleOptionViewItem &option, const QModelIndex &index) override;
|
||||||
void startDownloadForAll(); // 新增:批量下载所有应用
|
void startDownloadForAll();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void updateDisplay(const QString &packageName);
|
void updateDisplay(const QString &packageName);
|
||||||
@@ -29,4 +34,13 @@ private:
|
|||||||
DownloadManager *m_downloadManager;
|
DownloadManager *m_downloadManager;
|
||||||
QHash<QString, DownloadInfo> m_downloads;
|
QHash<QString, DownloadInfo> m_downloads;
|
||||||
QAbstractItemModel *m_model = nullptr;
|
QAbstractItemModel *m_model = nullptr;
|
||||||
|
|
||||||
|
QQueue<QString> m_installQueue;
|
||||||
|
bool m_isInstalling = false;
|
||||||
|
QProcess *m_installProcess = nullptr;
|
||||||
|
QString m_installingPackage; // 当前正在安装的包名
|
||||||
|
QElapsedTimer m_spinnerTimer; // 用于转圈动画
|
||||||
|
|
||||||
|
void enqueueInstall(const QString &packageName);
|
||||||
|
void startNextInstall();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user