diff --git a/appmanagercommon.cpp b/appmanagercommon.cpp index 830ee02b75d3b9903961cee97609e21ec2d6a2be..01cca1f0760d6dfb6acefe255058f1ea9311c61c 100644 --- a/appmanagercommon.cpp +++ b/appmanagercommon.cpp @@ -45,3 +45,9 @@ AM::PinyinInfo AM::getPinYinInfoFromStr(const QString &words) return result; } + +void AM::popupNormalSysNotify(const QString &summary, const QString &body) +{ + QProcess proc; + proc.startDetached("notify-send", {"-a", "com.github.ccc-app-manager", summary, body}); +} diff --git a/appmanagercommon.h b/appmanagercommon.h index fd5aa1c181a89eacb18dc4c1c809272d7070a4d2..c591d51ba407a0b2cc4af89a31379232994a723e 100644 --- a/appmanagercommon.h +++ b/appmanagercommon.h @@ -4,12 +4,19 @@ #define ONLY_SHOW_IN_VALUE_DEEPIN "Deepin" #define X_DEEPIN_VENDOR_STR "deepin" +// 应用默认图标 #define APP_THEME_ICON_DEFAULT "application-x-executable" // 列表数据角色定义 #define AM_LIST_VIEW_ITEM_DATA_ROLE_PKG_NAME Qt::ItemDataRole::UserRole + 1 namespace AM { +// 运行状态 +enum RunningStatus { + Normal = 0, + Busy +}; + struct PkgInfo { QString infosFilePath; // 包信息文件路径 qint64 contentOffset; // 内容在包信息文件中的地址偏移 @@ -77,4 +84,6 @@ struct PinyinInfo { bool isChineseChar(const QChar &character); // 字符串转拼音 PinyinInfo getPinYinInfoFromStr(const QString &words); + +void popupNormalSysNotify(const QString &summary, const QString &body); } // namespace AM diff --git a/appmanagerjob.cpp b/appmanagerjob.cpp index 5e58db0eb5cb675d7810deb185aae9d410e7fe9f..279986c57608c52463ff254b19283a7c56697401 100644 --- a/appmanagerjob.cpp +++ b/appmanagerjob.cpp @@ -14,8 +14,6 @@ #include #include // async I/O -using namespace AM; - int zlibCompress(char *dest, int &destLen, char *source, int sourceLen) { @@ -91,6 +89,7 @@ ComPressError zlibUnCompress(const char *srcName, const char *destName) AppManagerJob::AppManagerJob(QObject *parent) : QObject(parent) + , m_runningStatus(Normal) , m_isInitiallized(false) , m_downloadingFile(nullptr) , m_netManager(nullptr) @@ -107,6 +106,16 @@ AppManagerJob::~AppManagerJob() { } +RunningStatus AppManagerJob::getRunningStatus() +{ + RunningStatus status; + m_mutex.lock(); + status = m_runningStatus; + m_mutex.unlock(); + + return status; +} + QMap AppManagerJob::getAppInfosMap() { QMap appInfosMap; @@ -394,14 +403,18 @@ void AppManagerJob::uninstallPkg(const QString &pkgName) void AppManagerJob::installOhMyDDE() { + setRunningStatus(Busy); bool successed = installLocalPkg(OH_MY_DDE_LOCAL_PKG_PATH); Q_EMIT installOhMyDDEFinished(successed); + setRunningStatus(Normal); } void AppManagerJob::installProcInfoPlugin() { + setRunningStatus(Busy); bool successed = installLocalPkg(PROC_INFO_PLUGIN_LOCAL_PKG_PATH); Q_EMIT installProcInfoPluginFinished(successed); + setRunningStatus(Normal); } void AppManagerJob::onPkgInstalled(const QString &pkgName) @@ -446,6 +459,14 @@ void AppManagerJob::initConnection() connect(m_pkgMonitor, &PkgMonitor::pkgUninstalled, this, &AppManagerJob::onPkgUninstalled); } +void AppManagerJob::setRunningStatus(RunningStatus status) +{ + if (m_runningStatus != status) { + m_runningStatus = status; + Q_EMIT runningStatusChanged(m_runningStatus); + } +} + QList AppManagerJob::readSourceUrlList(const QString &filePath) { QList sourceUrlList; diff --git a/appmanagerjob.h b/appmanagerjob.h index 9984cb3ee979a7ed9f1ed46f5e24ef976c4f2df0..1163747cc43af6225b0de59bd1f7be9d4d8e69a0 100644 --- a/appmanagerjob.h +++ b/appmanagerjob.h @@ -20,6 +20,8 @@ QT_END_NAMESPACE #define OH_MY_DDE_LOCAL_PKG_PATH "/opt/apps/com.github.ccc-app-manager/files/pkg/top.yzzi.youjian_1.0.3_amd64.deb" #define PROC_INFO_PLUGIN_LOCAL_PKG_PATH "/opt/apps/com.github.ccc-app-manager/files/pkg/com.github.proc-info-plugin_0.0.1_amd64.deb" +using namespace AM; + class AppManagerJob : public QObject { Q_OBJECT @@ -27,6 +29,8 @@ public: explicit AppManagerJob(QObject *parent = nullptr); virtual ~AppManagerJob() override; + RunningStatus getRunningStatus(); + QMap getAppInfosMap(); QList getSearchedAppInfoList(); @@ -62,6 +66,7 @@ private Q_SLOTS: void onPkgUninstalled(const QString &pkgName); Q_SIGNALS: + void runningStatusChanged(RunningStatus status); void loadAppInfosFinished(); void downloadPkgFinished(const QString &pkgName); void fileDownloadProgressChanged(const QString &url, qint64 bytesRead, qint64 totalBytes); @@ -84,6 +89,8 @@ Q_SIGNALS: private: void initConnection(); + void setRunningStatus(RunningStatus status); + QList readSourceUrlList(const QString &filePath); void reloadSourceUrlList(); // 从包信息列表文件中获取包信息列表 @@ -113,6 +120,7 @@ private: private: QMutex m_mutex; + RunningStatus m_runningStatus; QList m_sourceUrlList; QMap m_appInfosMap; diff --git a/appmanagermodel.cpp b/appmanagermodel.cpp index 70364d90e8949ef8d138ea8f89f616a3d31ab24f..d01f3c95f91fe4178e2b24e0f68e1c2ef3ee456c 100644 --- a/appmanagermodel.cpp +++ b/appmanagermodel.cpp @@ -29,6 +29,11 @@ AppManagerModel::~AppManagerModel() m_appManagerJob = nullptr; } +RunningStatus AppManagerModel::getRunningStatus() +{ + return m_appManagerJob->getRunningStatus(); +} + QList AppManagerModel::getAppInfosList() { return m_appManagerJob->getAppInfosMap().values(); @@ -105,12 +110,8 @@ void AppManagerModel::openStoreAppDetailPage(const QString &pkgName) void AppManagerModel::openSpkStoreAppDetailPage(const QString &pkgName) { - QProcess spkopen; - QString cmd = QString("notify-send shenmo \"\因为无法获取分类信息,暂时没有实现这个功能\"\ "); - spkopen.start(cmd); - spkopen.waitForStarted(); - spkopen.waitForFinished(); - + Q_UNUSED(pkgName); + popupNormalSysNotify("shenmo", "因为无法获取分类信息,暂时没有实现这个功能"); } QString AppManagerModel::getDownloadDirPath() const @@ -220,11 +221,34 @@ AppInfo AppManagerModel::getAppInfo(const QString &pkgName) return m_appManagerJob->getAppInfosMap().value(pkgName); } +void AppManagerModel::onAppInstalled(const AppInfo &appInfo) +{ + popupNormalSysNotify("ccc-app-manager", QString("软件包 %1 已安装").arg(appInfo.pkgName)); + + Q_EMIT appInstalled(appInfo); +} + +void AppManagerModel::onAppUpdated(const AppInfo &appInfo) +{ + popupNormalSysNotify("ccc-app-manager", QString("软件包 %1 已更新").arg(appInfo.pkgName)); + + Q_EMIT appUpdated(appInfo); +} + +void AppManagerModel::onAppUninstalled(const AppInfo &appInfo) +{ + popupNormalSysNotify("ccc-app-manager", QString("软件包 %1 已卸载").arg(appInfo.pkgName)); + + Q_EMIT appUninstalled(appInfo); +} + void AppManagerModel::initData() { // 注册结构体 qRegisterMetaType("AM::AppInfo"); qRegisterMetaType>("QList"); + qRegisterMetaType("AM::RunningStatus"); + qRegisterMetaType("RunningStatus"); // 线程 m_appManagerJobThread = new QThread; @@ -235,6 +259,8 @@ void AppManagerModel::initData() void AppManagerModel::initConnection() { // 线程信号连接 + connect(m_appManagerJob, &AppManagerJob::runningStatusChanged, this, &AppManagerModel::runningStatusChanged); + connect(m_appManagerJobThread, &QThread::started, m_appManagerJob, &AppManagerJob::init); connect(this, &AppManagerModel::notifyThreadreloadAppInfos, m_appManagerJob, &AppManagerJob::reloadAppInfos); connect(this, &AppManagerModel::notifyThreadDownloadFile, m_appManagerJob, &AppManagerJob::downloadFile); @@ -260,11 +286,6 @@ void AppManagerModel::initConnection() connect(this, &AppManagerModel::notifyThreadUninstallPkg, m_appManagerJob, &AppManagerJob::uninstallPkg); connect(m_appManagerJob, &AppManagerJob::uninstallPkgFinished, this, [](const QString &pkgName) { - QProcess uninstnotify; - QString cmd = QString("notify-send ccc-app-manager \" 软件包 ")+ pkgName + QString(" 已卸载\" "); - uninstnotify.start(cmd); - uninstnotify.waitForStarted(); - uninstnotify.waitForFinished(); qInfo() << pkgName << "uninstalled"; }); @@ -282,9 +303,9 @@ void AppManagerModel::initConnection() connect(m_appManagerJob, &AppManagerJob::installProcInfoPluginFinished, this, &AppManagerModel::installProcInfoPluginFinished); // 包安装变动 - connect(m_appManagerJob, &AppManagerJob::appInstalled, this, &AppManagerModel::appInstalled); - connect(m_appManagerJob, &AppManagerJob::appUpdated, this, &AppManagerModel::appUpdated); - connect(m_appManagerJob, &AppManagerJob::appUninstalled, this, &AppManagerModel::appUninstalled); + connect(m_appManagerJob, &AppManagerJob::appInstalled, this, &AppManagerModel::onAppInstalled); + connect(m_appManagerJob, &AppManagerJob::appUpdated, this, &AppManagerModel::onAppUpdated); + connect(m_appManagerJob, &AppManagerJob::appUninstalled, this, &AppManagerModel::onAppUninstalled); } void AppManagerModel::postInit() diff --git a/appmanagermodel.h b/appmanagermodel.h index d32e9989610302794bc9b33f45ead443d96d7e3f..d41a2ddac430e93e79408a49a7f45a8e498bd214 100644 --- a/appmanagermodel.h +++ b/appmanagermodel.h @@ -18,6 +18,8 @@ public: explicit AppManagerModel(QObject *parent = nullptr); virtual ~AppManagerModel() override; + RunningStatus getRunningStatus(); + QList getAppInfosList(); QString formatePkgInfo(const AM::PkgInfo &info); @@ -40,6 +42,8 @@ public: AM::AppInfo getAppInfo(const QString &pkgName); Q_SIGNALS: + void runningStatusChanged(RunningStatus status); + void notifyThreadreloadAppInfos(); void loadAppInfosFinished(); void notifyThreadDownloadFile(const QString &url); @@ -71,6 +75,12 @@ Q_SIGNALS: void appUpdated(const AM::AppInfo &appInfo); void appUninstalled(const AM::AppInfo &appInfo); +private Q_SLOTS: + // 软件安装变动 + void onAppInstalled(const AM::AppInfo &appInfo); + void onAppUpdated(const AM::AppInfo &appInfo); + void onAppUninstalled(const AM::AppInfo &appInfo); + private: void initData(); void initConnection(); diff --git a/appmanagerwidget.cpp b/appmanagerwidget.cpp index 2331790fa5207c2629c444851f8b550ad0c9de6e..f97737d4c5ddc728542660704c0e7c6a89c9a425 100644 --- a/appmanagerwidget.cpp +++ b/appmanagerwidget.cpp @@ -378,6 +378,7 @@ AppManagerWidget::AppManagerWidget(AppManagerModel *model, QWidget *parent) connect(m_model, &AppManagerModel::appUpdated, this, &AppManagerWidget::onAppUpdated); connect(m_model, &AppManagerModel::appUninstalled, this, &AppManagerWidget::onAppUninstalled); + // post init setLoading(true); } diff --git a/mainwindow.cpp b/mainwindow.cpp index 58d8a93863a1d7073acc219d4690978651bbd44f..ee58c4335a9e8be0869e2c55f21c9dc7866bbc90 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,5 +1,4 @@ #include "mainwindow.h" -#include "appmanagerwidget.h" #include #include @@ -17,6 +16,8 @@ MainWindow::MainWindow(QWidget *parent) : DMainWindow(parent) , m_centralWidgetBlurBg(nullptr) , m_isDeepin(false) + , m_appManagerModel(nullptr) + , m_appManagerWidget(nullptr) { setMinimumSize(500, 300); resize(1000, 600); @@ -68,15 +69,20 @@ MainWindow::MainWindow(QWidget *parent) centralWidget->setLayout(mainLayout); // 应用管理 - AppManagerModel *appManagerModel = new AppManagerModel(this); - AppManagerWidget *appManagerWidget = new AppManagerWidget(appManagerModel, this); - mainLayout->addWidget(appManagerWidget); + m_appManagerModel = new AppManagerModel(this); + m_appManagerWidget = new AppManagerWidget(m_appManagerModel, this); + mainLayout->addWidget(m_appManagerWidget); // init connection - connect(watchGuiAppListAction, &QAction::triggered, this, [this, appManagerModel](bool checked) { + // 运行状态改变 + connect(m_appManagerModel, &AppManagerModel::runningStatusChanged, this, [this](RunningStatus) { + this->updateUIByRunningStatus(); + }); + + connect(watchGuiAppListAction, &QAction::triggered, this, [this](bool checked) { Q_UNUSED(checked); QString uiAppPkgNameList; - for (const AM::AppInfo &info : appManagerModel->getAppInfosList()) { + for (const AM::AppInfo &info : m_appManagerModel->getAppInfosList()) { if (info.desktopInfo.desktopPath.isEmpty()) { continue; } @@ -100,10 +106,10 @@ MainWindow::MainWindow(QWidget *parent) dlg->exec(); dlg->deleteLater(); }); - connect(openOhMyDDEAction, &QAction::triggered, this, [appManagerModel](bool checked) { + connect(openOhMyDDEAction, &QAction::triggered, this, [this](bool checked) { Q_UNUSED(checked); - if (appManagerModel->isPkgInstalled(OH_MY_DDE_PKG_NAME)) { - QProcess::startDetached("dex", {appManagerModel->getAppInfo(OH_MY_DDE_PKG_NAME).desktopInfo.desktopPath}); + if (m_appManagerModel->isPkgInstalled(OH_MY_DDE_PKG_NAME)) { + QProcess::startDetached("dex", {m_appManagerModel->getAppInfo(OH_MY_DDE_PKG_NAME).desktopInfo.desktopPath}); } else { // 安装 DDialog dlg; @@ -112,15 +118,15 @@ MainWindow::MainWindow(QWidget *parent) dlg.addButton("否", false, DDialog::ButtonType::ButtonNormal); int ret = dlg.exec(); if (0 == ret) { - Q_EMIT appManagerModel->notifyThreadInstallOhMyDDE(); + Q_EMIT m_appManagerModel->notifyThreadInstallOhMyDDE(); } } }); - connect(openProInfoWindowAction, &QAction::triggered, this, [appManagerModel](bool checked) { + connect(openProInfoWindowAction, &QAction::triggered, this, [this](bool checked) { Q_UNUSED(checked); - if (appManagerModel->isPkgInstalled(PROC_INFO_PLUGIN_PKG_NAME)) { - QProcess::startDetached("dex", {appManagerModel->getAppInfo(PROC_INFO_PLUGIN_PKG_NAME).desktopInfo.desktopPath}); + if (m_appManagerModel->isPkgInstalled(PROC_INFO_PLUGIN_PKG_NAME)) { + QProcess::startDetached("dex", {m_appManagerModel->getAppInfo(PROC_INFO_PLUGIN_PKG_NAME).desktopInfo.desktopPath}); } else { // 安装 DDialog dlg; @@ -129,7 +135,7 @@ MainWindow::MainWindow(QWidget *parent) dlg.addButton("否", false, DDialog::ButtonType::ButtonNormal); int ret = dlg.exec(); if (0 == ret) { - Q_EMIT appManagerModel->notifyThreadInstallProcInfoPlugin(); + Q_EMIT m_appManagerModel->notifyThreadInstallProcInfoPlugin(); } } }); @@ -144,6 +150,8 @@ MainWindow::MainWindow(QWidget *parent) m_centralWidgetBlurBg->setVisible(false); titlebar()->setBackgroundTransparent(false); } + + updateUIByRunningStatus(); } MainWindow::~MainWindow() @@ -161,3 +169,10 @@ void MainWindow::closeEvent(QCloseEvent *event) DMainWindow::closeEvent(event); qApp->exit(); } + +void MainWindow::updateUIByRunningStatus() +{ + bool enable = (RunningStatus::Normal == m_appManagerModel->getRunningStatus()); + titlebar()->menu()->setEnabled(enable); + m_appManagerWidget->setEnabled(enable); +} diff --git a/mainwindow.h b/mainwindow.h index 2193c20adea2ddce351d46f8f3073b23072f1ebc..161955687e3d5926e6eb94587c10cfbceba92d4b 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -1,4 +1,5 @@ #pragma once +#include "appmanagerwidget.h" #include @@ -20,8 +21,14 @@ protected: virtual void resizeEvent(QResizeEvent *event) override; virtual void closeEvent(QCloseEvent *event) override; +private: + void updateUIByRunningStatus(); + private: DBlurEffectWidget *m_barBlurBg; DBlurEffectWidget *m_centralWidgetBlurBg; bool m_isDeepin; + // 应用管理 + AppManagerModel *m_appManagerModel; + AppManagerWidget *m_appManagerWidget; };