This commit is contained in:
2022-12-09 11:16:11 +08:00
parent fbffe12501
commit 2ec4b1f4d4
168 changed files with 7008 additions and 10696 deletions

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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>

42
src/assets/assets.qrc Normal file
View File

@@ -0,0 +1,42 @@
<RCC>
<qresource prefix="/">
<file>icon/logo.svg</file>
<file>tags/a2d-small.png</file>
<file>tags/a2d.png</file>
<file>tags/community-small.png</file>
<file>tags/community.png</file>
<file>tags/community.svg</file>
<file>tags/deepin-small.png</file>
<file>tags/deepin.svg</file>
<file>tags/dtk-small.png</file>
<file>tags/dwine2-small.png</file>
<file>tags/dwine5-small.png</file>
<file>tags/dwine5.svg</file>
<file>tags/logo_icon.svg</file>
<file>tags/ubuntu-small.png</file>
<file>tags/ubuntu.png</file>
<file>tags/uos-authorize.svg</file>
<file>tags/uos-small.png</file>
<file>tags/uos.svg</file>
<file>icon/light/back.svg</file>
<file>icon/light/download.svg</file>
<file>icon/light/leftbutton_0.svg</file>
<file>icon/light/leftbutton_1.svg</file>
<file>icon/light/leftbutton_2.svg</file>
<file>icon/light/leftbutton_3.svg</file>
<file>icon/light/leftbutton_4.svg</file>
<file>icon/light/leftbutton_5.svg</file>
<file>icon/light/leftbutton_6.svg</file>
<file>icon/light/leftbutton_7.svg</file>
<file>icon/light/leftbutton_8.svg</file>
<file>icon/light/leftbutton_9.svg</file>
<file>icon/light/leftbutton_10.svg</file>
<file>icon/light/leftbutton_11.svg</file>
<file>icon/light/leftbutton_12.svg</file>
<file>icon/light/box.svg</file>
<file>icon/light/calendar.svg</file>
<file>icon/light/globe.svg</file>
<file>icon/light/folder.svg</file>
<file>icon/light/text.svg</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@@ -0,0 +1,3 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M44 24C44 24.6904 43.4404 25.25 42.75 25.25H10.3041L23.1264 37.8586C23.6187 38.3426 23.6253 39.134 23.1413 39.6263C22.6572 40.1185 21.8658 40.1252 21.3736 39.6411L6.38563 24.903C6.37656 24.8943 6.36759 24.8854 6.35872 24.8764C6.14696 24.6611 6.02911 24.3884 6.00476 24.1094C5.99775 24.029 5.99848 23.9481 6.00696 23.8679C6.03557 23.5967 6.15267 23.333 6.35872 23.1234C6.37242 23.1095 6.38611 23.096 6.39982 23.0829L21.3736 8.35872C21.8658 7.87468 22.6572 7.88134 23.1413 8.37358C23.6253 8.86582 23.6187 9.65724 23.1264 10.1413L10.304 22.75H42.75C43.4404 22.75 44 23.3096 44 24Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 708 B

View File

@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.2999 2.4808C10.4654 2.14702 9.53457 2.14702 8.70013 2.4808L2.94291 4.78369C2.37343 5.01148 2 5.56305 2 6.1764V13.8223C2 14.4357 2.37343 14.9873 2.94291 15.2151L8.70013 17.5179C9.53457 17.8517 10.4654 17.8517 11.2999 17.5179L17.0571 15.2151C17.6266 14.9873 18 14.4357 18 13.8223V6.1764C18 5.56305 17.6266 5.01148 17.0571 4.78369L11.2999 2.4808ZM9.07152 3.40928C9.66755 3.17087 10.3324 3.17087 10.9285 3.40928L16.1538 5.49941L13.8751 6.41088L7.72133 3.94935L9.07152 3.40928ZM6.37504 4.48787L12.5289 6.94939L10.0001 7.96088L3.84633 5.49935L6.37504 4.48787ZM10.5001 8.83791L17 6.23797V13.8223C17 14.0268 16.8755 14.2106 16.6857 14.2866L10.9285 16.5895C10.7889 16.6453 10.6455 16.6881 10.5001 16.7177V8.83791ZM9.50015 8.83791V16.7178C9.35467 16.6881 9.21121 16.6453 9.07152 16.5895L3.3143 14.2866C3.12448 14.2106 3 14.0268 3 13.8223V6.23785L9.50015 8.83791Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 987 B

View File

@@ -0,0 +1,3 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21.75 3C23.5449 3 25 4.45507 25 6.25V21.75C25 23.5449 23.5449 25 21.75 25H6.25C4.45507 25 3 23.5449 3 21.75V6.25C3 4.45507 4.45507 3 6.25 3H21.75ZM23.5 9.503H4.5V21.75C4.5 22.7165 5.2835 23.5 6.25 23.5H21.75C22.7165 23.5 23.5 22.7165 23.5 21.75V9.503ZM8.74878 17.5014C9.43913 17.5014 9.99878 18.0611 9.99878 18.7514C9.99878 19.4418 9.43913 20.0014 8.74878 20.0014C8.05842 20.0014 7.49878 19.4418 7.49878 18.7514C7.49878 18.0611 8.05842 17.5014 8.74878 17.5014ZM14.0033 17.5014C14.6936 17.5014 15.2533 18.0611 15.2533 18.7514C15.2533 19.4418 14.6936 20.0014 14.0033 20.0014C13.3129 20.0014 12.7533 19.4418 12.7533 18.7514C12.7533 18.0611 13.3129 17.5014 14.0033 17.5014ZM8.74878 12.5014C9.43913 12.5014 9.99878 13.0611 9.99878 13.7514C9.99878 14.4418 9.43913 15.0014 8.74878 15.0014C8.05842 15.0014 7.49878 14.4418 7.49878 13.7514C7.49878 13.0611 8.05842 12.5014 8.74878 12.5014ZM14.0033 12.5014C14.6936 12.5014 15.2533 13.0611 15.2533 13.7514C15.2533 14.4418 14.6936 15.0014 14.0033 15.0014C13.3129 15.0014 12.7533 14.4418 12.7533 13.7514C12.7533 13.0611 13.3129 12.5014 14.0033 12.5014ZM19.2577 12.5014C19.9481 12.5014 20.5077 13.0611 20.5077 13.7514C20.5077 14.4418 19.9481 15.0014 19.2577 15.0014C18.5674 15.0014 18.0077 14.4418 18.0077 13.7514C18.0077 13.0611 18.5674 12.5014 19.2577 12.5014ZM21.75 4.5H6.25C5.2835 4.5 4.5 5.2835 4.5 6.25V8.003H23.5V6.25C23.5 5.2835 22.7165 4.5 21.75 4.5Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,3 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.25 39.5H35.75C36.4404 39.5 37 40.0596 37 40.75C37 41.3972 36.5081 41.9295 35.8778 41.9935L35.75 42H12.25C11.5596 42 11 41.4404 11 40.75C11 40.1028 11.4919 39.5705 12.1222 39.5065L12.25 39.5H35.75H12.25ZM23.6222 6.00645L23.75 6C24.3972 6 24.9295 6.49187 24.9935 7.12219L25 7.25V31.54L30.6467 25.8943C31.1348 25.4061 31.9263 25.4061 32.4144 25.8943C32.9026 26.3824 32.9026 27.1739 32.4144 27.6621L24.6363 35.4402C24.1481 35.9284 23.3567 35.9284 22.8685 35.4402L15.0903 27.6621C14.6022 27.1739 14.6022 26.3824 15.0903 25.8943C15.5785 25.4061 16.3699 25.4061 16.8581 25.8943L22.5 31.536V7.25C22.5 6.60279 22.9919 6.07047 23.6222 6.00645L23.75 6L23.6222 6.00645Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 792 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 5V11C2 12.1046 2.89543 13 4 13H12C13.1046 13 14 12.1046 14 11V6C14 4.89543 13.1046 4 12 4H7.17539L6.06235 3.10957C5.97369 3.03864 5.86354 3 5.75 3H4C2.89543 3 2 3.89543 2 5ZM3 5C3 4.44772 3.44772 4 4 4H5.57461L6.44274 4.6945L5.5567 5.49998H3V5ZM7.5933 5H12C12.5523 5 13 5.44772 13 6V11C13 11.5523 12.5523 12 12 12H4C3.44772 12 3 11.5523 3 11V6.49998H5.75C5.87438 6.49998 5.9943 6.45362 6.08634 6.36995L7.5933 5Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 545 B

View File

@@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 30C23.732 30 30 23.732 30 16C30 8.26801 23.732 2 16 2C8.26801 2 2 8.26801 2 16C2 23.732 8.26801 30 16 30ZM16 4C17.0317 4 18.283 4.94804 19.3347 7.22667C19.7084 8.03639 20.0331 8.9697 20.2941 10H11.7059C11.9669 8.9697 12.2916 8.03639 12.6653 7.22667C13.717 4.94804 14.9683 4 16 4ZM10.8494 6.38855C10.36 7.44883 9.95424 8.66735 9.64867 10H5.60539C6.97928 7.62495 9.1438 5.76448 11.7391 4.77849C11.4088 5.27683 11.1118 5.81994 10.8494 6.38855ZM9.27878 12C9.0968 13.2705 9 14.6141 9 16C9 17.3859 9.0968 18.7295 9.27878 20H4.68282C4.24062 18.7489 4 17.4025 4 16C4 14.5975 4.24062 13.2511 4.68282 12H9.27878ZM9.64867 22C9.95424 23.3327 10.36 24.5512 10.8494 25.6114C11.1118 26.1801 11.4088 26.7232 11.7391 27.2215C9.1438 26.2355 6.97928 24.375 5.60539 22H9.64867ZM11.7059 22H20.2941C20.0331 23.0303 19.7084 23.9636 19.3347 24.7733C18.283 27.052 17.0317 28 16 28C14.9683 28 13.717 27.052 12.6653 24.7733C12.2916 23.9636 11.9669 23.0303 11.7059 22ZM20.6991 20H11.3009C11.1068 18.7518 11 17.4068 11 16C11 14.5932 11.1068 13.2482 11.3009 12H20.6991C20.8932 13.2482 21 14.5932 21 16C21 17.4068 20.8932 18.7518 20.6991 20ZM22.3513 22H26.3946C25.0207 24.375 22.8562 26.2355 20.2609 27.2215C20.5912 26.7232 20.8882 26.1801 21.1506 25.6114C21.64 24.5512 22.0458 23.3327 22.3513 22ZM27.3172 20H22.7212C22.9032 18.7295 23 17.3859 23 16C23 14.6141 22.9032 13.2705 22.7212 12H27.3172C27.7594 13.2511 28 14.5975 28 16C28 17.4025 27.7594 18.7489 27.3172 20ZM20.2609 4.77849C22.8562 5.76448 25.0207 7.62495 26.3946 10H22.3513C22.0458 8.66735 21.64 7.44883 21.1506 6.38855C20.8882 5.81994 20.5912 5.27683 20.2609 4.77849Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,3 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21.6062 5.85517C23.0048 4.71494 24.9952 4.71494 26.3938 5.85517L39.5688 16.5966C40.4736 17.3342 41 18.4492 41 19.628V39.1134C41 41.2599 39.2875 43 37.175 43H32.075C29.9625 43 28.25 41.2599 28.25 39.1134V29.7492C28.25 29.0337 27.6792 28.4536 26.975 28.4536H21.025C20.3208 28.4536 19.75 29.0337 19.75 29.7492V39.1134C19.75 41.2599 18.0375 43 15.925 43H10.825C8.71251 43 7 41.2599 7 39.1134V19.628C7 18.4493 7.52645 17.3342 8.43124 16.5966L21.6062 5.85517ZM24.7979 7.87612C24.3317 7.49604 23.6683 7.49604 23.2021 7.87612L10.0271 18.6175C9.72548 18.8634 9.55 19.2351 9.55 19.628V39.1134C9.55 39.8289 10.1208 40.4089 10.825 40.4089H15.925C16.6292 40.4089 17.2 39.8289 17.2 39.1134V29.7492C17.2 27.6027 18.9125 25.8626 21.025 25.8626H26.975C29.0875 25.8626 30.8 27.6027 30.8 29.7492V39.1134C30.8 39.8289 31.3708 40.4089 32.075 40.4089H37.175C37.8792 40.4089 38.45 39.8289 38.45 39.1134V19.628C38.45 19.2351 38.2745 18.8634 37.9729 18.6175L24.7979 7.87612Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 30C23.732 30 30 23.732 30 16C30 8.26801 23.732 2 16 2C8.26801 2 2 8.26801 2 16C2 23.732 8.26801 30 16 30ZM16 4C17.0317 4 18.283 4.94804 19.3347 7.22667C19.7084 8.03639 20.0331 8.9697 20.2941 10H11.7059C11.9669 8.9697 12.2916 8.03639 12.6653 7.22667C13.717 4.94804 14.9683 4 16 4ZM10.8494 6.38855C10.36 7.44883 9.95424 8.66735 9.64867 10H5.60539C6.97928 7.62495 9.1438 5.76448 11.7391 4.77849C11.4088 5.27683 11.1118 5.81994 10.8494 6.38855ZM9.27878 12C9.0968 13.2705 9 14.6141 9 16C9 17.3859 9.0968 18.7295 9.27878 20H4.68282C4.24062 18.7489 4 17.4025 4 16C4 14.5975 4.24062 13.2511 4.68282 12H9.27878ZM9.64867 22C9.95424 23.3327 10.36 24.5512 10.8494 25.6114C11.1118 26.1801 11.4088 26.7232 11.7391 27.2215C9.1438 26.2355 6.97928 24.375 5.60539 22H9.64867ZM11.7059 22H20.2941C20.0331 23.0303 19.7084 23.9636 19.3347 24.7733C18.283 27.052 17.0317 28 16 28C14.9683 28 13.717 27.052 12.6653 24.7733C12.2916 23.9636 11.9669 23.0303 11.7059 22ZM20.6991 20H11.3009C11.1068 18.7518 11 17.4068 11 16C11 14.5932 11.1068 13.2482 11.3009 12H20.6991C20.8932 13.2482 21 14.5932 21 16C21 17.4068 20.8932 18.7518 20.6991 20ZM22.3513 22H26.3946C25.0207 24.375 22.8562 26.2355 20.2609 27.2215C20.5912 26.7232 20.8882 26.1801 21.1506 25.6114C21.64 24.5512 22.0458 23.3327 22.3513 22ZM27.3172 20H22.7212C22.9032 18.7295 23 17.3859 23 16C23 14.6141 22.9032 13.2705 22.7212 12H27.3172C27.7594 13.2511 28 14.5975 28 16C28 17.4025 27.7594 18.7489 27.3172 20ZM20.2609 4.77849C22.8562 5.76448 25.0207 7.62495 26.3946 10H22.3513C22.0458 8.66735 21.64 7.44883 21.1506 6.38855C20.8882 5.81994 20.5912 5.27683 20.2609 4.77849Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.4089 2.51203C12.5053 2.14573 11.4947 2.14573 10.5911 2.51203L3.09252 5.552C2.43211 5.81973 2 6.46118 2 7.1738V16.8265C2 17.5391 2.43211 18.1806 3.09252 18.4483L10.5911 21.4883C10.7263 21.5431 10.8639 21.5897 11.0032 21.6281C11.0011 21.5857 11 21.543 11 21.5V20.0355L3.65607 17.0582C3.56173 17.0199 3.5 16.9283 3.5 16.8265V7.7493L11.2503 10.7633V15.4082C11.5487 14.7947 12.0906 14.3215 12.7503 14.1143V10.7647L20.5 7.77243V11.5498C21.3872 12.0033 21.9955 12.9245 22 13.9882V7.1738C22 6.46118 21.5679 5.81973 20.9075 5.552L13.4089 2.51203ZM11.1547 3.90214C11.6968 3.68236 12.3032 3.68236 12.8453 3.90214L19.4376 6.57469L16.7684 7.60531L9.24097 4.67796L11.1547 3.90214ZM7.21472 5.49941L14.6917 8.40714L12.0013 9.44593L4.58967 6.56362L7.21472 5.49941ZM14 15H13.5C12.6716 15 12 15.6716 12 16.5V18H14.5V17.75C14.5 17.3358 14.8358 17 15.25 17C15.6642 17 16 17.3358 16 17.75V18H19V17.75C19 17.3358 19.3358 17 19.75 17C20.1642 17 20.5 17.3358 20.5 17.75V18H23V16.5C23 15.6716 22.3284 15 21.5 15H21V14C21 13.0335 20.2165 12.25 19.25 12.25H15.75C14.7835 12.25 14 13.0335 14 14V15ZM15.5 14C15.5 13.8619 15.6119 13.75 15.75 13.75H19.25C19.3881 13.75 19.5 13.8619 19.5 14V15H15.5V14ZM12 21.5V19.5H14.5V20.25C14.5 20.6642 14.8358 21 15.25 21C15.6642 21 16 20.6642 16 20.25V19.5H19V20.25C19 20.6642 19.3358 21 19.75 21C20.1642 21 20.5 20.6642 20.5 20.25V19.5H23V21.5C23 22.3284 22.3284 23 21.5 23H13.5C12.6716 23 12 22.3284 12 21.5Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,6 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M37.75 6C38.4403 6 39 6.55964 39 7.25V9H40.75C41.4403 9 42 9.55964 42 10.25C42 10.9404 41.4403 11.5 40.75 11.5H39V13.25C39 13.9404 38.4403 14.5 37.75 14.5C37.0596 14.5 36.5 13.9404 36.5 13.25V11.5H34.75C34.0596 11.5 33.5 10.9404 33.5 10.25C33.5 9.55964 34.0596 9 34.75 9H36.5V7.25C36.5 6.55964 37.0596 6 37.75 6Z" fill="#212121"/>
<path d="M15 11.25C15 10.5596 14.4403 10 13.75 10C13.0596 10 12.5 10.5596 12.5 11.25V13H10.75C10.0596 13 9.49999 13.5596 9.49999 14.25C9.49999 14.9404 10.0596 15.5 10.75 15.5H12.5V17.25C12.5 17.9404 13.0596 18.5 13.75 18.5C14.4403 18.5 15 17.9404 15 17.25V15.5H16.75C17.4403 15.5 18 14.9404 18 14.25C18 13.5596 17.4403 13 16.75 13H15V11.25Z" fill="#212121"/>
<path d="M33.75 30C34.4403 30 35 30.5596 35 31.25V33H36.75C37.4403 33 38 33.5596 38 34.25C38 34.9404 37.4403 35.5 36.75 35.5H35V37.25C35 37.9404 34.4403 38.5 33.75 38.5C33.0596 38.5 32.5 37.9404 32.5 37.25V35.5H30.75C30.0596 35.5 29.5 34.9404 29.5 34.25C29.5 33.5596 30.0596 33 30.75 33H32.5V31.25C32.5 30.5596 33.0596 30 33.75 30Z" fill="#212121"/>
<path d="M25.8895 15.4044C27.7445 13.5494 30.7521 13.5494 32.607 15.4044C34.462 17.2594 34.462 20.2669 32.607 22.1219L12.1132 42.6158C10.2582 44.4707 7.25069 44.4707 5.3957 42.6158C3.54071 40.7608 3.54071 37.7532 5.3957 35.8982L25.8895 15.4044ZM24.5309 20.2986L7.16347 37.666C6.28479 38.5447 6.28479 39.9693 7.16347 40.848C8.04215 41.7267 9.46677 41.7267 10.3454 40.848L27.7129 23.4806L24.5309 20.2986ZM29.4806 21.7128L30.8393 20.3542C31.718 19.4755 31.718 18.0509 30.8393 17.1722C29.9606 16.2935 28.536 16.2935 27.6573 17.1722L26.2987 18.5308L29.4806 21.7128Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 18C11.1046 18 12 17.1046 12 16C12 14.8954 11.1046 14 10 14C8.89543 14 8 14.8954 8 16C8 17.1046 8.89543 18 10 18ZM16 18C17.1046 18 18 17.1046 18 16C18 14.8954 17.1046 14 16 14C14.8954 14 14 14.8954 14 16C14 17.1046 14.8954 18 16 18ZM24 16C24 17.1046 23.1046 18 22 18C20.8954 18 20 17.1046 20 16C20 14.8954 20.8954 14 22 14C23.1046 14 24 14.8954 24 16ZM30 16C30 23.732 23.732 30 16 30C8.26801 30 2 23.732 2 16C2 8.26801 8.26801 2 16 2C23.732 2 30 8.26801 30 16ZM28 16C28 9.37258 22.6274 4 16 4C9.37258 4 4 9.37258 4 16C4 22.6274 9.37258 28 16 28C22.6274 28 28 22.6274 28 16Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 707 B

