mirror of
https://gitee.com/spark-store-project/spark-store
synced 2026-06-22 22:23:49 +08:00
New Non-DTK store client prototype
This commit is contained in:
-102
@@ -1,102 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
#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
@@ -1,160 +0,0 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
#include "spkjsonapiconsumer.h"
|
||||
|
||||
void SpkJsonApiConsumer::RequestUrl(QUrl aUrl)
|
||||
{
|
||||
mNet.
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
#include "big_image.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QtConcurrent>
|
||||
|
||||
big_image::big_image(DBlurEffectWidget *parent) :
|
||||
DBlurEffectWidget(parent),
|
||||
m_image(new QLabel)
|
||||
{
|
||||
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 *)
|
||||
{
|
||||
hide();
|
||||
m_image->clear();
|
||||
}
|
||||
|
||||
void big_image::focusOutEvent(QFocusEvent *)
|
||||
{
|
||||
hide();
|
||||
m_image->clear();
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef BIG_IMAGE_H
|
||||
#define BIG_IMAGE_H
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QLabel>
|
||||
|
||||
#include <DBlurEffectWidget>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
class big_image : public DBlurEffectWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit big_image(DBlurEffectWidget *parent = nullptr);
|
||||
|
||||
QLabel *m_image;
|
||||
|
||||
void setimage(QPixmap);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void focusOutEvent(QFocusEvent *event) override;
|
||||
};
|
||||
|
||||
#endif // BIG_IMAGE_H
|
||||
@@ -1,255 +0,0 @@
|
||||
#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();
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#ifndef DOWNLOADLIST_H
|
||||
#define DOWNLOADLIST_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTextBrowser>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
|
||||
#include <DDialog>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
namespace Ui {
|
||||
class downloadlist;
|
||||
}
|
||||
|
||||
class downloadlist : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit downloadlist(QWidget *parent = nullptr);
|
||||
~downloadlist();
|
||||
|
||||
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();
|
||||
|
||||
void setFileName(QString);
|
||||
void seticon(const QPixmap);
|
||||
void closeDownload();
|
||||
void setSpeed(QString);
|
||||
|
||||
void install(int);
|
||||
|
||||
private:
|
||||
Ui::downloadlist *ui;
|
||||
|
||||
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();
|
||||
|
||||
};
|
||||
|
||||
#endif // DOWNLOADLIST_H
|
||||
@@ -1,294 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>downloadlist</class>
|
||||
<widget class="QWidget" name="downloadlist">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>666</width>
|
||||
<height>54</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>54</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>48</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>icon</string>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</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>
|
||||
<widget class="QLabel" name="label_filename">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>280</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Waiting to download</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</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>
|
||||
<widget class="DSpinner" name="widget_spinner" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_install">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Install</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Info</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>DSpinner</class>
|
||||
<extends>QWidget</extends>
|
||||
<header location="global">dspinner.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,277 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
#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
|
||||
@@ -1,223 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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]
|
||||
@@ -1,88 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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
|
||||
@@ -1,51 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#ifndef IMAGE_SHOW_H
|
||||
#define IMAGE_SHOW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "big_image.h"
|
||||
|
||||
class image_show : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit image_show(QWidget *parent = nullptr);
|
||||
|
||||
int desktop_w;
|
||||
int desktop_h;
|
||||
|
||||
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
|
||||
+14
-95
@@ -1,103 +1,22 @@
|
||||
#include <DApplication>
|
||||
#include <DApplicationSettings>
|
||||
#include <DWidgetUtil> // Dtk::Widget::moveToCenter(&w); 要调用它,就得引用 DWidgetUtil
|
||||
#include <QApplication>
|
||||
#include <QPushButton>
|
||||
#include <spklogging.h>
|
||||
#include "spkwindow.h"
|
||||
#include "spkui_general.h"
|
||||
#include "spkstore.h"
|
||||
|
||||
#include <QScreen>
|
||||
#include <QFile>
|
||||
#include "spkmsgbox.h"
|
||||
|
||||
#include "widget.h"
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
int main(int argc, char *argv[])
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
DApplication::loadDXcbPlugin(); // 让 bar 处在标题栏中
|
||||
DApplication a(argc, argv);
|
||||
QApplication a(argc, argv);
|
||||
|
||||
a.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
a.loadTranslator(); // 载入翻译
|
||||
QString LogPath = "";
|
||||
|
||||
/* 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");
|
||||
*/
|
||||
SpkStore store(false, LogPath);
|
||||
|
||||
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"
|
||||
)
|
||||
);
|
||||
//*((int*)0) = 0;
|
||||
|
||||
// 限制单实例运行
|
||||
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();
|
||||
return QApplication::exec();
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#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() + ";");
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef PROGRESSLOAD_H
|
||||
#define PROGRESSLOAD_H
|
||||
|
||||
#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);
|
||||
|
||||
private:
|
||||
QWidget *m_progess;
|
||||
QTimer *timer;
|
||||
int value;
|
||||
QPalette plt;
|
||||
|
||||
};
|
||||
|
||||
#endif // PROGRESSLOAD_H
|
||||
@@ -1,83 +0,0 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# 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
|
||||
@@ -0,0 +1,124 @@
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
#include "spklogging.h"
|
||||
#include "spkmsgbox.h"
|
||||
|
||||
SpkLogger *SpkLogger::Instance = nullptr;
|
||||
|
||||
SpkLogger::SpkLogger(QString suggestPath)
|
||||
{
|
||||
Initialize(suggestPath);
|
||||
|
||||
// Initialize libnotify
|
||||
if(!notify_init(QObject::tr("Spark\\ Store").toLocal8Bit()))
|
||||
{
|
||||
sErrPop(QObject::tr("libnotify failed to initialize. "
|
||||
"Desktop notifications will not work."));
|
||||
}
|
||||
else
|
||||
NotifyViable = true;
|
||||
}
|
||||
|
||||
SpkLogger::~SpkLogger()
|
||||
{
|
||||
if(NotifyViable)
|
||||
notify_uninit();
|
||||
}
|
||||
|
||||
void SpkLogger::Initialize(QString suggestPath)
|
||||
{
|
||||
if(Instance != nullptr) // Single instance
|
||||
return;
|
||||
|
||||
if(suggestPath != "")
|
||||
{
|
||||
if(QFile::permissions(suggestPath).testFlag(QFileDevice::WriteUser))
|
||||
mLogPath = suggestPath;
|
||||
}
|
||||
mLogPath = QDir::homePath() + "/.local/share/spark-store/logs/default.log";
|
||||
QString path = mLogPath.section('/', 1, -2, QString::SectionIncludeLeadingSep);
|
||||
if(!QDir().exists(path))
|
||||
if(!QDir().mkpath(path))
|
||||
{
|
||||
SpkLogger::Error(QObject::tr("Log directory \"%1\" cannot be created.").arg(path));
|
||||
return;
|
||||
}
|
||||
|
||||
mLogFile.setFileName(mLogPath);
|
||||
mLogFile.open(QFile::WriteOnly | QFile::Append);
|
||||
if(!mLogFile.isWritable())
|
||||
{
|
||||
Error(QObject::tr("Log file \"%1\" is not a writable file. "
|
||||
"Please check the permissions, or if it's a directory.").arg(mLogPath), true);
|
||||
return;
|
||||
}
|
||||
mLogWriter.setDevice(&mLogFile);
|
||||
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
void SpkLogger::Log(QString message)
|
||||
{
|
||||
message = QDateTime::currentDateTime().toString() + "[Log]" + message;
|
||||
mLogData.insertRow(mLogData.rowCount());
|
||||
auto id = mLogData.index(mLogData.rowCount() - 1, 0);
|
||||
mLogData.setData(id, message);
|
||||
mLogWriter << message << "\n";
|
||||
}
|
||||
|
||||
void SpkLogger::Warning(QString message)
|
||||
{
|
||||
message = QDateTime::currentDateTime().toString() + "[Warning]" + message;
|
||||
mLogData.insertRow(mLogData.rowCount());
|
||||
auto id = mLogData.index(mLogData.rowCount() - 1, 0);
|
||||
mLogData.setData(id, message);
|
||||
mLogWriter << message << "\n";
|
||||
}
|
||||
|
||||
void SpkLogger::Error(QString message, const bool pop)
|
||||
{
|
||||
message = QDateTime::currentDateTime().toString() + "[Error]" + message;
|
||||
mLogData.insertRow(mLogData.rowCount());
|
||||
auto id = mLogData.index(mLogData.rowCount() - 1, 0);
|
||||
mLogData.setData(id, message);
|
||||
mLogWriter << message << "\n";
|
||||
if(pop)
|
||||
{
|
||||
// QMessageBox msgbox;
|
||||
// msgbox.setIcon(QMessageBox::Critical);
|
||||
// msgbox.setText(QObject::tr("Spark Store has encountered an error.\n"
|
||||
// "Parts of the experience is expected to be broken.\n\n"
|
||||
// "Details:\n%1")
|
||||
// .arg(message));
|
||||
// msgbox.exec(); // I don't know whether we need to show it non-modal.
|
||||
SpkMsgBox::StaticExec(QObject::tr("Spark Store has encountered an error.\n"
|
||||
"Parts of the experience is expected to be broken.\n\n"
|
||||
"Details:\n%1"),
|
||||
QObject::tr("Spark Store Error"),
|
||||
QMessageBox::Critical,
|
||||
QMessageBox::Ok,
|
||||
message);
|
||||
}
|
||||
}
|
||||
|
||||
void SpkLogger::Critical(QString message)
|
||||
{
|
||||
message = QDateTime::currentDateTime().toString() + "[Critical]" + message;
|
||||
mLogData.insertRow(mLogData.rowCount());
|
||||
auto id = mLogData.index(mLogData.rowCount() - 1, 0);
|
||||
mLogData.setData(id, message);
|
||||
mLogWriter << message << "\n";
|
||||
QMessageBox::critical(nullptr,
|
||||
QObject::tr("Critical error in Spark Store"),
|
||||
QObject::tr("Spark Store has encountered a fatal error and cannot"
|
||||
"continue anymore. Please consider checking logs and send a"
|
||||
"bug report to us.\n\n"
|
||||
"Details:\n%1")
|
||||
.arg(message));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
#include <spkui_general.h>
|
||||
#include "spkstore.h"
|
||||
|
||||
SpkStore::SpkStore(bool aCli, QString &aLogPath)
|
||||
{
|
||||
mLogger = new SpkLogger(aLogPath);
|
||||
|
||||
Instance = this;
|
||||
|
||||
if(aCli)
|
||||
return;
|
||||
|
||||
SpkUi::Initialize();
|
||||
|
||||
mMainWindow = new SpkMainWindow;
|
||||
mMainWindow->show();
|
||||
}
|
||||
|
||||
SpkStore::~SpkStore()
|
||||
{
|
||||
delete mMainWindow;
|
||||
delete mLogger;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
#include "spkuimsg.h"
|
||||
|
||||
NotifyNotification *SpkUiMessage::_notify = nullptr; // Initialize statics
|
||||
int SpkUiMessage::mTimeoutDesktop = 5000;
|
||||
|
||||
void SpkUiMessage::SendDesktopNotification(QString s, const char * const icon)
|
||||
{
|
||||
if(_notify == nullptr)
|
||||
{
|
||||
_notify = notify_notification_new(tr("Spark\\ Store").toLocal8Bit(),
|
||||
s.toLocal8Bit(),
|
||||
icon);
|
||||
notify_notification_set_timeout(_notify, mTimeoutDesktop);
|
||||
}
|
||||
else
|
||||
{
|
||||
notify_notification_update(_notify, tr("Spark\\ Store").toLocal8Bit(),
|
||||
s.toLocal8Bit(),
|
||||
icon);
|
||||
}
|
||||
|
||||
notify_notification_show(_notify, nullptr);
|
||||
}
|
||||
|
||||
void SpkUiMessage::SendStoreNotification(QString s) // TODO: IMPLEMENT IN-APP NOTIFICATION
|
||||
{
|
||||
Q_UNUSED(s);
|
||||
}
|
||||
|
||||
void SpkUiMessage::SetDesktopNotifyTimeout(int ms)
|
||||
{
|
||||
if(!_notify)
|
||||
_notify = notify_notification_new("", "", "");
|
||||
notify_notification_set_timeout(_notify, ms);
|
||||
mTimeoutDesktop = ms;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
#include <QFile>
|
||||
|
||||
-1356
File diff suppressed because it is too large
Load Diff
-168
@@ -1,168 +0,0 @@
|
||||
#ifndef WIDGET_H
|
||||
#define WIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QFile>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QProcess>
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
#include <QToolButton>
|
||||
#include <QTimer>
|
||||
#include <QJsonArray>
|
||||
#include <QFontDatabase>
|
||||
#include <QMutex>
|
||||
|
||||
#include <DBlurEffectWidget>
|
||||
#include <DTitlebar>
|
||||
#include <DSearchEdit>
|
||||
#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, QString fileName);
|
||||
void searchApp(QString);
|
||||
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);
|
||||
void on_pushButton_updateServer_clicked();
|
||||
void on_pushButton_updateApt_clicked();
|
||||
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:
|
||||
QUrl url;
|
||||
|
||||
downloadlist download_list[LIST_MAX];
|
||||
Ui::Widget *ui;
|
||||
QNetworkAccessManager *manager;
|
||||
QNetworkReply *reply;
|
||||
QList<QUrl> urList;
|
||||
QFile *file;
|
||||
QString appName;
|
||||
QString urladdress;
|
||||
QString pkgName;
|
||||
QString appweb;
|
||||
bool themeIsDark;
|
||||
|
||||
QFont font;
|
||||
|
||||
private:
|
||||
void initUI();
|
||||
void initConfig();
|
||||
void chooseLeftMenu(int index);
|
||||
void setfoot(int);
|
||||
void updatefoot();
|
||||
void updateUI();
|
||||
|
||||
quint64 dirFileSize(const QString &path);
|
||||
|
||||
private:
|
||||
QPushButton * left_list[15];
|
||||
QUrl menuUrl[13];
|
||||
ProgressLoad *m_loadweb;
|
||||
QLabel *m_loaderror = new QLabel;
|
||||
QString serverUrl;
|
||||
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;
|
||||
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
|
||||
-1464
File diff suppressed because it is too large
Load Diff
@@ -1,188 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user