Compare commits
108 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0ab9f4dda6 | |||
| 5a97f6caef | |||
| 3da25b0904 | |||
|
|
116c824365 | ||
|
|
44edb08518 | ||
|
|
9a3d32ee11 | ||
|
|
e5fe80cb76 | ||
|
|
9314acd7e1 | ||
|
|
e64e7fcae2 | ||
| 536efeedfa | |||
|
|
6fd3c40e97 | ||
|
|
90513a8925 | ||
|
|
ed3d869b99 | ||
|
|
c80737a458 | ||
|
|
ebf30e67f9 | ||
|
|
90b684af87 | ||
|
|
3ff363d7b1 | ||
|
|
f7ced7739c | ||
|
|
e12f617f59 | ||
|
|
d164aec86d | ||
|
|
96cd1b9918 | ||
|
|
393c8220f5 | ||
|
|
01d1543cc4 | ||
|
|
4ccc8c0dae | ||
|
|
815036e28f | ||
|
|
9cc68fac86 | ||
|
|
2f8c11a30b | ||
| 1a4b1176fb | |||
| 3101f1fe70 | |||
| 58f32c119a | |||
| ccdcf407cc | |||
| 1a18a51d3c | |||
|
|
ab88af006b | ||
|
|
d02900cb10 | ||
|
|
3e473c091a | ||
|
|
84541d0c22 | ||
|
|
51f84bed1b | ||
| 4a0acf0575 | |||
|
|
e28d1c39ac | ||
|
|
f58201a612 | ||
| 405d3b6986 | |||
| b619d3cc7b | |||
|
|
14e3e7f9a2 | ||
|
|
1d0e0cc65c | ||
|
|
7a5b982dea | ||
|
|
91fcab56df | ||
|
|
4315f04023 | ||
|
|
736ede0742 | ||
|
|
a73a4416fc | ||
|
|
62f0dd097c | ||
|
|
6f3e4398df | ||
|
|
3cca0d87fe | ||
| b7e038bd88 | |||
|
|
4f0e00ad76 | ||
|
|
579008e8b2 | ||
|
|
ccb405c983 | ||
|
|
66ef37c1ca | ||
|
|
8972425c7c | ||
|
|
2ae6e80785 | ||
| f5788efb47 | |||
| 32bc272791 | |||
| c5f04b5675 | |||
| cf208d0736 | |||
| fdc7cb4cb6 | |||
| 8e89ce3ae3 | |||
| ee51f59874 | |||
| 3d09a28794 | |||
| 4b05758479 | |||
| 74d9d0b563 | |||
|
|
f1a4f7acb5 | ||
| 93be66e871 | |||
| 7b46cca1d4 | |||
| c529367998 | |||
|
|
beae3e3efa | ||
|
|
9706480931 | ||
|
|
ed64eb6f5b | ||
| 8f6e5408ae | |||
| d5783458fc | |||
| 6e05066dd9 | |||
| 58aa5a3787 | |||
| 6087c8a5c8 | |||
| ff758946be | |||
| d1cbf95447 | |||
|
|
187ce7e277 | ||
| d3e4f75254 | |||
|
|
949eb33511 | ||
|
|
3f65002dc9 | ||
|
|
cfd4c7689a | ||
|
|
367c8d857c | ||
| b41f846ea4 | |||
| 1dcd7d1c5c | |||
| 01ac388f50 | |||
| cfbbd34695 | |||
|
|
b7afc5ec8a | ||
| b911158274 | |||
| 67c28d0224 | |||
| 1d65bfc66d | |||
| 0e595db328 | |||
| 7a16028e38 | |||
|
|
1b56d3ad52 | ||
| 431e7b555f | |||
|
|
1cbabe7cc5 | ||
| d027d513a3 | |||
|
|
eff8878e8b | ||
| f0bf0e5aec | |||
|
|
678a4229f7 | ||
| e89c14b5ca | |||
|
|
d4c734627a |
2
.gitee/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM python:3
|
||||
RUN pip3 install requests
|
||||
31
.gitee/callback.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import os
|
||||
import requests
|
||||
import json
|
||||
|
||||
|
||||
# sha=os.system("git rev-parse HEAD")
|
||||
sha = os.getenv("GIT_COMMIT")
|
||||
# sha = '48fed26c51a8c42554e45f72f43e49703e04c97f'
|
||||
#get sha from environment
|
||||
url = "https://gitee.com/api/v5/repos/deepin-community-store/spark-store/commits/{}/comments".format(sha)
|
||||
|
||||
token = os.getenv("gitee_token")
|
||||
|
||||
# process = os.popen("git symbolic-ref --short -q HEAD")
|
||||
|
||||
body = "构建详情请见" + os.getenv("JENKINS_URL") + "blue/organizations/jenkins/" + os.getenv("JOB_NAME").replace("/", "/detail/") + "/" + str(os.getenv("BUILD_ID"))
|
||||
|
||||
# process.close()
|
||||
|
||||
d = {
|
||||
'access_token': token,
|
||||
"body": body
|
||||
}
|
||||
|
||||
h = {
|
||||
"Content-Type": "application/json;charset=UTF-8"
|
||||
}
|
||||
|
||||
res = requests.post(url,headers=h, data=json.dumps(d))
|
||||
# print(res.status_code)
|
||||
# print(res.content)
|
||||
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.pro.user*
|
||||
build/
|
||||
.vscode/
|
||||
Lib/
|
||||
33
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
pipeline {
|
||||
agent any
|
||||
stages {
|
||||
stage('build') {
|
||||
agent {
|
||||
docker {
|
||||
image 'jerry979/dtke:5.11'
|
||||
}
|
||||
|
||||
}
|
||||
steps {
|
||||
sh 'mkdir build && cd build && qmake .. && make '
|
||||
archiveArtifacts(artifacts: 'build/src/spark-store', allowEmptyArchive: true, defaultExcludes: true)
|
||||
}
|
||||
}
|
||||
|
||||
stage('send') {
|
||||
agent {
|
||||
dockerfile {
|
||||
filename '.gitee/Dockerfile'
|
||||
}
|
||||
|
||||
}
|
||||
environment {
|
||||
gitee_token = credentials('1')
|
||||
}
|
||||
steps {
|
||||
sh "python3 .gitee/callback.py"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
BIN
Logo-Spark.png
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 46 KiB |
354
README.md
@@ -1,28 +1,38 @@
|
||||
# 星火商店
|
||||
# 星火应用商店
|
||||
|
||||
|
||||
众所周知,国内的Linux应用比较少,wine应用难以获取,优质工具分散在民间各大论坛,无法形成合力,难以改善生态
|
||||
|
||||
生态构建需要的不是某一方的单打独斗,而是人人行动起来,汇聚星火,产生燎原之势
|
||||
|
||||
我们创建了这个应用商店,广泛收录大家需要的软件包,搜集优质小工具,主动适配wine应用,存放到储存库供大家获取
|
||||
|
||||
我们支持:Deepin 20 ; Ubuntu 20.04 LTS ; UOS Home 20
|
||||
|
||||
希望看到这里的人也可以加入我们的队伍,开发或者投递应用都很欢迎,共同构建Linux应用生态
|
||||
|
||||
### [在这里投稿](http://upload.spark-app.store)
|
||||
|
||||
#### 介绍
|
||||
星火商店商店,由深度社区爱好者维护
|
||||
web页面部分正在开发当中,详情请见[web仓库](https://gitee.com/deepin-community-store/DCSAPP_WEB)
|
||||
|
||||
|
||||
#### 说明
|
||||
|
||||
当前服务器线路列表(项目中包含):
|
||||
|
||||
```
|
||||
http://sucdn.jerrywang.top/
|
||||
http://store.jerrywang.top/
|
||||
http://dcstore.spark-app.store/
|
||||
https://d.store.deepinos.org.cn/
|
||||
https://store.deepinos.org.cn/
|
||||
```
|
||||
|
||||
#### 参数
|
||||
#### 调用参数(spk规则)
|
||||
|
||||
参数只有一个Url,该url应当遵循这种格式:`spk://<任意合法字符>/web分类/包名`
|
||||
|
||||
例如:
|
||||
|
||||
[spk://abcdefg/network/firefox-zh](spk://abcdefg/network/firefox-zh)
|
||||
[spk://abcdefg/games/store.spark-app.hmcl](spk://abcdefg/games/store.spark-app.hmcl)
|
||||
|
||||
[spk://higklmn/network/firefox-zh](spk://higklmn/network/firefox-zh)
|
||||
|
||||
可选的web分类:
|
||||
|
||||
@@ -32,29 +42,23 @@ http://dcstore.spark-app.store/
|
||||
| 社交沟通 | chat |
|
||||
| 音乐欣赏 | music |
|
||||
| 视频播放 | video |
|
||||
| 图形图像 | image_graphics |
|
||||
| 图形图像 | graphics |
|
||||
| 游戏娱乐 | games |
|
||||
| 办公学习 | office |
|
||||
| 阅读翻译 | reading |
|
||||
| 编程开发 | development |
|
||||
| 系统工具 | tools |
|
||||
| 主题美化 | themes |
|
||||
| 主题美化 | beautify |
|
||||
| 其他应用 | others |
|
||||
|
||||
#### 目录结构
|
||||
|
||||
安装软件过程中产生的包,图标,截图等被储存到`/tmp/deepin-community-store/`中。
|
||||
|
||||
配置文件被储存到`~/.config/deepin-community-store/`中。
|
||||
|
||||
线路文件:新版的线路文件被放置于源服务器中,可随时刷新更新源列表
|
||||
|
||||
#### 如何编译
|
||||
|
||||
Deepin V20/UOS 系统下, 安装依赖
|
||||
|
||||
```shell
|
||||
sudo apt install qt5-default libdtkcore-dev libdtkwidget-dev qtwebengine5-dev
|
||||
sudo apt install qt5-default libdtkcore-dev libdtkwidget-dev qtwebengine5-dev libnotify-dev
|
||||
```
|
||||
|
||||
```shell
|
||||
@@ -68,6 +72,316 @@ make -j
|
||||
|
||||
./build文件下的spark-store即为可执行文件
|
||||
|
||||
#### 参与贡献
|
||||
# 星火应用商店文档
|
||||
|
||||
1. Fork 本仓库
|
||||
# 目录结构
|
||||
几个目录结构
|
||||
```
|
||||
/
|
||||
/icons 图标文件夹
|
||||
/tags 首页图标
|
||||
/tras 多语言翻译
|
||||
```
|
||||
|
||||
主要的文件分析
|
||||
```js
|
||||
spark-store.pro Qt工程配置文件
|
||||
ssinstall 调用包安装器的脚本
|
||||
icons.qrc 图标资源文件
|
||||
main.cpp 入口文件
|
||||
widget.h widget.cpp widget.ui 主要窗口控件
|
||||
downloadlist.h downloadlist.cpp downloadlist.ui 单个软件的下载安装展示控件
|
||||
progressload.h progressload.cpp 网页加载显示? 得在deepin上编译运行才能搞清楚
|
||||
workerthreads.h workerthreads.cpp 应用信息加载线程
|
||||
image_show.h image_show.cpp 应用页面截图预览控件
|
||||
big_image.h big_image.cpp 大图查看控件
|
||||
```
|
||||
|
||||
# 使用的开源库及第三方工具
|
||||
* GDebi 一个 Ubuntu 软件中心的轻量级替代品 https://linux.cn/article-4982-1.html
|
||||
* libnotify 系统通知 https://developer.gnome.org/libnotify/unstable/
|
||||
|
||||
|
||||
# 源码分析
|
||||
## 应用的组成部分
|
||||
左侧应用分类菜单
|
||||
主窗口的下拉菜单
|
||||
应用列表页面
|
||||
应用详情页面
|
||||
应用首页,有几个链接跳转
|
||||
商店设置页面
|
||||
下载列表页面
|
||||
|
||||
## 应用初始化,及主控件加载
|
||||
初始化 `DApplication` 进入事件循环。
|
||||
设置关于我们弹窗 `DAboutDialog`。
|
||||
主控件 Widget 根据不同屏幕大小自适应。
|
||||
首页打开webview页面,如果传入了`spk://`参数,会打开应用详情页。
|
||||
```cpp
|
||||
// main.cpp
|
||||
QString arg1=argv[1];
|
||||
if(arg1.left(6)=="spk://"){
|
||||
w.openUrl(QUrl(argv[1]));
|
||||
}
|
||||
|
||||
// widget.cpp
|
||||
void Widget::openUrl(QUrl u)
|
||||
{
|
||||
QString app=serverUrl + "store"+u.path()+"/app.json";
|
||||
ui->webEngineView->setUrl(app); // 会触发 webEngineView 的
|
||||
}
|
||||
|
||||
```
|
||||
## Tags处理方式
|
||||
|
||||
**Tags处理方式**
|
||||
```cpp
|
||||
// widget.cpp
|
||||
QString tags=json["Tags"].toString(); //Read the Tags
|
||||
QStringList tagList=tags.split(";");
|
||||
for (int i=0;i<tagList.size();i++) {
|
||||
if(tagList[i]=="community")
|
||||
ui->tag_community->show();//Tags icon shows like this
|
||||
if(tagList[i]=="ubuntu")
|
||||
ui->tag_ubuntu->show();
|
||||
if(tagList[i]=="deepin")
|
||||
ui->tag_deepin->show();
|
||||
if(tagList[i]=="uos")
|
||||
ui->tag_uos->show();
|
||||
if(tagList[i]=="dtk5")
|
||||
ui->tag_dtk5->show();
|
||||
if(tagList[i]=="dwine2")
|
||||
ui->tag_dwine2->show();
|
||||
if(tagList[i]=="dwine5")
|
||||
ui->tag_dwine5->show();
|
||||
if(tagList[i]=="a2d")
|
||||
ui->tag_a2d->show();
|
||||
}
|
||||
```
|
||||
|
||||
**Widget 初始化**
|
||||
```cpp
|
||||
void Widget::initConfig()
|
||||
{
|
||||
...
|
||||
// 读取服务器URL并初始化菜单项的链接
|
||||
QSettings readConfig(QDir::homePath()+"/.config/spark-store/config.ini",QSettings::IniFormat);
|
||||
if(readConfig.value("server/choose").toString()!=""){
|
||||
ui->comboBox_server->setCurrentText(readConfig.value("server/choose").toString());
|
||||
appinfoLoadThread.setServer(serverUrl=readConfig.value("server/choose").toString());
|
||||
}else {
|
||||
appinfoLoadThread.setServer(serverUrl="http://sucdn.jerrywang.top/"); // 默认URL
|
||||
}
|
||||
configCanSave=true; // 防止触发保存配置信号
|
||||
menuUrl[0]=serverUrl + "store/#/"; // 首页
|
||||
// 下面是各个应用分类页面,直接加载的webview的
|
||||
// 每个连接对应一个左侧的菜单项,在构造函数用连接到 chooseLeftMenu 槽函数
|
||||
menuUrl[1]=serverUrl + "store/#/network";
|
||||
...
|
||||
menuUrl[12]=serverUrl + "store/#/others";
|
||||
...
|
||||
ui->webfoot->hide();
|
||||
|
||||
//初始化首页
|
||||
ui->webEngineView->setUrl(menuUrl[0]);
|
||||
}
|
||||
/**
|
||||
* 菜单切换逻辑
|
||||
*
|
||||
*/
|
||||
void Widget::chooseLeftMenu(int index)
|
||||
{
|
||||
nowMenu=index;
|
||||
updateUI();
|
||||
left_list[index]->setStyleSheet("color:#FFFFFF;background-color:"+main_color.name()+";border-radius:8;border:0px");
|
||||
// index <=12 加载某个分类的应用列表的webviejw
|
||||
// index == 13 加载下载列表页面
|
||||
if(index<=12){
|
||||
if(themeIsDark){
|
||||
darkurl = 夜间模式的URL
|
||||
ui->webEngineView->setUrl(darkurl);
|
||||
}else {
|
||||
ui->webEngineView->setUrl(menuUrl[index]);
|
||||
}
|
||||
ui->stackedWidget->setCurrentIndex(0);
|
||||
}else if (index==13) {
|
||||
ui->stackedWidget->setCurrentIndex(1);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 应用下载安装卸载分析
|
||||
**应用详情页面加载**
|
||||
```cpp
|
||||
/**
|
||||
* 加载单个应用的信息
|
||||
*/
|
||||
void Widget::on_webEngineView_urlChanged(const QUrl &arg1)
|
||||
{
|
||||
//分析出服务器中的分类名称
|
||||
...
|
||||
//如果是app.json就打开详情页
|
||||
if(arg1.path().right(8)=="app.json"){
|
||||
...
|
||||
// 读取相应的应用信息
|
||||
appinfoLoadThread.requestInterruption();
|
||||
appinfoLoadThread.wait(100);
|
||||
appinfoLoadThread.setUrl(arg1);
|
||||
appinfoLoadThread.start();
|
||||
}
|
||||
}
|
||||
// 设置详情页的APP信息
|
||||
SpkAppInfoLoaderThread::requestSetAppInformation() -> Widget::sltAppinfoDetails()
|
||||
// 设置详情页的APP图标
|
||||
SpkAppInfoLoaderThread::finishedIconLoad() -> Widget::sltAppinfoIcon()
|
||||
// 设置详情页的APP截图
|
||||
SpkAppInfoLoaderThread::finishedScreenshotLoad() -> Widget::sltAppinfoScreenshot()
|
||||
|
||||
// 下载APP详情信息线程
|
||||
void SpkAppInfoLoaderThread::run()
|
||||
{
|
||||
QProcess get_json;
|
||||
get_json.start("curl -o app.json " + targetUrl.toString());
|
||||
QFile app_json("app.json");
|
||||
读取 app.json 里的信息,提取应用名、描述、图标、截图
|
||||
处理完毕后发射相应的信号
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
**应用下载**
|
||||
Widget::on_pushButton_download_clicked() 是点击下载的安装方法。
|
||||
最终使用的是 `QNetwrokAccessManager` 进行GET请求获取数据写入文件。
|
||||
```cpp
|
||||
void Widget::on_pushButton_download_clicked()
|
||||
{
|
||||
if(!isBusy){
|
||||
file = new QFile(fileName);
|
||||
...
|
||||
nowDownload+=1;
|
||||
startRequest(urList.at(nowDownload-1)); // 进行链接请求
|
||||
}
|
||||
}
|
||||
void Widget::startRequest(QUrl url)
|
||||
{
|
||||
reply = manager->get(QNetworkRequest(url));
|
||||
// 请求响应完成,关闭文件,清理下载队列
|
||||
connect(reply,SIGNAL(finished()),this,SLOT(httpFinished()));
|
||||
// 接收应用下载数据
|
||||
connect(reply,SIGNAL(readyRead()),this,SLOT(httpReadyRead()));
|
||||
// 更新应用下载进度
|
||||
connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(updateDataReadProgress(qint64,qint64)));
|
||||
}
|
||||
```
|
||||
|
||||
使用 QSettings 来读取配置,更换服务源
|
||||
```cpp
|
||||
void Widget::on_comboBox_server_currentIndexChanged(const QString &arg1)
|
||||
{
|
||||
appinfoLoadThread.setServer(arg1); // 服务器信息更新
|
||||
if(configCanSave){
|
||||
ui->label_setting1->show();
|
||||
QSettings *setConfig=new QSettings(QDir::homePath()+"/.config/spark-store/config.ini",QSettings::IniFormat);
|
||||
setConfig->setValue("server/choose",arg1);
|
||||
}
|
||||
}
|
||||
```
|
||||
使用 `QProcess` 来调用各种小文件下载、包安装卸载的命令。
|
||||
|
||||
**应用安装**
|
||||
```cpp
|
||||
void Widget::httpFinished() // 完成下载
|
||||
{
|
||||
...清理资源
|
||||
download_list[nowDownload-1].readyInstall();
|
||||
download_list[nowDownload-1].free=true;
|
||||
if(nowDownload<allDownload){ // 如果有排队则下载下一个
|
||||
...队列的下一个下载请求
|
||||
}
|
||||
}
|
||||
void downloadlist::readyInstall()
|
||||
{
|
||||
...将安装按钮设置为允许点击
|
||||
ui->pushButton_install->setEnabled(true);
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_2->hide();
|
||||
Widget::sendNotification(tr("Finished downloading %1, awaiting to install").arg(ui->label->text()), 5000,
|
||||
"/tmp/spark-store/icon_"+QString::number(num).toUtf8()+".png");
|
||||
}
|
||||
void downloadlist::on_pushButton_install_clicked()
|
||||
{
|
||||
//弹出菜单
|
||||
menu_install->exec(cursor().pos());
|
||||
}
|
||||
在 downloadlist 构造函数里将三种安装方式的按钮按条件放入了 menu_install 菜单里
|
||||
用户点击时,downloadlist::install() 方法
|
||||
三种安装方式为: gdebi, dpkg, deepin-deb-installer
|
||||
void downloadlist::install(int t)
|
||||
{
|
||||
QtConcurrent::run([=](){
|
||||
QProcess installer;
|
||||
installer.start("pkexec gdebi -n /tmp/spark-store/"+ui->label_filename->text().toUtf8());
|
||||
installer.start("pkexec ssinstall /tmp/spark-store/"+ui->label_filename->text().toUtf8());
|
||||
installer.start("deepin-deb-installer /tmp/spark-store/"+ui->label_filename->text().toUtf8());
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
**应用卸载**
|
||||
```cpp
|
||||
void Widget::on_pushButton_uninstall_clicked()
|
||||
{
|
||||
QtConcurrent::run([=](){
|
||||
uninstall.start("pkexec apt purge -y "+pkgName);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
**仓库源更新**
|
||||
```cpp
|
||||
// 更新源列表
|
||||
void Widget::on_pushButton_updateServer_clicked()
|
||||
{
|
||||
QtConcurrent::run([=](){
|
||||
...
|
||||
QFile::remove(QDir::homePath().toUtf8()+"/.config/spark-store/server.list");
|
||||
system("curl -o "+QDir::homePath().toUtf8()+"/.config/spark-store/server.list http://dcstore.shenmo.tech/store/server.list");
|
||||
server.open(QDir::homePath().toUtf8()+"/.config/spark-store/server.list",std::ios::in);
|
||||
...
|
||||
while (getline(server,lineTmp)) {
|
||||
ui->comboBox_server->addItem(QString::fromStdString(lineTmp));
|
||||
}
|
||||
});
|
||||
}
|
||||
// 更新星火商店apt源
|
||||
void Widget::on_pushButton_updateApt_clicked()
|
||||
{
|
||||
QtConcurrent::run([=](){
|
||||
读取 comboBox_server 的内容,写入 /tmp/spark-store/sparkstore.list 文件
|
||||
创建bash脚本,内容为将 sparkstore.list 移动到 /etc/apt/sources.list.d/ 目录下
|
||||
使用QProcess 执行命令 pkexec update.sh
|
||||
}):
|
||||
}
|
||||
```
|
||||
|
||||
## 发送系统通知
|
||||
```cpp
|
||||
#include <libnotify/notify.h>
|
||||
|
||||
static NotifyNotification *_notify = nullptr; // 初始化
|
||||
notify_init(tr("Spark\\ Store").toLocal8Bit()); // 构造函数初始化
|
||||
notify_uninit(); // 析构函数调用
|
||||
|
||||
void Widget::sendNotification(const QString &message, const int msTimeout, const QString &icon)
|
||||
{
|
||||
if(_notify == nullptr)
|
||||
{
|
||||
_notify = notify_notification_new(tr("Spark\\ Store").toLocal8Bit(), message.toLocal8Bit(), icon.toLocal8Bit());
|
||||
notify_notification_set_timeout(_notify, msTimeout);
|
||||
}
|
||||
else
|
||||
notify_notification_update(_notify, tr("Spark\\ Store").toLocal8Bit(), message.toLocal8Bit(), icon.toLocal8Bit());
|
||||
|
||||
notify_notification_show(_notify, nullptr);
|
||||
}
|
||||
```
|
||||
|
||||
BIN
assets/fonts/hksnzt.ttf
Normal file
@@ -34,26 +34,36 @@
|
||||
<file>icons/refresh-page.svg</file>
|
||||
</qresource>
|
||||
<qresource prefix="/">
|
||||
<file>Logo-Spark.png</file>
|
||||
<file>big_image.cpp</file>
|
||||
<file>big_image.h</file>
|
||||
<file>downloadlist.cpp</file>
|
||||
<file>downloadlist.h</file>
|
||||
<file>image_show.cpp</file>
|
||||
<file>image_show.h</file>
|
||||
<file>main.cpp</file>
|
||||
<file>progressload.cpp</file>
|
||||
<file>progressload.h</file>
|
||||
<file>widget.cpp</file>
|
||||
<file>widget.h</file>
|
||||
<file>../Logo-Spark.png</file>
|
||||
<file>../src/big_image.cpp</file>
|
||||
<file>../src/big_image.h</file>
|
||||
<file>../src/downloadlist.cpp</file>
|
||||
<file>../src/downloadlist.h</file>
|
||||
<file>../src/image_show.cpp</file>
|
||||
<file>../src/image_show.h</file>
|
||||
<file>../src/main.cpp</file>
|
||||
<file>../src/progressload.cpp</file>
|
||||
<file>../src/progressload.h</file>
|
||||
<file>../src/widget.cpp</file>
|
||||
<file>../src/widget.h</file>
|
||||
<file>tags/a2d.png</file>
|
||||
<file>tags/community.svg</file>
|
||||
<file>tags/deepin.svg</file>
|
||||
<file>tags/logo_icon.svg</file>
|
||||
<file>tags/uos.svg</file>
|
||||
<file>tags/uos-authorize.svg</file>
|
||||
<file>tags/a2d-small.png</file>
|
||||
<file>tags/community-small.png</file>
|
||||
<file>tags/deepin-small.png</file>
|
||||
<file>tags/dtk-small.png</file>
|
||||
<file>tags/uos-small.png</file>
|
||||
<file>tags/community.png</file>
|
||||
<file>tags/ubuntu-small.png</file>
|
||||
<file>tags/ubuntu.png</file>
|
||||
<file>tags/dwine5-small.png</file>
|
||||
<file>tags/dwine5.svg</file>
|
||||
<file>tags/dwine2-small.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/fonts">
|
||||
<file>fonts/hksnzt.ttf</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
3
assets/icons/category_active.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="#536076" d="M10.138807,3.52000025 L10.138,12.5230002 L14.6066017,8.05523757 L15.3137085,8.76234435 L9.65685425,14.4191986 L4,8.76234435 L4.70710678,8.05523757 L9.138,12.4870002 L9.138807,3.52000025 L10.138807,3.52000025 Z" transform="rotate(90 9.657 11.518)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 366 B |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
3
assets/icons/category_active_dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="#536076" d="M10.138807,3.52000025 L10.138,12.5230002 L14.6066017,8.05523757 L15.3137085,8.76234435 L9.65685425,14.4191986 L4,8.76234435 L4.70710678,8.05523757 L9.138,12.4870002 L9.138807,3.52000025 L10.138807,3.52000025 Z" transform="rotate(90 9.657 11.518)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 366 B |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 523 B After Width: | Height: | Size: 523 B |
|
Before Width: | Height: | Size: 553 B After Width: | Height: | Size: 553 B |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 865 B After Width: | Height: | Size: 865 B |
|
Before Width: | Height: | Size: 895 B After Width: | Height: | Size: 895 B |
|
Before Width: | Height: | Size: 929 B After Width: | Height: | Size: 929 B |
|
Before Width: | Height: | Size: 959 B After Width: | Height: | Size: 959 B |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 810 B After Width: | Height: | Size: 810 B |
|
Before Width: | Height: | Size: 828 B After Width: | Height: | Size: 828 B |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 494 B After Width: | Height: | Size: 494 B |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
BIN
assets/tags/a2d-small.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 248 KiB After Width: | Height: | Size: 248 KiB |
BIN
assets/tags/community-small.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
assets/tags/community.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
BIN
assets/tags/deepin-small.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
BIN
assets/tags/dtk-small.png
Normal file
|
After Width: | Height: | Size: 954 B |
BIN
assets/tags/dwine2-small.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
assets/tags/dwine5-small.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
1
assets/tags/dwine5.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="305" height="304" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden"><defs><clipPath id="clip0"><path d="M688 378 993 378 993 682 688 682Z" fill-rule="evenodd" clip-rule="evenodd"/></clipPath><clipPath id="clip1"><path d="M751.382 385.273 984.326 440.078 929.522 673.022 696.578 618.218Z" fill-rule="evenodd" clip-rule="evenodd"/></clipPath><clipPath id="clip2"><path d="M751.382 385.273 984.326 440.078 929.522 673.022 696.578 618.218Z" fill-rule="evenodd" clip-rule="evenodd"/></clipPath><clipPath id="clip3"><path d="M751.382 385.273 984.326 440.078 929.522 673.022 696.578 618.218Z" fill-rule="evenodd" clip-rule="evenodd"/></clipPath></defs><g clip-path="url(#clip0)" transform="translate(-688 -378)"><path d="M689 529.5C689 445.829 756.829 378 840.5 378 924.171 378 992 445.829 992 529.5 992 613.171 924.171 681 840.5 681 756.829 681 689 613.171 689 529.5Z" fill="#A20000" fill-rule="evenodd"/><g clip-path="url(#clip1)"><g clip-path="url(#clip2)"><g clip-path="url(#clip3)"><path d="M812.478 604.512 826.339 545.597C790.456 531.483 772.809 490.952 786.924 455.069 792.525 440.83 802.648 428.825 815.737 420.901L910.837 443.275C931.459 475.856 921.763 518.985 889.182 539.607 876.253 547.79 860.994 551.499 845.751 550.164L831.89 609.079 851.302 613.646C856.662 614.908 859.986 620.276 858.724 625.636 857.463 630.996 852.095 634.32 846.735 633.058L788.499 619.357C783.138 618.096 779.815 612.728 781.076 607.368 782.338 602.007 787.705 598.684 793.066 599.945L812.478 604.512ZM803.34 469.2 900.4 492.035C901.355 477.612 900.407 467.146 897.544 460.634L819.896 442.366C814.431 446.918 808.915 455.864 803.34 469.2Z" fill="#FFFFFF"/></g></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
assets/tags/ubuntu-small.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/tags/ubuntu.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 873 B After Width: | Height: | Size: 873 B |
BIN
assets/tags/uos-small.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
13
assets/tags/uos.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
|
||||
<defs>
|
||||
<linearGradient id="uos-托盘1-a" x1="15.968%" x2="100%" y1="14.224%" y2="60.554%">
|
||||
<stop offset="0%" stop-color="#0071FF"/>
|
||||
<stop offset="48.72%" stop-color="#00E8FC"/>
|
||||
<stop offset="100%" stop-color="#00A2FF"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g fill="none" transform="translate(1 1)">
|
||||
<circle cx="9" cy="9" r="9" fill="url(#uos-托盘1-a)"/>
|
||||
<path fill="#FFF" d="M13,4.5 C13.5128358,4.5 13.9355072,4.88604019 13.9932723,5.38337887 L14,5.5 L14,9.5 C14,12.5 12,14.5 9,14.5 C6,14.5 4,12.5 4.0043492,9.70016408 L4,9.5 L4,5.5 C4,4.94771525 4.44771525,4.5 5,4.5 C5.51283584,4.5 5.93550716,4.88604019 5.99327227,5.38337887 L6,5.5 L6,9.5 C6,11.5 7.5,12.5 9,12.5 C10.5,12.5 12,11.5 12,9.5 L12,5.5 C12,4.94771525 12.4477153,4.5 13,4.5 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 873 B |
216
downloadlist.cpp
@@ -1,216 +0,0 @@
|
||||
#include "downloadlist.h"
|
||||
#include "ui_downloadlist.h"
|
||||
#include <QDebug>
|
||||
#include <QIcon>
|
||||
#include <QPixmap>
|
||||
#include <QtConcurrent>
|
||||
#include <QProcess>
|
||||
#include <QTextBrowser>
|
||||
bool downloadlist::isInstall=false;
|
||||
|
||||
downloadlist::downloadlist(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::downloadlist)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->pushButton_install->setEnabled(false);
|
||||
ui->progressBar->setValue(0);
|
||||
ui->label_filename->hide();
|
||||
ui->pushButton_install->hide();
|
||||
ui->pushButton_3->hide();
|
||||
ui->widget_spinner->start();
|
||||
ui->widget_spinner->hide();
|
||||
action_dpkg->setText("dpkg");
|
||||
action_gdebi->setText("gdebi");
|
||||
action_deepin->setText("deepin deb installer");
|
||||
connect(action_dpkg,&QAction::triggered,[=](){downloadlist::install(1);});
|
||||
connect(action_gdebi,&QAction::triggered,[=](){downloadlist::install(0);});
|
||||
connect(action_deepin,&QAction::triggered,[=](){downloadlist::install(2);});
|
||||
menu_install->addAction(action_gdebi);
|
||||
//ssinstall命令存在时再加入该选项
|
||||
QFile ssinstall("/bin/ssinstall");
|
||||
ssinstall.open(QIODevice::ReadOnly);
|
||||
if(ssinstall.isOpen()){
|
||||
menu_install->addAction(action_dpkg);
|
||||
}
|
||||
QFile deepin("/bin/deepin-deb-installer");
|
||||
deepin.open(QIODevice::ReadOnly);
|
||||
if(deepin.isOpen()){
|
||||
menu_install->addAction(action_deepin);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
downloadlist::~downloadlist()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void downloadlist::setValue(long long value)
|
||||
{
|
||||
ui->progressBar->setValue(int(value));
|
||||
ui->label_2->setText(QString::number(double(value)/100)+"% ("+speed+")");
|
||||
if(ui->label_2->text().left(4)=="100%"){
|
||||
ui->label_2->setText("Downloaded,waiting to Install");
|
||||
}
|
||||
}
|
||||
|
||||
void downloadlist::setMax(long long max)
|
||||
{
|
||||
ui->progressBar->setMaximum(int(max));
|
||||
}
|
||||
|
||||
void downloadlist::setName(QString name)
|
||||
{
|
||||
ui->label->setText(name);
|
||||
}
|
||||
|
||||
QString downloadlist::getName()
|
||||
{
|
||||
return ui->label_filename->text();
|
||||
}
|
||||
|
||||
void downloadlist::readyInstall()
|
||||
{
|
||||
if(ui->progressBar->value()!= ui->progressBar->maximum() && !close){
|
||||
ui->progressBar->hide();
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_2->hide();
|
||||
system("notify-send \""+ui->label->text().toUtf8()+"Download Failed\"" +" --icon=/tmp/spark-store/icon_"+QString::number(num).toUtf8()+".png");
|
||||
ui->label_2->setText("Download Failed,Check Your Connection");
|
||||
ui->pushButton_install->setEnabled(false);
|
||||
return;
|
||||
|
||||
}
|
||||
if(!close){
|
||||
ui->progressBar->hide();
|
||||
ui->pushButton_install->setEnabled(true);
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_2->hide();
|
||||
system("notify-send \""+ui->label->text().toUtf8()+"Download Finished,waiting to Install\"" +" --icon=/tmp/spark-store/icon_"+QString::number(num).toUtf8()+".png");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void downloadlist::setFileName(QString fileName)
|
||||
{
|
||||
ui->label_filename->setText(fileName);
|
||||
}
|
||||
|
||||
void downloadlist::seticon(const QPixmap icon)
|
||||
{
|
||||
ui->label_3->setPixmap(icon);
|
||||
}
|
||||
|
||||
void downloadlist::closeDownload()
|
||||
{
|
||||
on_pushButton_2_clicked();
|
||||
}
|
||||
|
||||
void downloadlist::setSpeed(QString s)
|
||||
{
|
||||
speed=s;
|
||||
}
|
||||
|
||||
void downloadlist::install(int t)
|
||||
{
|
||||
if(!isInstall){
|
||||
isInstall=true;
|
||||
ui->pushButton_install->hide();
|
||||
ui->widget_spinner->show();
|
||||
qDebug()<<"/tmp/spark-store/"+ui->label_filename->text().toUtf8();
|
||||
ui->label_2->setText("Installing...");
|
||||
QtConcurrent::run([=](){
|
||||
QProcess installer;
|
||||
if(!reinstall){
|
||||
switch (t) {
|
||||
case 0:
|
||||
installer.start("pkexec gdebi -n /tmp/spark-store/"+ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 1:
|
||||
installer.start("pkexec ssinstall /tmp/spark-store/"+ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 2:
|
||||
installer.start("deepin-deb-installer /tmp/spark-store/"+ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
}
|
||||
}else {
|
||||
switch (t) {
|
||||
case 0:
|
||||
installer.start("pkexec gdebi -n /tmp/spark-store/"+ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 1:
|
||||
installer.start("pkexec ssinstall /tmp/spark-store/"+ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 2:
|
||||
installer.start("deepin-deb-installer /tmp/spark-store/"+ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool haveError=false;
|
||||
bool notRoot=false;
|
||||
installer.waitForFinished();
|
||||
out=installer.readAllStandardOutput();
|
||||
QStringList everyOut=out.split("\n");
|
||||
for (int i=0;i<everyOut.size();i++) {
|
||||
if(everyOut[i].left(2)=="E:"){
|
||||
haveError=true;
|
||||
}
|
||||
if(everyOut[i].right(14)=="Not authorized"){
|
||||
notRoot=true;
|
||||
}
|
||||
}
|
||||
QProcess isInstall;
|
||||
isInstall.start("dpkg -s "+pkgName);
|
||||
isInstall.waitForFinished();
|
||||
int error=QString::fromStdString(isInstall.readAllStandardError().toStdString()).length();
|
||||
if(error==0){
|
||||
ui->pushButton_install->hide();
|
||||
ui->label_2->setText("Finish");
|
||||
ui->pushButton_3->show();
|
||||
}else {
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_install->setText("Retry");
|
||||
ui->label_2->setText("Error happened in dpkg progress , you can try it again");
|
||||
ui->pushButton_3->show();
|
||||
}
|
||||
if(notRoot){
|
||||
ui->label_2->setText("dpkg progress had been aborted,you can retry installation");
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_3->hide();
|
||||
}
|
||||
ui->widget_spinner->hide();
|
||||
downloadlist::isInstall=false;
|
||||
|
||||
});
|
||||
|
||||
qDebug()<<ui->label_filename->text().toUtf8();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void downloadlist::on_pushButton_install_clicked()
|
||||
{
|
||||
//弹出菜单
|
||||
menu_install->exec(cursor().pos());
|
||||
}
|
||||
|
||||
void downloadlist::on_pushButton_2_clicked()
|
||||
{
|
||||
ui->label_2->setText("Download Canceled");
|
||||
ui->pushButton_2->setEnabled(false);
|
||||
ui->progressBar->hide();
|
||||
close=true;
|
||||
}
|
||||
|
||||
void downloadlist::on_pushButton_3_clicked()
|
||||
{
|
||||
output_w.layout()->addWidget(textbrowser);
|
||||
textbrowser->setLineWidth(0);
|
||||
textbrowser->setText(out);
|
||||
output_w.layout()->setMargin(20);
|
||||
output_w.setTitle(ui->label->text());
|
||||
output_w.setMinimumHeight(600);
|
||||
output_w.setAttribute(Qt::WA_TranslucentBackground);
|
||||
output_w.show();
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
#include "image_show.h"
|
||||
#include <QHBoxLayout>
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <DDialog>
|
||||
#include <DBlurEffectWidget>
|
||||
#include <DWidgetUtil>
|
||||
#include <DApplication>
|
||||
#include <QDesktopWidget>
|
||||
DWIDGET_USE_NAMESPACE
|
||||
image_show::image_show(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
QHBoxLayout *layout=new QHBoxLayout;
|
||||
layout->addWidget(m_label);
|
||||
setLayout(layout);
|
||||
m_label->setText("layout");
|
||||
}
|
||||
|
||||
void image_show::setImage(QPixmap image)
|
||||
{
|
||||
|
||||
QImage screen0;
|
||||
screen0=image.toImage();
|
||||
// QPainter painter(&screen0);
|
||||
QImage re_screen1;
|
||||
QImage re_screen0=screen0.scaled(QSize(400,300),Qt::KeepAspectRatio,Qt::SmoothTransformation);
|
||||
desktop_w=DApplication::desktop()->width();
|
||||
desktop_h=DApplication::desktop()->height();
|
||||
if(screen0.width()>(desktop_w-20) || screen0.height()>(desktop_h-20)){
|
||||
re_screen1=screen0.scaled(QSize(desktop_w-20,desktop_h-20),Qt::KeepAspectRatio,Qt::SmoothTransformation);
|
||||
m_image=QPixmap::fromImage(re_screen1);
|
||||
}else {
|
||||
m_image=image;
|
||||
}
|
||||
|
||||
m_label->setPixmap(QPixmap::fromImage(re_screen0));
|
||||
}
|
||||
|
||||
void image_show::mousePressEvent(QMouseEvent *)
|
||||
{
|
||||
m_dialog->setimage(m_image);
|
||||
m_dialog->showFullScreen();
|
||||
m_dialog->setFixedSize(desktop_w,desktop_h);
|
||||
m_dialog->move(0,0);/*
|
||||
moveToCenter(m_dialog);*/
|
||||
|
||||
}
|
||||
67
main.cpp
@@ -1,67 +0,0 @@
|
||||
#include <DApplication>
|
||||
#include <DWidgetUtil> //Dtk::Widget::moveToCenter(&w); 要调用它,就得引用DWidgetUtil
|
||||
#include <QDesktopWidget>
|
||||
#include <widget.h>
|
||||
#include <QTranslator>
|
||||
#include <DAboutDialog>
|
||||
DWIDGET_USE_NAMESPACE
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
DApplication::loadDXcbPlugin(); //让bar处在标题栏中
|
||||
DApplication a(argc, argv);
|
||||
DAboutDialog dialog;
|
||||
a.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
a.loadTranslator();
|
||||
a.setAboutDialog(&dialog);
|
||||
dialog.setLicense("We publish this program under GPL V3");
|
||||
dialog.setVersion(DApplication::buildVersion(" Version 2.0+1"));
|
||||
dialog.setAcknowledgementVisible(true);
|
||||
dialog.setAcknowledgementLink("https://gitee.com/deepin-community-store/spark-store");
|
||||
a.setApplicationAcknowledgementPage("https://gitee.com/deepin-community-store/spark-store");
|
||||
dialog.setProductIcon(QIcon::fromTheme("spark-store")); //设置Logo
|
||||
dialog.setProductName(QLabel::tr("Spark Store"));
|
||||
//dialog.setDescription(QLabel::tr("An appstore powered by deepin community\n We born for change"));
|
||||
dialog.setDescription(
|
||||
"<span style=' font-size:10pt;font-weight:60;'>An appstore powered by deepin community</span><br/>"
|
||||
"<a href='https://www.spark-app.store/'>https://www.spark-app.store</a><br/>"
|
||||
"<span style=' font-size:12pt;'>Spark developers</span>");
|
||||
dialog.setProductName(QLabel::tr("Spark Store"));
|
||||
dialog.setCompanyLogo(QPixmap(":/Logo-Spark.png"));
|
||||
dialog.setWebsiteName("The Spark Project");
|
||||
dialog.setWebsiteLink("https://gitee.com/deepin-community-store");
|
||||
Widget w;
|
||||
QDesktopWidget *s=DApplication::desktop();
|
||||
int d_w=s->width();
|
||||
int d_h=s->height();
|
||||
if(d_w<=1366){
|
||||
w.setMinimumWidth(925);
|
||||
w.resize(925,650);
|
||||
}else if(d_w<=1920){
|
||||
w.setMinimumWidth(1180);
|
||||
w.resize(1180,760);
|
||||
}else {
|
||||
w.setMinimumWidth(1180);
|
||||
w.resize(1180,760);
|
||||
}
|
||||
if(d_h<=768){
|
||||
w.setMinimumHeight(650);
|
||||
w.resize(925,650);
|
||||
}else if(d_h<=1080){
|
||||
w.setMinimumHeight(760);
|
||||
w.resize(1180,760);
|
||||
}else {
|
||||
w.setMinimumHeight(760);
|
||||
w.resize(1180,760);
|
||||
}
|
||||
// w.resize(925,650);
|
||||
|
||||
w.show();
|
||||
QString arg1=argv[1];
|
||||
if(arg1.left(6)=="spk://"){
|
||||
w.openUrl(QUrl(argv[1]));
|
||||
}
|
||||
//让打开时界面显示在正中
|
||||
Dtk::Widget::moveToCenter(&w);
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#include "progressload.h"
|
||||
|
||||
ProgressLoad::ProgressLoad(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
m_progess=new QWidget(this);
|
||||
m_progess->move(0,0);
|
||||
m_progess->show();
|
||||
timer=new QTimer;
|
||||
value=0;
|
||||
timer->setInterval(10);
|
||||
timer->start();
|
||||
connect(timer,&QTimer::timeout,[=](){
|
||||
m_progess->setFixedWidth(width()/100*value);
|
||||
m_progess->setFixedHeight(height());
|
||||
});
|
||||
}
|
||||
|
||||
void ProgressLoad::setValue(int v)
|
||||
{
|
||||
value=v;
|
||||
m_progess->setFixedWidth(width()/100*value);
|
||||
}
|
||||
|
||||
void ProgressLoad::setTheme(bool dark, QColor color)
|
||||
{
|
||||
if(dark){
|
||||
plt.setColor(QPalette::Background,QColor(28,28,28));
|
||||
setAutoFillBackground(true);
|
||||
setPalette(plt);
|
||||
|
||||
}else {
|
||||
plt.setColor(QPalette::Background,QColor(255,255,255));
|
||||
setAutoFillBackground(true);
|
||||
setPalette(plt);
|
||||
}
|
||||
m_progess->setStyleSheet("background-color:"+color.name());
|
||||
}
|
||||
9
spark-store-project.pro
Normal file
@@ -0,0 +1,9 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
CONFIG += ordered
|
||||
|
||||
SUBDIRS += \
|
||||
third-party/QtNetworkService \
|
||||
src/spark-store.pro
|
||||
|
||||
spark-store.depends = third-party/QtNetworkService
|
||||
@@ -1,54 +0,0 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2019-06-30T12:53:03
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui network concurrent webenginewidgets
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
TRANSLATIONS = ./trans/lang_English.ts \
|
||||
./trans/lang_Chinses.ts
|
||||
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG += dtkwidget
|
||||
|
||||
TARGET = spark-store
|
||||
TEMPLATE = app
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which as been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
|
||||
SOURCES += main.cpp\
|
||||
widget.cpp \
|
||||
downloadlist.cpp \
|
||||
image_show.cpp \
|
||||
big_image.cpp \
|
||||
progressload.cpp
|
||||
|
||||
HEADERS += \
|
||||
widget.h \
|
||||
downloadlist.h \
|
||||
image_show.h \
|
||||
big_image.h \
|
||||
progressload.h
|
||||
|
||||
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
FORMS += \
|
||||
widget.ui \
|
||||
downloadlist.ui
|
||||
|
||||
RESOURCES += \
|
||||
icons.qrc
|
||||
@@ -1,326 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.8.2, 2020-09-29T19:48:57. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
<value type="QByteArray">{fbec18d5-0eff-4f51-b839-fdf91314dc72}</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||
<value type="QString" key="language">Cpp</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||
<value type="QString" key="language">QmlJS</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
|
||||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">桌面</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">桌面</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{ccf49870-890c-4cd1-b393-ff8b20f60cce}</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/sy120zx/Desktop/build-spark-store-unknown-Debug</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/sy120zx/Desktop/build-spark-store-unknown-Release</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/sy120zx/Desktop/build-spark-store-unknown-Profile</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">spark-store</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/sy120zx/Desktop/spark-store/spark-store.pro</value>
|
||||
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">spark-store.pro</value>
|
||||
<value type="QString" key="RunConfiguration.Arguments"></value>
|
||||
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/sy120zx/Desktop/build-spark-store-unknown-Debug</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||
<value type="int">1</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
<value type="int">20</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>Version</variable>
|
||||
<value type="int">20</value>
|
||||
</data>
|
||||
</qtcreator>
|
||||
102
src/appitem.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "appitem.h"
|
||||
#include "ui_appitem.h"
|
||||
#include <QtConcurrent>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QEventLoop>
|
||||
#include <QPainter>
|
||||
#include <QGraphicsDropShadowEffect>
|
||||
|
||||
AppItem::AppItem(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::AppItem)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// auto shadow = new QGraphicsDropShadowEffect();
|
||||
// shadow->setXOffset(0);
|
||||
// shadow->setYOffset(1);
|
||||
// shadow->setBlurRadius(2);
|
||||
// shadow->setColor(QColor::fromRgba(qRgba(0, 0, 0, 180)));
|
||||
// ui->container->setGraphicsEffect(shadow);
|
||||
}
|
||||
|
||||
AppItem::~AppItem()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void AppItem::setTitle(QString title)
|
||||
{
|
||||
m_title = title;
|
||||
ui->lbl_title->setText(title);
|
||||
}
|
||||
|
||||
void AppItem::setDescription(QString description)
|
||||
{
|
||||
m_description = description;
|
||||
QString elidedText = ui->lbl_desc->fontMetrics().elidedText(
|
||||
description, Qt::ElideRight,
|
||||
ui->lbl_desc->width(), Qt::TextShowMnemonic);
|
||||
ui->lbl_desc->setText(elidedText);
|
||||
ui->lbl_desc->setAlignment(Qt::AlignTop);
|
||||
}
|
||||
|
||||
void AppItem::setIcon(QString icon)
|
||||
{
|
||||
m_icon = icon;
|
||||
if(!icon.isEmpty())
|
||||
{
|
||||
downloadIcon(icon);
|
||||
}
|
||||
}
|
||||
|
||||
void AppItem::setUrl(QString url)
|
||||
{
|
||||
m_url = url;
|
||||
}
|
||||
|
||||
void AppItem::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
emit clicked(QUrl(m_url));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 下载图标
|
||||
* @param icon
|
||||
*/
|
||||
void AppItem::downloadIcon(QString icon)
|
||||
{
|
||||
QtConcurrent::run([=]()
|
||||
{
|
||||
auto reqManager = new QNetworkAccessManager();
|
||||
|
||||
QUrl url(icon);
|
||||
QNetworkReply *reply = reqManager->get(QNetworkRequest(url));
|
||||
QEventLoop loop;
|
||||
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
connect(reply, &QNetworkReply::finished, this, [=] () { emit finished(); });
|
||||
loop.exec();
|
||||
reqManager->deleteLater();
|
||||
|
||||
QPixmap pixmap;
|
||||
pixmap.loadFromData(reply->readAll());
|
||||
pixmap = pixmap.scaled(78, 78, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
if (reply->error() == QNetworkReply::NoError)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "loadIcon", Qt::QueuedConnection, Q_ARG(QPixmap, pixmap));
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << reply->errorString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void AppItem::loadIcon(QPixmap pic)
|
||||
{
|
||||
ui->lbl_icon->setPixmap(pic);
|
||||
}
|
||||
45
src/appitem.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef APPITEM_H
|
||||
#define APPITEM_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QUrl>
|
||||
|
||||
namespace Ui {
|
||||
class AppItem;
|
||||
}
|
||||
|
||||
class AppItem : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AppItem(QWidget *parent = nullptr);
|
||||
~AppItem() override;
|
||||
|
||||
void setTitle(QString title);
|
||||
void setDescription(QString description);
|
||||
void setIcon(QString icon);
|
||||
void setUrl(QString url);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
Ui::AppItem *ui;
|
||||
|
||||
QString m_title;
|
||||
QString m_description;
|
||||
QString m_icon;
|
||||
QString m_url;
|
||||
|
||||
public slots:
|
||||
void downloadIcon(QString icon);
|
||||
void loadIcon(QPixmap pic);
|
||||
|
||||
signals:
|
||||
void clicked(QUrl url);
|
||||
void finished();
|
||||
|
||||
};
|
||||
|
||||
#endif // APPITEM_H
|
||||
160
src/appitem.ui
Normal file
@@ -0,0 +1,160 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AppItem</class>
|
||||
<widget class="QWidget" name="AppItem">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>333</width>
|
||||
<height>133</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QWidget#AppItem {
|
||||
width: 300px;
|
||||
height: 100px;
|
||||
margin: 15px;
|
||||
color: #6d6d6d;
|
||||
border-radius: 18px;
|
||||
background-color: width: 300px;
|
||||
height: 100px;
|
||||
margin: 15px;
|
||||
color: #6d6d6d;
|
||||
border-radius: 18px;
|
||||
background-color: #F4F4F6;
|
||||
}
|
||||
|
||||
QWidget#container {
|
||||
background-color: #F4F4F6;
|
||||
}
|
||||
|
||||
QLabel#lbl_icon {
|
||||
background: transparent;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
QLabel#lbl_title {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
padding-right: 10px;
|
||||
font-size: 19px;
|
||||
|
||||
}
|
||||
|
||||
QLabel#lbl_desc {
|
||||
text-align: left;
|
||||
font-weight: lighter;
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
color: grey;
|
||||
}</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="container" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbl_icon">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">width: 78px;
|
||||
height: 70px;
|
||||
padding: 10px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lbl_title">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbl_desc">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,22 +1,30 @@
|
||||
#include "big_image.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QtConcurrent>
|
||||
big_image::big_image(DBlurEffectWidget *parent) : DBlurEffectWidget(parent)
|
||||
|
||||
big_image::big_image(DBlurEffectWidget *parent) :
|
||||
DBlurEffectWidget(parent),
|
||||
m_image(new QLabel)
|
||||
{
|
||||
// m_image->setParent(this);
|
||||
QHBoxLayout *layout=new QHBoxLayout;
|
||||
setLayout(layout);
|
||||
layout->addWidget(m_image);
|
||||
layout->setMargin(0);
|
||||
m_image->setAlignment(Qt::AlignCenter);
|
||||
// m_image->setMaximumSize(1360,768);
|
||||
setWindowFlags(this->windowFlags() | Qt::WindowStaysOnTopHint);//设置图片对话框总在最前
|
||||
setWindowFlags(this->windowFlags() | Qt::WindowStaysOnTopHint); // 设置图片对话框总在最前
|
||||
setRadius(0);
|
||||
setMaskAlpha(60);
|
||||
setMaskColor(QColor("#000000"));
|
||||
|
||||
QHBoxLayout *layout = new QHBoxLayout;
|
||||
setLayout(layout);
|
||||
layout->addWidget(m_image);
|
||||
layout->setMargin(0);
|
||||
|
||||
// m_image->setParent(this);
|
||||
// m_image->setMaximumSize(1360,768);
|
||||
m_image->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void big_image::setimage(QPixmap image)
|
||||
{
|
||||
m_image->setPixmap(image);
|
||||
}
|
||||
|
||||
void big_image::mousePressEvent(QMouseEvent *)
|
||||
@@ -25,11 +33,6 @@ void big_image::mousePressEvent(QMouseEvent *)
|
||||
m_image->clear();
|
||||
}
|
||||
|
||||
void big_image::setimage(QPixmap image)
|
||||
{
|
||||
m_image->setPixmap(image);
|
||||
}
|
||||
|
||||
void big_image::focusOutEvent(QFocusEvent *)
|
||||
{
|
||||
hide();
|
||||
@@ -1,25 +1,27 @@
|
||||
#ifndef BIG_IMAGE_H
|
||||
#define BIG_IMAGE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <DBlurEffectWidget>
|
||||
#include <QMouseEvent>
|
||||
#include <QLabel>
|
||||
|
||||
#include <DBlurEffectWidget>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
class big_image : public DBlurEffectWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit big_image(DBlurEffectWidget *parent = nullptr);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
QLabel *m_image=new QLabel;
|
||||
|
||||
QLabel *m_image;
|
||||
|
||||
void setimage(QPixmap);
|
||||
void focusOutEvent(QFocusEvent *event);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void focusOutEvent(QFocusEvent *event) override;
|
||||
};
|
||||
|
||||
#endif // BIG_IMAGE_H
|
||||
255
src/downloadlist.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
#include "downloadlist.h"
|
||||
#include "ui_downloadlist.h"
|
||||
|
||||
#include <QtConcurrent>
|
||||
#include <QProcess>
|
||||
|
||||
#include "widget.h"
|
||||
|
||||
bool downloadlist::isInstall = false;
|
||||
|
||||
downloadlist::downloadlist(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
reinstall(false),
|
||||
close(false),
|
||||
ui(new Ui::downloadlist),
|
||||
menu_install(new QMenu),
|
||||
action_dpkg(new QAction),
|
||||
action_deepin(new QAction),
|
||||
action_gdebi(new QAction),
|
||||
output_w(new DDialog),
|
||||
textbrowser(new QTextBrowser)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->pushButton_install->setEnabled(false);
|
||||
ui->progressBar->setValue(0);
|
||||
ui->label_filename->hide();
|
||||
ui->pushButton_install->hide();
|
||||
ui->pushButton_3->hide();
|
||||
ui->widget_spinner->start();
|
||||
ui->widget_spinner->hide();
|
||||
action_dpkg->setText(tr("Spark Store App Installer"));
|
||||
action_deepin->setText(tr("deepin deb installer"));
|
||||
action_gdebi->setText(tr("gdebi"));
|
||||
|
||||
connect(action_dpkg,&QAction::triggered,[=](){downloadlist::install(0);});
|
||||
connect(action_deepin,&QAction::triggered,[=](){downloadlist::install(1);});
|
||||
connect(action_gdebi,&QAction::triggered,[=](){downloadlist::install(2);});
|
||||
|
||||
// ssinstall 命令存在时再加入该选项
|
||||
QFile ssinstall("/usr/local/bin/ssinstall");
|
||||
ssinstall.open(QIODevice::ReadOnly);
|
||||
if(ssinstall.isOpen())
|
||||
{
|
||||
menu_install->addAction(action_dpkg);
|
||||
}
|
||||
|
||||
QFile deepin("/usr/bin/deepin-deb-installer");
|
||||
deepin.open(QIODevice::ReadOnly);
|
||||
if(deepin.isOpen())
|
||||
{
|
||||
menu_install->addAction(action_deepin);
|
||||
}
|
||||
|
||||
menu_install->addAction(action_gdebi);
|
||||
}
|
||||
|
||||
downloadlist::~downloadlist()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void downloadlist::setValue(qint64 value)
|
||||
{
|
||||
ui->progressBar->setValue(qint32(value));
|
||||
ui->label_2->setText(QString::number(double(value) / 100) + "% (" + speed + ")");
|
||||
if(ui->label_2->text().left(4) == "100%")
|
||||
{
|
||||
ui->label_2->setText(tr("Downloaded, waiting to install"));
|
||||
}
|
||||
}
|
||||
|
||||
void downloadlist::setMax(qint64 max)
|
||||
{
|
||||
ui->progressBar->setMaximum(qint32(max));
|
||||
}
|
||||
|
||||
void downloadlist::setName(QString name)
|
||||
{
|
||||
ui->label->setText(name);
|
||||
}
|
||||
|
||||
QString downloadlist::getName()
|
||||
{
|
||||
return ui->label_filename->text();
|
||||
}
|
||||
|
||||
void downloadlist::readyInstall()
|
||||
{
|
||||
if(ui->progressBar->value() != ui->progressBar->maximum() && !close)
|
||||
{
|
||||
ui->progressBar->hide();
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_2->hide();
|
||||
Widget::sendNotification(tr("Failed to download %1").arg(ui->label->text()), 5000,
|
||||
"/tmp/spark-store/icon_" + QString::number(num).toUtf8() + ".png");
|
||||
ui->label_2->setText(tr("Download Failed,Check Your Connection"));
|
||||
ui->pushButton_install->setEnabled(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!close)
|
||||
{
|
||||
ui->progressBar->hide();
|
||||
ui->pushButton_install->setEnabled(true);
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_2->hide();
|
||||
Widget::sendNotification(tr("Finished downloading %1, awaiting to install").arg(ui->label->text()), 5000,
|
||||
"/tmp/spark-store/icon_" + QString::number(num).toUtf8() + ".png");
|
||||
}
|
||||
}
|
||||
|
||||
void downloadlist::setFileName(QString fileName)
|
||||
{
|
||||
ui->label_filename->setText(fileName);
|
||||
}
|
||||
|
||||
void downloadlist::seticon(const QPixmap icon)
|
||||
{
|
||||
ui->label_3->setPixmap(icon);
|
||||
}
|
||||
|
||||
void downloadlist::closeDownload()
|
||||
{
|
||||
on_pushButton_2_clicked();
|
||||
}
|
||||
|
||||
void downloadlist::setSpeed(QString s)
|
||||
{
|
||||
speed = s;
|
||||
}
|
||||
|
||||
void downloadlist::install(int t)
|
||||
{
|
||||
if(!isInstall)
|
||||
{
|
||||
isInstall = true;
|
||||
ui->pushButton_install->hide();
|
||||
ui->widget_spinner->show();
|
||||
qDebug() << "/tmp/spark-store/" + ui->label_filename->text().toUtf8();
|
||||
ui->label_2->setText(tr("Installing"));
|
||||
|
||||
QtConcurrent::run([=]()
|
||||
{
|
||||
QProcess installer;
|
||||
if(!reinstall)
|
||||
{
|
||||
switch(t)
|
||||
{
|
||||
case 0:
|
||||
installer.start("pkexec ssinstall /tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 1:
|
||||
installer.start("deepin-deb-installer /tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 2:
|
||||
installer.start("pkexec gdebi -n /tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(t)
|
||||
{
|
||||
case 0:
|
||||
installer.start("pkexec ssinstall /tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 1:
|
||||
installer.start("deepin-deb-installer /tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 2:
|
||||
installer.start("pkexec gdebi -n /tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool haveError = false;
|
||||
bool notRoot = false;
|
||||
installer.waitForFinished();
|
||||
out = installer.readAllStandardOutput();
|
||||
|
||||
QStringList everyOut = out.split("\n");
|
||||
for(int i=0;i<everyOut.size();i++)
|
||||
{
|
||||
if(everyOut[i].left(2) == "E:")
|
||||
{
|
||||
haveError = true;
|
||||
}
|
||||
if(everyOut[i].right(14) == "Not authorized")
|
||||
{
|
||||
notRoot = true;
|
||||
}
|
||||
}
|
||||
|
||||
QProcess isInstall;
|
||||
isInstall.start("dpkg -s " + pkgName);
|
||||
isInstall.waitForFinished();
|
||||
int error = QString::fromStdString(isInstall.readAllStandardError().toStdString()).length();
|
||||
if(error == 0)
|
||||
{
|
||||
ui->pushButton_install->hide();
|
||||
ui->label_2->setText(tr("Finish"));
|
||||
ui->pushButton_3->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_install->setText(tr("Retry"));
|
||||
ui->label_2->setText(tr("Error happened in dpkg progress , you can try it again"));
|
||||
ui->pushButton_3->show();
|
||||
}
|
||||
|
||||
if(notRoot)
|
||||
{
|
||||
ui->label_2->setText(tr("dpkg progress had been aborted,you can retry installation"));
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_3->hide();
|
||||
}
|
||||
|
||||
ui->widget_spinner->hide();
|
||||
downloadlist::isInstall = false;
|
||||
});
|
||||
|
||||
qDebug()<<ui->label_filename->text().toUtf8();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void downloadlist::on_pushButton_install_clicked()
|
||||
{
|
||||
// 弹出菜单
|
||||
menu_install->exec(cursor().pos());
|
||||
}
|
||||
|
||||
void downloadlist::on_pushButton_2_clicked()
|
||||
{
|
||||
ui->label_2->setText(tr("Download canceled"));
|
||||
ui->pushButton_2->setEnabled(false);
|
||||
ui->progressBar->hide();
|
||||
close = true;
|
||||
}
|
||||
|
||||
void downloadlist::on_pushButton_3_clicked()
|
||||
{
|
||||
textbrowser->setLineWidth(0);
|
||||
textbrowser->setText(out);
|
||||
|
||||
output_w->setMinimumHeight(600);
|
||||
output_w->setAttribute(Qt::WA_TranslucentBackground);
|
||||
output_w->setTitle(ui->label->text());
|
||||
output_w->layout()->setMargin(20);
|
||||
output_w->layout()->addWidget(textbrowser);
|
||||
output_w->show();
|
||||
}
|
||||
@@ -2,11 +2,14 @@
|
||||
#define DOWNLOADLIST_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <DDialog>
|
||||
#include <QTextBrowser>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
|
||||
#include <DDialog>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
namespace Ui {
|
||||
class downloadlist;
|
||||
}
|
||||
@@ -18,40 +21,45 @@ class downloadlist : public QWidget
|
||||
public:
|
||||
explicit downloadlist(QWidget *parent = nullptr);
|
||||
~downloadlist();
|
||||
void setValue(long long);
|
||||
void setMax(long long);
|
||||
|
||||
int num;
|
||||
bool free;
|
||||
static bool isInstall;
|
||||
bool reinstall;
|
||||
QString speed;
|
||||
QString out;
|
||||
QString pkgName;
|
||||
bool close;
|
||||
|
||||
void setValue(qint64);
|
||||
void setMax(qint64);
|
||||
void setName(QString);
|
||||
QString getName();
|
||||
void readyInstall();
|
||||
bool free;
|
||||
|
||||
void setFileName(QString);
|
||||
void seticon(const QPixmap);
|
||||
void closeDownload();
|
||||
void setSpeed(QString);
|
||||
int num;
|
||||
bool close=false;
|
||||
QString out;
|
||||
DDialog output_w;
|
||||
QTextBrowser *textbrowser=new QTextBrowser;
|
||||
bool reinstall=false;
|
||||
QString pkgName;
|
||||
QMenu *menu_install=new QMenu;
|
||||
QAction *action_gdebi=new QAction;
|
||||
QAction *action_dpkg=new QAction;
|
||||
QAction *action_deepin=new QAction;
|
||||
|
||||
void install(int);
|
||||
private slots:
|
||||
void on_pushButton_install_clicked();
|
||||
// void on_pushButton_maninst_clicked();
|
||||
void on_pushButton_2_clicked();
|
||||
void on_pushButton_3_clicked();
|
||||
|
||||
private:
|
||||
Ui::downloadlist *ui;
|
||||
static bool isInstall;
|
||||
QString speed;
|
||||
|
||||
QMenu *menu_install;
|
||||
QAction *action_dpkg;
|
||||
QAction *action_deepin;
|
||||
QAction *action_gdebi;
|
||||
|
||||
DDialog *output_w;
|
||||
QTextBrowser *textbrowser;
|
||||
|
||||
private slots:
|
||||
void on_pushButton_install_clicked();
|
||||
void on_pushButton_2_clicked();
|
||||
void on_pushButton_3_clicked();
|
||||
|
||||
};
|
||||
//bool downloadlist::isInstall=false;
|
||||
|
||||
#endif // DOWNLOADLIST_H
|
||||
277
src/downloadworker.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
#include "downloadworker.h"
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
#include <QThread>
|
||||
#include <QRegularExpression>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
|
||||
DownloadWorker::DownloadWorker(QObject *parent)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
}
|
||||
|
||||
void DownloadWorker::setIdentifier(int identifier)
|
||||
{
|
||||
this->identifier = identifier;
|
||||
}
|
||||
|
||||
void DownloadWorker::setParamter(const QString &url, QPair<qint64, qint64> range, QFile *file)
|
||||
{
|
||||
this->url = url;
|
||||
this->startPos = range.first;
|
||||
this->endPos = range.second;
|
||||
this->file = file;
|
||||
}
|
||||
|
||||
qint64 DownloadWorker::getReceivedPos()
|
||||
{
|
||||
return receivedPos;
|
||||
}
|
||||
|
||||
void DownloadWorker::doWork()
|
||||
{
|
||||
mgr = new QNetworkAccessManager(this);
|
||||
QNetworkRequest request;
|
||||
request.setUrl(url);
|
||||
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
request.setRawHeader("Range", QString("bytes=%1-%2").arg(startPos).arg(endPos).toLocal8Bit());
|
||||
reply = mgr->get(request);
|
||||
qDebug() << "开始下载数据:" << QString(" %1~%2 -> writePos Start %3").arg(startPos).arg(endPos).arg(receivedPos);
|
||||
|
||||
connect(reply, static_cast<void(QNetworkReply::*)(QNetworkReply::NetworkError) > (&QNetworkReply::error),
|
||||
[this](QNetworkReply::NetworkError error)
|
||||
{
|
||||
if(error != QNetworkReply::NoError)
|
||||
{
|
||||
qDebug() << "出错了:" << reply->errorString();
|
||||
}
|
||||
});
|
||||
connect(reply, &QNetworkReply::finished, mgr, &QNetworkAccessManager::deleteLater);
|
||||
connect(reply, &QNetworkReply::readyRead, this, &DownloadWorker::dataReady);
|
||||
connect(reply, &QNetworkReply::finished, this, &DownloadWorker::slotFinish);
|
||||
connect(reply, &QNetworkReply::downloadProgress, this, &DownloadWorker::handleProcess);
|
||||
// connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
connect(reply, &QNetworkReply::finished, this, &DownloadWorker::doStop);
|
||||
}
|
||||
|
||||
void DownloadWorker::doStop()
|
||||
{
|
||||
if (reply) {
|
||||
reply->disconnect();
|
||||
reply->aboutToClose();
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadWorker::dataReady()
|
||||
{
|
||||
QByteArray data = reply->readAll();
|
||||
file->seek(startPos + receivedPos);
|
||||
file->write(data);
|
||||
receivedPos += data.size();
|
||||
}
|
||||
|
||||
void DownloadWorker::slotFinish()
|
||||
{
|
||||
file->flush();
|
||||
qDebug() << "数据块下载完毕:" << QString(" %1~%2 -> writePos Start %3").arg(startPos).arg(endPos).arg(receivedPos);
|
||||
emit workFinished();
|
||||
}
|
||||
|
||||
void DownloadWorker::handleProcess(qint64, qint64)
|
||||
{
|
||||
emit this->downloadProcess();
|
||||
}
|
||||
|
||||
|
||||
DownloadController::DownloadController(QObject *parent)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
domains = {
|
||||
"d1.store.deepinos.org.cn",
|
||||
"d2.store.deepinos.org.cn",
|
||||
"d3.store.deepinos.org.cn",
|
||||
"d4.store.deepinos.org.cn",
|
||||
"d5.store.deepinos.org.cn"
|
||||
};
|
||||
this->threadNum = domains.size() > 5 ? 5 : domains.size();
|
||||
}
|
||||
|
||||
DownloadController::~DownloadController()
|
||||
{
|
||||
if(workers.size() > 0)
|
||||
{
|
||||
for(int i = 0; i < workers.size(); i++)
|
||||
{
|
||||
workers.at(i)->doStop();
|
||||
workers.at(i)->disconnect();
|
||||
workers.at(i)->deleteLater();
|
||||
}
|
||||
workers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadController::setFilename(QString filename)
|
||||
{
|
||||
this->filename = filename;
|
||||
}
|
||||
|
||||
void DownloadController::setThreadNum(int threadNum)
|
||||
{
|
||||
this->threadNum = threadNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 开始下载
|
||||
*/
|
||||
void DownloadController::startDownload(const QString &url)
|
||||
{
|
||||
finish = 0;
|
||||
|
||||
// 下载任务等分,计算每个线程的下载数据
|
||||
fileSize = getFileSize(url);
|
||||
if(fileSize == 0)
|
||||
{
|
||||
emit errorOccur("文件大小获取失败");
|
||||
return;
|
||||
}
|
||||
|
||||
qint64 segmentSize = fileSize / threadNum;
|
||||
ranges.resize(threadNum);
|
||||
QVector<qint64> receivedBytes;
|
||||
receivedBytes.resize(threadNum);
|
||||
for(int i = 0; i < threadNum; i++)
|
||||
{
|
||||
ranges[i].first = i * segmentSize;
|
||||
ranges[i].second = i * segmentSize + segmentSize - 1;
|
||||
receivedBytes[i] = 0;
|
||||
}
|
||||
ranges[threadNum - 1].second = fileSize; // 余数部分加入最后一个
|
||||
|
||||
// 打开文件
|
||||
QDir tmpdir("/tmp/spark-store");
|
||||
file = new QFile;
|
||||
file->setFileName(tmpdir.absoluteFilePath(filename));
|
||||
|
||||
if(file->exists())
|
||||
{
|
||||
file->remove();
|
||||
}
|
||||
|
||||
if(!file->open(QIODevice::WriteOnly))
|
||||
{
|
||||
delete file;
|
||||
file = nullptr;
|
||||
emit errorOccur(file->errorString());
|
||||
return;
|
||||
}
|
||||
|
||||
file->resize(fileSize);
|
||||
|
||||
// 创建下载线程
|
||||
workers.clear();
|
||||
for(int i = 0; i < ranges.size(); i++)
|
||||
{
|
||||
qDebug() << QString("第%1个下载请求:%2-%3").arg(i).arg(ranges.at(i).first).arg(ranges.at(i).second);
|
||||
auto worker = new DownloadWorker(this);
|
||||
auto range = ranges.at(i);
|
||||
QString chunkUrl = replaceDomain(url, domains.at(i));
|
||||
worker->setIdentifier(i);
|
||||
worker->setParamter(chunkUrl, range, file);
|
||||
workers.append(worker);
|
||||
|
||||
connect(worker, &DownloadWorker::downloadProcess, this, &DownloadController::handleProcess);
|
||||
connect(worker, &DownloadWorker::workFinished, this, &DownloadController::chunkDownloadFinish);
|
||||
|
||||
worker->doWork();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 停止下载
|
||||
*/
|
||||
void DownloadController::stopDownload()
|
||||
{
|
||||
for(int i = 0; i < workers.size(); i++)
|
||||
{
|
||||
workers.at(i)->doStop();
|
||||
workers.at(i)->disconnect();
|
||||
workers.at(i)->deleteLater();
|
||||
}
|
||||
workers.clear();
|
||||
qDebug() << "文件下载路径:" << QFileInfo(file->fileName()).absoluteFilePath();
|
||||
|
||||
file->flush();
|
||||
file->close();
|
||||
delete file;
|
||||
file = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void DownloadController::handleProcess()
|
||||
{
|
||||
qint64 bytesReceived = 0;
|
||||
for(int i = 0; i < workers.size(); i++)
|
||||
{
|
||||
bytesReceived += workers.at(i)->getReceivedPos();
|
||||
}
|
||||
qDebug() << QString("下载进度 %1-%2").arg(bytesReceived).arg(fileSize);
|
||||
emit downloadProcess(bytesReceived, fileSize);
|
||||
}
|
||||
|
||||
void DownloadController::chunkDownloadFinish()
|
||||
{
|
||||
finish++;
|
||||
qDebug() << QString("已下载了%1块,共%2块!!!").arg(finish).arg(threadNum);
|
||||
if(finish == threadNum)
|
||||
{
|
||||
stopDownload();
|
||||
emit downloadFinished();
|
||||
}
|
||||
}
|
||||
|
||||
qint64 DownloadController::getFileSize(const QString& url)
|
||||
{
|
||||
QEventLoop event;
|
||||
QNetworkAccessManager requestManager;
|
||||
QNetworkRequest request;
|
||||
request.setUrl(QUrl(url));
|
||||
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
QNetworkReply *reply = requestManager.head(request);
|
||||
connect(reply, static_cast<void(QNetworkReply::*)(QNetworkReply::NetworkError) > (&QNetworkReply::error),
|
||||
[this, reply](QNetworkReply::NetworkError error)
|
||||
{
|
||||
if(error != QNetworkReply::NoError)
|
||||
{
|
||||
emit errorOccur(reply->errorString());
|
||||
}
|
||||
});
|
||||
connect(reply, &QNetworkReply::finished, &event, &QEventLoop::quit);
|
||||
event.exec();
|
||||
|
||||
qint64 fileSize = 0;
|
||||
if(reply->rawHeader("Accept-Ranges") == QByteArrayLiteral("bytes")
|
||||
&& reply->hasRawHeader(QString("Content-Length").toLocal8Bit()))
|
||||
{
|
||||
fileSize = reply->header(QNetworkRequest::ContentLengthHeader).toUInt();
|
||||
}
|
||||
qDebug() << "文件大小为:" << fileSize;
|
||||
reply->deleteLater();
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
QString DownloadController::replaceDomain(const QString& url, const QString domain)
|
||||
{
|
||||
QRegularExpression regex(R"((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9])");
|
||||
if(regex.match(url).hasMatch())
|
||||
{
|
||||
return QString(url).replace(regex.match(url).captured(), domain);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
81
src/downloadworker.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#ifndef DOWNLOADWORKER_H
|
||||
#define DOWNLOADWORKER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QFile>
|
||||
#include <QNetworkReply>
|
||||
|
||||
class DownloadWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DownloadWorker(QObject *parent = nullptr);
|
||||
|
||||
void setIdentifier(int identifier);
|
||||
void setParamter(const QString &url, QPair<qint64, qint64> range, QFile *flle);
|
||||
qint64 getReceivedPos();
|
||||
|
||||
public slots:
|
||||
void doWork();
|
||||
void doStop();
|
||||
void dataReady();
|
||||
void slotFinish();
|
||||
void handleProcess(qint64, qint64);
|
||||
|
||||
private:
|
||||
int identifier;
|
||||
QString url;
|
||||
qint64 startPos;
|
||||
qint64 endPos;
|
||||
qint64 receivedPos = 0;
|
||||
QNetworkReply *reply;
|
||||
QNetworkAccessManager *mgr;
|
||||
QFile *file;
|
||||
|
||||
signals:
|
||||
void resultReady(int identifier, QByteArray data);
|
||||
void testSignals();
|
||||
void workFinished();
|
||||
void downloadProcess();
|
||||
|
||||
};
|
||||
|
||||
class DownloadController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DownloadController(QObject *parent = nullptr);
|
||||
~DownloadController();
|
||||
|
||||
void setFilename(QString filename);
|
||||
void setThreadNum(int threadNum);
|
||||
void startDownload(const QString &url);
|
||||
void stopDownload();
|
||||
qint64 getFileSize(const QString& url);
|
||||
QString replaceDomain(const QString& url, const QString domain);
|
||||
|
||||
private:
|
||||
int threadNum;
|
||||
QString filename;
|
||||
qint64 fileSize;
|
||||
QVector<QPair<qint64, qint64>> ranges;
|
||||
QFile *file;
|
||||
QList<DownloadWorker*> workers;
|
||||
int finish = 0;
|
||||
QVector<QString> domains;
|
||||
|
||||
public slots:
|
||||
void handleProcess();
|
||||
void chunkDownloadFinish();
|
||||
|
||||
signals:
|
||||
void errorOccur(const QString& msg);
|
||||
void downloadProcess(qint64, qint64);
|
||||
void downloadFinished();
|
||||
|
||||
};
|
||||
|
||||
#endif // FILEDOWNLOADWORKER_H
|
||||
223
src/flowlayout.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "flowlayout.h"
|
||||
//! [1]
|
||||
FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
|
||||
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
}
|
||||
|
||||
FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
|
||||
: m_hSpace(hSpacing), m_vSpace(vSpacing)
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
FlowLayout::~FlowLayout()
|
||||
{
|
||||
QLayoutItem *item;
|
||||
while ((item = takeAt(0)))
|
||||
delete item;
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
void FlowLayout::addItem(QLayoutItem *item)
|
||||
{
|
||||
itemList.append(item);
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
int FlowLayout::horizontalSpacing() const
|
||||
{
|
||||
if (m_hSpace >= 0) {
|
||||
return m_hSpace;
|
||||
} else {
|
||||
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
|
||||
}
|
||||
}
|
||||
|
||||
int FlowLayout::verticalSpacing() const
|
||||
{
|
||||
if (m_vSpace >= 0) {
|
||||
return m_vSpace;
|
||||
} else {
|
||||
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
|
||||
}
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
int FlowLayout::count() const
|
||||
{
|
||||
return itemList.size();
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::itemAt(int index) const
|
||||
{
|
||||
return itemList.value(index);
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::takeAt(int index)
|
||||
{
|
||||
if (index >= 0 && index < itemList.size())
|
||||
return itemList.takeAt(index);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
//! [5]
|
||||
|
||||
//! [6]
|
||||
Qt::Orientations FlowLayout::expandingDirections() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
//! [6]
|
||||
|
||||
//! [7]
|
||||
bool FlowLayout::hasHeightForWidth() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int FlowLayout::heightForWidth(int width) const
|
||||
{
|
||||
int height = doLayout(QRect(0, 0, width, 0), true);
|
||||
return height;
|
||||
}
|
||||
//! [7]
|
||||
|
||||
//! [8]
|
||||
void FlowLayout::setGeometry(const QRect &rect)
|
||||
{
|
||||
QLayout::setGeometry(rect);
|
||||
doLayout(rect, false);
|
||||
}
|
||||
|
||||
QSize FlowLayout::sizeHint() const
|
||||
{
|
||||
return minimumSize();
|
||||
}
|
||||
|
||||
QSize FlowLayout::minimumSize() const
|
||||
{
|
||||
QSize size;
|
||||
QLayoutItem *item;
|
||||
foreach (item, itemList)
|
||||
size = size.expandedTo(item->minimumSize());
|
||||
|
||||
size += QSize(2*margin(), 2*margin());
|
||||
return size;
|
||||
}
|
||||
//! [8]
|
||||
|
||||
//! [9]
|
||||
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
|
||||
{
|
||||
int left, top, right, bottom;
|
||||
getContentsMargins(&left, &top, &right, &bottom);
|
||||
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
|
||||
int x = effectiveRect.x();
|
||||
int y = effectiveRect.y();
|
||||
int lineHeight = 0;
|
||||
//! [9]
|
||||
|
||||
//! [10]
|
||||
QLayoutItem *item;
|
||||
foreach (item, itemList) {
|
||||
QWidget *wid = item->widget();
|
||||
int spaceX = horizontalSpacing();
|
||||
if (spaceX == -1)
|
||||
spaceX = wid->style()->layoutSpacing(
|
||||
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
|
||||
int spaceY = verticalSpacing();
|
||||
if (spaceY == -1)
|
||||
spaceY = wid->style()->layoutSpacing(
|
||||
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
|
||||
//! [10]
|
||||
//! [11]
|
||||
int nextX = x + item->sizeHint().width() + spaceX;
|
||||
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
|
||||
x = effectiveRect.x();
|
||||
y = y + lineHeight + spaceY;
|
||||
nextX = x + item->sizeHint().width() + spaceX;
|
||||
lineHeight = 0;
|
||||
}
|
||||
|
||||
if (!testOnly)
|
||||
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
|
||||
|
||||
x = nextX;
|
||||
lineHeight = qMax(lineHeight, item->sizeHint().height());
|
||||
}
|
||||
return y + lineHeight - rect.y() + bottom;
|
||||
}
|
||||
//! [11]
|
||||
//! [12]
|
||||
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
|
||||
{
|
||||
QObject *parent = this->parent();
|
||||
if (!parent) {
|
||||
return -1;
|
||||
} else if (parent->isWidgetType()) {
|
||||
QWidget *pw = static_cast<QWidget *>(parent);
|
||||
return pw->style()->pixelMetric(pm, nullptr, pw);
|
||||
} else {
|
||||
return static_cast<QLayout *>(parent)->spacing();
|
||||
}
|
||||
}
|
||||
//! [12]
|
||||
88
src/flowlayout.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef FLOWLAYOUT_H
|
||||
#define FLOWLAYOUT_H
|
||||
|
||||
#include <QLayout>
|
||||
#include <QRect>
|
||||
#include <QStyle>
|
||||
//! [0]
|
||||
class FlowLayout : public QLayout
|
||||
{
|
||||
public:
|
||||
explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
~FlowLayout() override;
|
||||
|
||||
void addItem(QLayoutItem *item) override;
|
||||
int horizontalSpacing() const;
|
||||
int verticalSpacing() const;
|
||||
Qt::Orientations expandingDirections() const override;
|
||||
bool hasHeightForWidth() const override;
|
||||
int heightForWidth(int) const override;
|
||||
int count() const override;
|
||||
QLayoutItem *itemAt(int index) const override;
|
||||
QSize minimumSize() const override;
|
||||
void setGeometry(const QRect &rect) override;
|
||||
QSize sizeHint() const override;
|
||||
QLayoutItem *takeAt(int index) override;
|
||||
|
||||
private:
|
||||
int doLayout(const QRect &rect, bool testOnly) const;
|
||||
int smartSpacing(QStyle::PixelMetric pm) const;
|
||||
|
||||
QList<QLayoutItem *> itemList;
|
||||
int m_hSpace;
|
||||
int m_vSpace;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif // FLOWLAYOUT_H
|
||||
51
src/image_show.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "image_show.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QScreen> // Qt5 不再建议使用 QDesktopWidget
|
||||
#include <QGuiApplication>
|
||||
|
||||
image_show::image_show(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_dialog(new big_image),
|
||||
m_label(new QLabel)
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout;
|
||||
layout->addWidget(m_label);
|
||||
setLayout(layout);
|
||||
m_label->setText("layout");
|
||||
}
|
||||
|
||||
void image_show::setImage(QPixmap image)
|
||||
{
|
||||
QImage screen0;
|
||||
screen0 = image.toImage();
|
||||
QImage re_screen1;
|
||||
QImage re_screen0 = screen0.scaled(QSize(400, 300), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
// 获取主屏幕尺寸
|
||||
desktop_w = QGuiApplication::primaryScreen()->geometry().width();
|
||||
desktop_h = QGuiApplication::primaryScreen()->geometry().height();
|
||||
|
||||
if(screen0.width() > (desktop_w - 20) || screen0.height() > (desktop_h - 20))
|
||||
{
|
||||
re_screen1 = screen0.scaled(QSize(desktop_w - 20, desktop_h - 20), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
m_image = QPixmap::fromImage(re_screen1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_image = image;
|
||||
}
|
||||
|
||||
m_label->setPixmap(QPixmap::fromImage(re_screen0));
|
||||
}
|
||||
|
||||
void image_show::mousePressEvent(QMouseEvent *)
|
||||
{
|
||||
m_dialog->setimage(m_image);
|
||||
m_dialog->showFullScreen();
|
||||
|
||||
// 识别主屏幕尺寸并设置 widget 大小
|
||||
m_dialog->setFixedSize(desktop_w, desktop_h);
|
||||
|
||||
m_dialog->move(0,0);
|
||||
}
|
||||
@@ -3,30 +3,30 @@
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMouseEvent>
|
||||
#include <QLabel>
|
||||
#include <QPixmap>
|
||||
#include <DDialog>
|
||||
#include <DBlurEffectWidget>
|
||||
#include <big_image.h>
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
#include "big_image.h"
|
||||
|
||||
class image_show : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit image_show(QWidget *parent = nullptr);
|
||||
|
||||
void setImage(QPixmap);
|
||||
int desktop_w;
|
||||
int desktop_h;
|
||||
private:
|
||||
QLabel *m_label=new QLabel;
|
||||
QPixmap m_image;
|
||||
QLabel image;
|
||||
big_image *m_dialog=new big_image;
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void setImage(QPixmap);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
big_image *m_dialog;
|
||||
QLabel *m_label;
|
||||
QLabel image;
|
||||
QPixmap m_image;
|
||||
|
||||
};
|
||||
|
||||
#endif // IMAGE_SHOW_H
|
||||
103
src/main.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include <DApplication>
|
||||
#include <DApplicationSettings>
|
||||
#include <DWidgetUtil> // Dtk::Widget::moveToCenter(&w); 要调用它,就得引用 DWidgetUtil
|
||||
|
||||
#include <QScreen>
|
||||
|
||||
#include "widget.h"
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
DApplication::loadDXcbPlugin(); // 让 bar 处在标题栏中
|
||||
DApplication a(argc, argv);
|
||||
|
||||
a.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
a.loadTranslator(); // 载入翻译
|
||||
|
||||
/* Customized DAboutDialog (Can't work on other distro like Ubuntu...)
|
||||
*
|
||||
* DAboutDialog dialog;
|
||||
* a.setAboutDialog(&dialog);
|
||||
* dialog.setLicense(QObject::tr("We publish this program under GPL V3"));
|
||||
* dialog.setVersion(DApplication::buildVersion("Version 2.0.2.5"));
|
||||
* dialog.setProductIcon(QIcon::fromTheme("spark-store")); // 设置Logo
|
||||
* dialog.setProductName(QLabel::tr("Spark Store"));
|
||||
* dialog.setDescription(
|
||||
* QObject::tr(
|
||||
* "<span style=' font-size:10pt;font-weight:60;'>An appstore powered by deepin community</span><br/>"
|
||||
* "<a href='https://www.spark-app.store/'>https://www.spark-app.store</a><br/>"
|
||||
* "<span style=' font-size:12pt;'>Spark developers</span>"
|
||||
* )
|
||||
* );
|
||||
* dialog.setProductName(QLabel::tr("Spark Store"));
|
||||
* dialog.setCompanyLogo(QPixmap(":/Logo-Spark.png"));
|
||||
* dialog.setWebsiteName(QObject::tr("The Spark Project"));
|
||||
* dialog.setWebsiteLink("https://gitee.com/deepin-community-store");
|
||||
*/
|
||||
|
||||
a.setProductName(QLabel::tr("Spark Store"));
|
||||
a.setProductIcon(QIcon::fromTheme("spark-store")); //设置Logo
|
||||
a.setOrganizationName("spark-union");
|
||||
a.setOrganizationDomain("https://www.deepinos.org/");
|
||||
a.setApplicationName("Spark Store"); //不需要翻译,否则 ~/.local/share/ 下文件夹名称也被翻译为中文
|
||||
a.setApplicationVersion(DApplication::buildVersion("3.0"));
|
||||
a.setApplicationAcknowledgementPage("https://gitee.com/deepin-community-store/spark-store");
|
||||
a.setApplicationDescription(
|
||||
QObject::tr(
|
||||
"<span style='font-size:10pt;font-weight:60;'>An appstore powered by deepin community</span><br/>"
|
||||
"<a href='https://www.spark-app.store/'>https://www.spark-app.store</a><br/>"
|
||||
"<span style='font-size:12pt;'>Spark developers</span><br/><br/>"
|
||||
"Published under GPL V3"
|
||||
)
|
||||
);
|
||||
|
||||
// 限制单实例运行
|
||||
if(!a.setSingleInstance("spark-store"))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 保存窗口主题设置
|
||||
DApplicationSettings settings;
|
||||
|
||||
Widget w;
|
||||
QScreen *s = DApplication::primaryScreen();
|
||||
int d_w = s->geometry().width();
|
||||
int d_h = s->geometry().height();
|
||||
|
||||
if(d_w <= 1366)
|
||||
{
|
||||
w.setMinimumWidth(925);
|
||||
w.resize(925,650);
|
||||
}
|
||||
else
|
||||
{
|
||||
w.setMinimumWidth(1180);
|
||||
w.resize(1180,760);
|
||||
}
|
||||
|
||||
if(d_h <= 768)
|
||||
{
|
||||
w.setMinimumHeight(650);
|
||||
w.resize(925,650);
|
||||
}
|
||||
else
|
||||
{
|
||||
w.setMinimumHeight(760);
|
||||
w.resize(1180,760);
|
||||
}
|
||||
|
||||
QString arg1 = argv[1];
|
||||
if(arg1.left(6)=="spk://")
|
||||
{
|
||||
w.openUrl(QUrl(argv[1]));
|
||||
}
|
||||
|
||||
// 让打开时界面显示在正中
|
||||
Dtk::Widget::moveToCenter(&w);
|
||||
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
44
src/progressload.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "progressload.h"
|
||||
|
||||
#include <DApplicationHelper>
|
||||
|
||||
ProgressLoad::ProgressLoad(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_progess(new QWidget(this)),
|
||||
timer(new QTimer),
|
||||
value(0)
|
||||
{
|
||||
m_progess->move(0,0);
|
||||
m_progess->show();
|
||||
|
||||
timer->setInterval(10);
|
||||
timer->start();
|
||||
connect(timer, &QTimer::timeout, [=]()
|
||||
{
|
||||
m_progess->setFixedWidth(width() / 100 * value);
|
||||
m_progess->setFixedHeight(height());
|
||||
});
|
||||
}
|
||||
|
||||
void ProgressLoad::setValue(int v)
|
||||
{
|
||||
value = v;
|
||||
m_progess->setFixedWidth(width() / 100 * value);
|
||||
}
|
||||
|
||||
void ProgressLoad::setTheme(bool dark, QColor color)
|
||||
{
|
||||
if(dark)
|
||||
{
|
||||
plt.setColor(QPalette::Background, QColor(40, 40, 40));
|
||||
setAutoFillBackground(true);
|
||||
setPalette(plt);
|
||||
}
|
||||
else
|
||||
{
|
||||
plt.setColor(QPalette::Background, QColor(255, 255, 255));
|
||||
setAutoFillBackground(true);
|
||||
setPalette(plt);
|
||||
}
|
||||
m_progess->setStyleSheet("background-color: " + color.name() + ";");
|
||||
}
|
||||
@@ -4,21 +4,23 @@
|
||||
#include <QWidget>
|
||||
#include <QTimer>
|
||||
#include <QPalette>
|
||||
|
||||
class ProgressLoad : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ProgressLoad(QWidget *parent = nullptr);
|
||||
void setValue(int v);
|
||||
void setTheme(bool dark,QColor color);
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void setValue(int v);
|
||||
void setTheme(bool dark, QColor color);
|
||||
|
||||
private:
|
||||
QWidget *m_progess;
|
||||
int value;
|
||||
QTimer *timer;
|
||||
int value;
|
||||
QPalette plt;
|
||||
|
||||
};
|
||||
|
||||
#endif // PROGRESSLOAD_H
|
||||
83
src/spark-store.pro
Normal file
@@ -0,0 +1,83 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2019-06-30T12:53:03
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui network concurrent webenginewidgets
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = spark-store
|
||||
TEMPLATE = app
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which as been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
DEFINES += QT_APP_DEBUG
|
||||
include(../third-party/QtNetworkService/QtNetworkService.pri)
|
||||
|
||||
CONFIG += c++11 link_pkgconfig
|
||||
PKGCONFIG += dtkwidget glib-2.0 gdk-pixbuf-2.0 libnotify
|
||||
|
||||
# 禁止输出 qWarning / qDebug 信息
|
||||
CONFIG(release, debug|release): DEFINES += QT_NO_WARNING_OUTPUT QT_NO_DEBUG_OUTPUT
|
||||
|
||||
SOURCES += \
|
||||
appitem.cpp \
|
||||
big_image.cpp \
|
||||
downloadlist.cpp \
|
||||
downloadworker.cpp \
|
||||
flowlayout.cpp \
|
||||
image_show.cpp \
|
||||
main.cpp \
|
||||
progressload.cpp \
|
||||
widget.cpp \
|
||||
workerthreads.cpp
|
||||
|
||||
HEADERS += \
|
||||
appitem.h \
|
||||
big_image.h \
|
||||
downloadlist.h \
|
||||
downloadworker.h \
|
||||
flowlayout.h \
|
||||
image_show.h \
|
||||
progressload.h \
|
||||
widget.h \
|
||||
workerthreads.h
|
||||
|
||||
FORMS += \
|
||||
appitem.ui \
|
||||
downloadlist.ui \
|
||||
widget.ui
|
||||
|
||||
RESOURCES += \
|
||||
../assets/icons.qrc
|
||||
|
||||
DISTFILES += \
|
||||
../assets/tags/a2d-small.png \
|
||||
../assets/tags/a2d.png \
|
||||
../assets/tags/community-small.png \
|
||||
../assets/tags/community.png \
|
||||
../assets/tags/deepin-small.png \
|
||||
../assets/tags/dtk-small.png \
|
||||
../assets/tags/ubuntu-small.png \
|
||||
../assets/tags/ubuntu.png \
|
||||
../assets/tags/uos-small.png \
|
||||
../assets/tags/community.svg \
|
||||
../assets/tags/deepin.svg \
|
||||
../assets/tags/logo_icon.svg \
|
||||
../assets/tags/uos.svg
|
||||
|
||||
TRANSLATIONS += \
|
||||
../translations/spark-store_en.ts \
|
||||
../translations/spark-store_fr.ts \
|
||||
../translations/spark-store_zh_CN.ts
|
||||
1356
src/widget.cpp
Normal file
@@ -2,56 +2,88 @@
|
||||
#define WIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QUrl>
|
||||
#include <QFile>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <downloadlist.h>
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QProcess>
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
#include <QToolButton>
|
||||
#include <QTimer>
|
||||
#include <DSettings>
|
||||
#include <QJsonArray>
|
||||
#include <QFontDatabase>
|
||||
#include <QMutex>
|
||||
|
||||
#include <DBlurEffectWidget>
|
||||
#include <DSpinner>
|
||||
#include <DWaterProgress>
|
||||
#include <QLabel>
|
||||
#include <DTitlebar>
|
||||
#include <DSearchEdit>
|
||||
#include <progressload.h>
|
||||
#define LIST_MAX 99 //一次最多下载数量
|
||||
#include <DSettings>
|
||||
#include <DSpinner>
|
||||
#include <DWaterProgress>
|
||||
|
||||
#include "image_show.h"
|
||||
#include "downloadlist.h"
|
||||
#include "progressload.h"
|
||||
#include "workerthreads.h"
|
||||
|
||||
#define LIST_MAX 99 // 一次最多下载数量
|
||||
#define TMP_PATH "/tmp/spark-store"
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
namespace Ui {
|
||||
class Widget;
|
||||
}
|
||||
|
||||
class FlowLayout;
|
||||
class DownloadController;
|
||||
|
||||
namespace AeaQt {
|
||||
class HttpClient;
|
||||
}
|
||||
|
||||
class Widget : public DBlurEffectWidget
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Widget(DBlurEffectWidget *parent = nullptr);
|
||||
~Widget();
|
||||
void startRequest(QUrl url);
|
||||
|
||||
void startRequest(QUrl url, QString fileName);
|
||||
void searchApp(QString);
|
||||
int nowDownload=0;
|
||||
int allDownload=0;
|
||||
int isdownload=false;
|
||||
int nowDownload = 0;
|
||||
int allDownload = 0;
|
||||
int isdownload = false;
|
||||
void opensetting(); //打开设置页面
|
||||
void openUrl(QUrl);
|
||||
void setTheme(bool,QColor);
|
||||
DTitlebar* getTitlebar();
|
||||
|
||||
static void sendNotification(const QString &message, const int msTimeout = 5000, const QString &icon = "spark-store");
|
||||
static void sendNotification(const char *message, const int msTimeout = 5000, const QString &icon = "spark-store");
|
||||
|
||||
private slots:
|
||||
|
||||
void httpFinished();
|
||||
void httpReadyRead();
|
||||
void updateDataReadProgress(qint64,qint64);
|
||||
|
||||
// SpkAppInfoLoaderThread的槽函数
|
||||
void sltAppinfoResetUi();
|
||||
void sltAppinfoTags(QStringList *tagList);
|
||||
void sltAppinfoDetails(QString *name, QString *details, QString *info,
|
||||
QString *website, QString *packageName,
|
||||
QUrl *fileUrl, bool isInstalled);
|
||||
void sltAppinfoIcon(QPixmap *icon);
|
||||
void sltAppinfoScreenshot(QPixmap *picture, int index);
|
||||
void sltAppinfoFinish();
|
||||
|
||||
void displaySearchApp(QJsonArray array); // 展示搜索的APP信息
|
||||
void downloadIconsFinished(int arraysize); // 当前搜索列表图标是否下载完成
|
||||
|
||||
void on_pushButton_download_clicked();
|
||||
void on_pushButton_return_clicked();
|
||||
void on_comboBox_server_currentIndexChanged(const QString &arg1);
|
||||
@@ -60,25 +92,17 @@ private slots:
|
||||
void on_pushButton_uninstall_clicked();
|
||||
void on_pushButton_clear_clicked();
|
||||
void on_pushButton_website_clicked();
|
||||
|
||||
void on_pushButton_clicked();
|
||||
|
||||
void on_btn_openDir_clicked();
|
||||
|
||||
void on_stackedWidget_currentChanged(int arg1);
|
||||
|
||||
void on_webEngineView_urlChanged(const QUrl &arg1);
|
||||
|
||||
void on_webEngineView_loadStarted();
|
||||
|
||||
void on_webEngineView_loadProgress(int progress);
|
||||
|
||||
void on_webEngineView_loadFinished(bool arg1);
|
||||
|
||||
void on_pushButton_refresh_clicked();
|
||||
void on_pushButton_translate_clicked();
|
||||
|
||||
public:
|
||||
|
||||
public:
|
||||
QUrl url;
|
||||
|
||||
downloadlist download_list[LIST_MAX];
|
||||
@@ -93,12 +117,11 @@ private slots:
|
||||
QString appweb;
|
||||
bool themeIsDark;
|
||||
|
||||
|
||||
QFont font;
|
||||
|
||||
private:
|
||||
void initUI();
|
||||
void initConfig();
|
||||
int loadappinfo(QUrl);
|
||||
void chooseLeftMenu(int index);
|
||||
void setfoot(int);
|
||||
void updatefoot();
|
||||
@@ -110,23 +133,36 @@ private:
|
||||
QPushButton * left_list[15];
|
||||
QUrl menuUrl[13];
|
||||
ProgressLoad *m_loadweb;
|
||||
QLabel *m_loaderror=new QLabel;
|
||||
QLabel *m_loaderror = new QLabel;
|
||||
QString serverUrl;
|
||||
bool configCanSave=false;
|
||||
bool isBusy=false;
|
||||
int nowMenu=0; //定位当前菜单
|
||||
long download_size=0;
|
||||
long size1=0;
|
||||
long size2=0;
|
||||
bool configCanSave = false;
|
||||
bool isBusy = false;
|
||||
int nowMenu = 0; // 定位当前菜单
|
||||
int prePage = 0; // 定位前一个页面
|
||||
long download_size = 0;
|
||||
long size1 = 0;
|
||||
long size2 = 0;
|
||||
QPixmap screen[5];
|
||||
QFuture<void> load;
|
||||
QFutureWatcher<void> watchScreenshotLoad;
|
||||
QTimer download_speed;
|
||||
QString type_name;
|
||||
QColor main_color;
|
||||
int foot;
|
||||
DSearchEdit *searchEdit=new DSearchEdit;
|
||||
DSearchEdit *searchEdit = new DSearchEdit;
|
||||
DTitlebar *titlebar;
|
||||
DSpinner *spinner = new DSpinner;
|
||||
|
||||
int count = 0; // 记录当前搜索列表下载图标完成的个数
|
||||
QMutex mutex; // 禁止多次搜索事件同时发生
|
||||
|
||||
QList<image_show*> label_screen;
|
||||
SpkAppInfoLoaderThread appinfoLoadThread;
|
||||
|
||||
AeaQt::HttpClient *httpClient;
|
||||
FlowLayout *applist_grid;
|
||||
QHBoxLayout *main;
|
||||
DownloadController *downloadController;
|
||||
};
|
||||
|
||||
#endif // WIDGET_H
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1053</width>
|
||||
<height>674</height>
|
||||
<height>711</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -29,6 +29,38 @@
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="1">
|
||||
<widget class="ProgressLoad" name="progressload" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>3</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>3</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTipDuration">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="DTitlebar" name="titlebar" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="4">
|
||||
<widget class="QWidget" name="widget_menuList" native="true">
|
||||
<property name="minimumSize">
|
||||
@@ -61,33 +93,21 @@
|
||||
<property name="rightMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item row="6" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_video">
|
||||
<property name="text">
|
||||
<string>Videos</string>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_download">
|
||||
<property name="text">
|
||||
<string>Download List</string>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_system">
|
||||
<property name="text">
|
||||
<string>Tools</string>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_theme">
|
||||
<property name="text">
|
||||
<string>Beautify</string>
|
||||
</property>
|
||||
</widget>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_music">
|
||||
@@ -96,6 +116,20 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_photo">
|
||||
<property name="text">
|
||||
<string>Graphics</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_dev">
|
||||
<property name="text">
|
||||
<string>Development</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="icon">
|
||||
<property name="minimumSize">
|
||||
@@ -115,22 +149,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
@@ -147,10 +165,30 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="11" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_dev">
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_system">
|
||||
<property name="text">
|
||||
<string>Coding</string>
|
||||
<string>Tools</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_read">
|
||||
<property name="text">
|
||||
<string>Reading</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -161,6 +199,33 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="pushButton_refresh">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Reload</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../assets/icons.qrc">
|
||||
<normaloff>:/icons/icons/refresh-page.svg</normaloff>:/icons/icons/refresh-page.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_chat">
|
||||
<property name="text">
|
||||
<string>Chat</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QPushButton" name="pushButton_return">
|
||||
<property name="maximumSize">
|
||||
@@ -170,13 +235,13 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>回到分类</string>
|
||||
<string>Back to category</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="icons.qrc">
|
||||
<iconset resource="../assets/icons.qrc">
|
||||
<normaloff>:/icons/icons/category_active.svg</normaloff>:/icons/icons/category_active.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
@@ -194,10 +259,24 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_read">
|
||||
<item row="13" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_theme">
|
||||
<property name="text">
|
||||
<string>Translate</string>
|
||||
<string>Beautify</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_network">
|
||||
<property name="text">
|
||||
<string>Network</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_game">
|
||||
<property name="text">
|
||||
<string>Games</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -211,38 +290,27 @@
|
||||
<item row="2" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_main">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
<string notr="true">font: 11pt "Zeniq";</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>FrontPage</string>
|
||||
<string>Home</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_photo">
|
||||
<item row="16" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_download">
|
||||
<property name="text">
|
||||
<string>Images</string>
|
||||
<string>Download</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_game">
|
||||
<item row="6" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_video">
|
||||
<property name="text">
|
||||
<string>Games</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_chat">
|
||||
<property name="text">
|
||||
<string>Chatting</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="6">
|
||||
<widget class="QPushButton" name="menu_network">
|
||||
<property name="text">
|
||||
<string>Network</string>
|
||||
<string>Video</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -265,39 +333,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="pushButton_refresh">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>重新加载</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="icons.qrc">
|
||||
<normaloff>:/icons/icons/refresh-page.svg</normaloff>:/icons/icons/refresh-page.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -310,7 +345,7 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>4</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
@@ -377,7 +412,7 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>The List is empty now.Go and Download some software!</string>
|
||||
<string>The list is currently empty. Go and download some softwares!</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
@@ -409,7 +444,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>打开文件夹</string>
|
||||
<string>Open download directory</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -454,7 +489,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>903</width>
|
||||
<width>582</width>
|
||||
<height>849</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -474,6 +509,45 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Maximum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Maximum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QPushButton" name="pushButton_download">
|
||||
<property name="text">
|
||||
<string>Install</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3" colspan="2">
|
||||
<widget class="QLabel" name="label_appname">
|
||||
<property name="font">
|
||||
@@ -487,7 +561,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3" rowspan="5" colspan="7">
|
||||
<item row="3" column="3" rowspan="5" colspan="8">
|
||||
<widget class="QLabel" name="label_info">
|
||||
<property name="font">
|
||||
<font>
|
||||
@@ -533,7 +607,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="9">
|
||||
<item row="0" column="10">
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@@ -546,45 +620,6 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Maximum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Maximum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QPushButton" name="pushButton_download">
|
||||
<property name="text">
|
||||
<string>Install</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1" rowspan="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
@@ -669,7 +704,14 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="3" colspan="7">
|
||||
<item row="0" column="8">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="text">
|
||||
<string>Share</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3" colspan="8">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@@ -724,7 +766,7 @@
|
||||
<string><html><head/><body><p>Capable to Ubuntu 20.04</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>UB</string>
|
||||
<string><html><head/><body><p><img src=":/tags/ubuntu-small.png"/></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -762,7 +804,7 @@
|
||||
<string><html><head/><body><p>Capable to UOS home 20</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><img src=":/tags/uos.svg"/></p></body></html></string>
|
||||
<string><html><head/><body><p><img src=":/tags/uos-small.png"/></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -793,8 +835,14 @@
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>A deepin-wine2 app.If you are using ubuntu or other non-deepin distro,you should deploy deepin-wine2 by your self.</p></body></html></string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>A deepin-wine2 app.If you are using ubuntu or other non-deepin distro,you should deploy deepin-wine2 by your self.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
<string><html><head/><body><p><img src=":/tags/dwine2-small.png"/></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -813,7 +861,7 @@
|
||||
<string><html><head/><body><p>A deepin-wine5 app.If you are using ubuntu or other non-deepin distro,you should deploy deepin-wine5 by your self.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>wine</string>
|
||||
<string><html><head/><body><p><img src=":/tags/dwine5-small.png"/></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -852,10 +900,10 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="8">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<item row="0" column="9">
|
||||
<widget class="QPushButton" name="pushButton_translate">
|
||||
<property name="text">
|
||||
<string>Share</string>
|
||||
<string>Contribute translation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -880,7 +928,7 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="label_more">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>由社区爱好者开发的软件商店</p></body></html></string>
|
||||
<string><html><head/><body><p>An app store developed by community enthusiasts</p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
@@ -919,7 +967,7 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ScreenShots</string>
|
||||
<string>Screenshots</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -936,8 +984,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>869</width>
|
||||
<height>325</height>
|
||||
<width>98</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
@@ -1066,8 +1114,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>903</width>
|
||||
<height>852</height>
|
||||
<width>738</width>
|
||||
<height>886</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_23">
|
||||
@@ -1134,7 +1182,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Take effect when restart </string>
|
||||
<string>Take effect when restart</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -1338,38 +1386,48 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="DTitlebar" name="titlebar" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="ProgressLoad" name="progressload" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>3</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>3</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTipDuration">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<widget class="QWidget" name="applist_page">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="applist_scrollarea">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="applist_scrollAreaWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>903</width>
|
||||
<height>681</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -1400,7 +1458,7 @@
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="icons.qrc"/>
|
||||
<include location="../assets/icons.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
188
src/workerthreads.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
#include "workerthreads.h"
|
||||
|
||||
#include <QProcess>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "widget.h"
|
||||
#include "HttpClient.h"
|
||||
|
||||
void SpkAppInfoLoaderThread::run()
|
||||
{
|
||||
emit requestResetUi();
|
||||
|
||||
httpClient = new AeaQt::HttpClient;
|
||||
|
||||
httpClient->get(targetUrl.toString())
|
||||
.header("content-type", "application/json")
|
||||
.onResponse([this](QByteArray json_array)
|
||||
{
|
||||
qDebug() << "请求应用信息 " << json_array;
|
||||
QString urladdress, deatils, more, packagename, appweb;
|
||||
bool isInstalled;
|
||||
|
||||
// 将路径转化为相应源的下载路径
|
||||
urladdress = targetUrl.toString().left(targetUrl.toString().length() - 8);
|
||||
QStringList downloadurl = urladdress.split("/");
|
||||
|
||||
QString deburl = serverUrl;
|
||||
deburl = deburl.left(urladdress.length() - 1);
|
||||
urladdress = "https://img.jerrywang.top/"; // 使用图片专用服务器请保留这行,删除后将使用源服务器
|
||||
urladdress = urladdress.left(urladdress.length() - 1);
|
||||
|
||||
for(int i = 3; i < downloadurl.size(); i++)
|
||||
{
|
||||
urladdress += "/" + downloadurl[i];
|
||||
deburl += "/" + downloadurl[i];
|
||||
}
|
||||
|
||||
// 路径转化完成
|
||||
QJsonObject json = QJsonDocument::fromJson(json_array).object();
|
||||
QString appName = json["Name"].toString();
|
||||
QUrl fileUrl = deburl + json["Filename"].toString();
|
||||
|
||||
// 软件信息加载
|
||||
QString details;
|
||||
details = tr("PkgName: ") + json["Pkgname"].toString() + "\n";
|
||||
details += tr("Version: ") + json["Version"].toString() + "\n";
|
||||
if(!json["Author"].toString().trimmed().isEmpty())
|
||||
{
|
||||
details += tr("Author: ") + json["Author"].toString() + "\n";
|
||||
}
|
||||
|
||||
if(!json["Website"].toString().trimmed().isEmpty())
|
||||
{
|
||||
details += tr("Official Site: ") + json["Website"].toString() + "\n";
|
||||
// ui->pushButton_website->show(); // move to setinfo slot
|
||||
appweb = json["Website"].toString();
|
||||
}
|
||||
details += tr("Contributor: ") + json["Contributor"].toString() + "\n";
|
||||
details += tr("Update Time: ") + json["Update"].toString() + "\n";
|
||||
details += tr("Installed Size: ") + json["Size"].toString() + "\n";
|
||||
more = json["More"].toString();
|
||||
|
||||
QProcess isInstall;
|
||||
packagename = json["Pkgname"].toString();
|
||||
isInstall.start("dpkg -s " + json["Pkgname"].toString());
|
||||
isInstall.waitForFinished();
|
||||
int error = QString::fromStdString(isInstall.readAllStandardError().toStdString()).length();
|
||||
if(error == 0)
|
||||
{
|
||||
isInstalled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isInstalled = false;
|
||||
}
|
||||
|
||||
emit requestSetAppInformation(&appName, &details, &more, &appweb, &packagename, &fileUrl, isInstalled);
|
||||
|
||||
// tag 加载
|
||||
QString tags = json["Tags"].toString();
|
||||
QStringList tagList = tags.split(";");
|
||||
emit requestSetTags(&tagList);
|
||||
|
||||
// 图标加载
|
||||
httpClient->get(urladdress+"icon.png")
|
||||
.onResponse([this](QByteArray imgData)
|
||||
{
|
||||
QPixmap appicon;
|
||||
appicon.loadFromData(imgData);
|
||||
emit finishedIconLoad(&appicon);
|
||||
})
|
||||
.onError([this](QString errorStr)
|
||||
{
|
||||
Q_UNUSED(this)
|
||||
Q_UNUSED(errorStr)
|
||||
|
||||
Widget::sendNotification(tr("Failed to load application icon."));
|
||||
})
|
||||
.block()
|
||||
.timeout(5 * 100)
|
||||
.exec();
|
||||
|
||||
|
||||
// 截图展示加载
|
||||
QPixmap screenshotCache[5];
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
httpClient->get(urladdress + "screen_" + QString::number(i + 1) + ".png")
|
||||
.onResponse([this, i, &screenshotCache](QByteArray imgData)
|
||||
{
|
||||
bool s = screenshotCache[i].loadFromData(imgData);
|
||||
if(s)
|
||||
{
|
||||
emit finishedScreenshotLoad(&screenshotCache[i], i);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit finishedScreenshotLoad(nullptr, i);
|
||||
}
|
||||
})
|
||||
.onError([this](QString errorStr)
|
||||
{
|
||||
Q_UNUSED(this)
|
||||
Q_UNUSED(errorStr)
|
||||
|
||||
qDebug() << "截图下载失败";
|
||||
// Widget::sendNotification(tr("Failed to load application screenshot."));
|
||||
})
|
||||
.block()
|
||||
.timeout(4 * 100)
|
||||
.exec();
|
||||
}
|
||||
emit finishAllLoading();
|
||||
|
||||
httpClient->deleteLater();
|
||||
})
|
||||
.onError([](QString errorStr)
|
||||
{
|
||||
Q_UNUSED(errorStr)
|
||||
|
||||
Widget::sendNotification(tr("Failed to download app info. Please check internet connection."));
|
||||
})
|
||||
.timeout(5 * 100)
|
||||
.block()
|
||||
.exec();
|
||||
}
|
||||
|
||||
|
||||
void SpkAppInfoLoaderThread::setUrl(const QUrl &url)
|
||||
{
|
||||
targetUrl = url;
|
||||
}
|
||||
|
||||
void SpkAppInfoLoaderThread::setServer(const QString &server)
|
||||
{
|
||||
serverUrl = server;
|
||||
}
|
||||
|
||||
void SpkAppInfoLoaderThread::downloadFinished(int exitcode, QProcess::ExitStatus status)
|
||||
{
|
||||
Q_UNUSED(exitcode)
|
||||
Q_UNUSED(status)
|
||||
|
||||
qDebug() << "Finish one download";
|
||||
finishedDownload = true;
|
||||
}
|
||||
|
||||
int SpkAppInfoLoaderThread::waitDownload(QProcess& downloader)
|
||||
{
|
||||
while(!downloader.waitForFinished(100))
|
||||
{
|
||||
if(downloader.state() == QProcess::NotRunning)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(this->isInterruptionRequested())
|
||||
{
|
||||
downloader.terminate();
|
||||
downloader.waitForFinished(-1);
|
||||
qDebug() << "Appinfo loader thread was forcefully terminated";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
50
src/workerthreads.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef WORKERTHREADS_H
|
||||
#define WORKERTHREADS_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QPixmap>
|
||||
#include <QUrl>
|
||||
#include <QProcess>
|
||||
|
||||
namespace AeaQt {
|
||||
class HttpClient;
|
||||
}
|
||||
|
||||
class SpkAppInfoLoaderThread Q_DECL_FINAL : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// explicit SpkAppInfoLoaderThread() = default;
|
||||
|
||||
protected:
|
||||
void run() Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QUrl targetUrl;
|
||||
QString serverUrl;
|
||||
bool finishedDownload = false;
|
||||
int downloaderRetval = 0;
|
||||
|
||||
AeaQt::HttpClient *httpClient;
|
||||
|
||||
int waitDownload(QProcess& downloader);
|
||||
|
||||
public slots:
|
||||
void setUrl(const QUrl &url);
|
||||
void setServer(const QString &server);
|
||||
void downloadFinished(int exitcode, QProcess::ExitStatus status);
|
||||
|
||||
signals:
|
||||
void requestResetUi();
|
||||
void requestSetTags(QStringList *tagList);
|
||||
void requestSetAppInformation(QString *name, QString *details, QString *info,
|
||||
QString *website, QString *packageName,
|
||||
QUrl *fileUrl, bool isInstalled);
|
||||
void finishedIconLoad(QPixmap *icon);
|
||||
void finishedScreenshotLoad(QPixmap *icon, int index); // 该信号必须以 BlockingQueued 方式连接
|
||||
void finishAllLoading(); // 该信号必须以 BlockingQueued 方式连接
|
||||
|
||||
};
|
||||
|
||||
#endif // WORKERTHREADS_H
|
||||
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 701 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 622 B |
42
third-party/QtNetworkService/HttpClient.cpp
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/**********************************************************
|
||||
Author: Qt君
|
||||
微信公众号: Qt君(文章首发)
|
||||
Website: qtbig.com(后续更新)
|
||||
Email: 2088201923@qq.com
|
||||
QQ交流群: 732271126
|
||||
LISCENSE: MIT
|
||||
**********************************************************/
|
||||
#include "HttpClient.h"
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QBuffer>
|
||||
|
||||
using namespace AeaQt;
|
||||
|
||||
HttpClient::HttpClient()
|
||||
{
|
||||
}
|
||||
|
||||
HttpClient::~HttpClient()
|
||||
{
|
||||
}
|
||||
|
||||
HttpRequest HttpClient::get(const QString &url)
|
||||
{
|
||||
return HttpRequest(QNetworkAccessManager::GetOperation, this).url(url);
|
||||
}
|
||||
|
||||
HttpRequest HttpClient::post(const QString &url)
|
||||
{
|
||||
return HttpRequest(QNetworkAccessManager::PostOperation, this).url(url);
|
||||
}
|
||||
|
||||
HttpRequest HttpClient::put(const QString &url)
|
||||
{
|
||||
return HttpRequest(QNetworkAccessManager::PutOperation, this).url(url);
|
||||
}
|
||||
|
||||
HttpRequest HttpClient::send(const QString &url, QNetworkAccessManager::Operation op)
|
||||
{
|
||||
return HttpRequest(op, this).url(url);
|
||||
}
|
||||
36
third-party/QtNetworkService/HttpClient.h
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/**********************************************************
|
||||
Author: Qt君
|
||||
微信公众号: Qt君(文章首发)
|
||||
Website: qtbig.com(后续更新)
|
||||
Email: 2088201923@qq.com
|
||||
QQ交流群: 732271126
|
||||
LISCENSE: MIT
|
||||
**********************************************************/
|
||||
#ifndef HTTP_CLIENT_H
|
||||
#define HTTP_CLIENT_H
|
||||
|
||||
#include "HttpRequest.h"
|
||||
#include "HttpResponse.h"
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
|
||||
namespace AeaQt {
|
||||
|
||||
class HttpClient : public QNetworkAccessManager
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
friend class HttpRequest;
|
||||
|
||||
HttpClient();
|
||||
~HttpClient();
|
||||
|
||||
HttpRequest get(const QString &url);
|
||||
HttpRequest post(const QString &url);
|
||||
HttpRequest put(const QString &url);
|
||||
|
||||
HttpRequest send(const QString &url, Operation op = GetOperation);
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
268
third-party/QtNetworkService/HttpRequest.cpp
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
/**********************************************************
|
||||
Author: Qt君
|
||||
微信公众号: Qt君(文章首发)
|
||||
Website: qtbig.com(后续更新)
|
||||
Email: 2088201923@qq.com
|
||||
QQ交流群: 732271126
|
||||
LISCENSE: MIT
|
||||
**********************************************************/
|
||||
#include "HttpRequest.h"
|
||||
#include "HttpClient.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QUrlQuery>
|
||||
#include <QBuffer>
|
||||
#include <QMetaEnum>
|
||||
|
||||
using namespace AeaQt;
|
||||
|
||||
static const char *s_httpOperation[] = {
|
||||
"UnknownOperation",
|
||||
"HeadOperation",
|
||||
"GetOperation",
|
||||
"PutOperation",
|
||||
"PostOperation",
|
||||
"DeleteOperation",
|
||||
"CustomOperation"
|
||||
};
|
||||
|
||||
HttpRequest::HttpRequest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HttpRequest::~HttpRequest()
|
||||
{
|
||||
}
|
||||
|
||||
HttpRequest::HttpRequest(QNetworkAccessManager::Operation op, HttpClient *jsonHttpClient) :
|
||||
m_body(QByteArray()),
|
||||
m_op(op),
|
||||
m_httpService(jsonHttpClient),
|
||||
m_timeout(-1)
|
||||
{
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::url(const QString &url)
|
||||
{
|
||||
m_networkRequest.setUrl(QUrl(url));
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::header(const QString &key, const QVariant &value)
|
||||
{
|
||||
m_networkRequest.setRawHeader(QByteArray(key.toStdString().data()), QByteArray(value.toString().toStdString().data()));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::headers(const QMap<QString, QVariant> &headers)
|
||||
{
|
||||
QMapIterator<QString, QVariant> iter(headers);
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
header(iter.key(), iter.value());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::body(const QVariantMap &content)
|
||||
{
|
||||
m_body = QJsonDocument(QJsonObject::fromVariantMap(content)).toJson();
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::body(const QJsonObject &content)
|
||||
{
|
||||
m_body = QJsonDocument(QJsonObject::fromVariantMap(content.toVariantMap())).toJson();
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::body(const QByteArray &content)
|
||||
{
|
||||
m_body = content;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if 0
|
||||
HttpRequest &HttpRequest::body(const QVariant &body)
|
||||
{
|
||||
/// clear m_jsonBody
|
||||
m_jsonBody = QJsonObject();
|
||||
|
||||
if (type == X_Www_Form_Urlencoded) {
|
||||
QUrl url;
|
||||
QUrlQuery urlQuery(url);
|
||||
|
||||
if (body.type() == QVariant::Map
|
||||
|| body.typeName() == QMetaType::typeName(QMetaType::QJsonObject)) {
|
||||
|
||||
QMapIterator<QString, QVariant> i(body.toMap());
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
urlQuery.addQueryItem(i.key(), i.value().toString());
|
||||
}
|
||||
|
||||
url.setQuery(urlQuery);
|
||||
m_body = url.toString(QUrl::FullyEncoded).toUtf8().remove(0, 1);
|
||||
}
|
||||
else {
|
||||
m_body = body.toByteArray();
|
||||
}
|
||||
}
|
||||
else if (type == Raw_Text_Json) {
|
||||
if (body.type() == QVariant::Map
|
||||
|| body.typeName() == QMetaType::typeName(QMetaType::QJsonObject)) {
|
||||
|
||||
m_body = QJsonDocument(QJsonObject::fromVariantMap(body.toMap())).toJson();
|
||||
}
|
||||
else {
|
||||
log_warning << "This is not data in JSON format(QVariantMap or QJsonObject).";
|
||||
m_body = QByteArray();
|
||||
// warning output
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_body = QByteArray();
|
||||
log_warning << "Disable body.";
|
||||
}
|
||||
|
||||
log_debugger << "Body Content:" << m_body;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
HttpRequest &HttpRequest::onResponse(const QObject *receiver, const char *slot, HttpResponse::SupportMethod type)
|
||||
{
|
||||
m_slotsMap.insert(type, {slot, QVariant::fromValue((QObject *)receiver)});
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::onResponse(std::function<void (QNetworkReply *)> lambda)
|
||||
{
|
||||
return onResponse(QVariant::fromValue(lambda));
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::onResponse(std::function<void (QVariantMap)> lambda)
|
||||
{
|
||||
return onResponse(QVariant::fromValue(lambda));
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::onResponse(std::function<void (QByteArray)> lambda)
|
||||
{
|
||||
return onResponse(QVariant::fromValue(lambda));
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::onResponse(std::function<void (qint64, qint64)> lambda)
|
||||
{
|
||||
return onResponse(QVariant::fromValue(lambda));
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::onError(const QObject *receiver, const char *slot)
|
||||
{
|
||||
return onResponse(receiver, slot, HttpResponse::AutoInfer);
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::onError(std::function<void (QNetworkReply::NetworkError)> lambda)
|
||||
{
|
||||
return onResponse(QVariant::fromValue(lambda));
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::onError(std::function<void (QString)> lambda)
|
||||
{
|
||||
return onResponse(QVariant::fromValue(lambda));
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::onError(std::function<void (QNetworkReply::NetworkError, QNetworkReply *)> lambda)
|
||||
{
|
||||
return onResponse(QVariant::fromValue(lambda));
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::onError(std::function<void (QString, QNetworkReply *)> lambda)
|
||||
{
|
||||
return onResponse(QVariant::fromValue(lambda));
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::timeout(const int &msec)
|
||||
{
|
||||
m_timeout = msec;
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::block()
|
||||
{
|
||||
m_isBlock = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::onResponse(QVariant lambda)
|
||||
{
|
||||
m_slotsMap.insert(HttpResponse::AutoInfer, {lambda.typeName(), lambda});
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpResponse *HttpRequest::exec()
|
||||
{
|
||||
QNetworkReply* reply = NULL;
|
||||
QBuffer* sendBuffer = new QBuffer();
|
||||
if (! m_body.isEmpty()) {
|
||||
sendBuffer->setData(m_body);
|
||||
}
|
||||
|
||||
log_debugger << "Http Client info: ";
|
||||
log_debugger << "Type: " << s_httpOperation[m_op];
|
||||
log_debugger << "Url: " << m_networkRequest.url().toString();
|
||||
QString headers;
|
||||
for (int i = 0; i < m_networkRequest.rawHeaderList().count(); i++) {
|
||||
QString each = m_networkRequest.rawHeaderList().at(i);
|
||||
QString header = m_networkRequest.rawHeader(each.toUtf8());
|
||||
headers += QString("%1: %2;").arg(each)
|
||||
.arg(header);
|
||||
}
|
||||
log_debugger << "Header: " << headers;
|
||||
log_debugger << "Send buffer(Body):\r\n" << m_body;
|
||||
|
||||
reply = m_httpService->createRequest(m_op, m_networkRequest, sendBuffer);
|
||||
|
||||
if (reply == NULL) {
|
||||
sendBuffer->deleteLater();
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
sendBuffer->setParent(reply);
|
||||
}
|
||||
|
||||
return new HttpResponse(reply, m_slotsMap, m_timeout, m_isBlock);
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::queryParam(const QString &key, const QVariant &value)
|
||||
{
|
||||
QUrl url(m_networkRequest.url());
|
||||
QUrlQuery urlQuery(url);
|
||||
|
||||
urlQuery.addQueryItem(key, value.toString());
|
||||
url.setQuery(urlQuery);
|
||||
|
||||
m_networkRequest.setUrl(url);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::queryParams(const QMap<QString, QVariant> ¶ms)
|
||||
{
|
||||
QMapIterator<QString, QVariant> iter(params);
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
queryParam(iter.key(), iter.value());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpRequest &HttpRequest::userAttribute(const QVariant &value)
|
||||
{
|
||||
m_networkRequest.setAttribute(QNetworkRequest::User, value);
|
||||
return *this;
|
||||
}
|
||||
115
third-party/QtNetworkService/HttpRequest.h
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/**********************************************************
|
||||
Author: Qt君
|
||||
微信公众号: Qt君(文章首发)
|
||||
Website: qtbig.com(后续更新)
|
||||
Email: 2088201923@qq.com
|
||||
QQ交流群: 732271126
|
||||
LISCENSE: MIT
|
||||
**********************************************************/
|
||||
#ifndef HTTP_REQUEST_H
|
||||
#define HTTP_REQUEST_H
|
||||
|
||||
#include "HttpResponse.h"
|
||||
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QJsonObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace AeaQt {
|
||||
|
||||
#ifdef QT_APP_DEBUG
|
||||
#define log_debugger qDebug().noquote().nospace() \
|
||||
<< "[AeaQt::Network] Debug: -> " \
|
||||
<< "function: " << __func__ << "; " \
|
||||
<< "line: " << __LINE__ << "; "
|
||||
#else
|
||||
#define log_debugger QString()
|
||||
#endif
|
||||
|
||||
#define log_warning qWarning().noquote().nospace() \
|
||||
<< "[AeaQt::Network] Warning: -> " \
|
||||
<< "function: " << __func__ << "; " \
|
||||
<< "line: " << __LINE__ << "; "
|
||||
|
||||
class HttpClient;
|
||||
|
||||
class HttpRequest
|
||||
{
|
||||
public:
|
||||
enum BodyType {
|
||||
None = 0, // This request does not have a body.
|
||||
X_Www_Form_Urlencoded, // x-www-form-urlencoded
|
||||
Raw_Text_Json, // application/json
|
||||
};
|
||||
|
||||
explicit HttpRequest(QNetworkAccessManager::Operation op, HttpClient *jsonHttpClient);
|
||||
virtual ~HttpRequest();
|
||||
|
||||
HttpRequest &url(const QString &url);
|
||||
HttpRequest &header(const QString &key, const QVariant &value);
|
||||
HttpRequest &headers(const QMap<QString, QVariant> &headers);
|
||||
|
||||
HttpRequest &queryParam(const QString &key, const QVariant &value);
|
||||
HttpRequest &queryParams(const QMap<QString, QVariant> ¶ms);
|
||||
|
||||
/* Mainly used for identification */
|
||||
HttpRequest &userAttribute(const QVariant &value);
|
||||
|
||||
HttpRequest &body(const QVariantMap &content);
|
||||
HttpRequest &body(const QJsonObject &content);
|
||||
HttpRequest &body(const QByteArray &content);
|
||||
|
||||
/*
|
||||
* @onRespone slot support type: void function(QVariantMap resultMap) OR
|
||||
* void function(QByteArray resultData) OR
|
||||
* void function(QNetworkReply* reply)
|
||||
* note: The same type is only triggered once
|
||||
*/
|
||||
HttpRequest &onResponse(const QObject *receiver, const char *slot, HttpResponse::SupportMethod type = HttpResponse::AutoInfer);
|
||||
HttpRequest &onResponse(std::function<void (QNetworkReply*)> lambda);
|
||||
HttpRequest &onResponse(std::function<void (QVariantMap)> lambda);
|
||||
HttpRequest &onResponse(std::function<void (QByteArray)> lambda);
|
||||
HttpRequest &onResponse(std::function<void (qint64, qint64)> lambda);
|
||||
/*
|
||||
* @onError slot support type: void function(QNetworkReply::NetworkError error)
|
||||
* void function(QString errorString);
|
||||
* void function(QNetworkReply::NetworkError error, QNetworkReply* reply);
|
||||
* void function(QString errorString, QNetworkReply* reply);
|
||||
* note: The same type is only triggered once
|
||||
*/
|
||||
HttpRequest &onError(const QObject *receiver, const char *slot);
|
||||
HttpRequest &onError(std::function<void (QNetworkReply::NetworkError)> lambda);
|
||||
HttpRequest &onError(std::function<void (QString)> lambda);
|
||||
HttpRequest &onError(std::function<void (QNetworkReply::NetworkError, QNetworkReply*)> lambda);
|
||||
HttpRequest &onError(std::function<void (QString, QNetworkReply*)> lambda);
|
||||
|
||||
/**
|
||||
* @brief msec <= 0, disable timeout
|
||||
* msec > 0, enable timeout
|
||||
*/
|
||||
HttpRequest &timeout(const int &msec = -1);
|
||||
|
||||
/**
|
||||
* @brief Block current thread, entering an event loop.
|
||||
*/
|
||||
HttpRequest &block();
|
||||
|
||||
HttpResponse *exec();
|
||||
|
||||
private:
|
||||
HttpRequest();
|
||||
HttpRequest &onResponse(QVariant lambda);
|
||||
|
||||
private:
|
||||
QNetworkRequest m_networkRequest;
|
||||
QByteArray m_body;
|
||||
QNetworkAccessManager::Operation m_op;
|
||||
HttpClient *m_httpService;
|
||||
int m_timeout;
|
||||
bool m_isBlock;
|
||||
QMultiMap<HttpResponse::SupportMethod, QPair<QString, QVariant>> m_slotsMap;
|
||||
};
|
||||
|
||||
}
|
||||
#endif // HTTP_REQUEST_H
|
||||
331
third-party/QtNetworkService/HttpResponse.cpp
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
/**********************************************************
|
||||
Author: Qt君
|
||||
微信公众号: Qt君(文章首发)
|
||||
Website: qtbig.com(后续更新)
|
||||
Email: 2088201923@qq.com
|
||||
QQ交流群: 732271126
|
||||
LISCENSE: MIT
|
||||
**********************************************************/
|
||||
#include "HttpResponse.h"
|
||||
|
||||
#include <QRegExp>
|
||||
#include <QStringList>
|
||||
#include <QByteArray>
|
||||
#include <QNetworkConfigurationManager>
|
||||
#include <QMetaEnum>
|
||||
#include <QEventLoop>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#define T2S(t) (QString(#t).remove(QRegExp("\\s"))) //type to string
|
||||
|
||||
#define _exec(target, type, arg) \
|
||||
if (target.canConvert<std::function<void (type)> >()) { \
|
||||
std::function<void (type)> func = target.value<std::function<void (type)> >(); func(arg); \
|
||||
} \
|
||||
else
|
||||
|
||||
#define _exec2(target, type1, type2, arg1, arg2) \
|
||||
if (target.canConvert<std::function<void (type1, type2)> >()) { \
|
||||
std::function<void (type1, type2)> func = target.value<std::function<void (type1, type2)> >(); func(arg1, arg2); \
|
||||
} else
|
||||
|
||||
using namespace AeaQt;
|
||||
|
||||
static const QMap<HttpResponse::SupportMethod, QMap<QString, QVariant>> methodParams =
|
||||
{
|
||||
{
|
||||
HttpResponse::onResponse_QNetworkReply_A_Pointer,
|
||||
{
|
||||
{"types", QStringList({T2S(QNetworkReply*)})},
|
||||
{"lambda", T2S(std::function<void (QNetworkReply*)>)},
|
||||
{"signal", SIGNAL(finished(QNetworkReply*))},
|
||||
{"isAutoInfer", true}
|
||||
}
|
||||
},
|
||||
{
|
||||
HttpResponse::onResponse_QByteArray,
|
||||
{
|
||||
{"types", QStringList({T2S(QByteArray)})},
|
||||
{"lambda", T2S(std::function<void (QByteArray)>)},
|
||||
{"signal", SIGNAL(finished(QByteArray))},
|
||||
{"isAutoInfer", true}
|
||||
}
|
||||
},
|
||||
{
|
||||
HttpResponse::onResponse_QVariantMap,
|
||||
{
|
||||
{"types", QStringList({T2S(QVariantMap)})},
|
||||
{"lambda", T2S(std::function<void (QVariantMap)>)},
|
||||
{"signal", SIGNAL(finished(QVariantMap))},
|
||||
{"isAutoInfer", true}
|
||||
}
|
||||
},
|
||||
{
|
||||
HttpResponse::onDownloadProgress_qint64_qint64,
|
||||
{
|
||||
{"types", QStringList({T2S(qint64), T2S(qint64)})},
|
||||
{"lambda", T2S(std::function<void (qint64, qint64)>)},
|
||||
{"signal", SIGNAL(downloadProgress(qint64, qint64))},
|
||||
{"isAutoInfer", true}
|
||||
}
|
||||
},
|
||||
{
|
||||
HttpResponse::onError_QNetworkReply_To_NetworkError,
|
||||
{
|
||||
{"types", QStringList({T2S(QNetworkReply::NetworkError)})},
|
||||
{"lambda", T2S(std::function<void (QNetworkReply::NetworkError)>)},
|
||||
{"signal", SIGNAL(error(QNetworkReply::NetworkError))},
|
||||
{"isAutoInfer", true}
|
||||
}
|
||||
},
|
||||
{
|
||||
HttpResponse::onError_QString,
|
||||
{
|
||||
{"types", QStringList({T2S(QString)})},
|
||||
{"lambda", T2S(std::function<void (QString)>)},
|
||||
{"signal", SIGNAL(error(QString))},
|
||||
{"isAutoInfer", true}
|
||||
}
|
||||
},
|
||||
{
|
||||
HttpResponse::onError_QNetworkReply_To_NetworkError_QNetworkReply_A_Pointer,
|
||||
{
|
||||
{"types", QStringList({T2S(QNetworkReply::NetworkError), T2S(QNetworkReply*)})},
|
||||
{"lambda", T2S(std::function<void (QNetworkReply::NetworkError, QNetworkReply*)>)},
|
||||
{"signal", SIGNAL(error(QNetworkReply::NetworkError, QNetworkReply*))},
|
||||
{"isAutoInfer", true}
|
||||
}
|
||||
},
|
||||
{
|
||||
HttpResponse::onError_QString_QNetworkReply_A_Poniter,
|
||||
{
|
||||
{"types", QStringList({T2S(QString), T2S(QNetworkReply*)})},
|
||||
{"lambda", T2S(std::function<void (QString, QNetworkReply*)>)},
|
||||
{"signal", SIGNAL(error(QString, QNetworkReply*))},
|
||||
{"isAutoInfer", true}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static int extractCode(const char *member)
|
||||
{
|
||||
/* extract code, ensure QMETHOD_CODE <= code <= QSIGNAL_CODE */
|
||||
return (((int)(*member) - '0') & 0x3);
|
||||
}
|
||||
|
||||
HttpResponse::HttpResponse(QNetworkReply *networkReply,
|
||||
const QMultiMap<SupportMethod, QPair<QString, QVariant> > &slotsMap,
|
||||
const int &timeout,
|
||||
bool isBlock)
|
||||
: m_networkReply(networkReply),
|
||||
m_slotsMap(slotsMap),
|
||||
QObject(networkReply)
|
||||
{
|
||||
slotsMapOperation(m_slotsMap);
|
||||
new HttpResponseTimeout(networkReply, timeout);
|
||||
|
||||
connect(m_networkReply, SIGNAL(finished()), this, SLOT(onFinished()));
|
||||
connect(m_networkReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
|
||||
connect(m_networkReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(onDownloadProgress(qint64, qint64)));
|
||||
|
||||
if (isBlock) {
|
||||
QEventLoop loop;
|
||||
QObject::connect(m_networkReply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||
loop.exec();
|
||||
}
|
||||
}
|
||||
|
||||
HttpResponse::~HttpResponse()
|
||||
{
|
||||
}
|
||||
|
||||
QNetworkReply *HttpResponse::networkReply()
|
||||
{
|
||||
return m_networkReply;
|
||||
}
|
||||
|
||||
void HttpResponse::onFinished()
|
||||
{
|
||||
QNetworkReply *reply = m_networkReply;
|
||||
if (reply->error() != QNetworkReply::NoError)
|
||||
return;
|
||||
|
||||
if (m_slotsMap.contains(onResponse_QNetworkReply_A_Pointer)) {
|
||||
_exec(m_slotsMap.value(onResponse_QNetworkReply_A_Pointer).second, QNetworkReply*, reply) {
|
||||
emit finished(reply);
|
||||
}
|
||||
}
|
||||
else if (m_slotsMap.contains((onResponse_QByteArray))) {
|
||||
QByteArray result = reply->readAll();
|
||||
|
||||
_exec(m_slotsMap.value((onResponse_QByteArray)).second, QByteArray, result) {
|
||||
emit finished(result);
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
else if (m_slotsMap.contains((onResponse_QVariantMap))) {
|
||||
QByteArray result = reply->readAll();
|
||||
QVariantMap resultMap = QJsonDocument::fromJson(result).object().toVariantMap();
|
||||
|
||||
_exec(m_slotsMap.value((onResponse_QVariantMap)).second, QVariantMap, resultMap){
|
||||
emit finished(resultMap);
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void HttpResponse::onError(QNetworkReply::NetworkError error)
|
||||
{
|
||||
QNetworkReply *reply = m_networkReply;
|
||||
const QMetaObject & metaObject = QNetworkReply::staticMetaObject;
|
||||
QMetaEnum metaEnum = metaObject.enumerator(metaObject.indexOfEnumerator("NetworkError"));
|
||||
QString errorString = reply->errorString().isEmpty() ? metaEnum.valueToKey(error) : reply->errorString();
|
||||
|
||||
if (m_slotsMap.contains((onError_QString_QNetworkReply_A_Poniter))) {
|
||||
_exec2(m_slotsMap.value((onError_QString_QNetworkReply_A_Poniter)).second, QString, QNetworkReply*, errorString, reply) {
|
||||
emit this->error(errorString, reply);
|
||||
}
|
||||
}
|
||||
else if (m_slotsMap.contains((onError_QNetworkReply_To_NetworkError_QNetworkReply_A_Pointer))) {
|
||||
_exec2(m_slotsMap.value((onError_QNetworkReply_To_NetworkError_QNetworkReply_A_Pointer)).second,
|
||||
QNetworkReply::NetworkError, QNetworkReply*,
|
||||
error, reply) {
|
||||
emit this->error(error, reply);
|
||||
}
|
||||
}
|
||||
else if (m_slotsMap.contains((onError_QString))) {
|
||||
_exec(m_slotsMap.value((onError_QString)).second, QString, errorString) {
|
||||
emit this->error(errorString);
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
else if (m_slotsMap.contains((onError_QNetworkReply_To_NetworkError))) {
|
||||
_exec(m_slotsMap.value((onError_QNetworkReply_To_NetworkError)).second, QNetworkReply::NetworkError, error) {
|
||||
emit this->error(error);
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void HttpResponse::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
|
||||
{
|
||||
if (m_slotsMap.contains((onDownloadProgress_qint64_qint64))) {
|
||||
_exec2(m_slotsMap.value((onDownloadProgress_qint64_qint64)).second, qint64, qint64, bytesReceived, bytesTotal) {
|
||||
emit downloadProgress(bytesReceived, bytesTotal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void extractSlot(const QString &respReceiverSlot, QString &extractSlot, QStringList &extractSlotTypes)
|
||||
{
|
||||
QString slot(respReceiverSlot);
|
||||
if (extractCode(respReceiverSlot.toStdString().data()) == QSLOT_CODE && !slot.isEmpty()) {
|
||||
slot.remove(0, 1);
|
||||
|
||||
QString unconvertedSlotType = slot;
|
||||
int startIndex = slot.indexOf('(');
|
||||
int endIndex = slot.indexOf(')');
|
||||
Q_ASSERT(startIndex != -1 && endIndex != -1);
|
||||
|
||||
extractSlot = slot.remove(startIndex, endIndex-startIndex+1);
|
||||
|
||||
extractSlotTypes = unconvertedSlotType.mid(startIndex+1, endIndex-startIndex-1)
|
||||
.remove(QRegExp("\\s"))
|
||||
.split(',');
|
||||
}
|
||||
}
|
||||
|
||||
/* from slotMap get [SupportMethod] */
|
||||
static HttpResponse::SupportMethod getSupportMethod(const QPair<QString, QVariant> &slotMap) {
|
||||
|
||||
QMapIterator<HttpResponse::SupportMethod, QMap<QString, QVariant>> iter(methodParams);
|
||||
|
||||
QString receiverSlot = slotMap.first;
|
||||
QString slot;
|
||||
QStringList slotTypes;
|
||||
extractSlot(receiverSlot, slot, slotTypes);
|
||||
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
HttpResponse::SupportMethod supportMethod = iter.key();
|
||||
QMap<QString, QVariant> value = iter.value();
|
||||
if (slotTypes == value.value("types").toStringList()) {
|
||||
return supportMethod;
|
||||
}
|
||||
else if (receiverSlot == value.value("lambda").toString()) {
|
||||
return supportMethod;
|
||||
}
|
||||
}
|
||||
|
||||
return HttpResponse::Invalid;
|
||||
}
|
||||
|
||||
static void autoInfterConvertedSupportMethod(QMultiMap<HttpResponse::SupportMethod, QPair<QString, QVariant> > &unconvertedSlotsMap)
|
||||
{
|
||||
QMultiMap<HttpResponse::SupportMethod, QPair<QString, QVariant> > convertedSlotsMap;
|
||||
QMapIterator<HttpResponse::SupportMethod, QPair<QString, QVariant> > iter(unconvertedSlotsMap);
|
||||
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
const HttpResponse::SupportMethod supportMethod = iter.key();
|
||||
const QPair<QString, QVariant> slotMap = iter.value();
|
||||
|
||||
if (supportMethod == HttpResponse::AutoInfer) {
|
||||
HttpResponse::SupportMethod supportMethod = getSupportMethod(slotMap);
|
||||
if (supportMethod == HttpResponse::Invalid) {
|
||||
qDebug()<<"Not find support Method!"<<slotMap.first;
|
||||
}
|
||||
else {
|
||||
if (methodParams[supportMethod].value("isAutoInfer").toBool())
|
||||
convertedSlotsMap.insert(supportMethod, slotMap);
|
||||
else
|
||||
qDebug()<<"This type["<<methodParams[supportMethod].value("types").toString()<<"] does not support automatic derivation";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (methodParams[supportMethod].value("isAutoInfer").toBool())
|
||||
convertedSlotsMap.insert(supportMethod, slotMap);
|
||||
else
|
||||
qDebug()<<"This type["<<methodParams[supportMethod].value("types").toString()<<"] does not support automatic derivation";
|
||||
}
|
||||
}
|
||||
|
||||
unconvertedSlotsMap = convertedSlotsMap;
|
||||
|
||||
}
|
||||
|
||||
void HttpResponse::slotsMapOperation(QMultiMap<SupportMethod, QPair<QString, QVariant> > &slotsMap)
|
||||
{
|
||||
autoInfterConvertedSupportMethod(slotsMap);
|
||||
|
||||
QMapIterator<SupportMethod, QPair<QString, QVariant> > iter(slotsMap);
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
SupportMethod supportMethod = iter.key();
|
||||
const QPair<QString, QVariant> &slotMap = iter.value();
|
||||
|
||||
const QString &receiverSlot = slotMap.first;
|
||||
QVariant target = slotMap.second;
|
||||
const QObject *receiver = target.value<QObject*>();
|
||||
|
||||
if (receiver) {
|
||||
if (methodParams.contains(supportMethod)) {
|
||||
connect(this,
|
||||
methodParams[supportMethod].value("signal").toString().toStdString().data(),
|
||||
receiver,
|
||||
receiverSlot.toStdString().data(),
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HttpResponse::HttpResponse()
|
||||
{
|
||||
|
||||
}
|
||||
107
third-party/QtNetworkService/HttpResponse.h
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/**********************************************************
|
||||
Author: Qt君
|
||||
微信公众号: Qt君(文章首发)
|
||||
Website: qtbig.com(后续更新)
|
||||
Email: 2088201923@qq.com
|
||||
QQ交流群: 732271126
|
||||
LISCENSE: MIT
|
||||
**********************************************************/
|
||||
#ifndef HTTP_RESPONSE_H
|
||||
#define HTTP_RESPONSE_H
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QMultiMap>
|
||||
#include <functional>
|
||||
#include <QTimer>
|
||||
|
||||
namespace AeaQt {
|
||||
|
||||
class HttpResponseTimeout : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
HttpResponseTimeout(QNetworkReply *parent = NULL, const int timeout = -1) : QObject(parent) {
|
||||
if (timeout > 0)
|
||||
QTimer::singleShot(timeout, this, SLOT(onTimeout()));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void onTimeout() {
|
||||
QNetworkReply *reply = static_cast<QNetworkReply*>(parent());
|
||||
if (reply->isRunning()) {
|
||||
reply->abort();
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class HttpResponse : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/*
|
||||
* Support Reflex Method
|
||||
* default: AutoInfer
|
||||
* AutoInfer: Automatic derivation based on type
|
||||
*/
|
||||
enum SupportMethod {
|
||||
Invalid = 0,
|
||||
AutoInfer,
|
||||
onResponse_QNetworkReply_A_Pointer, /* method: void function(QNetworkReply* reply); Is_AutoInfer: true */
|
||||
onResponse_QByteArray, /* method: void function(QByteArray data); Is_AutoInfer: true */
|
||||
onResponse_QVariantMap, /* method: void function(QVariantMap map); Is_AutoInfer: true */
|
||||
onDownloadProgress_qint64_qint64, /* method: void function(qint64 bytesReceived, qint64 bytesTotal); Is_AutoInfer: true */
|
||||
onError_QNetworkReply_To_NetworkError, /* method: void function(QNetworkReply::NetworkError error); Is_AutoInfer: true */
|
||||
onError_QString, /* method: void function(QString errorString); Is_AutoInfer: true */
|
||||
onError_QNetworkReply_To_NetworkError_QNetworkReply_A_Pointer, /* method: void function(QNetworkReply::NetworkError error, QNetworkReply* reply); Is_AutoInfer: true */
|
||||
onError_QString_QNetworkReply_A_Poniter/* method: void function(QString errorString, QNetworkReply* reply); Is_AutoInfer: true */
|
||||
};
|
||||
|
||||
explicit HttpResponse(QNetworkReply *networkReply,
|
||||
const QMultiMap<SupportMethod, QPair<QString, QVariant> > &slotsMap,
|
||||
const int &timeout,
|
||||
bool isBlock);
|
||||
|
||||
virtual ~HttpResponse();
|
||||
|
||||
QNetworkReply *networkReply();
|
||||
|
||||
protected:
|
||||
void slotsMapOperation(QMultiMap<SupportMethod, QPair<QString, QVariant> > &slotsMap);
|
||||
|
||||
signals:
|
||||
void finished(QNetworkReply *reply);
|
||||
void finished(QByteArray data);
|
||||
void finished(QVariantMap map);
|
||||
void error(QString errorString);
|
||||
void error(QNetworkReply::NetworkError error);
|
||||
void error(QString errorString, QNetworkReply *reply);
|
||||
void error(QNetworkReply::NetworkError error, QNetworkReply *reply);
|
||||
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
|
||||
|
||||
private slots:
|
||||
void onFinished();
|
||||
void onError(QNetworkReply::NetworkError error);
|
||||
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
|
||||
|
||||
private:
|
||||
HttpResponse();
|
||||
|
||||
private:
|
||||
QMultiMap<SupportMethod, QPair<QString, QVariant> > m_slotsMap;
|
||||
QNetworkReply *m_networkReply;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(std::function<void (QNetworkReply*)>)
|
||||
Q_DECLARE_METATYPE(std::function<void (QByteArray)>)
|
||||
Q_DECLARE_METATYPE(std::function<void (QVariantMap)>)
|
||||
|
||||
Q_DECLARE_METATYPE(std::function<void (QString)>)
|
||||
Q_DECLARE_METATYPE(std::function<void (QNetworkReply::NetworkError)>)
|
||||
Q_DECLARE_METATYPE(std::function<void (QNetworkReply::NetworkError, QNetworkReply *)>)
|
||||
Q_DECLARE_METATYPE(std::function<void (QString, QNetworkReply *)>)
|
||||
|
||||
Q_DECLARE_METATYPE(std::function<void (qint64, qint64)>)
|
||||
|
||||
#endif // HTTP_RESPONSE_H
|
||||