View File

@@ -0,0 +1,5 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.9958 20.2505C15.9958 19.5601 16.5555 19.0005 17.2458 19.0005H30.7503C31.4406 19.0005 32.0003 19.5601 32.0003 20.2505C32.0003 20.9408 31.4406 21.5005 30.7503 21.5005H17.2458C16.5555 21.5005 15.9958 20.9408 15.9958 20.2505Z" fill="#212121"/>
<path d="M17.2502 26.4755C16.5599 26.4755 16.0002 27.0351 16.0002 27.7255C16.0002 28.4158 16.5599 28.9755 17.2502 28.9755H26.7502C27.4406 28.9755 28.0002 28.4158 28.0002 27.7255C28.0002 27.0351 27.4406 26.4755 26.7502 26.4755H17.2502Z" fill="#212121"/>
<path d="M16.5358 5.45151C33.8238 -1.46711 50.882 16.8873 41.5929 33.6076C37.3737 41.2022 26.8909 47.318 14.6846 41.5336L6.20039 43.9576C4.88396 44.3338 3.66741 43.1222 4.03682 41.8046C4.54321 39.9986 5.74306 35.7407 6.44459 33.4333C1.18328 24.045 4.73099 10.1758 16.5358 5.45151ZM39.4076 32.3935C47.4934 17.839 32.6847 1.68154 17.4647 7.77254C6.98817 11.9652 3.9394 24.4657 8.87032 32.6319L9.16123 33.1136L8.99336 33.6508C8.46122 35.3537 7.45649 38.8846 6.80827 41.1839L14.922 38.8657L15.3554 39.0806C26.3618 44.5367 35.6773 39.1079 39.4076 32.3935Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.6977 2.14829C19.8879 2.28981 20 2.51293 20 2.75001V16.25C20 16.2767 19.9986 16.303 19.9959 16.329C19.9986 16.3856 20 16.4427 20 16.5C20 18.433 18.433 20 16.5 20C14.567 20 13 18.433 13 16.5C13 14.567 14.567 13 16.5 13C17.2436 13 17.9331 13.2319 18.5 13.6273V7.75803L10 10.308V18.25C10 18.2766 9.99861 18.303 9.99589 18.3289C9.99862 18.3856 10 18.4426 10 18.5C10 20.433 8.433 22 6.5 22C4.567 22 3 20.433 3 18.5C3 16.567 4.567 15 6.5 15C7.24362 15 7.93308 15.2319 8.5 15.6273V5.75001C8.5 5.4188 8.71725 5.12681 9.03449 5.03164L19.0345 2.03164C19.2616 1.96351 19.5075 2.00677 19.6977 2.14829ZM10 8.74198L18.5 6.19198V3.75803L10 6.30803V8.74198ZM6.5 16.5C5.39543 16.5 4.5 17.3954 4.5 18.5C4.5 19.6046 5.39543 20.5 6.5 20.5C7.60457 20.5 8.5 19.6046 8.5 18.5C8.5 17.3954 7.60457 16.5 6.5 16.5ZM14.5 16.5C14.5 17.6046 15.3954 18.5 16.5 18.5C17.6046 18.5 18.5 17.6046 18.5 16.5C18.5 15.3954 17.6046 14.5 16.5 14.5C15.3954 14.5 14.5 15.3954 14.5 16.5Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.25 4H17.75C19.483 4 20.8992 5.35645 20.9949 7.06558L21 7.25V16.75C21 18.483 19.6435 19.8992 17.9344 19.9949L17.75 20H6.25C4.51697 20 3.10075 18.6435 3.00514 16.9344L3 16.75V7.25C3 5.51697 4.35645 4.10075 6.06558 4.00514L6.25 4H17.75H6.25ZM17.75 5.5H6.25C5.33183 5.5 4.57881 6.20711 4.5058 7.10647L4.5 7.25V16.75C4.5 17.6682 5.20711 18.4212 6.10647 18.4942L6.25 18.5H17.75C18.6682 18.5 19.4212 17.7929 19.4942 16.8935L19.5 16.75V7.25C19.5 6.33183 18.7929 5.57881 17.8935 5.5058L17.75 5.5ZM10.0528 9.58541C10.1626 9.36586 10.4121 9.26237 10.6396 9.32882L10.7236 9.3618L15.1056 11.5528C15.2023 11.6012 15.2808 11.6796 15.3292 11.7764C15.439 11.9959 15.372 12.2576 15.1824 12.3998L15.1056 12.4472L10.7236 14.6382C10.6542 14.6729 10.5776 14.691 10.5 14.691C10.2545 14.691 10.0504 14.5141 10.0081 14.2809L10 14.191V9.80902C10 9.73139 10.0181 9.65484 10.0528 9.58541Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 994 B

View File

@@ -0,0 +1,3 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30.9968 12C33.7582 12 35.9968 14.2386 35.9968 17C35.9968 19.7614 33.7582 22 30.9968 22C28.2354 22 25.9968 19.7614 25.9968 17C25.9968 14.2386 28.2354 12 30.9968 12ZM28.4968 17C28.4968 18.3807 29.6161 19.5 30.9968 19.5C32.3775 19.5 33.4968 18.3807 33.4968 17C33.4968 15.6193 32.3775 14.5 30.9968 14.5C29.6161 14.5 28.4968 15.6193 28.4968 17ZM6 10.75C6 8.12665 8.12665 6 10.75 6H37.25C39.8734 6 42 8.12665 42 10.75V37.25C42 38.4377 41.5641 39.5236 40.8435 40.3565C40.7898 40.4531 40.7223 40.5441 40.641 40.6268C40.5548 40.7144 40.4589 40.7866 40.3566 40.8434C39.5238 41.564 38.4378 42 37.25 42H10.75C9.55998 42 8.47218 41.5624 7.63873 40.8393C7.53919 40.7832 7.44575 40.7123 7.36158 40.6268C7.28258 40.5466 7.21664 40.4583 7.16373 40.3648C6.43884 39.5309 6 38.4417 6 37.25V10.75ZM39.5 37.25V10.75C39.5 9.50736 38.4926 8.5 37.25 8.5H10.75C9.50736 8.5 8.5 9.50736 8.5 10.75V37.25C8.5 37.4065 8.51598 37.5592 8.54639 37.7067L21.3697 25.0851C22.8291 23.6486 25.171 23.6485 26.6306 25.0849L39.454 37.7048C39.4842 37.5579 39.5 37.4058 39.5 37.25ZM10.75 39.5H37.25C37.3948 39.5 37.5364 39.4863 37.6736 39.4602L24.877 26.8668C24.3905 26.388 23.6099 26.388 23.1234 26.8668L10.3284 39.4606C10.465 39.4865 10.6059 39.5 10.75 39.5Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,3 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.25 18C16.9404 18 17.5 18.5596 17.5 19.25V23H20.75C21.4404 23 22 23.5596 22 24.25C22 24.9404 21.4404 25.5 20.75 25.5H17.5V28.75C17.5 29.4404 16.9404 30 16.25 30C15.5596 30 15 29.4404 15 28.75V25.5H11.25C10.5596 25.5 10 24.9404 10 24.25C10 23.5596 10.5596 23 11.25 23H15V19.25C15 18.5596 15.5596 18 16.25 18ZM32 27.5C32 28.8807 30.8807 30 29.5 30C28.1193 30 27 28.8807 27 27.5C27 26.1193 28.1193 25 29.5 25C30.8807 25 32 26.1193 32 27.5ZM33.5 23C34.8807 23 36 21.8807 36 20.5C36 19.1193 34.8807 18 33.5 18C32.1193 18 31 19.1193 31 20.5C31 21.8807 32.1193 23 33.5 23ZM4 23.9998C4 16.2679 10.268 9.99985 18 9.99985H30C37.732 9.99985 44 16.2679 44 23.9998C44 31.7318 37.732 37.9998 30 37.9998H18C10.268 37.9998 4 31.7318 4 23.9998ZM18 12.4998C11.6487 12.4998 6.5 17.6486 6.5 23.9998C6.5 30.3511 11.6487 35.4998 18 35.4998H30C36.3513 35.4998 41.5 30.3511 41.5 23.9998C41.5 17.6486 36.3513 12.4998 30 12.4998H18Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.7499 2.00098C18.9407 2.00098 19.9155 2.92614 19.9947 4.09693L19.9999 4.25098V19.749C19.9999 20.9399 19.0747 21.9147 17.9039 21.9939L17.7499 21.999H6.25C5.05914 21.999 4.08436 21.0739 4.00519 19.9031L4 19.749V4.25098C4 3.06011 4.92516 2.08533 6.09595 2.00617L6.25 2.00098H17.7499ZM17.7499 3.50098H6.25C5.8703 3.50098 5.55651 3.78313 5.50685 4.14921L5.5 4.25098V19.749C5.5 20.1287 5.78215 20.4425 6.14823 20.4922L6.25 20.499H17.7499C18.1296 20.499 18.4434 20.2169 18.493 19.8508L18.4999 19.749V4.25098C18.4999 3.87128 18.2177 3.55749 17.8516 3.50782L17.7499 3.50098Z" fill="#212121"/>
<path d="M6.99994 15.75C6.99994 15.3358 7.33572 15 7.74994 15H16.2499C16.6642 15 16.9999 15.3358 16.9999 15.75C16.9999 16.1642 16.6642 16.5 16.2499 16.5H7.74994C7.33572 16.5 6.99994 16.1642 6.99994 15.75Z" fill="#212121"/>
<path d="M6.99994 7.75001C6.99994 7.3358 7.33572 7.00001 7.74994 7.00001H16.2499C16.6642 7.00001 16.9999 7.3358 16.9999 7.75001C16.9999 8.16422 16.6642 8.50001 16.2499 8.50001H7.74994C7.33572 8.50001 6.99994 8.16422 6.99994 7.75001Z" fill="#212121"/>
<path d="M6.99994 11.75C6.99994 11.3358 7.33572 11 7.74994 11H16.2499C16.6642 11 16.9999 11.3358 16.9999 11.75C16.9999 12.1642 16.6642 12.5 16.2499 12.5H7.74994C7.33572 12.5 6.99994 12.1642 6.99994 11.75Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.5416 8.60759L11.642 6.37799C11.8907 5.874 12.6094 5.874 12.8581 6.37799L13.9585 8.60759L16.419 8.96512C16.9752 9.04594 17.1972 9.72944 16.7948 10.1217L15.0143 11.8572L15.4347 14.3078C15.5297 14.8617 14.9482 15.2842 14.4508 15.0226L12.25 13.8656L10.0493 15.0226C9.55182 15.2842 8.9704 14.8617 9.06541 14.3078L9.48571 11.8572L7.70527 10.1217C7.30281 9.72944 7.5249 9.04594 8.08108 8.96512L10.5416 8.60759ZM11.6 9.52747C11.5012 9.72761 11.3103 9.86633 11.0894 9.89842L9.6358 10.1096L10.6876 11.1349C10.8474 11.2907 10.9204 11.5152 10.8826 11.7351L10.6343 13.1829L11.9345 12.4993C12.132 12.3955 12.368 12.3955 12.5656 12.4993L13.8657 13.1829L13.6174 11.7351C13.5797 11.5152 13.6526 11.2907 13.8124 11.1349L14.8643 10.1096L13.4107 9.89842C13.1898 9.86633 12.9989 9.72761 12.9001 9.52747L12.25 8.21029L11.6 9.52747Z" fill="#212121"/>
<path d="M6.5 2C5.11929 2 4 3.11929 4 4.5V19.5C4 20.8807 5.11929 22 6.5 22H19.75C20.1642 22 20.5 21.6642 20.5 21.25C20.5 20.8358 20.1642 20.5 19.75 20.5H6.5C5.94772 20.5 5.5 20.0523 5.5 19.5H19.75C20.1642 19.5 20.5 19.1642 20.5 18.75V4.5C20.5 3.11929 19.3807 2 18 2H6.5ZM19 18H5.5V4.5C5.5 3.94772 5.94772 3.5 6.5 3.5H18C18.5523 3.5 19 3.94772 19 4.5V18Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 5.25C2 3.45507 3.45507 2 5.25 2H16.75C18.5449 2 20 3.45507 20 5.25V8.00934C19.4951 7.95675 18.9878 7.99076 18.5 8.10566V7H3.5V16.75C3.5 17.7165 4.2835 18.5 5.25 18.5H13.2347L12.7935 19.2641C12.6577 19.4994 12.5652 19.7477 12.5135 20H5.25C3.45507 20 2 18.5449 2 16.75V5.25ZM5.25 3.5C4.2835 3.5 3.5 4.2835 3.5 5.25V5.5H18.5V5.25C18.5 4.2835 17.7165 3.5 16.75 3.5H5.25ZM19.8565 9C19.6411 8.98005 19.4255 8.9803 19.2123 9C18.1194 9.10098 17.0907 9.71296 16.5002 10.7357C15.7915 11.9632 15.9109 13.4415 16.685 14.5239L13.6595 19.7641C13.6153 19.8407 13.5788 19.9196 13.5499 20C13.3149 20.6516 13.5724 21.3977 14.1933 21.7562C14.8908 22.1589 15.7828 21.9199 16.1855 21.2224L19.2166 15.9724C20.5321 16.0903 21.8586 15.4548 22.5624 14.2357C23.3244 12.916 23.1291 11.3063 22.1921 10.2105L20.5417 13.0691C20.2195 13.6271 19.506 13.8183 18.948 13.4961C18.39 13.1739 18.1988 12.4604 18.521 11.9024L20.1714 9.04377C20.0667 9.0243 19.9616 9.00974 19.8565 9ZM10.3029 9.2432C10.5828 9.54854 10.5621 10.023 10.2568 10.3029L7.85992 12.5L10.2568 14.6971C10.5621 14.977 10.5828 15.4515 10.3029 15.7568C10.023 16.0621 9.54855 16.0828 9.24321 15.8029L6.24321 13.0529C6.08823 12.9108 6 12.7102 6 12.5C6 12.2898 6.08823 12.0892 6.24321 11.9471L9.24321 9.19713C9.54855 8.91724 10.023 8.93786 10.3029 9.2432ZM13.2568 15.8029L15.2766 13.9514C14.9587 13.0273 14.9412 12.0035 15.2685 11.0412L13.2568 9.19714C12.9515 8.91724 12.477 8.93787 12.1971 9.24321C11.9172 9.54855 11.9379 10.023 12.2432 10.3029L14.6401 12.5L12.2432 14.6971C11.9379 14.977 11.9172 15.4515 12.1971 15.7568C12.477 16.0621 12.9515 16.0828 13.2568 15.8029Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.5 5C5.22386 5 5 5.22386 5 5.5C5 5.77614 5.22386 6 5.5 6H10.5C10.7761 6 11 5.77614 11 5.5C11 5.22386 10.7761 5 10.5 5H5.5ZM5.5 7C5.22386 7 5 7.22386 5 7.5C5 7.77614 5.22386 8 5.5 8H8.5C8.77614 8 9 7.77614 9 7.5C9 7.22386 8.77614 7 8.5 7H5.5ZM5.5 9C5.22386 9 5 9.22386 5 9.5C5 9.77614 5.22386 10 5.5 10H10.5C10.7761 10 11 9.77614 11 9.5C11 9.22386 10.7761 9 10.5 9H5.5ZM4.5 2C3.11929 2 2 3.11929 2 4.5V11.5C2 12.8807 3.11929 14 4.5 14H11.5C12.8807 14 14 12.8807 14 11.5V4.5C14 3.11929 12.8807 2 11.5 2H4.5ZM3 4.5C3 3.67157 3.67157 3 4.5 3H11.5C12.3284 3 13 3.67157 13 4.5V11.5C13 12.3284 12.3284 13 11.5 13H4.5C3.67157 13 3 12.3284 3 11.5V4.5Z" fill="#212121"/>
</svg>

After

Width:  |  Height:  |  Size: 775 B

268
src/assets/icon/logo.svg Normal file
View File

@@ -0,0 +1,268 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="200mm"
height="200mm"
viewBox="0 0 200 200"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="deepin-community-store.svg">
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient1200">
<stop
style="stop-color:#000000;stop-opacity:0.1299435"
offset="0"
id="stop1196" />
<stop
style="stop-color:#dadada;stop-opacity:0.81960785"
offset="1"
id="stop1198" />
</linearGradient>
<linearGradient
id="linearGradient1138"
inkscape:collect="always">
<stop
id="stop1134"
offset="0"
style="stop-color:#99e7ea;stop-opacity:1" />
<stop
id="stop1136"
offset="1"
style="stop-color:#007ffc;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient1128">
<stop
style="stop-color:#99e7ea;stop-opacity:1"
offset="0"
id="stop1124" />
<stop
style="stop-color:#007ffc;stop-opacity:1"
offset="1"
id="stop1126" />
</linearGradient>
<inkscape:path-effect
effect="bspline"
id="path-effect960"
is_visible="true"
weight="33.333333"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1128"
id="radialGradient1130"
cx="100.35268"
cy="199.86011"
fx="100.35268"
fy="199.86011"
r="90.135414"
gradientTransform="matrix(1,0,0,0.98112945,0,3.7714702)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1138"
id="radialGradient1132"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.98112945,0,3.7714702)"
cx="100.35268"
cy="199.86011"
fx="100.35268"
fy="199.86011"
r="90.135414" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1200"
id="radialGradient1202"
cx="100.35268"
cy="199.86011"
fx="100.35268"
fy="199.86011"
r="90.135414"
gradientTransform="matrix(1,0,0,0.98112945,0,3.7714702)"
gradientUnits="userSpaceOnUse" />
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter1448">
<feFlood
flood-opacity="0.372549"
flood-color="rgb(145,145,145)"
result="flood"
id="feFlood1438" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite1440" />
<feGaussianBlur
in="composite1"
stdDeviation="5.2918"
result="blur"
id="feGaussianBlur1442" />
<feOffset
dx="0"
dy="0"
result="offset"
id="feOffset1444" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite1446" />
</filter>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter2201">
<feFlood
flood-opacity="0.372549"
flood-color="rgb(145,145,145)"
result="flood"
id="feFlood2191" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite2193" />
<feGaussianBlur
in="composite1"
stdDeviation="3.76995"
result="blur"
id="feGaussianBlur2195" />
<feOffset
dx="0"
dy="0"
result="offset"
id="feOffset2197" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite2199" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="120.33119"
inkscape:cy="507.94585"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1040"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-97)">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ebebeb;stroke-width:2.87003541;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter2201)"
id="rect2119"
width="162.54665"
height="170.16383"
x="20.431099"
y="112.51035"
rx="30"
ry="30" />
<circle
style="opacity:1;fill:#959595;fill-opacity:1;stroke:#e9e9e9;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path2121"
cx="58.208336"
cy="131.8244"
r="6.0476193" />
<circle
style="opacity:1;fill:#9c9c9c;fill-opacity:1;stroke:#eaeaea;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path2121-5"
cx="143.63095"
cy="133.71429"
r="6.0476193" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<path
style="fill:#ffc344;fill-opacity:1;stroke:none;stroke-width:0.3091144px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 94.205599,42.389243 c 0,0 11.145081,-0.157476 22.599701,6.928753 11.45465,7.086223 18.11074,13.857508 20.27783,18.266716 2.16708,4.409209 9.28755,12.125332 9.13277,26.297795 -0.15488,14.172433 -3.40543,23.620763 -8.97797,31.494323 -5.57254,7.87359 -15.63405,13.85751 -27.70786,14.17247 -12.073829,0.31494 -19.813453,-7.55863 -22.444927,-11.96786 -2.631469,-4.4092 -3.715019,-13.85751 -0.464377,-20.62877 3.250645,-6.77132 8.358796,-6.77132 10.061513,-6.14141 1.702724,0.6299 2.167092,1.5747 3.095852,3.30689 0.928749,1.73219 1.547929,1.41726 2.941089,0.47243 1.39311,-0.94484 1.85748,-2.04715 1.54792,-3.46439 -0.30958,-1.417253 -2.16711,-3.149433 -3.71505,-3.621853 -1.547909,-0.47241 -3.715016,-1.88966 -6.810869,-1.41721 -3.095848,0.47238 -9.132757,2.04711 -14.240906,8.975843 -5.108153,6.92875 -4.488988,17.63684 -1.393134,22.67593 3.095849,5.0391 8.977962,14.48739 21.980539,17.79431 13.00259,3.30693 34.05435,-6.45633 41.32959,-21.57361 7.27524,-15.1173 7.43004,-22.20352 7.12048,-34.643764 C 148.22821,76.875544 137.23793,58.293884 125.00933,51.522601 112.78073,44.751315 103.64797,40.814522 94.205599,42.389243 Z"
id="path1002"
inkscape:connector-curvature="0" />
<path
style="fill:#f06767;fill-opacity:1;stroke:none;stroke-width:0.3091144px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 100.67541,105.29647 c 0,0 -3.06474,-2.8951 -5.801108,2.22698 -2.736373,5.12205 -4.049827,9.68737 -1.313459,15.25486 2.736367,5.56745 8.428007,8.90792 17.184447,8.79659 8.75636,-0.11148 15.21419,-2.22699 19.0451,-8.5739 3.83094,-6.34692 6.7862,-11.02357 7.11457,-13.36191 0.32839,-2.33835 2.07965,0.33404 1.53239,2.33834 -0.54728,2.00426 -0.43783,5.9015 1.09454,5.12204 1.53237,-0.77942 2.73637,-2.00427 2.95526,-1.44753 0.21893,0.55673 -1.75127,4.00859 -2.68162,5.73449 -0.93039,1.7259 -3.83094,5.90153 -5.5275,7.51607 -1.69652,1.61458 -4.04981,3.89724 -6.84092,5.56747 -2.79109,1.67024 -7.11454,3.61887 -9.52255,4.06427 -2.40801,0.44539 -7.22403,1.39184 -9.96042,1.2805 -2.73635,-0.11137 -6.23892,-0.61243 -10.124558,-2.56104 -3.885645,-1.94859 -8.099657,-4.95505 -9.741479,-7.96148 -1.641825,-3.00643 -4.159283,-5.73449 -3.61201,-13.30623 0.547277,-7.57175 3.010008,-11.46899 4.870741,-13.25056 1.860731,-1.7816 4.597103,-2.56105 6.403105,-2.17131 1.806004,0.38971 2.955282,1.44755 3.393102,2.22697 0.43781,0.77944 1.149279,2.22699 1.532369,2.50538 z"
id="path1012"
inkscape:connector-curvature="0" />
<path
style="fill:#3f62eb;fill-opacity:1;stroke:none;stroke-width:0.3091144px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 128.47695,145.38219 c 0,0 13.13457,-7.6831 19.26404,-19.82016 6.12948,-12.13707 8.7564,-19.93152 7.99021,-31.84592 -0.76619,-11.914358 -2.62692,-6.012854 -0.54728,-11.134928 2.07964,-5.122074 -1.31345,-15.254857 0.10943,-15.922949 1.42292,-0.668097 4.48765,4.453971 5.3633,8.573903 0.87562,4.119922 4.70654,16.813721 1.64181,32.959394 -3.06472,16.14564 -10.28872,22.60391 -15.10475,26.94655 -4.81603,4.34261 -15.7615,11.91437 -17.40332,11.80302 -1.64183,-0.11148 -1.86073,-0.11148 -1.31348,-1.55891 z"
id="path1014"
inkscape:connector-curvature="0" />
<path
style="fill:#fce102;fill-opacity:1;stroke:none;stroke-width:0.3091144px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 104.83471,121.99883 c 0,0 7.00512,1.5589 12.36838,-1.78156 5.3633,-3.3405 9.5226,-8.79661 10.17931,-10.91225 0.65672,-2.11564 0.76619,1.89294 1.53236,-0.11125 0.76618,-2.00432 3.83093,-6.01288 2.29855,-15.366239 -1.53237,-9.35333 -1.64182,-9.798747 -4.48762,-14.809463 -2.84586,-5.010719 -9.63207,-11.91437 -13.79134,-14.141359 -4.15927,-2.226986 -9.96037,-5.567464 -17.950594,-5.344766 -7.990202,0.222699 -5.363286,-0.334048 -13.025124,1.002146 -7.661836,1.336187 -14.557491,5.010717 -16.856041,7.015006 -2.298552,2.004286 -8.428023,7.460405 -10.61712,10.46684 -2.189098,3.00643 -8.209113,9.798741 -11.383303,19.263442 -3.174189,9.464683 -4.487646,10.466823 -4.706555,16.702393 -0.21891,6.23557 0.547274,7.90578 -0.766185,8.46256 -1.31346,0.55673 -1.094547,-4.67668 -0.985094,-8.35123 0.109463,-3.6745 0.109463,-13.25056 4.925468,-23.940084 4.816015,-10.689538 13.353489,-19.597489 18.169503,-22.826622 4.816009,-3.229128 10.398208,-7.571752 19.045135,-9.687392 8.646933,-2.115635 17.293863,-1.781586 22.65716,-0.779443 5.3633,1.002145 13.68187,4.453974 18.1695,7.905802 4.48766,3.45183 9.41314,7.683099 13.13459,14.586765 3.72146,6.903648 4.70654,15.700251 4.59709,19.374771 -0.10943,3.674543 -1.97019,12.137103 -4.81601,16.257013 -2.84583,4.11993 -6.67674,9.0193 -10.61711,10.80089 -3.94039,1.78157 -8.75642,2.33833 -12.69675,0.55674 -3.94039,-1.78161 -3.72147,-2.44969 -4.3782,-4.34263 z"
id="path1016"
inkscape:connector-curvature="0" />
<path
style="fill:#5ed938;fill-opacity:1;stroke:none;stroke-width:0.3091144px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 104.83471,121.99883 c 0,0 5.54674,1.56707 10.22918,-0.55878 4.68248,-2.12587 6.4239,-4.17301 7.54615,-5.3934 1.12223,-1.22042 3.25064,-3.50376 3.83112,-4.56669 0.58046,-1.06292 1.19962,-1.69282 1.19962,-2.08649 0,-0.39369 -1.08353,-1.33853 -0.0386,-3.62186 1.04482,-2.28333 1.97361,-7.519273 1.50922,-9.881333 -0.46438,-2.362073 -1.54792,-15.471616 -10.83547,-24.211303 -9.28753,-8.739678 -18.497709,-9.763242 -18.497709,-9.763242 0,0 14.705309,4.645415 21.593569,18.739134 6.88828,14.093741 4.64376,23.148344 0.23218,28.659854 -4.41158,5.51151 -10.68068,6.14141 -12.38342,4.72415 -1.70268,-1.41725 -5.2113,6.47164 -4.38574,7.95996 z"
id="path1018"
inkscape:connector-curvature="0" />
<path
style="fill:#8fdbe9;fill-opacity:1;stroke:none;stroke-width:0.3091144px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 86.930353,71.44277 c 0,0 -9.906718,-0.07875 -17.414156,4.881616 -7.507436,4.960371 -11.14506,8.975903 -13.23476,12.125332 -2.089697,3.149446 -4.488981,7.479909 -4.179395,7.401179 0.309585,-0.0788 9.055364,-12.2828 15.866229,-15.432236 6.81087,-3.149436 13.621741,-7.558644 22.986687,-4.330482 9.364952,3.228184 13.776542,7.716118 15.788842,6.613829 2.0123,-1.1023 2.3993,-2.440824 1.23835,-3.936804 -1.16094,-1.495979 -9.364961,-8.818417 -21.051797,-7.322434 z"
id="path1020"
inkscape:connector-curvature="0" />
<path
style="fill:#fd7aff;fill-opacity:1;stroke:none;stroke-width:0.3091144px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 72.107699,134.35862 c 0.65673,0.33404 5.58219,8.90795 9.522571,10.35548 3.940372,1.44755 6.567286,1.55888 7.005104,2.227 0.437821,0.66809 0.328367,4.00858 3.830921,5.45614 3.502555,1.44753 19.920785,6.01284 24.627325,6.45824 4.70658,0.4454 0.76621,3.22911 3.61202,4.23125 2.84584,1.00217 14.99532,1.5589 17.95061,0.33405 2.95527,-1.22483 2.95527,1.1135 -2.1891,3.1178 -5.14437,2.00427 -18.71677,6.79231 -27.58261,5.67882 -8.86586,-1.1135 -19.373526,-3.00644 -25.284086,-7.23772 -5.910565,-4.23126 -8.42802,-6.1242 -6.238924,-6.45824 2.189096,-0.33407 7.990199,5.9015 10.507662,6.56959 2.517463,0.66809 4.597103,0.66809 3.064735,-0.8908 -1.532366,-1.55888 -11.492755,-8.46253 -12.477849,-8.1285 -0.985092,0.33405 -3.064737,0.55674 -4.816012,-1.78159 -1.751278,-2.33832 -10.945484,-15.25485 -10.39821,-22.1585 0.547273,-6.90365 2.298552,-5.12208 4.378195,-2.56103 2.079641,2.56103 4.487648,4.78801 4.487648,4.78801 z"
id="path1022"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#939393;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 56.889259,34.981831 c 0,0 16.252976,26.08036 43.845241,26.83631 27.59226,0.75596 42.33333,-23.8125 42.33333,-23.8125"
id="path2138"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/assets/tags/a2d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -0,0 +1,240 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="deepin-community-store.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
id="svg8"
version="1.1"
viewBox="0 0 200 200"
height="200mm"
width="200mm">
<defs
id="defs2">
<linearGradient
id="linearGradient1200"
inkscape:collect="always">
<stop
id="stop1196"
offset="0"
style="stop-color:#000000;stop-opacity:0.1299435" />
<stop
id="stop1198"
offset="1"
style="stop-color:#dadada;stop-opacity:0.81960785" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient1138">
<stop
style="stop-color:#99e7ea;stop-opacity:1"
offset="0"
id="stop1134" />
<stop
style="stop-color:#007ffc;stop-opacity:1"
offset="1"
id="stop1136" />
</linearGradient>
<linearGradient
id="linearGradient1128"
inkscape:collect="always">
<stop
id="stop1124"
offset="0"
style="stop-color:#99e7ea;stop-opacity:1" />
<stop
id="stop1126"
offset="1"
style="stop-color:#007ffc;stop-opacity:1" />
</linearGradient>
<inkscape:path-effect
only_selected="false"
apply_with_weight="true"
apply_no_weight="true"
helper_size="0"
steps="2"
weight="33.333333"
is_visible="true"
id="path-effect960"
effect="bspline" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.98112945,0,3.7714702)"
r="90.135414"
fy="199.86011"
fx="100.35268"
cy="199.86011"
cx="100.35268"
id="radialGradient1130"
xlink:href="#linearGradient1128"
inkscape:collect="always" />
<radialGradient
r="90.135414"
fy="199.86011"
fx="100.35268"
cy="199.86011"
cx="100.35268"
gradientTransform="matrix(1,0,0,0.98112945,0,3.7714702)"
gradientUnits="userSpaceOnUse"
id="radialGradient1132"
xlink:href="#linearGradient1138"
inkscape:collect="always" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.98112945,0,3.7714702)"
r="90.135414"
fy="199.86011"
fx="100.35268"
cy="199.86011"
cx="100.35268"
id="radialGradient1202"
xlink:href="#linearGradient1200"
inkscape:collect="always" />
<filter
id="filter1448"
inkscape:label="Drop Shadow"
style="color-interpolation-filters:sRGB;">
<feFlood
id="feFlood1438"
result="flood"
flood-color="rgb(145,145,145)"
flood-opacity="0.372549" />
<feComposite
id="feComposite1440"
result="composite1"
operator="in"
in2="SourceGraphic"
in="flood" />
<feGaussianBlur
id="feGaussianBlur1442"
result="blur"
stdDeviation="5.2918"
in="composite1" />
<feOffset
id="feOffset1444"
result="offset"
dy="0"
dx="0" />
<feComposite
id="feComposite1446"
result="composite2"
operator="over"
in2="offset"
in="SourceGraphic" />
</filter>
<filter
id="filter2201"
inkscape:label="Drop Shadow"
style="color-interpolation-filters:sRGB;">
<feFlood
id="feFlood2191"
result="flood"
flood-color="rgb(145,145,145)"
flood-opacity="0.372549" />
<feComposite
id="feComposite2193"
result="composite1"
operator="in"
in2="SourceGraphic"
in="flood" />
<feGaussianBlur
id="feGaussianBlur2195"
result="blur"
stdDeviation="3.76995"
in="composite1" />
<feOffset
id="feOffset2197"
result="offset"
dy="0"
dx="0" />
<feComposite
id="feComposite2199"
result="composite2"
operator="over"
in2="offset"
in="SourceGraphic" />
</filter>
</defs>
<sodipodi:namedview
inkscape:document-rotation="0"
inkscape:window-maximized="1"
inkscape:window-y="-8"
inkscape:window-x="-8"
inkscape:window-height="705"
inkscape:window-width="1366"
showgrid="false"
inkscape:current-layer="layer2"
inkscape:document-units="mm"
inkscape:cy="507.94585"
inkscape:cx="120.33119"
inkscape:zoom="0.35"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(0,-97)"
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1" />
<g
inkscape:label="Layer 2"
id="layer2"
inkscape:groupmode="layer">
<path
inkscape:connector-curvature="0"
id="path1002"
d="m 91.937746,32.561862 c 0,0 11.145084,-0.157476 22.599704,6.928753 11.45465,7.086223 18.11074,13.857508 20.27783,18.266716 2.16708,4.409213 9.28755,12.125333 9.13277,26.297793 -0.15488,14.17244 -3.40543,23.620766 -8.97797,31.494326 -5.57254,7.87359 -15.63405,13.85751 -27.70786,14.17247 -12.073834,0.31494 -19.813464,-7.55863 -22.444934,-11.96786 -2.63147,-4.4092 -3.71502,-13.85751 -0.46438,-20.628766 3.25065,-6.77132 8.3588,-6.77132 10.06152,-6.14141 1.70272,0.6299 2.16709,1.5747 3.09585,3.30689 0.92875,1.73219 1.54793,1.41726 2.941094,0.47243 1.39311,-0.94484 1.85748,-2.04715 1.54792,-3.46439 -0.30958,-1.41726 -2.167114,-3.14944 -3.715054,-3.62186 -1.54791,-0.47241 -3.71502,-1.88966 -6.81087,-1.41721 -3.09585,0.47238 -9.13276,2.04711 -14.24091,8.97585 -5.10815,6.928746 -4.48899,17.636836 -1.39313,22.675926 3.09585,5.0391 8.97796,14.48739 21.98054,17.79431 13.002594,3.30693 34.054354,-6.45633 41.329594,-21.57361 7.27524,-15.117296 7.43004,-22.203516 7.12048,-34.643766 C 145.96036,67.048164 134.97008,48.466503 122.74148,41.69522 110.51288,34.923934 101.38012,30.987141 91.937746,32.561862 Z"
style="fill:#ffc344;fill-opacity:1;stroke:none;stroke-width:0.309114px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1012"
d="m 98.407556,95.469094 c 0,0 -3.06474,-2.8951 -5.80111,2.22698 -2.73637,5.122046 -4.04983,9.687366 -1.31346,15.254856 2.73637,5.56745 8.42801,8.90792 17.184454,8.79659 8.75636,-0.11148 15.21419,-2.22699 19.0451,-8.5739 3.83094,-6.34692 6.7862,-11.02357 7.11457,-13.361906 0.32839,-2.33835 2.07965,0.334036 1.53239,2.338336 -0.54728,2.00426 -0.43783,5.9015 1.09454,5.12204 1.53237,-0.77942 2.73637,-2.00427 2.95526,-1.44753 0.21893,0.55673 -1.75127,4.00859 -2.68162,5.73449 -0.93039,1.7259 -3.83094,5.90153 -5.5275,7.51607 -1.69652,1.61458 -4.04981,3.89724 -6.84092,5.56747 -2.79109,1.67024 -7.11454,3.61887 -9.52255,4.06427 -2.40801,0.44539 -7.22403,1.39184 -9.96042,1.2805 -2.73635,-0.11137 -6.238924,-0.61243 -10.124564,-2.56104 -3.88565,-1.94859 -8.09966,-4.95505 -9.74148,-7.96148 -1.64182,-3.00643 -4.15928,-5.73449 -3.61201,-13.30623 0.54728,-7.571746 3.01001,-11.468986 4.87074,-13.250556 1.86073,-1.7816 4.5971,-2.56105 6.40311,-2.17131 1.806,0.38971 2.95528,1.44755 3.3931,2.22697 0.43781,0.77944 1.14928,2.22699 1.53237,2.50538 z"
style="fill:#f06767;fill-opacity:1;stroke:none;stroke-width:0.309114px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1014"
d="m 126.2091,135.55481 c 0,0 13.13457,-7.6831 19.26404,-19.82016 6.12948,-12.13707 8.7564,-19.931516 7.99021,-31.845916 -0.76619,-11.91436 -2.62692,-6.01286 -0.54728,-11.13493 2.07964,-5.12208 -1.31345,-15.25486 0.10943,-15.922952 1.42292,-0.668097 4.48765,4.453972 5.3633,8.573902 0.87562,4.11992 4.70654,16.81372 1.64181,32.9594 -3.06472,16.145636 -10.28872,22.603906 -15.10475,26.946546 -4.81603,4.34261 -15.7615,11.91437 -17.40332,11.80302 -1.64183,-0.11148 -1.86073,-0.11148 -1.31348,-1.55891 z"
style="fill:#3f62eb;fill-opacity:1;stroke:none;stroke-width:0.309114px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1016"
d="m 102.56686,112.17145 c 0,0 7.00512,1.5589 12.36838,-1.78156 5.3633,-3.3405 9.5226,-8.79661 10.17931,-10.912246 0.65672,-2.11564 0.76619,1.892936 1.53236,-0.11125 0.76618,-2.00432 3.83093,-6.01288 2.29855,-15.36624 -1.53237,-9.35333 -1.64182,-9.79875 -4.48762,-14.80947 -2.84586,-5.01072 -9.63207,-11.914367 -13.79134,-14.141356 -4.15927,-2.226986 -9.96037,-5.567464 -17.950604,-5.344766 -7.9902,0.222699 -5.36328,-0.334048 -13.02512,1.002146 -7.66184,1.336187 -14.55749,5.010717 -16.85604,7.015006 -2.29855,2.004286 -8.42802,7.46041 -10.61712,10.46684 -2.1891,3.00643 -8.20911,9.79874 -11.3833,19.26344 -3.17419,9.46469 -4.48765,10.46683 -4.70656,16.702396 -0.21891,6.23557 0.54727,7.90578 -0.76618,8.46256 -1.31346,0.55673 -1.09455,-4.67668 -0.9851,-8.35123 0.10946,-3.6745 0.10946,-13.250556 4.92547,-23.940086 4.81601,-10.68954 13.35349,-19.59749 18.1695,-22.826621 4.81601,-3.229128 10.39821,-7.571752 19.04514,-9.687392 8.64693,-2.115635 17.29386,-1.781586 22.65716,-0.779443 5.363304,1.002145 13.681874,4.453974 18.169504,7.905802 4.48766,3.45183 9.41314,7.683104 13.13459,14.586764 3.72146,6.90365 4.70654,15.70025 4.59709,19.37477 -0.10943,3.67455 -1.97019,12.137106 -4.81601,16.257016 -2.84583,4.11993 -6.67674,9.0193 -10.61711,10.80089 -3.94039,1.78157 -8.75642,2.33833 -12.69675,0.55674 -3.94039,-1.78161 -3.72147,-2.44969 -4.3782,-4.34263 z"
style="fill:#fce102;fill-opacity:1;stroke:none;stroke-width:0.309114px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1018"
d="m 102.56686,112.17145 c 0,0 5.54674,1.56707 10.22918,-0.55878 4.68248,-2.12587 6.4239,-4.17301 7.54615,-5.3934 1.12223,-1.22042 3.25064,-3.50376 3.83112,-4.56669 0.58046,-1.06292 1.19962,-1.692816 1.19962,-2.086486 0,-0.39369 -1.08353,-1.33853 -0.0386,-3.62186 1.04482,-2.28333 1.97361,-7.51928 1.50922,-9.88134 -0.46438,-2.36207 -1.54792,-15.47161 -10.83547,-24.2113 -9.28753,-8.739679 -18.497714,-9.763243 -18.497714,-9.763243 0,0 14.705314,4.645415 21.593574,18.739133 6.88828,14.09374 4.64376,23.14835 0.23218,28.65986 -4.41158,5.511506 -10.68068,6.141406 -12.38342,4.724146 -1.70268,-1.41725 -5.2113,6.47164 -4.38574,7.95996 z"
style="fill:#5ed938;fill-opacity:1;stroke:none;stroke-width:0.309114px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1020"
d="m 84.662496,61.615394 c 0,0 -9.90672,-0.0787 -17.41416,4.88161 -7.50743,4.96037 -11.14506,8.9759 -13.23476,12.12533 -2.08969,3.14945 -4.48898,7.47991 -4.17939,7.40118 0.30958,-0.0788 9.05536,-12.2828 15.86623,-15.43223 6.81087,-3.14944 13.62174,-7.55865 22.98669,-4.33049 9.36495,3.22819 13.776544,7.71612 15.788844,6.61383 2.0123,-1.1023 2.3993,-2.44082 1.23835,-3.9368 -1.16094,-1.49598 -9.364964,-8.81842 -21.051804,-7.32243 z"
style="fill:#8fdbe9;fill-opacity:1;stroke:none;stroke-width:0.309114px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1022"
d="m 69.839846,124.53124 c 0.65673,0.33404 5.58219,8.90795 9.52257,10.35548 3.94037,1.44755 6.56728,1.55888 7.0051,2.227 0.43782,0.66809 0.32837,4.00858 3.83092,5.45614 3.50256,1.44753 19.920794,6.01284 24.627334,6.45824 4.70658,0.4454 0.76621,3.22911 3.61202,4.23125 2.84584,1.00217 14.99532,1.5589 17.95061,0.33405 2.95527,-1.22483 2.95527,1.1135 -2.1891,3.1178 -5.14437,2.00427 -18.71677,6.79231 -27.58261,5.67882 -8.865864,-1.1135 -19.373534,-3.00644 -25.284094,-7.23772 -5.91056,-4.23126 -8.42802,-6.1242 -6.23892,-6.45824 2.18909,-0.33407 7.9902,5.9015 10.50766,6.56959 2.51746,0.66809 4.5971,0.66809 3.06473,-0.8908 -1.53236,-1.55888 -11.49275,-8.46253 -12.47784,-8.1285 -0.9851,0.33405 -3.06474,0.55674 -4.81602,-1.78159 -1.75127,-2.33832 -10.94548,-15.25485 -10.39821,-22.1585 0.54728,-6.90365 2.29856,-5.12208 4.3782,-2.56103 2.07964,2.56103 4.48765,4.78801 4.48765,4.78801 z"
style="fill:#fd7aff;fill-opacity:1;stroke:none;stroke-width:0.309114px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,35 @@
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path d="m17,129c0,-61.30371 49.69629,-111 111,-111c61.30371,0 111,49.69629 111,111c0,61.30371 -49.69629,111 -111,111c-61.30371,0 -111,-49.69629 -111,-111z" id="deepin-launcher-b"/>
<filter filterUnits="objectBoundingBox" y="-6.3%" x="-8.1%" height="116.2%" width="116.2%" id="deepin-launcher-a">
<feGaussianBlur stdDeviation="5"/>
</filter>
<path d="m172.29023,47.20405c-13.1683,-7.14564 -28.25541,-11.20405 -44.29023,-11.20405c-3.85759,0 -7.66034,0.23489 -11.39471,0.69114c-13.8375,19.06416 -21.01047,50.16415 -20.43985,69.1948c0,0 -0.90954,28.19993 18.37748,38.20231c0,0 17.33291,7.61701 29.14502,-17.01295c0,0 8.11834,-13.89983 4.81381,-45.31395c0,0 3.16155,0.55793 3.51901,1.05927c0.35746,0.49728 6.98241,24.18523 2.32747,44.13339c0,0 -4.28556,23.44132 -25.35592,28.80234c-21.06242,5.36102 -37.47784,-7.60893 -48.62269,-19.82688c-8.29983,-9.09853 -20.62176,-33.53254 -26.69028,-62.84231c-11.72709,15.56323 -18.67934,34.92741 -18.67934,55.91495c0,14.49236 3.31502,28.21045 9.22816,40.43737c20.53097,6.06549 72.70224,17.88328 105.89216,-6.44123c21.96964,-16.10443 19.13893,-41.89451 19.13893,-41.89451c-0.36372,-19.61754 -12.30727,-39.10374 -12.30727,-39.10374c46.44186,42.01354 18.99265,88.68931 18.99265,88.68931c-12.77926,26.10154 -39.04908,42.79526 -62.02961,50.25104c4.59324,0.69782 9.29685,1.05965 14.08498,1.05965c51.36266,0 93,-41.63639 93,-92.99789c0,-21.72407 -7.44877,-41.70884 -19.93152,-57.53933c-4.54487,0.31322 -9.825,0.49664 -15.30337,0.31684c0,0 -24.70889,1.15387 -38.56418,8.0646c0,0 -10.33212,4.60716 -20.65999,12.41858c0,0 -2.19192,1.09575 -2.08593,5.12183c0.09327,4.01362 -2.10288,14.71385 -9.42058,20.98539c0,0 -5.22329,2.68544 -2.61165,6.52889c0,0 3.52742,5.12183 8.49633,-0.25734c0,0 12.81233,-13.18228 13.59668,-34.42501c0,0 4.05314,-3.4616 10.45506,-4.48264c0,0 1.17863,31.86824 -14.63539,47.86878c0,0 -15.04241,16.38239 -19.87565,-7.93593c0,0 -5.88469,-23.16861 24.45027,-50.68289c0,0 20.448,-20.42091 32.46751,-29.98388c1.66104,0.69233 3.29908,1.42749 4.91265,2.20406l-0.00001,-0.00001zm-44.29023,183.79595c-56.33322,0 -102,-45.66583 -102,-101.99789c0,-56.33281 45.66752,-102.00211 102,-102.00211c56.33248,0 102,45.6693 102,102.00211c0,56.33206 -45.66678,101.99789 -102,101.99789z" id="deepin-launcher-f"/>
<filter filterUnits="objectBoundingBox" y="-.5%" x="-.5%" height="102%" width="101%" id="deepin-launcher-e"/>
<filter filterUnits="objectBoundingBox" y="-.5%" x="-.5%" height="102%" width="101%" id="deepin-launcher-g"/>
<linearGradient y2="97.178%" y1="4.64%" x2="50%" x1="50%" id="deepin-launcher-c">
<stop stop-color="#00ABFF" offset="0%"/>
<stop stop-color="#0163FA" offset="100%"/>
</linearGradient>
<linearGradient y2="100%" y1="0%" x2="50%" x1="50%" id="deepin-launcher-d">
<stop stop-color="#32BBFF" offset="0%"/>
<stop stop-color="#004FC5" offset="100%"/>
</linearGradient>
</defs>
<g>
<title>background</title>
<rect fill="none" id="canvas_background" height="514" width="514" y="-1" x="-1"/>
</g>
<g>
<title>Layer 1</title>
<g stroke="null" id="svg_1" fill-rule="evenodd" fill="none">
<use x="0" y="0" transform="matrix(2.15315318107605,0,0,2.15315318107605,-19.603604078292847,-20.756757259368896) " stroke="null" id="svg_2" xlink:href="#deepin-launcher-b" filter="url(#deepin-launcher-a)" fill="#000"/>
<use x="0" y="0" transform="matrix(2.15315318107605,0,0,2.15315318107605,-19.603604078292847,-20.756757259368896) " stroke="url(#deepin-launcher-d)" id="svg_3" xlink:href="#deepin-launcher-b" stroke-width="2" fill="url(#deepin-launcher-c)"/>
<g stroke="null" id="svg_4" fill-rule="nonzero">
<use x="0" y="0" transform="matrix(2.15315318107605,0,0,2.15315318107605,-19.603604078292847,-20.756757259368896) " stroke="null" id="svg_5" xlink:href="#deepin-launcher-f" filter="url(#deepin-launcher-e)" fill="#000"/>
<use x="0" y="0" transform="matrix(2.15315318107605,0,0,2.15315318107605,-19.603604078292847,-20.756757259368896) " stroke="null" id="svg_6" xlink:href="#deepin-launcher-f" fill="#F0F9FF"/>
<use x="0" y="0" transform="matrix(2.15315318107605,0,0,2.15315318107605,-19.603604078292847,-20.756757259368896) " stroke="null" id="svg_7" xlink:href="#deepin-launcher-f" filter="url(#deepin-launcher-g)" fill="#000"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View 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

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>logo icon</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#00F1FF" offset="0%"></stop>
<stop stop-color="#008AFF" offset="100%"></stop>
</linearGradient>
</defs>
<g id="light" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1" transform="translate(-460.000000, -159.000000)">
<g id="tittlebar" transform="translate(450.000000, 150.000000)">
<g id="logo-icon" transform="translate(10.000000, 9.000000)">
<g>
<rect id="矩形" fill="url(#linearGradient-1)" x="0" y="0" width="32" height="32" rx="8"></rect>
<path d="M23,25 L23,24.0002278 C21.6666667,24.0002278 21,24.0002278 21,24.0002278 L21,20 L22,20 L22,19 L21,19 L21,17 L20,17.5 L20,19 L19,19 L19,20 L20,20 L20,24.0002278 C20,24.0002278 20,24.0002278 20,24.0002278 C20,24.5523868 20.4476132,25 20.9997722,25 C20.9998481,25 20.9999241,25 21,25 L23,25 Z M24.0210414,23.9789586 L24.0210414,22.2215556 L24.0210414,22.2215556 L24.6565969,21.6226667 L27.2207674,25 L29.0052118,25 L25.6099302,20.7304444 L28.4678057,18.0074755 L26.6711391,18.0074755 L24.0210414,20.6204444 L24,15.5 L23,15 L23,25 C23.5639056,25 24.0210414,24.5428642 24.0210414,23.9789586 Z" id="tk" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M10.275,24 C13.175,24 15.35,23.2 16.85,21.6 C18.275,20.075 19,17.825 19,15 C19,12.15 18.275,10.05 16.85,8.55 C15.35,6.95 13.175,6 10.275,6 L4,6 L4,24 L10.275,24 Z M9.725,21 L7,21 L7,9 L9.725,9 C11.95,9 13.575,9.15 14.6,10.175 C15.6,11.175 16,12.75 16,15 C16,17.2 15.6,18.9 14.6,19.95 C13.575,20.975 11.95,21 9.725,21 Z" id="D" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
src/assets/tags/ubuntu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

13
src/assets/tags/uos.svg Normal file
View 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

View File

@@ -1,248 +1,248 @@
#include "downloadworker.h"
#include <QEventLoop>
#include <QProcess>
#include <QRegularExpression>
#include <QDir>
#include <QtConcurrent>
DownloadController::DownloadController(QObject *parent)
{
Q_UNUSED(parent)
// 初始化默认域名
domains.clear();
domains.append("d.store.deepinos.org.cn");
/*
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();
}
void DownloadController::setFilename(QString filename)
{
this->filename = filename;
}
bool checkMeatlink(QString metaUrl)
{
QFile metaStatus("/tmp/spark-store/metaStatus.txt");
if (metaStatus.exists())
{
metaStatus.remove();
}
system("curl -I -s --connect-timeout 5 " + metaUrl.toUtf8() + " -w %{http_code} |tail -n1 > /tmp/spark-store/metaStatus.txt");
if (metaStatus.open(QFile::ReadOnly) && QString(metaStatus.readAll()).toUtf8() == "200")
{
metaStatus.remove();
return true;
}
return false;
}
void gennerateDomain(QVector<QString> &domains)
{
QFile serverList(QDir::homePath().toUtf8() + "/.config/spark-store/server.list");
if (serverList.open(QFile::ReadOnly))
{
QStringList list = QString(serverList.readAll()).trimmed().split("\n");
qDebug() << list << list.size();
domains.clear();
for (int i = 0; i < list.size(); i++)
{
if (list.at(i).contains("镜像源 Download only") && i + 1 < list.size())
{
for (int j = i + 1; j < list.size(); j++)
{
domains.append(list.at(j));
}
break;
}
}
if (domains.size() == 0)
{
domains.append("d.store.deepinos.org.cn");
}
}
}
/**
* @brief
*/
void DownloadController::startDownload(const QString &url)
{
// 获取下载任务信息
fileSize = getFileSize(url);
if (fileSize == 0)
{
emit errorOccur("文件大小获取失败");
return;
}
QtConcurrent::run([=]()
{
QString metaUrl = url + ".metalink";
qDebug() << "metalink" << metaUrl;
bool useMetalink = false;
if (checkMeatlink(metaUrl)){
useMetalink = true;
qDebug() << "useMetalink:" << useMetalink;
}else{
gennerateDomain(domains);
// qDebug() << domains << domains.size();
}
QString aria2Command = "-d";
QString aria2Urls = "";
QString aria2Verbose = "--summary-interval=1";
QString aria2SizePerThreads = "--min-split-size=1M";
QString aria2NoConfig = "--no-conf";
QString aria2NoSeeds = "--seed-time=0";
QStringList command;
QString downloadDir = "/tmp/spark-store/";
QString aria2ConnectionPerServer = "--max-connection-per-server=1";
QString aria2ConnectionMax = "--max-concurrent-downloads=16";
QString aria2DNSCommand = "--async-dns-server=119.29.29.29,223.5.5.5";
if (useMetalink){
command.append(metaUrl.toUtf8());
}
else{
for (int i = 0; i < domains.size(); i++)
{
command.append(replaceDomain(url, domains.at(i)).replace("+","%2B").toUtf8()); //对+进行转译避免oss出错
}
}
qint64 downloadSizeRecord = 0;
QString speedInfo = "";
QString percentInfo = "";
command.append(aria2Command.toUtf8());
command.append(downloadDir.toUtf8());
command.append(aria2Verbose.toUtf8());
command.append(aria2NoConfig.toUtf8());
command.append(aria2SizePerThreads.toUtf8());
command.append(aria2ConnectionPerServer.toUtf8());
command.append(aria2ConnectionMax.toUtf8());
command.append(aria2DNSCommand.toUtf8());
if (useMetalink){
command.append(aria2NoSeeds.toUtf8());
}
qDebug() << command;
auto cmd = new QProcess();
cmd->setProcessChannelMode(QProcess::MergedChannels);
cmd->setProgram("aria2c");
cmd->setArguments(command);
cmd->start();
cmd->waitForStarted(); //等待启动完成
QObject::connect(cmd, &QProcess::readyReadStandardOutput,
[&]()
{
//通过读取输出计算下载速度
QString message = cmd->readAllStandardOutput().data();
// qDebug() << message;
message = message.replace(" ", "");
QStringList list;
qint64 downloadSize = 0;
int downloadSizePlace1 = message.indexOf("(");
int downloadSizePlace2 = message.indexOf(")");
int speedPlace1 = message.indexOf("DL:");
int speedPlace2 = message.indexOf("ETA");
if (downloadSizePlace1 != -1 && downloadSizePlace2 != -1)
{
percentInfo = message.mid(downloadSizePlace1 + 1, downloadSizePlace2 - downloadSizePlace1 - 1).replace("%", "");
if (percentInfo != "s")
{
int percentInfoNumber = percentInfo.toUInt();
downloadSize = percentInfoNumber * fileSize / 100;
}
}
if (speedPlace1 != -1 && speedPlace2 != -1 && speedPlace2 - speedPlace1 <= 15)
{
speedInfo = message.mid(speedPlace1 + 3, speedPlace2 - speedPlace1 - 3);
speedInfo += "/s";
}
// qDebug() << percentInfo << speedInfo;
if (downloadSize >= downloadSizeRecord)
{
downloadSizeRecord = downloadSize;
}
if (percentInfo == "OK")
{
finished = true;
emit downloadProcess("", fileSize, fileSize);
qDebug() << "finished:" << finished;
}
else
{
emit downloadProcess(speedInfo, downloadSizeRecord, fileSize);
}
});
QObject::connect(cmd, &QProcess::readyReadStandardError,
[&]()
{
emit errorOccur(cmd->readAllStandardError().data());
return;
});
auto pidNumber = cmd->processId();
this->pidNumber = pidNumber;
while (cmd->waitForFinished(-1))
{
continue;
}
// 统计下载量
QString SenderdPath = "/opt/durapps/spark-store/bin/ss-feedback/sender-d";
/*
* https://en.wikipedia.org/wiki/HD_70642
* HD 70642 is a star with an exoplanetary companion in the southern constellation of Puppis.
*/
QProcess mailProcess;
mailProcess.start(SenderdPath.toUtf8() + " " + metaUrl.toUtf8() + " " + "HD70642");
mailProcess.waitForStarted();
mailProcess.waitForFinished(3);
mailProcess.deleteLater();
emit downloadFinished(); });
}
/**
* @brief
*/
void DownloadController::stopDownload()
{
// 实现下载进程退出
QString killCmd = QString("kill -9 %1").arg(pidNumber);
system(killCmd.toUtf8());
qDebug() << "kill aria2!";
}
qint64 DownloadController::getFileSize(const QString &url)
{
// 已经无需使用 qtnetwork 再获取 filesize完全交给 aria2 来计算进度。 为保证兼容性,故保留此函数。
qint64 fileSize = 10000;
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;
}
#include "downloadworker.h"
#include <QEventLoop>
#include <QProcess>
#include <QRegularExpression>
#include <QDir>
#include <QtConcurrent>
DownloadController::DownloadController(QObject *parent)
{
Q_UNUSED(parent)
// 初始化默认域名
domains.clear();
domains.append("d.store.deepinos.org.cn");
/*
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();
}
void DownloadController::setFilename(QString filename)
{
this->filename = filename;
}
bool checkMeatlink(QString metaUrl)
{
QFile metaStatus("/tmp/spark-store/metaStatus.txt");
if (metaStatus.exists())
{
metaStatus.remove();
}
system("curl -I -s --connect-timeout 5 " + metaUrl.toUtf8() + " -w %{http_code} |tail -n1 > /tmp/spark-store/metaStatus.txt");
if (metaStatus.open(QFile::ReadOnly) && QString(metaStatus.readAll()).toUtf8() == "200")
{
metaStatus.remove();
return true;
}
return false;
}
void gennerateDomain(QVector<QString> &domains)
{
QFile serverList(QDir::homePath().toUtf8() + "/.config/spark-store/server.list");
if (serverList.open(QFile::ReadOnly))
{
QStringList list = QString(serverList.readAll()).trimmed().split("\n");
qDebug() << list << list.size();
domains.clear();
for (int i = 0; i < list.size(); i++)
{
if (list.at(i).contains("镜像源 Download only") && i + 1 < list.size())
{
for (int j = i + 1; j < list.size(); j++)
{
domains.append(list.at(j));
}
break;
}
}
if (domains.size() == 0)
{
domains.append("d.store.deepinos.org.cn");
}
}
}
/**
* @brief
*/
void DownloadController::startDownload(const QString &url)
{
// 获取下载任务信息
fileSize = getFileSize(url);
if (fileSize == 0)
{
emit errorOccur("文件大小获取失败");
return;
}
QtConcurrent::run([=]()
{
QString metaUrl = url + ".metalink";
qDebug() << "metalink" << metaUrl;
bool useMetalink = false;
if (checkMeatlink(metaUrl)){
useMetalink = true;
qDebug() << "useMetalink:" << useMetalink;
}else{
gennerateDomain(domains);
// qDebug() << domains << domains.size();
}
QString aria2Command = "-d";
QString aria2Urls = "";
QString aria2Verbose = "--summary-interval=1";
QString aria2SizePerThreads = "--min-split-size=1M";
QString aria2NoConfig = "--no-conf";
QString aria2NoSeeds = "--seed-time=0";
QStringList command;
QString downloadDir = "/tmp/spark-store/";
QString aria2ConnectionPerServer = "--max-connection-per-server=1";
QString aria2ConnectionMax = "--max-concurrent-downloads=16";
QString aria2DNSCommand = "--async-dns-server=119.29.29.29,223.5.5.5";
if (useMetalink){
command.append(metaUrl.toUtf8());
}
else{
for (int i = 0; i < domains.size(); i++)
{
command.append(replaceDomain(url, domains.at(i)).replace("+","%2B").toUtf8()); //对+进行转译避免oss出错
}
}
qint64 downloadSizeRecord = 0;
QString speedInfo = "";
QString percentInfo = "";
command.append(aria2Command.toUtf8());
command.append(downloadDir.toUtf8());
command.append(aria2Verbose.toUtf8());
command.append(aria2NoConfig.toUtf8());
command.append(aria2SizePerThreads.toUtf8());
command.append(aria2ConnectionPerServer.toUtf8());
command.append(aria2ConnectionMax.toUtf8());
command.append(aria2DNSCommand.toUtf8());
if (useMetalink){
command.append(aria2NoSeeds.toUtf8());
}
qDebug() << command;
auto cmd = new QProcess();
cmd->setProcessChannelMode(QProcess::MergedChannels);
cmd->setProgram("aria2c");
cmd->setArguments(command);
cmd->start();
cmd->waitForStarted(); //等待启动完成
QObject::connect(cmd, &QProcess::readyReadStandardOutput,
[&]()
{
//通过读取输出计算下载速度
QString message = cmd->readAllStandardOutput().data();
// qDebug() << message;
message = message.replace(" ", "");
QStringList list;
qint64 downloadSize = 0;
int downloadSizePlace1 = message.indexOf("(");
int downloadSizePlace2 = message.indexOf(")");
int speedPlace1 = message.indexOf("DL:");
int speedPlace2 = message.indexOf("ETA");
if (downloadSizePlace1 != -1 && downloadSizePlace2 != -1)
{
percentInfo = message.mid(downloadSizePlace1 + 1, downloadSizePlace2 - downloadSizePlace1 - 1).replace("%", "");
if (percentInfo != "s")
{
int percentInfoNumber = percentInfo.toUInt();
downloadSize = percentInfoNumber * fileSize / 100;
}
}
if (speedPlace1 != -1 && speedPlace2 != -1 && speedPlace2 - speedPlace1 <= 15)
{
speedInfo = message.mid(speedPlace1 + 3, speedPlace2 - speedPlace1 - 3);
speedInfo += "/s";
}
// qDebug() << percentInfo << speedInfo;
if (downloadSize >= downloadSizeRecord)
{
downloadSizeRecord = downloadSize;
}
if (percentInfo == "OK")
{
finished = true;
emit downloadProcess("", fileSize, fileSize);
qDebug() << "finished:" << finished;
}
else
{
emit downloadProcess(speedInfo, downloadSizeRecord, fileSize);
}
});
QObject::connect(cmd, &QProcess::readyReadStandardError,
[&]()
{
emit errorOccur(cmd->readAllStandardError().data());
return;
});
auto pidNumber = cmd->processId();
this->pidNumber = pidNumber;
while (cmd->waitForFinished(-1))
{
continue;
}
// 统计下载量
QString SenderdPath = "/opt/durapps/spark-store/bin/ss-feedback/sender-d";
/*
* https://en.wikipedia.org/wiki/HD_70642
* HD 70642 is a star with an exoplanetary companion in the southern constellation of Puppis.
*/
QProcess mailProcess;
mailProcess.start(SenderdPath.toUtf8() + " " + metaUrl.toUtf8() + " " + "HD70642");
mailProcess.waitForStarted();
mailProcess.waitForFinished(3);
mailProcess.deleteLater();
emit downloadFinished(); });
}
/**
* @brief
*/
void DownloadController::stopDownload()
{
// 实现下载进程退出
QString killCmd = QString("kill -9 %1").arg(pidNumber);
system(killCmd.toUtf8());
qDebug() << "kill aria2!";
}
qint64 DownloadController::getFileSize(const QString &url)
{
// 已经无需使用 qtnetwork 再获取 filesize完全交给 aria2 来计算进度。 为保证兼容性,故保留此函数。
qint64 fileSize = 10000;
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;
}

View File

@@ -1,41 +1,41 @@
#ifndef DOWNLOADWORKER_H
#define DOWNLOADWORKER_H
#include <QObject>
#include <QList>
#include <QFile>
#include <QNetworkReply>
class DownloadController : public QObject
{
Q_OBJECT
public:
explicit DownloadController(QObject *parent = nullptr);
void setFilename(QString filename);
void startDownload(const QString &url);
void stopDownload();
qint64 getFileSize(const QString& url);
QString replaceDomain(const QString& url, const QString domain);
private:
int threadNum;
int pidNumber;
QString filename;
qint64 fileSize;
QVector<QPair<qint64, qint64>> ranges;
QFile *file;
bool finished = false;
QVector<QString> domains;
signals:
void errorOccur(const QString& msg);
void downloadProcess(QString, qint64, qint64);
void downloadFinished();
};
#endif // FILEDOWNLOADWORKER_H
#ifndef DOWNLOADWORKER_H
#define DOWNLOADWORKER_H
#include <QObject>
#include <QList>
#include <QFile>
#include <QNetworkReply>
class DownloadController : public QObject
{
Q_OBJECT
public:
explicit DownloadController(QObject *parent = nullptr);
void setFilename(QString filename);
void startDownload(const QString &url);
void stopDownload();
qint64 getFileSize(const QString& url);
QString replaceDomain(const QString& url, const QString domain);
private:
int threadNum;
int pidNumber;
QString filename;
qint64 fileSize;
QVector<QPair<qint64, qint64>> ranges;
QFile *file;
bool finished = false;
QVector<QString> domains;
signals:
void errorOccur(const QString& msg);
void downloadProcess(QString, qint64, qint64);
void downloadFinished();
};
#endif // FILEDOWNLOADWORKER_H

View File

@@ -13,6 +13,7 @@ image_show::image_show(QWidget *parent) :
layout->addWidget(m_label);
setLayout(layout);
m_label->setText("layout");
m_label->setScaledContents(true);
}
void image_show::setImage(QPixmap image)
@@ -49,3 +50,8 @@ void image_show::mousePressEvent(QMouseEvent *)
m_dialog->move(0,0);
}
image_show::~image_show()
{
delete m_dialog;
delete m_label;
}

View File

@@ -4,7 +4,7 @@
#include <QWidget>
#include <QMouseEvent>
#include "big_image.h"
#include "widgets/big_image.h"
class image_show : public QWidget
{
@@ -17,6 +17,7 @@ public:
int desktop_h;
void setImage(QPixmap);
~image_show();
protected:
void mousePressEvent(QMouseEvent *event) override;
@@ -26,7 +27,6 @@ private:
QLabel *m_label;
QLabel image;
QPixmap m_image;
};
#endif // IMAGE_SHOW_H

49
src/backend/sparkapi.cpp Normal file
View File

@@ -0,0 +1,49 @@
#include "sparkapi.h"
#include <QDebug>
SparkAPI::SparkAPI(QObject *parent) : QObject(parent)
{
}
void SparkAPI::get(QUrl url)
{
QNetworkRequest request;
HttpRequest *httprequest=new HttpRequest;
request.setUrl(url);
connect(httprequest,&HttpRequest::finished,[=](QString data){
QByteArray arr = data.toUtf8();
//解析Json
QJsonParseError error;
if(QJsonDocument::fromJson(arr,&error).isArray())
{
auto doc = QJsonDocument::fromJson(arr,&error).array();
emit finished(doc);
}else {
auto doc = QJsonDocument::fromJson(arr,&error).object();
emit finishedObject(doc);
}
httprequest->deleteLater();
});
httprequest->getRequest(request);
}
void SparkAPI::getAppList(QString type)
{
get(QUrl(getServerUrl()+"store/"+type+"/applist.json"));
}
void SparkAPI::getSearchList(QString keyword)
{
get(QUrl("https://search.deepinos.org.cn/appinfo/search?keyword="+keyword));
}
void SparkAPI::getAppInfo(QUrl spk)
{
get(QUrl(getServerUrl()+"store"+spk.path() + "/app.json"));
}
QString SparkAPI::getServerUrl()
{
return "https://cdn.d.store.deepinos.org.cn/";
}
QString SparkAPI::getImgServerUrl()
{
return "https://cdn.d.store.deepinos.org.cn/";
}

27
src/backend/sparkapi.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef SPARKAPI_H
#define SPARKAPI_H
#include <QObject>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonParseError>
#include "utils/httprequest.h"
class SparkAPI : public QObject
{
Q_OBJECT
public:
static QString getServerUrl();
static QString getImgServerUrl();
void getSearchList(QString keyword);
void get(QUrl url);
void getAppList(QString type);
void getAppInfo(QUrl spk);
explicit SparkAPI(QObject *parent = nullptr);
signals:
void finished(QJsonArray);
void finishedObject(QJsonObject);
public slots:
};
#endif // SPARKAPI_H

View File

@@ -1,12 +0,0 @@
#include "dbussparkstore.h"
#include <QDebug>
DBusSparkStoreService::DBusSparkStoreService(QObject *parent)
: QDBusAbstractAdaptor(parent)
{
}
void DBusSparkStoreService::activeWindow(const QString & arg)
{
emit sigOpenUrl(arg);
}

View File

@@ -1,24 +0,0 @@
#ifndef DBUSSPARKSTORE_H
#define DBUSSPARKSTORE_H
#include <QObject>
#include <QUrl>
#include <QtDBus/QtDBus>
class Wallpaper;
class DBusSparkStoreService : public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "com.gitee.spark.store")
public:
explicit DBusSparkStoreService(QObject *parent);
signals :
void sigOpenUrl(const QString &url);
public Q_SLOTS:
void activeWindow(const QString &arg);
};
#endif // DBUSSPARKSTORE_H

View File

@@ -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]

View File

@@ -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

View File

@@ -1,156 +1,59 @@
#include <DApplication>
#include <DApplicationSettings>
#include <DWidgetUtil> // Dtk::Widget::moveToCenter(&w); 要调用它,就得引用 DWidgetUtil
#include <DAboutDialog>
#include <QVector>
#include <QScreen>
#include <QDir>
#include <QSettings>
//新增dbus
#include <QDBusInterface>
#include <QDBusPendingCall>
// build time
#include <QDate>
#include <QTime>
#include "widget.h"
DWIDGET_USE_NAMESPACE
int main(int argc, char *argv[])
{
// Get build time
static const QString version = "Version 3.4~test1";
static const QDate buildDate = QLocale( QLocale::English ).toDate( QString(__DATE__).replace(" ", " 0"), "MMM dd yyyy");
static const QTime buildTime = QTime::fromString(__TIME__, "hh:mm:ss");
DApplication::loadDXcbPlugin(); // 已废弃但是对于非deepin桌面可以正常使用标题栏
DApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // 开启 Hidpi 支持
// 程序内强制添加"-platformtheme deepin"参数喂给Qt让Qt正确使用Deepin主题修复各种奇怪样式问题
// 浏览器开启 GPU 支持
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--ignore-gpu-blocklist --enable-gpu-rasterization --enable-native-gpu-memory-buffers --enable-accelerated-video-decode");
QVector<char*> fakeArgs(argc + 2);
fakeArgs[0] = argv[0];
fakeArgs[1] = "-platformtheme";
fakeArgs[2] = "deepin";
for(int i = 1; i < argc; i++) fakeArgs[i + 2] = argv[i];
int fakeArgc = argc + 2; // 为啥DApplication的argc要用引用啊
DApplication a(fakeArgc, fakeArgs.data());
a.setAttribute(Qt::AA_UseHighDpiPixmaps);
a.loadTranslator(); // 载入翻译
QSettings readConfig(QDir::homePath() + "/.config/spark-store/config.ini", QSettings::IniFormat);
if (readConfig.value("build/version").toString() != version){
qDebug() << "Spark Store has been updated!";
QSettings *setConfig = new QSettings(QDir::homePath() + "/.config/spark-store/config.ini", QSettings::IniFormat);
setConfig->setValue("build/version", version);
setConfig->setValue("build/time", buildDate.toString("yyyy.MM.dd")+"-"+buildTime.toString());
setConfig->deleteLater();
}
//Customized DAboutDialog
DAboutDialog dialog;
a.setAboutDialog(&dialog);
dialog.setLicense(QObject::tr("We publish this program under GPL V3"));
dialog.setVersion(DApplication::buildVersion(readConfig.value("build/version").toString()+"-"+readConfig.value("build/time").toString()));
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 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(":/spark-store.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(readConfig.value("build/version").toString()));
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"))
{
qDebug() << "The application is already running!";
QDBusInterface iface("com.gitee.spark.store",
"/com/gitee/spark/store",
"com.gitee.spark.store",
QDBusConnection::sessionBus());
QString arg1 = argv[1];
iface.asyncCall("activeWindow",arg1);
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();
}
#include "mainwindow-dtk.h"
#include <DApplication>
#include <DLog>
#include <DPlatformWindowHandle>
#include <DApplicationSettings>
DCORE_USE_NAMESPACE
DWIDGET_USE_NAMESPACE
int main(int argc, char *argv[])
{
//设置桌面环境环境变量
if (!QString(qgetenv("XDG_CURRENT_DESKTOP")).toLower().startsWith("deepin")) {
setenv("XDG_CURRENT_DESKTOP", "Deepin", 1);
}
DApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // 开启 Hidpi 支持
#ifndef DSTORE_NO_DXCBs
DApplication::loadDXcbPlugin(); // 加载 DXCB 插件
#endif
//初始化日志模块 (默认日志位置 ~/.cache/deepin/spark-store)
DLogManager::registerConsoleAppender();
DLogManager::registerFileAppender();
DApplication a(argc, argv);
//Wayland 环境下使用,防止子控件 Native 化
if (!DPlatformWindowHandle::pluginVersion().isEmpty()) {
a.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
}
a.setAttribute(Qt::AA_UseHighDpiPixmaps);
a.loadDXcbPlugin();
a.loadTranslator(); // 载入翻译
a.setOrganizationName("spark-union");
a.setProductName(QObject::tr("Spark Store"));
a.setApplicationName("Spark Store"); // 不用翻译,影响 ~/.local/share/spark-union 下文件夹名称
a.setApplicationDisplayName(QObject::tr("Spark Store")); // 设置窗口显示标题 (Wayland 下会显示 Qt 原生标题栏)
a.setWindowIcon(QIcon::fromTheme("spark-store"));
// 限制单实例运行
if (!a.setSingleInstance("spark-store")) {
return -1;
}
DGuiApplicationHelper::instance()->setPaletteType(DGuiApplicationHelper::LightType); //固定主题为浅色主题
DApplicationSettings settings; // 定义 DApplicationSettings自动保存主题设置
MainWindow w;
QString arg1 = argv[1];
if (arg1.startsWith("spk://")) {
w.openUrl(QUrl(argv[1]));
}
w.show();
return a.exec();
}

195
src/mainwindow-dtk.cpp Normal file
View File

@@ -0,0 +1,195 @@
#include "mainwindow-dtk.h"
#include "ui_mainwindow-dtk.h"
#include <DWidgetUtil>
#include <DGuiApplicationHelper>
#include <QSizePolicy>
MainWindow::MainWindow(QWidget *parent)
: DBlurEffectWidget(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
moveToCenter(this); //让窗口居中显示
downloadlistwidget = new DownloadListWidget;
downloadButton = new QPushButton(ui->titlebar);
backButtom = new QPushButton(ui->titlebar);
ui->appintopage->setDownloadWidget(downloadlistwidget);
ui->stackedWidget->setCurrentIndex(0);
ui->titlebar->setBackgroundTransparent(true);
//ui->titlebar->setSwitchThemeMenuVisible(false); // 去除 dtk 标题栏主题切换菜单
setMaskAlpha(240);
setMaskColor(QColor("#f3f7f8"));
initConfig();
updateUi(0);
//主题切换
connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, [=](DGuiApplicationHelper::ColorType themeType) {
if (themeType == DGuiApplicationHelper::DarkType) {
//深色模式
} else {
//亮色模式
this->setStyleSheet("#mainpage{background-color: transparent;border-radius:14px;}\
QLabel#cardtitle,QLabel#title,QLabel#title_1,QLabel#title_2,QLabel#title_3 {color:#000000}\
");
backButtom->setIcon(QIcon(":/icon/light/back.svg"));
downloadButton->setIcon(QIcon(":/icon/light/download.svg"));
int i = 0;
while (i < ui->buttonGroup->buttons().size()) {
ui->buttonGroup->buttons()[i]->setIcon(QIcon(":/icon/light/leftbutton_" + QString::number(i) + ".svg"));
if (QLocale::system().name() == "zh_CN") {
ui->buttonGroup->buttons()[i]->setStyleSheet("QPushButton{background-color:transparent;}\
QPushButton:hover{background-color:#eAeAeA;border:0px;border-radius:8px;}\
QPushButton:checked{background-color:#dddddd;border:0px;border-radius:8px;}");
} else {
ui->buttonGroup->buttons()[i]->setStyleSheet("QPushButton{background-color:transparent;text-align: left; padding-left: 15px;}\
QPushButton:hover{background-color:#eAeAeA;border:0px;border-radius:8px;text-align: left; padding-left: 15px;}\
QPushButton:checked{background-color:#dddddd;border:0px;border-radius:8px;text-align: left; padding-left: 15px;}");
}
i++;
}
}
ui->applistpage->setTheme(themeType == DGuiApplicationHelper::DarkType);
ui->applistpage_1->setTheme(themeType == DGuiApplicationHelper::DarkType);
ui->appintopage->setTheme(themeType == DGuiApplicationHelper::DarkType);
});
//初始化标题栏控件
connect(downloadButton, &QPushButton::clicked, [=]() {
QPoint pos;
pos.setX(downloadButton->mapToGlobal(QPoint(0, 0)).x() + downloadButton->width() / 2 - downloadlistwidget->width() / 2);
pos.setY(downloadButton->mapToGlobal(QPoint(0, 0)).y() + downloadButton->height() + 5);
downloadlistwidget->m_move(pos.x(), pos.y());
downloadlistwidget->show();
});
connect(backButtom, &QPushButton::clicked, [=]() {
ui->stackedWidget->setCurrentIndex(pageHistory.at(pageHistory.count() - 2));
if (pageHistory.at(pageHistory.count() - 1) == 3) {
ui->appintopage->clear();
}
pageHistory.removeLast();
if (pageHistory.count() > 1) {
backButtom->show();
} else {
backButtom->hide();
}
});
downloadlistwidget->hide();
backButtom->hide();
ui->titlebar->setIcon(QIcon::fromTheme(":/icon/logo.svg"));
QWidget *w_titlebar = new QWidget(ui->titlebar);
QHBoxLayout *ly_titlebar = new QHBoxLayout(w_titlebar);
QLabel *title = new QLabel(this);
title->setText(tr("Spark Store"));
searchEdit->setPlaceholderText(tr("Search or enter spk://"));
ly_titlebar->addWidget(title);
ly_titlebar->addWidget(backButtom);
ly_titlebar->addStretch(2.5);
ly_titlebar->addWidget(searchEdit);
ly_titlebar->addWidget(downloadButton);
ly_titlebar->addStretch(1);
ui->titlebar->setCustomWidget(w_titlebar);
//侧边栏按钮
int i = 0;
while (i < ui->buttonGroup->buttons().size()) {
ui->buttonGroup->buttons()[i]->setStyleSheet("QPushButton{qproperty-icon: url(data/images/userMangaer/teacher.png);}");
connect(ui->buttonGroup->buttons()[i], &QPushButton::toggled, [=](bool checked) {
if (checked == true) {
ui->appintopage->clear();
updateUi(i);
}
});
i++;
}
// 搜索事件
connect(searchEdit, &DSearchEdit::returnPressed, this, [=]() {
QString searchtext = searchEdit->text();
if (!searchtext.isEmpty()) {
if (searchtext.startsWith("spk://")) {
openUrl(QUrl(searchtext));
searchEdit->clearEdit();
} else {
ui->applistpage_1->getSearchList(searchtext);
switchPage(2);
searchEdit->clearEdit();
}
}
this->setFocus();
});
// 列表点击事件
connect(ui->applistpage, &AppListPage::clicked, this, [=](QUrl spk) {
openUrl(spk);
});
connect(ui->applistpage_1, &AppListPage::clicked, this, [=](QUrl spk) {
openUrl(spk);
});
emit DGuiApplicationHelper::instance()->themeTypeChanged(DGuiApplicationHelper::instance()->themeType());
}
MainWindow::~MainWindow()
{
delete searchEdit;
delete downloadlistwidget;
delete ui;
}
void MainWindow::openUrl(QUrl url)
{
if (url.toString().startsWith("spk://")) {
ui->appintopage->openUrl(url);
switchPage(3);
} else {
QDesktopServices::openUrl(url);
}
}
void MainWindow::initConfig()
{
// 新建临时文件夹
QDir dir;
dir.mkpath("/tmp/spark-store");
}
void MainWindow::switchPage(int now) //临时方案,回家后修改
{
qDebug() << pageHistory.count();
if (pageHistory.count() >= 1) {
backButtom->show();
} else {
backButtom->hide();
}
ui->stackedWidget->setCurrentIndex(now);
pageHistory << now;
}
//刷新界面
void MainWindow::updateUi(int now)
{
pageHistory.clear();
QStringList itemlist;
itemlist << ""
<< "network"
<< "relations"
<< "musicandsound"
<< "videos"
<< "photos"
<< "games"
<< "office"
<< "reading"
<< "programming"
<< "tools"
<< "themes"
<< "others";
ui->applistpage->getAppList(itemlist[now]);
qDebug() << itemlist[now];
switchPage(1);
}

48
src/mainwindow-dtk.h Normal file
View File

@@ -0,0 +1,48 @@
#ifndef MAINWINDOWDTK_H
#define MAINWINDOWDTK_H
#include <DMainWindow>
#include <DBlurEffectWidget>
#include <DTitlebar>
#include <DSearchEdit>
#include <QGraphicsDropShadowEffect>
#include <DGuiApplicationHelper>
#include <QPushButton>
#include <QDir>
#include <QDesktopServices>
#include "widgets/downloadlistwidget.h"
DWIDGET_USE_NAMESPACE
namespace Ui {
class MainWindow;
}
class MainWindow : public DBlurEffectWidget
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void openUrl(QUrl);
private:
void initConfig();
void switchPage(int now);
void updateUi(int now);
private:
QList<int> pageHistory;
DownloadListWidget *downloadlistwidget;
QPushButton *downloadButton;
QPushButton *backButtom;
DSearchEdit *searchEdit = new DSearchEdit;
Ui::MainWindow *ui;
};
#endif // MAINWINDOWDTK_H

595
src/mainwindow-dtk.ui Normal file
View File

@@ -0,0 +1,595 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QWidget" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1190</width>
<height>651</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<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>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0" colspan="2">
<widget class="DTitlebar" name="titlebar" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<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>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="leftbar" native="true">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="pushButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>主页</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>网络</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>社交</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_4">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>音乐</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_5">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>视频</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_6">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>图像</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_7">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>游戏</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_8">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>办公</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_9">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>阅读</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_10">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>开发</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_11">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>工具</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_12">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>主题</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_13">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="text">
<string>其他</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRepeat">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="QWidget" name="mainpage" native="true">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<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 row="0" column="0">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="page">
<layout class="QGridLayout" name="gridLayout_3">
<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>
</layout>
</widget>
<widget class="QWidget" name="page_1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<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="AppListPage" name="applistpage" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_3">
<layout class="QVBoxLayout" name="verticalLayout_3">
<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="AppListPage" name="applistpage_1" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QVBoxLayout" name="verticalLayout_4">
<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="AppIntoPage" name="appintopage" native="true"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>DTitlebar</class>
<extends>QWidget</extends>
<header>DTitlebar</header>
<container>1</container>
</customwidget>
<customwidget>
<class>AppListPage</class>
<extends>QWidget</extends>
<header>pages/applistpage.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>AppIntoPage</class>
<extends>QWidget</extends>
<header>pages/appintopage.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="buttonGroup"/>
</buttongroups>
</ui>

295
src/pages/appintopage.cpp Normal file
View File

@@ -0,0 +1,295 @@
#include "appintopage.h"
#include "ui_appintopage.h"
AppIntoPage::AppIntoPage(QWidget *parent) :
QWidget(parent),
ui(new Ui::AppIntoPage)
{
ui->setupUi(this);
ui->listWidget->setViewMode(QListView::IconMode);
ui->listWidget->setMovement(QListView::Static);
ui->listWidget->setMaximumHeight(200);
ui->listWidget->setFlow(QListView::TopToBottom);
clear();
}
void AppIntoPage::clear()
{
ui->tag_a2d->hide();
ui->tag_uos->hide();
ui->tag_dtk5->hide();
ui->tag_deepin->hide();
ui->tag_dwine2->hide();
ui->tag_dwine5->hide();
ui->tag_ubuntu->hide();
ui->tag_community->hide();
ui->icon->clear();
ui->title->clear();
ui->author->clear();
ui->label_2->clear();
ui->downloadButton->hide();
ui->pushButton_3->hide();
int n=ui->listWidget->count();
for(int i=0;i<n;i++)
{
QListWidgetItem *item = ui->listWidget->takeItem(0);
QWidget *card = ui->listWidget->itemWidget(item);
delete card;
card = NULL;
delete item;
item = NULL;
}
ui->listWidget->clear();
}
void AppIntoPage::setDownloadWidget(DownloadListWidget *w)
{
dw=w;
}
void AppIntoPage::openUrl(QUrl url)
{
spk=url;
SparkAPI *api=new SparkAPI(this);
connect(api,&SparkAPI::finishedObject,[=](QJsonObject appinfo){
info = appinfo;
qDebug()<<url;
//获取图标
QNetworkAccessManager *naManager;
QNetworkRequest request;
naManager=new QNetworkAccessManager(this);
request.setUrl(QUrl(api->getImgServerUrl()+"store"+url.path() + "/icon.png"));
request.setRawHeader("User-Agent", "Mozilla/5.0");
request.setRawHeader("Content-Type", "charset='utf-8'");
naManager->get(request);
QObject::connect(naManager,&QNetworkAccessManager::finished,[=](QNetworkReply *reply){
QByteArray jpegData = reply->readAll();
iconpixmap.loadFromData(jpegData);
iconpixmap.scaled(210, 200, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
ui->icon->setPixmap(iconpixmap);
ui->icon->setScaledContents(true);
});
ui->title->setText(info["Name"].toString());
ui->author->setText(info["Author"].toString());
ui->d_author->setText(info["Author"].toString());
ui->d_size->setText(info["Size"].toString());
ui->d_update->setText(info["Update"].toString());
ui->d_pkgname->setText(info["Pkgname"].toString());
ui->d_website->setText("<a href=\""+info["Website"].toString()+"\">"+tr("Click Open"));
ui->d_contributor->setText(info["Contributor"].toString());
ui->label_2->setText(info["More"].toString());
QProcess isInstall;
bool isInstalled;
bool isUpdated;
QString packagename = info["Pkgname"].toString();
isInstall.start("dpkg -s " + info["Pkgname"].toString());
isInstall.waitForFinished();
int error = QString::fromStdString(isInstall.readAllStandardError().toStdString()).length();
if(error == 0)
{
isInstalled = true;
QProcess isUpdate;
isUpdate.start("dpkg-query --showformat='${Version}' --show " + info["Pkgname"].toString());
isUpdate.waitForFinished();
QString localVersion = isUpdate.readAllStandardOutput();
localVersion.replace("'", "");
isUpdate.start("dpkg --compare-versions " + localVersion + " ge " + info["Version"].toString());
isUpdate.waitForFinished();
if(!isUpdate.exitCode())
{
isUpdated = true;
}
else
{
isUpdated = false;
}
}
else
{
isInstalled = false;
isUpdated = false;
}
if(isInstalled)
{
if(isUpdated)
{
ui->downloadButton->setText(tr("Reinstall"));
ui->pushButton_3->show();
}
else
{
ui->downloadButton->setText(tr("Upgrade"));
ui->pushButton_3->show();
}
}
else
{
ui->downloadButton->setText(tr("Install"));
ui->downloadButton->setEnabled(true);
ui->downloadButton->show();
}
isDownloading();
QStringList taglist = info["Tags"].toString().split(";");
QString tmp=info["img_urls"].toString();
qDebug()<<tmp;
if(tmp.left(2)=="[\"")
{
tmp.remove(0,2);
}
if(tmp.right(2)=="\"]")
{
tmp.remove(tmp.size()-2,tmp.size());
}
QStringList imglist = tmp.split("\",\"");
qDebug()<<imglist;
for(int i=0;i < imglist.size();i++)
{
QNetworkAccessManager *naManager;
QNetworkRequest request;
naManager=new QNetworkAccessManager(this);
request.setUrl(QUrl(imglist[i]));
request.setRawHeader("User-Agent", "Mozilla/5.0");
request.setRawHeader("Content-Type", "charset='utf-8'");
naManager->get(request);
QObject::connect(naManager,&QNetworkAccessManager::finished,[=](QNetworkReply *reply){
QByteArray jpegData = reply->readAll();
QPixmap pixmap;
pixmap.loadFromData(jpegData);
pixmap.scaled(100, 100, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
image_show *img=new image_show(this);
img->setImage(pixmap);
//img->setScaledContents(true);
QListWidgetItem* pItem = new QListWidgetItem();
pItem->setSizeHint(QSize(280, 200));
ui->listWidget->addItem(pItem);
ui->listWidget->setItemWidget(pItem, img);
});
}
this->sltAppinfoTags(&taglist);
disconnect(api,&SparkAPI::finished,nullptr,nullptr);
api->deleteLater();
});
api->getAppInfo(url);
}
void AppIntoPage::isDownloading()
{
switch (dw->isDownloading(SparkAPI::getServerUrl()+"store"+spk.path()+"/"+info["Filename"].toString())) {
case 3:{
ui->downloadButton->setEnabled(true);
ui->downloadButton->setText(tr("Install"));
break;
}
case 1:{
ui->downloadButton->setEnabled(false);
ui->downloadButton->setText(tr("Downloading"));
break;
}
case 2:{
ui->downloadButton->setEnabled(false);
ui->downloadButton->setText(tr("Downloaded"));
break;
}
}
}
void AppIntoPage::sltAppinfoTags(QStringList *tagList)
{
foreach(const QString &tag, *tagList)
{
if(tag=="community")
{
ui->tag_community->show();
}
else if(tag=="ubuntu")
{
ui->tag_ubuntu->show();
}
else if(tag=="deepin")
{
ui->tag_deepin->show();
}
else if(tag=="uos")
{
ui->tag_uos->show();
}
else if(tag=="dtk5")
{
ui->tag_dtk5->show();
}
else if(tag=="dwine2")
{
ui->tag_dwine2->show();
}
else if(tag=="dwine5")
{
ui->tag_dwine5->show();
}
else if(tag=="a2d")
{
ui->tag_a2d->show();
}
}
}
void AppIntoPage::setTheme(bool dark)
{
if(dark)
{}else {
//亮色模式
QString frameStyleSheet ="#frame,#frame_2,#frame_3,#frame_4{background-color: #fbfbfb;border-radius:14px;border:1px solid rgb(229,229,229);}";
ui->frame->setStyleSheet(frameStyleSheet);
ui->frame_2->setStyleSheet(frameStyleSheet);
ui->frame_3->setStyleSheet(frameStyleSheet);
ui->frame_4->setStyleSheet(frameStyleSheet);
ui->icon_1->setPixmap(QPixmap(":/icon/light/box.svg"));
ui->icon_2->setPixmap(QPixmap(":/icon/light/box.svg"));
ui->icon_3->setPixmap(QPixmap(":/icon/light/calendar.svg"));
ui->icon_4->setPixmap(QPixmap(":/icon/light/text.svg"));
ui->icon_5->setPixmap(QPixmap(":/icon/light/folder.svg"));
ui->icon_6->setPixmap(QPixmap(":/icon/light/globe.svg"));
}
}
AppIntoPage::~AppIntoPage()
{
delete ui;
}
void AppIntoPage::on_downloadButton_clicked()
{
dw->addItem(info["Name"].toString(),info["Filename"].toString(),info["Pkgname"].toString(),iconpixmap,SparkAPI::getServerUrl()+"store"+spk.path()+"/"+info["Filename"].toString());
isDownloading();
}
void AppIntoPage::on_pushButton_3_clicked()
{
QtConcurrent::run([=]()
{
ui->downloadButton->setEnabled(false);
ui->pushButton_3->setEnabled(false);
QProcess uninstall;
uninstall.start("pkexec", QStringList() << "apt" << "purge" << "-y" << info["Pkgname"].toString().toLower());
uninstall.waitForFinished();
QProcess check;
check.start("dpkg", QStringList() << "-s" << info["Pkgname"].toString().toLower());
check.waitForFinished();
if (check.readAllStandardOutput().isEmpty())
{
ui->downloadButton->setText(tr("Install"));
ui->pushButton_3->hide();
updatesEnabled();
//sendNotification(tr("Uninstall succeeded"));
}
ui->downloadButton->setEnabled(true);
ui->pushButton_3->setEnabled(true);
});
}

42
src/pages/appintopage.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef APPINTOPAGE_H
#define APPINTOPAGE_H
#include <QWidget>
#include <QUrl>
#include <QString>
#include <QtConcurrent>
#include "backend/sparkapi.h"
#include "backend/image_show.h"
#include "widgets/downloadlistwidget.h"
namespace Ui {
class AppIntoPage;
}
class AppIntoPage : public QWidget
{
Q_OBJECT
public:
void clear();
void setDownloadWidget(DownloadListWidget *w);
void setTheme(bool dark);
void openUrl(QUrl url);
explicit AppIntoPage(QWidget *parent = nullptr);
~AppIntoPage();
private slots:
void on_downloadButton_clicked();
void on_pushButton_3_clicked();
private:
QJsonObject info;
QPixmap iconpixmap;
QUrl spk;
void isDownloading();
void sltAppinfoTags(QStringList *tagList);
DownloadListWidget *dw;
Ui::AppIntoPage *ui;
};
#endif // APPINTOPAGE_H

1287
src/pages/appintopage.ui Normal file

File diff suppressed because it is too large Load Diff

76
src/pages/applistpage.cpp Normal file
View File

@@ -0,0 +1,76 @@
#include "applistpage.h"
#include "ui_applistpage.h"
AppListPage::AppListPage(QWidget *parent) :
QWidget(parent),
ui(new Ui::AppListPage)
{
ui->setupUi(this);
ui->webEngineView->page()->setBackgroundColor(Qt::transparent);
}
void AppListPage::setTheme(bool dark)
{
isDark=dark;
if(dark)
{
}else {
//亮色模式
this->setStyleSheet("#frame{background-color: #ffffff;border-radius:14px;border:1px solid rgb(229,229,229);}#webEngineView{border-radius:14px;}");
}
if(isSearch)
{
getSearchList(nowType);
}else{
getAppList(nowType);
}
}
void AppListPage::getAppList(QString type)
{
isSearch=false;
nowType=type;
SparkAPI *api=new SparkAPI(this);
QString url;
if(isDark)
{
url=api->getServerUrl()+"store/#/dark"+type;
}else{
url=api->getServerUrl()+"store/#/"+type;
}
ui->webEngineView->setUrl(url);
}
void AppListPage::getSearchList(QString keyword)
{
isSearch=true;
nowType=keyword;
SparkAPI *api=new SparkAPI(this);
QString url;
if(isDark)
{
url=api->getServerUrl()+"store/#/darksearch?keywords="+keyword;
}else{
url=api->getServerUrl()+"store/#/search?keywords="+keyword;
}
ui->webEngineView->setUrl(url);
}
AppListPage::~AppListPage()
{
delete ui;
}
void AppListPage::on_webEngineView_urlChanged(const QUrl &arg1)
{
if(arg1.path().right(8) == "app.json")
{
QString url = arg1.toString();
url = url.mid(url.indexOf("/store/"));
url = "spk:/"+url;
url = url.mid(0,url.indexOf("/app.json"));
qDebug() << "程序跳转链接地址:" << url;
ui->webEngineView->back();
emit clicked(url);
}
}

34
src/pages/applistpage.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef APPLISTPAGE_H
#define APPLISTPAGE_H
#include <QMutex>
#include <QWidget>
#include <QListWidgetItem>
#include "backend/sparkapi.h"
namespace Ui {
class AppListPage;
}
class AppListPage : public QWidget
{
Q_OBJECT
public:
void setTheme(bool dark);
void getSearchList(QString keyword);
void getAppList(QString type);
explicit AppListPage(QWidget *parent = nullptr);
~AppListPage();
private:
QMutex mutex; // 禁止多次搜索事件同时发生
bool isDark;
bool isSearch;
QString nowType;
Ui::AppListPage *ui;
signals:
void clicked(QUrl spk);
private slots:
void on_webEngineView_urlChanged(const QUrl &arg1);
};
#endif // APPLISTPAGE_H

84
src/pages/applistpage.ui Normal file
View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AppListPage</class>
<widget class="QWidget" name="AppListPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>645</width>
<height>409</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<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="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<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>0</number>
</property>
<item>
<widget class="WebEngineView" name="webEngineView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="url">
<url>
<string>about:blank</string>
</url>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QWebEngineView</class>
<extends>QWidget</extends>
<header location="global">QtWebEngineWidgets/QWebEngineView</header>
</customwidget>
<customwidget>
<class>WebEngineView</class>
<extends>QWebEngineView</extends>
<header>widgets/common/webengineview.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -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() + ";");
}

View File

@@ -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

View File

@@ -1,9 +0,0 @@
TARGET = spark-dstore-patch
TEMPLATE += app
QT += widgets
SOURCES += spark-dstore-tool.cpp
# Default rules for deployment.
qnx: target.path = /tmp/spark-store/bin
else: unix:!android: target.path = /opt/durapps/spark-store/bin
!isEmpty(target.path): INSTALLS += target

View File

@@ -1,195 +0,0 @@
#include <QCoreApplication>
#include <QDir>
#include <QJsonObject>
#include <QJsonDocument>
#include <QDebug>
#include <QDirIterator>
#include <QProcess>
#include <unistd.h>
QList<QJsonObject> enumAppInfoList()
{
QList<QJsonObject> appInfoList;
QDir apps("/opt/apps");
auto list = apps.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for (auto &appID : list) {
auto infoPath = apps.absoluteFilePath(appID + "/info");
QFile infoFile(infoPath);
if (!infoFile.open(QIODevice::ReadOnly)) {
continue;
}
auto doc = QJsonDocument::fromJson(infoFile.readAll());
appInfoList.push_back(doc.object());
}
return appInfoList;
}
//这段是去找appid和info没看懂用来干啥的在此之后info文件也没再用过
//可能以后版本的实现会用到,等官方加功能再说
void linkDir(const QString &source, const QString &target)
{
auto ensureTargetDir = [](const QString &targetFile) {
QFileInfo t(targetFile);
QDir tDir(t.dir());
tDir.mkpath(".");
};
QDir sourceDir(source);
QDir targetDir(target);
QDirIterator iter(source, QDir::Files | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (iter.hasNext()) {
auto sourceFile = iter.next();
auto targetFile = targetDir.absoluteFilePath(sourceDir.relativeFilePath(sourceFile));
QFileInfo tfi(targetFile);
// if (tfi.isSymLink() && (tfi.canonicalFilePath() == sourceFile)) {
//这里官方应该是写错了,否则会每触发一次就把所有软链接都删了重新创建一次
if (tfi.isSymLink() && (tfi.symLinkTarget() == sourceFile)) {
continue;
} else {
QFile::remove(targetFile);
}
ensureTargetDir(targetFile);
auto ret = symlink(sourceFile.toStdString().c_str(), targetFile.toStdString().c_str());
if (0 != ret) {
qDebug() << "link failed" << sourceFile << "=>" << targetFile << ret;
}
}
}
//reset Dynamic library rpath
void setRpath(const QString &file, const QString &path)
{
if (!QFileInfo::exists(path))
return;
QProcess p;
auto cmd = "patchelf " + file + " --set-rpath " + path;
p.start("bash", QStringList {"-c", cmd});
p.waitForFinished();
}
QString getGlic()
{
//get arch & glibc
QProcess p;
auto cmd = "gcc -dumpmachine";
p.start("bash", QStringList {"-c", cmd});
p.waitForFinished();
return p.readAll();
}
void linkApp(const QJsonObject &app)
{
auto appID = app.value("appid").toString();
auto appEntriesDir = QDir("/opt/apps/" + appID + "/entries");
auto appLibsDir = QDir("/opt/apps/" + appID + "/files/lib");
auto autoStartDir = QDir(appEntriesDir.absoluteFilePath("autostart"));
bool autoStart = app.value("permissions").toObject().value("autostart").toBool();
if (autoStart) {
linkDir(appEntriesDir.absoluteFilePath("autostart"), "/etc/xdg/autostart");
}
// link application
auto sysShareDir = QDir("/usr/share");
linkDir(appEntriesDir.absoluteFilePath("applications"), sysShareDir.absoluteFilePath("applications"));
linkDir(appEntriesDir.absoluteFilePath("icons"), sysShareDir.absoluteFilePath("icons"));
linkDir(appEntriesDir.absoluteFilePath("mime"), sysShareDir.absoluteFilePath("mime"));
linkDir(appEntriesDir.absoluteFilePath("glib-2.0"), sysShareDir.absoluteFilePath("glib-2.0"));
linkDir(appEntriesDir.absoluteFilePath("services"), sysShareDir.absoluteFilePath("dbus-1/services"));
linkDir(appEntriesDir.absoluteFilePath("GConf"), sysShareDir.absoluteFilePath("GConf"));
linkDir(appEntriesDir.absoluteFilePath("help"), sysShareDir.absoluteFilePath("help"));
linkDir(appEntriesDir.absoluteFilePath("locale"), sysShareDir.absoluteFilePath("locale"));
linkDir(appEntriesDir.absoluteFilePath("fcitx"), sysShareDir.absoluteFilePath("fcitx"));
linkDir(appEntriesDir.absoluteFilePath("polkit"), sysShareDir.absoluteFilePath("polkit-1"));
linkDir(appEntriesDir.absoluteFilePath("fonts/conf"), "/etc/fonts/conf.d");
linkDir(appEntriesDir.absoluteFilePath("fonts/files"), sysShareDir.absoluteFilePath("fonts"));
//原来会导致Gtk相关应用翻译缺失补足了
auto pluginDir = QDir(appEntriesDir.absoluteFilePath("plugins"));
if (pluginDir.exists()) {
QString arch = getGlic();
// if (pluginDir.exists()) {
// QDirIterator iter(pluginDir.absolutePath(), QDir::Files | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
// while (iter.hasNext()) {
// auto sourceFile = iter.next();
// setRpath(sourceFile, appLibsDir.absolutePath()); //set rpath
// }
// }
linkDir(appEntriesDir.absoluteFilePath("plugins/fcitx"), "/usr/lib/" + arch + "/fcitx");
linkDir(appEntriesDir.absoluteFilePath("plugins/browser"), "/usr/lib/mozilla/plugins");
}
}
void cleanLink()
{
auto cleanDirBrokenLink = [](const QString &dir) {
QProcess p;
auto cmd = "find " + dir + " -xtype l -delete";
p.start("bash", QStringList {"-c", cmd});
p.waitForFinished();
};
QString arch = getGlic();
auto sysShareDir = QDir("/usr/share");
cleanDirBrokenLink(sysShareDir.absoluteFilePath("applications"));
cleanDirBrokenLink(sysShareDir.absoluteFilePath("icons"));
cleanDirBrokenLink(sysShareDir.absoluteFilePath("mime/packages"));
cleanDirBrokenLink(sysShareDir.absoluteFilePath("glib-2.0"));
cleanDirBrokenLink(sysShareDir.absoluteFilePath("dbus-1/services"));
cleanDirBrokenLink("/etc/xdg/autostart");
cleanDirBrokenLink(sysShareDir.absoluteFilePath("fcitx"));
cleanDirBrokenLink(sysShareDir.absoluteFilePath("help"));
cleanDirBrokenLink(sysShareDir.absoluteFilePath("locale"));
cleanDirBrokenLink("/usr/lib/" + arch + "/fcitx");
cleanDirBrokenLink("/usr/lib/mozilla/plugins");
cleanDirBrokenLink(sysShareDir.absoluteFilePath("polkit-1/actions"));
cleanDirBrokenLink(sysShareDir.absoluteFilePath("fonts"));
cleanDirBrokenLink("/etc/fonts/conf.d");
}
void update()
{
QProcess p;
auto cmd = "glib-compile-schemas /usr/share/glib-2.0/schemas/";
p.start("bash", QStringList {"-c", cmd});
p.waitForFinished();
cmd = "update-icon-caches /usr/share/icons/*";
p.start("bash", QStringList {"-c", cmd});
p.waitForFinished();
cmd = "update-desktop-database -q";
p.start("bash", QStringList {"-c", cmd});
p.waitForFinished();
cmd = "update-mime-database -V /usr/share/mime";
p.start("bash", QStringList {"-c", cmd});
p.waitForFinished();
}
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
cleanLink();
for (auto &a : enumAppInfoList()) {
linkApp(a);
}
qInfo()<<"Spark dstore patch (c) The Spark Project 2022-Now. Modified from deepin-app-store-tool";
// trigger
update();
return 0;
}

View File

@@ -1,10 +1,10 @@
#-------------------------------------------------
#
# Project created by QtCreator 2019-06-30T12:53:03
# Project created by QtCreator 2021-10-29T16:58:36
#
#-------------------------------------------------
QT += core gui network concurrent webenginewidgets dbus
QT += core gui network concurrent webenginewidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
@@ -23,70 +23,55 @@ DEFINES += QT_DEPRECATED_WARNINGS
#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 += dtkcore dtkgui dtkwidget libnotify
# 禁止输出 qWarning / qDebug 信息
#CONFIG(release, debug|release): DEFINES += QT_NO_WARNING_OUTPUT QT_NO_DEBUG_OUTPUT
# Disable qWarning / qDebug output in Release
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 \
dbus/dbussparkstore.cpp \
webengine/webenginepage.cpp \
webengine/webengineview.cpp
main.cpp \
mainwindow-dtk.cpp \
backend/sparkapi.cpp \
widgets/common/webenginepage.cpp \
widgets/common/webengineview.cpp \
widgets/downloadlistwidget.cpp \
widgets/common/downloaditem.cpp \
widgets/common/smoothlistwidget.cpp \
widgets/common/smoothscrollbar.cpp \
utils/httprequest.cpp \
pages/applistpage.cpp \
backend/downloadworker.cpp \
pages/appintopage.cpp \
widgets/big_image.cpp \
backend/image_show.cpp
HEADERS += \
appitem.h \
big_image.h \
downloadlist.h \
downloadworker.h \
flowlayout.h \
image_show.h \
progressload.h \
widget.h \
workerthreads.h \
dbus/dbussparkstore.h \
webengine/webenginepage.h \
webengine/webengineview.h
mainwindow-dtk.h \
backend/sparkapi.h \
widgets/common/webenginepage.h \
widgets/common/webengineview.h \
widgets/downloadlistwidget.h \
widgets/common/downloaditem.h \
widgets/common/smoothlistwidget.h \
widgets/common/smoothscrollbar.h \
utils/httprequest.h \
pages/applistpage.h \
backend/downloadworker.h \
pages/appintopage.h \
widgets/big_image.h \
backend/image_show.h
FORMS += \
appitem.ui \
downloadlist.ui \
widget.ui
mainwindow-dtk.ui \
widgets/downloadlistwidget.ui \
widgets/common/downloaditem.ui \
pages/applistpage.ui \
pages/appintopage.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
assets/assets.qrc
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin

43
src/utils/httprequest.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include "httprequest.h"
HttpRequest::HttpRequest()
{
}
void HttpRequest::getRequest(QNetworkRequest request)
{
QNetworkAccessManager *naManager=new QNetworkAccessManager(this);
request.setRawHeader("User-Agent", "Mozilla/5.0");
request.setRawHeader("Content-Type", "charset='utf-8'");
request.setRawHeader("Content-Type", "application/json");
naManager->get(request);
QObject::connect(naManager,&QNetworkAccessManager::finished,this,&HttpRequest::readdata_slot);
}
void HttpRequest::readdata_slot(QNetworkReply *reply)
{
emit finished(reply->readAll());
}
QString HttpRequest::postRequest(QString url, QString jsondata)
{
QByteArray array= jsondata.toLatin1();
QNetworkRequest request;
QNetworkAccessManager *naManager=new QNetworkAccessManager(this);
QUrl strUrl = url;
request.setUrl(strUrl);
request.setRawHeader("Content-Type", "charset='utf-8'");
request.setRawHeader("Content-Type", "application/json");
QNetworkReply* reply = naManager->post(request, array);
QEventLoop eventLoop;
connect(naManager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
eventLoop.exec();
QTextCodec* codec = QTextCodec::codecForName("utf8");
QString strReply = codec->toUnicode(reply->readAll());
reply->deleteLater();
return strReply;
}

26
src/utils/httprequest.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef HTTPREQUEST_H
#define HTTPREQUEST_H
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QEventLoop>
#include <QTextCodec>
class HttpRequest : public QObject
{
Q_OBJECT
public:
HttpRequest();
void getRequest(QNetworkRequest request);
QString postRequest(QString url, QString jsondata);
signals:
void finished(QString);
private slots:
void readdata_slot(QNetworkReply *reply);
};
#endif // HTTPREQUEST_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,177 +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");
void initDbus();
private slots:
void httpFinished();
void httpReadyRead();
void updateDataReadProgress(QString, 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,
bool isUpdated);
void sltAppinfoIcon(QPixmap *icon);
void sltAppinfoScreenshot(QPixmap *picture, int index);
void sltAppinfoFinish();
void clearSearchApp(); // 清除搜索的APP信息
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_clearWebCache_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_update_clicked();
//接受来自dbus的url
void onGetUrl(const QString &url);
public:
QUrl url;
QString cdnSeverUrl;
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();
void closeEvent(QCloseEvent *event);
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 theSpeed;
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

File diff suppressed because it is too large Load Diff

View File

@@ -1,230 +1,226 @@
#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);
// }
// QFile gdebi("/usr/bin/gdebi");
// gdebi.open(QIODevice::ReadOnly);
// if(gdebi.isOpen())
// {
// 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. Open APP Upgrade and Install Settings to enable password-free installation"));
}
}
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(!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;
switch(t)
{
case 0:
installer.start("pkexec", QStringList() << "ssinstall" << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
break;
case 1:
installer.start("deepin-deb-installer", QStringList() << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
break;
case 2:
installer.start("pkexec", QStringList() << "gdebi" << "-n" << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
break;
}
bool haveError = false;
bool notRoot = false;
installer.waitForFinished(-1); // 不设置超时
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(180); // 默认超时 3 分钟
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 abortedyou 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);
textbrowser->setMinimumHeight(500);
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();
}
#include "downloaditem.h"
#include "ui_downloaditem.h"
#include <QtConcurrent>
#include <QProcess>
bool DownloadItem::isInstall = false;
DownloadItem::DownloadItem(QWidget *parent) :
QWidget(parent),
reinstall(false),
close(false),
ui(new Ui::DownloadItem),
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,[=](){DownloadItem::install(0);});
connect(action_deepin,&QAction::triggered,[=](){DownloadItem::install(1);});
connect(action_gdebi,&QAction::triggered,[=](){DownloadItem::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);
// }
// QFile gdebi("/usr/bin/gdebi");
// gdebi.open(QIODevice::ReadOnly);
// if(gdebi.isOpen())
// {
// menu_install->addAction(action_gdebi);
// }
}
DownloadItem::~DownloadItem()
{
delete ui;
}
void DownloadItem::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. Open APP Upgrade and Install Settings to enable password-free installation"));
}
}
void DownloadItem::setMax(qint64 max)
{
ui->progressBar->setMaximum(qint32(max));
}
void DownloadItem::setName(QString name)
{
ui->label->setText(name);
}
QString DownloadItem::getName()
{
return ui->label_filename->text();
}
void DownloadItem::readyInstall()
{
if(!close)
{
ui->progressBar->hide();
ui->pushButton_install->setEnabled(true);
ui->pushButton_install->show();
ui->pushButton_2->hide();
}
}
void DownloadItem::setFileName(QString fileName)
{
ui->label_filename->setText(fileName);
}
void DownloadItem::seticon(const QPixmap icon)
{
ui->label_3->setPixmap(icon);
}
void DownloadItem::closeDownload()
{
on_pushButton_2_clicked();
}
void DownloadItem::setSpeed(QString s)
{
speed = s;
}
void DownloadItem::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;
switch(t)
{
case 0:
installer.start("pkexec", QStringList() << "ssinstall" << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
break;
case 1:
installer.start("deepin-deb-installer", QStringList() << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
break;
case 2:
installer.start("pkexec", QStringList() << "gdebi" << "-n" << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
break;
}
bool haveError = false;
bool notRoot = false;
installer.waitForFinished(-1); // 不设置超时
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(180); // 默认超时 3 分钟
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 abortedyou can retry installation"));
ui->pushButton_install->show();
ui->pushButton_3->hide();
}
ui->widget_spinner->hide();
DownloadItem::isInstall = false;
});
qDebug()<<ui->label_filename->text().toUtf8();
}
}
void DownloadItem::on_pushButton_install_clicked()
{
// 弹出菜单
menu_install->exec(cursor().pos());
}
void DownloadItem::on_pushButton_2_clicked()
{
ui->label_2->setText(tr("Download canceled"));
ui->pushButton_2->setEnabled(false);
ui->progressBar->hide();
close = true;
}
void DownloadItem::on_pushButton_3_clicked()
{
textbrowser->setLineWidth(0);
textbrowser->setText(out);
textbrowser->setMinimumHeight(500);
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();
}

View File

@@ -1,5 +1,5 @@
#ifndef DOWNLOADLIST_H
#define DOWNLOADLIST_H
#ifndef DOWNLOADITEM_H
#define DOWNLOADITEM_H
#include <QWidget>
#include <QTextBrowser>
@@ -7,20 +7,19 @@
#include <QAction>
#include <DDialog>
DWIDGET_USE_NAMESPACE
namespace Ui {
class downloadlist;
class DownloadItem;
}
class downloadlist : public QWidget
class DownloadItem : public QWidget
{
Q_OBJECT
public:
explicit downloadlist(QWidget *parent = nullptr);
~downloadlist();
explicit DownloadItem(QWidget *parent = nullptr);
~DownloadItem();
int num;
bool free;
@@ -45,7 +44,7 @@ public:
void install(int);
private:
Ui::downloadlist *ui;
Ui::DownloadItem *ui;
QMenu *menu_install;
QAction *action_dpkg;
@@ -60,6 +59,8 @@ private slots:
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
signals:
void finished();
};
#endif // DOWNLOADLIST_H
#endif // DOWNLOADITEM_H

View File

@@ -1,294 +1,294 @@
<?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>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DownloadItem</class>
<widget class="QWidget" name="DownloadItem">
<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>

View File

@@ -0,0 +1,25 @@
#include "smoothlistwidget.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QWheelEvent>
#include <QDebug>
SmoothListWidget::SmoothListWidget(QWidget *parent) : QListWidget(parent)
{
vScrollBar->setOrientation(Qt::Orientation::Vertical); //将滚动条设置为纵向
setVerticalScrollBar(vScrollBar); //设置纵向滚动条
connect(vScrollBar, SIGNAL(valueChanged(int)), this, SLOT(onSliderChanged(int)));
}
void SmoothListWidget::wheelEvent(QWheelEvent *e)
{
//当捕获到事件后,调用相对滚动的槽函数
vScrollBar->scroll(e->angleDelta().y());
}
void SmoothListWidget::onSliderChanged(int p)
{
int startRow = count();
if (p == vScrollBar->maximum())
{
emit reachedBottom(); // 1
}
emit msliderChanged(p); // 2
}

View File

@@ -0,0 +1,24 @@
#ifndef SMOOTHLISTWIDGET_H
#define SMOOTHLISTWIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QListWidget>
#include "smoothscrollbar.h"
class SmoothListWidget: public QListWidget
{
Q_OBJECT
public:
explicit SmoothListWidget(QWidget *parent = nullptr);
SmoothScrollBar* vScrollBar=new SmoothScrollBar(); //纵向滚动条
private:
void wheelEvent(QWheelEvent* e); //捕获鼠标滚轮事件
signals:
void msliderChanged(int p);
void reachedBottom();
private slots:
void onSliderChanged(int p);
};
#endif // SMOOTHLISTWIDGET_H

View File

@@ -0,0 +1,56 @@
#include "smoothscrollbar.h"
#include <QWheelEvent>
#include <QDebug>
SmoothScrollBar::SmoothScrollBar(QWidget* parent):QScrollBar(parent)
{
m_scrollAni=new QPropertyAnimation(this);
m_scrollAni->setTargetObject(this);
m_scrollAni->setPropertyName("value");
m_scrollAni->setEasingCurve(QEasingCurve::OutQuint); //设置动画曲线在Qt文档中有详细的介绍
m_scrollAni->setDuration(500); //设置动画时间,数值越小播放越快
m_targetValue_v=value(); //将m_targetValue_v初始化
}
void SmoothScrollBar::setValue(int value)
{
m_scrollAni->stop();//停止现在的动画,防止出现冲突
m_scrollAni->setStartValue(this->value()); //设置动画滚动的初始值为当前位置
m_scrollAni->setEndValue(value); //设置动画的结束位置为目标值
m_scrollAni->start(); //开始动画
}
void SmoothScrollBar::scrollTop()
{
setValue(-m_targetValue_v); //开始动画
m_targetValue_v=0;
}
void SmoothScrollBar::scroll(int value)
{
//这里推荐评论区中大佬优化的写法
if(m_targetValue_v-value>=0)
{
m_targetValue_v-=value; //将目标值和相对位置进行运算
setValue(m_targetValue_v); //开始动画
}
}
void SmoothScrollBar::mousePressEvent(QMouseEvent *e)
{
//当使用鼠标操作滚动条时不会刷新m_targetValue_v的值因而需要重写事件对其进行刷新。
m_scrollAni->stop();
QScrollBar::mousePressEvent(e);
m_targetValue_v=value();
}
void SmoothScrollBar::mouseReleaseEvent(QMouseEvent *e)
{
m_scrollAni->stop();
QScrollBar::mouseReleaseEvent(e);
m_targetValue_v=value();
}
void SmoothScrollBar::mouseMoveEvent(QMouseEvent *e)
{
m_scrollAni->stop();
QScrollBar::mouseMoveEvent(e);
m_targetValue_v=value();
}

View File

@@ -0,0 +1,27 @@
#ifndef SMOOTHSCROLLBAR_H
#define SMOOTHSCROLLBAR_H
#include <QScrollBar>
#include <QPropertyAnimation>
class SmoothScrollBar : public QScrollBar
{
Q_OBJECT
public:
SmoothScrollBar(QWidget *parent=nullptr);
private:
//这里重写鼠标事件的目的是在手动点击或拖动滚动条时更新m_targetValue_v变量并且在拖动时立即结束滚动的动画。
//这里如果不明白作用,可以先注释掉看看手动拖动滚动条时对动画有什么影响。
void mousePressEvent(QMouseEvent *) override;
void mouseReleaseEvent(QMouseEvent *) override;
void mouseMoveEvent(QMouseEvent *) override;
QPropertyAnimation *m_scrollAni; //用来实现动画
int m_targetValue_v; //用来记录目标位置的变量
public slots:
void scrollTop();
void setValue(int value); //重写的setValue槽函数实现动画效果
void scroll(int value); //新增相对滚动的槽函数value为滚动距离的矢量表示
signals:
};
#endif // SMOOTHSCROLLBAR_H

View File

@@ -0,0 +1,201 @@
#include "downloadlistwidget.h"
#include "ui_downloadlistwidget.h"
#include <QGraphicsOpacityEffect>
#include <QPropertyAnimation>
#include <QDebug>
DownloadListWidget::DownloadListWidget(QWidget *parent) :
DBlurEffectWidget(parent),
ui(new Ui::DownloadListWidget)
{
ui->setupUi(this);
installEventFilter(this);
this->setAttribute(Qt::WA_Hover,true);
setFocus();
setFixedSize(500,400);
// 计算显示下载速度
download_speed.setInterval(1000);
download_speed.start();
connect(&download_speed,&QTimer::timeout,[=]()
{
if(isdownload && theSpeed == "")
{
size1 = download_size;
double bspeed;
bspeed = size1 - size2;
if(bspeed < 1024)
{
theSpeed = QString::number(bspeed) + "B/s";
}
else if(bspeed < 1024 * 1024)
{
theSpeed = QString::number(0.01 * int(100 * (bspeed / 1024))) + "KB/s";
}
else if(bspeed < 1024 * 1024 * 1024)
{
theSpeed = QString::number(0.01 * int(100 * (bspeed / (1024 * 1024)))) + "MB/s";
}
else
{
theSpeed = QString::number(0.01 * int(100 * (bspeed / (1024 * 1024 * 1024)))) + "GB/s";
}
size2 = download_size;
}
if(isdownload){
downloaditemlist[nowDownload - 1]->setSpeed(theSpeed);
}
});
}
DownloadListWidget::~DownloadListWidget()
{
delete ui;
}
void DownloadListWidget::clearItem()
{
ui->listWidget->vScrollBar->scrollTop();
int n=ui->listWidget->count();
for(int i=0;i<n;i++)
{
QListWidgetItem *item = ui->listWidget->takeItem(0);
QWidget *card = ui->listWidget->itemWidget(item);
delete card;
card = NULL;
delete item;
item = NULL;
}
ui->listWidget->clear();
}
void DownloadListWidget::addItem(QString name,QString fileName,QString pkgName,const QPixmap icon,QString downloadurl)
{
allDownload += 1;
urList.append(downloadurl);
if(dlist.contains(downloadurl))
{
return;
}
if(fileName.isEmpty())
{
return;
}
DownloadItem *di=new DownloadItem(this);
dlist<<downloadurl;
downloaditemlist<<di;
di->setName(name);
di->setFileName(fileName);
di->pkgName=pkgName;
di->seticon(icon);
QListWidgetItem* pItem = new QListWidgetItem();
pItem->setSizeHint(QSize(240, 50));
ui->listWidget->addItem(pItem);
ui->listWidget->setItemWidget(pItem, di);
if(!isBusy)
{
nowDownload += 1;
startRequest(urList.at(nowDownload - 1), fileName); // 进行链接请求
}
}
void DownloadListWidget::startRequest(QUrl url, QString fileName)
{
ui->listWidget->show();
isBusy = true;
isdownload = true;
downloaditemlist[allDownload - 1]->free = false;
downloadController = new DownloadController(this); // 并发下载,在点击下载按钮的时候才会初始化
connect(downloadController, &DownloadController::downloadProcess, this, &DownloadListWidget::updateDataReadProgress);
connect(downloadController, &DownloadController::downloadFinished, this, &DownloadListWidget::httpFinished);
//connect(downloadController, &DownloadController::errorOccur, this, [=](QString msg){this->sendNotification(msg);});
downloadController->setFilename(fileName);
downloadController->startDownload(url.toString());
}
void DownloadListWidget::httpFinished() // 完成下载
{
isdownload = false;
isBusy = false;
downloaditemlist[nowDownload - 1]->readyInstall();
downloaditemlist[nowDownload - 1]->free = true;
if(nowDownload < allDownload)
{
// 如果有排队则下载下一个
qDebug() << "切换下一个下载...";
nowDownload += 1;
while(downloaditemlist[nowDownload - 1]->close)
{
nowDownload += 1;
}
QString fileName = downloaditemlist[nowDownload - 1]->getName();
startRequest(urList.at(nowDownload-1), fileName);
}
}
int DownloadListWidget::isDownloading(QString url)
{
int i = urList.indexOf(QUrl(url),0);
if(i == -1){
return 3;
}else if(i==nowDownload-1 && isdownload)
{
return 1;
}else if(i==nowDownload-1 && !isdownload)
{
return 2;
}else if(i<nowDownload-1)
{
return 2;
}
return 0;
}
void DownloadListWidget::updateDataReadProgress(QString speedInfo, qint64 bytesRead, qint64 totalBytes)
{
if(totalBytes <= 0)
{
return;
}
theSpeed = speedInfo;
downloaditemlist[nowDownload - 1]->setMax(10000); // 最大值
downloaditemlist[nowDownload - 1]->setValue(int(bytesRead * 100 / totalBytes) * 100); // 当前值
download_size = bytesRead;
if(downloaditemlist[nowDownload - 1]->close)
{
// 随时检测下载是否被取消
downloadController->disconnect();
downloadController->stopDownload();
downloaditemlist[nowDownload - 1]->closeDownload();
httpFinished();
}
}
void DownloadListWidget::m_move(int x,int y)
{
m_rect.setX(x);
m_rect.setY(y);
move(x,y);
return;
}
bool DownloadListWidget::eventFilter(QObject *watched, QEvent *event)
{
if (Q_NULLPTR == watched) {
return false;
}
if (QEvent::ActivationChange == event->type()) {
if(QApplication::activeWindow() != this){
this->close();
}
}
return QWidget::eventFilter(watched, event);
}
void DownloadListWidget::mouseMoveEvent(QMouseEvent *event)
{
setGeometry(m_rect);
}
void DownloadListWidget::on_pushButton_clicked()
{
QDesktopServices::openUrl(QUrl("file:///tmp/spark-store", QUrl::TolerantMode));
}

View File

@@ -0,0 +1,56 @@
#ifndef DOWNLOADLISTWIDGET_H
#define DOWNLOADLISTWIDGET_H
#include <QWidget>
#include <QTimer>
#include <DBlurEffectWidget>
#include <QNetworkAccessManager>
#include <QDesktopServices>
#include "widgets/common/downloaditem.h"
#include "backend/sparkapi.h"
#include "backend/downloadworker.h"
DWIDGET_USE_NAMESPACE
namespace Ui {
class DownloadListWidget;
}
class DownloadListWidget : public DBlurEffectWidget
{
Q_OBJECT
public:
void addItem(QString name, QString fileName, QString pkgName, const QPixmap icon, QString downloadurl);
int isDownloading(QString url);
void m_move(int x, int y);
explicit DownloadListWidget(QWidget *parent = nullptr);
~DownloadListWidget();
private:
int nowDownload = 0;
int allDownload = 0;
int isdownload = false;
bool isBusy = false;
QStringList dlist;
QList<QUrl> urList;
QList<DownloadItem *> downloaditemlist;
DownloadController *downloadController;
int nowdownload = 0;
QString theSpeed;
QTimer download_speed;
long download_size = 0;
long size1 = 0;
long size2 = 0;
void startRequest(QUrl url, QString fileName);
void httpFinished();
void updateDataReadProgress(QString speedInfo, qint64 bytesRead, qint64 totalBytes);
void clearItem();
QRect m_rect;
Ui::DownloadListWidget *ui;
private slots:
bool eventFilter(QObject *, QEvent *);
void mouseMoveEvent(QMouseEvent *event);
void on_pushButton_clicked();
};
#endif // DOWNLOADLISTWIDGET_H

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DownloadListWidget</class>
<widget class="QWidget" name="DownloadListWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>547</width>
<height>416</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="SmoothListWidget" name="listWidget">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QListView,QScrollArea,QWidget#viewport,QWidget#scrollAreaWidgetContents
{
background-color:transparent;
margin:0px;
}
/**列表项选中*/
QListWidget::item::selected
{
background-color:transparent;
}</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="autoScroll">
<bool>true</bool>
</property>
<property name="autoScrollMargin">
<number>10</number>
</property>
<property name="resizeMode">
<enum>QListView::Fixed</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Open download directory</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SmoothListWidget</class>
<extends>QListWidget</extends>
<header>widgets/common/smoothlistwidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -1,238 +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;
QString oriSeverUrl = "https://d.store.deepinos.org.cn";
QString cdnSeverUrl = "https://cdn.d.store.deepinos.org.cn";
QString downloadTimesUrl = targetUrl.toString();
downloadTimesUrl = downloadTimesUrl.replace(oriSeverUrl, cdnSeverUrl);
downloadTimesUrl = downloadTimesUrl.replace("app.json", "download-times.txt");
httpClient->get(downloadTimesUrl)
.onResponse([this](QString downloadTimesFeedback)
{
qDebug() << "请求应用下载量信息 " << downloadTimesFeedback;
this->downloadTimes = downloadTimesFeedback.replace("\n","");
})
.onError([this](QString errorStr)
{
qDebug() << "请求下载量失败:" << errorStr;
this->downloadTimes = "0";
})
.block()
.timeout(3*1000)
.exec();
httpClient->get(targetUrl.toString().replace(oriSeverUrl, cdnSeverUrl))
.header("content-type", "application/json")
.onResponse([this](QByteArray json_array)
{
qDebug() << "请求应用信息 " << json_array;
QString urladdress, deatils, more, packagename, appweb;
bool isInstalled;
bool isUpdated;
// 将路径转化为相应源的下载路径
urladdress = targetUrl.toString().left(targetUrl.toString().length() - 8);
QStringList downloadurl = urladdress.split("/");
QString deburl = serverUrl;
deburl = deburl.left(urladdress.length() - 1);
QStringList url_ = targetUrl.toString().replace("//", "/").split("/");
urladdress = "https://" + url_[1];
// 使用 cdn 服务器
urladdress = "https://cdn.d.store.deepinos.org.cn"; // 使用图片专用服务器请保留这行,删除后将使用源服务器
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\n";
details += tr("Download Times: ") + this->downloadTimes + "\n";
more = json["More"].toString();
QProcess isInstall;
packagename = json["Pkgname"].toString();
isInstall.start("dpkg -s " + json["Pkgname"].toString());
isInstall.waitForFinished(180); // 默认超时 3 分钟
int error = QString::fromStdString(isInstall.readAllStandardError().toStdString()).length();
if(error == 0)
{
isInstalled = true;
QProcess isUpdate;
isUpdate.start("dpkg-query --showformat='${Version}' --show " + json["Pkgname"].toString());
isUpdate.waitForFinished(180); // 默认超时 3 分钟
QString localVersion = isUpdate.readAllStandardOutput();
localVersion.replace("'", "");
isUpdate.start("dpkg --compare-versions " + localVersion + " ge " + json["Version"].toString());
isUpdate.waitForFinished(180); // 默认超时 3 分钟
if(!isUpdate.exitCode())
{
isUpdated = true;
}
else
{
isUpdated = false;
}
}
else
{
isInstalled = false;
isUpdated = false;
}
emit requestSetAppInformation(&appName, &details, &more, &appweb, &packagename, &fileUrl, isInstalled, isUpdated);
// 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);
QFile icon("/tmp/spark-store/icon.png");
icon.open(QFile::WriteOnly);
appicon.save(&icon, "PNG");
icon.close();
})
.onError([this](QString errorStr)
{
Q_UNUSED(this)
Q_UNUSED(errorStr)
Widget::sendNotification(tr("Failed to load application icon."));
})
.block()
.timeout(-1)
.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(-1)
.exec();
}
emit finishAllLoading();
httpClient->deleteLater();
})
.onError([](QString errorStr)
{
Q_UNUSED(errorStr)
Widget::sendNotification(tr("Failed to download app info. Please check internet connection."));
})
.block()
.timeout(-1)
.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;
}

View File

@@ -1,52 +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;
QString downloadTimes;
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,
bool isUpdated);
void finishedIconLoad(QPixmap *icon);
void finishedScreenshotLoad(QPixmap *icon, int index); // 该信号必须以 BlockingQueued 方式连接
void finishAllLoading(); // 该信号必须以 BlockingQueued 方式连接
};
#endif // WORKERTHREADS_H