mirror of
https://gitee.com/spark-store-project/spark-store
synced 2025-07-19 03:52:22 +08:00
下载页面雏形,修复SpkPopup(改用弹出),添加应用列表固定图标缓存
This commit is contained in:
parent
f5a31affff
commit
179e57b9b5
@ -69,6 +69,7 @@ set(SOURCE_FILES
|
||||
inc/spkloading.h gui/spkloading.cpp
|
||||
inc/spksidebartree.h gui/spksidebartree.cpp
|
||||
inc/spkappitem.h gui/spkappitem.cpp
|
||||
inc/spkdownloadentry.h gui/spkdownloadentry.cpp
|
||||
inc/spkpopup.h gui/spkpopup.cpp
|
||||
inc/spkstretchlayout.h gui/spkstretchlayout.cpp
|
||||
inc/spkfocuslineedit.h
|
||||
@ -77,6 +78,7 @@ set(SOURCE_FILES
|
||||
inc/page/spkpageuitest.h gui/page/spkpageuitest.cpp
|
||||
inc/page/spkpageapplist.h gui/page/spkpageapplist.cpp
|
||||
inc/page/spkpageappdetails.h gui/page/spkpageappdetails.cpp
|
||||
inc/page/spkpagedownloads.h gui/page/spkpagedownloads.cpp
|
||||
|
||||
inc/spkstore.h src/spkstore.cpp
|
||||
inc/spkuimsg.h src/spkuimsg.cpp
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "page/spkpageappdetails.h"
|
||||
#include "spkutils.h"
|
||||
#include "spkappitem.h"
|
||||
|
||||
namespace SpkUi
|
||||
{
|
||||
@ -112,8 +113,8 @@ namespace SpkUi
|
||||
mAuthor->SetTitle(tr("Author"));
|
||||
mContributor = new SpkDetailEntry;
|
||||
mContributor->SetTitle(tr("Contributor"));
|
||||
mSite = new SpkDetailEntry;
|
||||
mSite->SetTitle(tr("Website"));
|
||||
// mSite = new SpkDetailEntry;
|
||||
// mSite->SetTitle(tr("Website"));
|
||||
mArch = new SpkDetailEntry;
|
||||
mArch->SetTitle(tr("Architecture"));
|
||||
mSize = new SpkDetailEntry;
|
||||
|
@ -7,6 +7,9 @@ namespace SpkUi
|
||||
{
|
||||
SpkPageAppList::SpkPageAppList(QWidget *parent) : SpkPageBase(parent)
|
||||
{
|
||||
mLoadingIcon = new QPixmap(QIcon(":/icons/loading-icon.svg").pixmap(SpkAppItem::IconSize_));
|
||||
mBrokenIcon = new QPixmap(QIcon(":/icons/broken-icon.svg").pixmap(SpkAppItem::IconSize_));
|
||||
|
||||
mAppsWidget = new QWidget;
|
||||
mAppsArea = new QScrollArea(this);
|
||||
mMainLay = new QVBoxLayout(this);
|
||||
@ -63,6 +66,7 @@ namespace SpkUi
|
||||
|
||||
auto iconRes = RES->RequestResource(id, pkgName, SpkResource::ResourceType::AppIcon,
|
||||
iconUrl, 0);
|
||||
// TODO: cache scaled icons
|
||||
QPixmap icon;
|
||||
if(iconRes.status == SpkResource::ResourceStatus::Ready)
|
||||
{
|
||||
@ -72,13 +76,13 @@ namespace SpkUi
|
||||
Qt::SmoothTransformation));
|
||||
else
|
||||
{
|
||||
item->SetIcon(QIcon(":/icons/broken-icon.svg").pixmap(SpkAppItem::IconSize_));
|
||||
item->SetIcon(*mBrokenIcon);
|
||||
RES->PurgeCachedResource(pkgName, SpkResource::ResourceType::AppIcon, 0);
|
||||
}
|
||||
}
|
||||
//TODO: prepare icons for loading entries
|
||||
// else
|
||||
// item->SetIcon(QPixmap(":/icons/loading_icon.svg").scaled(SpkAppItem::IconSize_));
|
||||
//TODO: [TEST] prepare icons for loading entries
|
||||
else
|
||||
item->SetIcon(*mLoadingIcon);
|
||||
|
||||
mAppItemList.append(item);
|
||||
mItemLay->addWidget(item);
|
||||
@ -110,11 +114,11 @@ namespace SpkUi
|
||||
Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation));
|
||||
else
|
||||
item->SetIcon(QIcon(":/icons/broken-icon.svg").pixmap(SpkAppItem::IconSize_));
|
||||
item->SetIcon(*mBrokenIcon);
|
||||
}
|
||||
else if(result.status == SpkResource::ResourceStatus::Failed)
|
||||
{
|
||||
item->SetIcon(QIcon(":/icons/broken-icon.svg").pixmap(SpkAppItem::IconSize_));
|
||||
item->SetIcon(*mBrokenIcon);
|
||||
RES->PurgeCachedResource(item->property("pkg_name").toString(),
|
||||
SpkResource::ResourceType::AppIcon, 0);
|
||||
}
|
||||
|
29
gui/page/spkpagedownloads.cpp
Normal file
29
gui/page/spkpagedownloads.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
|
||||
#include "page/spkpagedownloads.h"
|
||||
#include "spkutils.h"
|
||||
|
||||
SpkUi::SpkPageDownloads::SpkPageDownloads(QWidget *parent) :
|
||||
SpkPageBase(parent)
|
||||
{
|
||||
mMainLay = new QVBoxLayout(this);
|
||||
mLayEntries = new QVBoxLayout;
|
||||
mScrollWidget = new QWidget;
|
||||
mScrollArea = new QScrollArea(this);
|
||||
|
||||
mScrollWidget->setLayout(mLayEntries);
|
||||
mScrollArea->setWidget(mScrollWidget);
|
||||
mScrollArea->setWidgetResizable(true);
|
||||
mMainLay->addWidget(mScrollArea);
|
||||
setLayout(mMainLay);
|
||||
}
|
||||
|
||||
SpkUi::SpkPageDownloads::~SpkPageDownloads()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SpkUi::SpkPageDownloads::DownloadProgress(qint64 downloadedBytes, qint64 totalBytes, int id)
|
||||
{
|
||||
// TODO
|
||||
}
|
111
gui/spkdownloadentry.cpp
Normal file
111
gui/spkdownloadentry.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
|
||||
#include "spkdownloadentry.h"
|
||||
#include "spklogging.h"
|
||||
|
||||
constexpr QSize SpkDownloadEntry::IconSize;
|
||||
|
||||
SpkDownloadEntry::SpkDownloadEntry(QWidget *parent)
|
||||
{
|
||||
mIcon = new QLabel;
|
||||
mAppName = new ElidedLabel;
|
||||
mMessage = new QLabel;
|
||||
mProgress = new QProgressBar;
|
||||
mLoading = new SpkLoading;
|
||||
mBtnDelete = new QPushButton;
|
||||
mBtnActions = new QPushButton;
|
||||
|
||||
mLayInfo = new QVBoxLayout;
|
||||
mLayMsgs = new QHBoxLayout;
|
||||
mLayMain = new QHBoxLayout;
|
||||
|
||||
mLoading->setVisible(false);
|
||||
mIcon->setFixedSize(IconSize);
|
||||
mProgress->setRange(0, 1000);
|
||||
|
||||
mLayMsgs->addWidget(mAppName);
|
||||
mLayMsgs->addStretch();
|
||||
mLayMsgs->addWidget(mMessage);
|
||||
|
||||
mLayInfo->addLayout(mLayMsgs);
|
||||
mLayInfo->addWidget(mProgress);
|
||||
mLayInfo->setAlignment(Qt::AlignVCenter);
|
||||
|
||||
mLayMain->addWidget(mIcon);
|
||||
mLayMain->addLayout(mLayInfo);
|
||||
mLayMain->addWidget(mLoading);
|
||||
mLayMain->addWidget(mBtnActions);
|
||||
mLayMain->addWidget(mBtnDelete);
|
||||
|
||||
setLayout(mLayMain);
|
||||
}
|
||||
|
||||
|
||||
SpkDownloadEntry::~SpkDownloadEntry()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SpkDownloadEntry::SetBasicInfo(QString name, QPixmap icon)
|
||||
{
|
||||
mAppName->setText(name);
|
||||
mIcon->setPixmap(icon.scaled(IconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
}
|
||||
|
||||
void SpkDownloadEntry::SetStatus(DownloadEntryStatus status)
|
||||
{
|
||||
switch(status)
|
||||
{
|
||||
case Waiting:
|
||||
mMessage->setText(tr("Waiting for download"));
|
||||
mProgress->setVisible(false);
|
||||
mBtnActions->setVisible(false);
|
||||
mBtnDelete->setVisible(true);
|
||||
break;
|
||||
|
||||
case Downloading:
|
||||
mMessage->setText(tr(""));
|
||||
mProgress->setVisible(true);
|
||||
mBtnActions->setVisible(true);
|
||||
break;
|
||||
|
||||
case Paused:
|
||||
mMessage->setText(tr("Paused"));
|
||||
break;
|
||||
|
||||
case Failed:
|
||||
mMessage->setText(tr("Download Failed"));
|
||||
mProgress->setVisible(false);
|
||||
break;
|
||||
|
||||
case ToBeInstalled:
|
||||
mMessage->setText(tr("Download Finished"));
|
||||
mProgress->setVisible(false);
|
||||
break;
|
||||
|
||||
case Installing:
|
||||
mMessage->setText("");
|
||||
mProgress->setVisible(false);
|
||||
mLoading->setVisible(true);
|
||||
mLoading->Begin();
|
||||
|
||||
case Installed:
|
||||
mMessage->setText(tr("Installed"));
|
||||
mLoading->End();
|
||||
mLoading->setVisible(false);
|
||||
break;
|
||||
|
||||
case InstallFailed:
|
||||
mMessage->setText(tr("Install Failed"));
|
||||
mLoading->End();
|
||||
mLoading->setVisible(false);
|
||||
break;
|
||||
|
||||
case Invalid:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpkDownloadEntry::SetProgress(int p)
|
||||
{
|
||||
mProgress->setValue(p);
|
||||
}
|
@ -435,8 +435,13 @@ SpkUi::SpkMainWidget::SpkMainWidget(QWidget *parent) : QFrame(parent)
|
||||
AppDetailsItem = new QTreeWidgetItem(QStringList(tr("App Details")));
|
||||
AppDetailsItem->setData(0, SpkSidebarSelector::RoleItemIsCategory, false);
|
||||
AppDetailsItem->setData(0, SpkSidebarSelector::RoleItemCategoryPageId, SpkStackedPages::PgAppDetails);
|
||||
|
||||
CategoryParentItem = new QTreeWidgetItem(QStringList(tr("Categories")));
|
||||
CategoryParentItem->setFlags(CategoryParentItem->flags().setFlag(Qt::ItemIsSelectable, false));
|
||||
|
||||
DownloadsItem = new QTreeWidgetItem(QStringList(tr("Downloads")));
|
||||
DownloadsItem->setData(0, SpkSidebarSelector::RoleItemIsCategory, false);
|
||||
DownloadsItem->setData(0, SpkSidebarSelector::RoleItemCategoryPageId, SpkStackedPages::PgDownloads);
|
||||
#ifndef NDEBUG
|
||||
UiTestItem = new QTreeWidgetItem(QStringList(tr("UI TEST")));
|
||||
UiTestItem->setData(0, SpkSidebarSelector::RoleItemIsCategory, false);
|
||||
@ -525,6 +530,10 @@ SpkUi::SpkMainWidget::SpkMainWidget(QWidget *parent) : QFrame(parent)
|
||||
PageAppDetails->setProperty("spk_pageid", SpkStackedPages::PgAppDetails);
|
||||
sorter[PgAppDetails] = PageAppDetails;
|
||||
|
||||
PageDownloads = new SpkUi::SpkPageDownloads(this);
|
||||
PageDownloads->setProperty("spk_pageid", SpkStackedPages::PgDownloads);
|
||||
sorter[PgDownloads] = PageDownloads;
|
||||
|
||||
#ifndef NDEBUG // If only in debug mode should we initialize QSS test page
|
||||
PageQssTest = new SpkUi::SpkPageUiTest(this);
|
||||
PageQssTest->setProperty("spk_pageid", SpkStackedPages::PgQssTest);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include "spkui_general.h"
|
||||
#include "spkmainwindow.h"
|
||||
#include "spkmsgbox.h"
|
||||
#include "spkstore.h"
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
|
||||
#include "spkmainwindow.h"
|
||||
#include "spkpopup.h"
|
||||
#include <QDebug>
|
||||
|
||||
namespace SpkUi
|
||||
{
|
||||
SpkPopup::SpkPopup(QWidget *parent, int aMillis) : QWidget(parent)
|
||||
{
|
||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint);
|
||||
setWindowFlags(Qt::FramelessWindowHint);
|
||||
mText = new QLabel();
|
||||
mText->setStyleSheet("border-radius: 11px;"
|
||||
"background-color: rgba(0,0,0,150);"
|
||||
@ -22,19 +23,33 @@ namespace SpkUi
|
||||
// Qt::WA_TranslucentBackground will cause the entire background of QLabel transparent.
|
||||
// Therefore we need a container (SpkPopup) with a transparent background as the canvas layer
|
||||
// of the actual displayed text.
|
||||
mAnimFadeIn = new QPropertyAnimation(this, "windowOpacity");
|
||||
mAnimFadeOut = new QPropertyAnimation(this, "windowOpacity");
|
||||
mAnim = new QSequentialAnimationGroup(this);
|
||||
mAnimFadeIn->setStartValue(0);
|
||||
mAnimFadeIn->setEndValue(1);
|
||||
|
||||
// Disabled as translucency doesn't work well on every platform
|
||||
// mAnimFadeIn = new QPropertyAnimation(this, "windowOpacity");
|
||||
// mAnimFadeOut = new QPropertyAnimation(this, "windowOpacity");
|
||||
// mAnimFadeIn->setStartValue(0.0);
|
||||
// mAnimFadeIn->setEndValue(1.0);
|
||||
// mAnimFadeOut->setStartValue(1.0);
|
||||
// mAnimFadeOut->setEndValue(0.0);
|
||||
// Using moving animation instead
|
||||
mAnimFadeIn = new QPropertyAnimation(this, "pos");
|
||||
mAnimFadeOut = new QPropertyAnimation(this, "pos");
|
||||
mAnimFadeIn->setDuration(250);
|
||||
mAnimFadeOut->setStartValue(1);
|
||||
mAnimFadeOut->setEndValue(0);
|
||||
mAnimFadeOut->setDuration(250);
|
||||
mAnimFadeIn->setEasingCurve(QEasingCurve::InQuad);
|
||||
mAnimFadeOut->setEasingCurve(QEasingCurve::InQuad);
|
||||
|
||||
mAnim->addAnimation(mAnimFadeIn);
|
||||
mAnim->addPause(aMillis);
|
||||
mAnim->addAnimation(mAnimFadeOut);
|
||||
setVisible(false);
|
||||
|
||||
connect(mAnim, &QAnimationGroup::stateChanged,
|
||||
[=](QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
|
||||
{
|
||||
qDebug() << "OldState" << oldState << "NewState" << newState;
|
||||
});
|
||||
}
|
||||
|
||||
void SpkPopup::Show(QString aText)
|
||||
@ -44,11 +59,22 @@ namespace SpkUi
|
||||
QSize parentSize = parentWidget()->size();
|
||||
mText->setText(aText);
|
||||
adjustSize();
|
||||
move(QPoint((parentSize.width() - width()) / 2, parentSize.height() - height() - 30) +
|
||||
parentWidget()->pos());
|
||||
move(QPoint((parentSize.width() - width()) / 2, parentSize.height() - height() - 30)/* +
|
||||
parentWidget()->pos()*/);
|
||||
setMaximumWidth(parentSize.width() - 200);
|
||||
setWindowOpacity(1);
|
||||
show();
|
||||
|
||||
mAnimFadeIn->setStartValue(QPoint((parentSize.width() - width()) / 2,
|
||||
parentSize.height() + height()));
|
||||
mAnimFadeIn->setEndValue(QPoint((parentSize.width() - width()) / 2,
|
||||
parentSize.height() - height() - 80));
|
||||
mAnimFadeOut->setStartValue(QPoint((parentSize.width() - width()) / 2,
|
||||
parentSize.height() - height() - 80));
|
||||
mAnimFadeOut->setEndValue(QPoint((parentSize.width() - width()) / 2,
|
||||
parentSize.height() + height()));
|
||||
|
||||
qDebug() << "Popup size " << size() << "position" << pos() << "parent size" << parentWidget()->size();
|
||||
mAnim->start();
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,10 @@ namespace SpkUi
|
||||
SpkStretchLayout *mItemLay;
|
||||
QList<SpkAppItem *> mAppItemList;
|
||||
|
||||
// Cached icons
|
||||
QPixmap *mLoadingIcon,
|
||||
*mBrokenIcon;
|
||||
|
||||
QIntValidator *mPageValidator;
|
||||
|
||||
int mCategoryId, mCurrentPage;
|
||||
|
@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "spkstore.h"
|
||||
#include <QTimer>
|
||||
|
||||
/**
|
||||
* @note SpkDownloadMgr does NOT do download scheduling and other things; it's only a multithreaded
|
||||
@ -68,6 +69,8 @@ class SpkDownloadMgr : public QObject
|
||||
QFile mDestFile;
|
||||
QString mDestFolder, mCurrentRemotePath;
|
||||
RemoteFileInfo mCurrentRemoteFileInfo;
|
||||
QTimer mProgressEmitterTimer;
|
||||
qint64 mDownloadedBytes;
|
||||
|
||||
int mCurrentDownloadId;
|
||||
int mActiveWorkerCount;
|
||||
@ -88,6 +91,7 @@ class SpkDownloadMgr : public QObject
|
||||
private slots:
|
||||
void WorkerFinish();
|
||||
void WorkerDownloadProgress(); ///< Be connected to ***QNetworkReply::readyRead***
|
||||
void ProgressTimer();
|
||||
|
||||
private:
|
||||
void LinkReplyWithMe(QNetworkReply*);
|
||||
@ -95,7 +99,7 @@ class SpkDownloadMgr : public QObject
|
||||
void TryScheduleFailureRetries(int i); ///< Try schedule on a specific task slot.
|
||||
|
||||
signals:
|
||||
void DownloadProgressed(qint64 bytes, qint64 total);
|
||||
void DownloadProgressed(qint64 bytes, qint64 total, int id);
|
||||
void DownloadStopped(TaskResult status, int id);
|
||||
|
||||
|
||||
|
52
inc/spkdownloadentry.h
Normal file
52
inc/spkdownloadentry.h
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include "qt/elidedlabel.h"
|
||||
#include "spkloading.h"
|
||||
#include <QProgressBar>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class SpkDownloadEntry : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SpkDownloadEntry(QWidget* parent = nullptr);
|
||||
~SpkDownloadEntry();
|
||||
|
||||
static constexpr QSize IconSize { 64, 64 };
|
||||
|
||||
enum DownloadEntryStatus
|
||||
{
|
||||
Invalid = -1,
|
||||
Waiting,
|
||||
Downloading,
|
||||
Paused,
|
||||
Failed,
|
||||
ToBeInstalled,
|
||||
Installing,
|
||||
Installed,
|
||||
InstallFailed
|
||||
};
|
||||
|
||||
public slots:
|
||||
void SetBasicInfo(QString name, QPixmap icon);
|
||||
void SetStatus(DownloadEntryStatus status);
|
||||
void SetProgress(int);
|
||||
|
||||
private:
|
||||
QLabel *mIcon, *mMessage;
|
||||
ElidedLabel *mAppName;
|
||||
QProgressBar *mProgress;
|
||||
QPushButton *mBtnDelete,
|
||||
*mBtnActions; // Actions include Retry Pause Install etc, one status at a time
|
||||
SpkLoading *mLoading;
|
||||
|
||||
QHBoxLayout *mLayMsgs, *mLayMain;
|
||||
QVBoxLayout *mLayInfo;
|
||||
|
||||
};
|
@ -18,6 +18,7 @@
|
||||
#include "page/spkpageuitest.h"
|
||||
#include "page/spkpageapplist.h"
|
||||
#include "page/spkpageappdetails.h"
|
||||
#include "page/spkpagedownloads.h"
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
@ -28,6 +29,7 @@ namespace SpkUi
|
||||
PgInvalid = -1,
|
||||
PgAppList,
|
||||
PgAppDetails,
|
||||
PgDownloads,
|
||||
PgQssTest // Must be at last
|
||||
};
|
||||
|
||||
@ -152,6 +154,7 @@ namespace SpkUi
|
||||
|
||||
QTreeWidgetItem *CategoryParentItem,
|
||||
*AppDetailsItem,
|
||||
*DownloadsItem,
|
||||
*UiTestItem;
|
||||
|
||||
// Title bar search bar
|
||||
@ -163,6 +166,7 @@ namespace SpkUi
|
||||
SpkPageUiTest *PageQssTest;
|
||||
SpkPageAppList *PageAppList;
|
||||
SpkPageAppDetails *PageAppDetails;
|
||||
SpkPageDownloads *PageDownloads;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,8 @@ class SpkResource : public QObject
|
||||
|
||||
inline QString GetCachePath(const ResourceTask &task);
|
||||
|
||||
ResourceResult CacheLookup(QString pkgName, ResourceType type, QVariant info);
|
||||
|
||||
/**
|
||||
* @brief When the resource context was changed, the new context needs to acquire the resource
|
||||
* manager, so the resource manager can download resource for the new context.
|
||||
|
@ -8,9 +8,10 @@
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
|
||||
#include "spklogging.h"
|
||||
#include "spkmainwindow.h"
|
||||
#include "spkresource.h"
|
||||
|
||||
class SpkMainWindow;
|
||||
|
||||
/**
|
||||
* @brief SpkStore class is the core of the store client side program, it is constructed first and
|
||||
* handling all processing after the launch. All client side data should be held by it,
|
||||
|
@ -15,5 +15,6 @@
|
||||
<file>icons/settings.svg</file>
|
||||
<file>icons/daynight-dark.svg</file>
|
||||
<file>icons/daynight.svg</file>
|
||||
<file>icons/loading-icon.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -1,7 +1,10 @@
|
||||
|
||||
#include "spkdownload.h"
|
||||
#include "spkutils.h"
|
||||
#include "spkui_general.h"
|
||||
#include "spkpopup.h"
|
||||
#include <QEventLoop>
|
||||
#include <QDir>
|
||||
|
||||
SpkDownloadMgr::SpkDownloadMgr(QObject *parent)
|
||||
{
|
||||
@ -18,6 +21,12 @@ SpkDownloadMgr::SpkDownloadMgr(QObject *parent)
|
||||
|
||||
mCurrentDownloadId = -1;
|
||||
mActiveWorkerCount = 0;
|
||||
mDownloadedBytes = 0;
|
||||
|
||||
mProgressEmitterTimer.setInterval(800);
|
||||
|
||||
connect(&mProgressEmitterTimer, &QTimer::timeout,
|
||||
this, &SpkDownloadMgr::ProgressTimer);
|
||||
}
|
||||
|
||||
SpkDownloadMgr::~SpkDownloadMgr()
|
||||
@ -139,6 +148,8 @@ bool SpkDownloadMgr::StartNewDownload(QString path, int downloadId)
|
||||
i.Reply->setProperty("failCount", 0); // Used for fail retry algorithm
|
||||
}
|
||||
|
||||
mProgressEmitterTimer.start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -150,7 +161,27 @@ bool SpkDownloadMgr::PauseCurrentDownload()
|
||||
|
||||
bool SpkDownloadMgr::CancelCurrentDownload()
|
||||
{
|
||||
// UNIMPLEMENTED
|
||||
// Don't proceed when no downloads are there
|
||||
if(mCurrentDownloadId == -1)
|
||||
return false;
|
||||
|
||||
// Terminate all workers
|
||||
for(auto &i : mScheduledWorkers)
|
||||
{
|
||||
auto r = i.Reply;
|
||||
r->blockSignals(true);
|
||||
r->abort();
|
||||
r->deleteLater();
|
||||
}
|
||||
|
||||
// Terminate and delete the temporary file
|
||||
mDestFile.close();
|
||||
if(!mDestFile.remove())
|
||||
{
|
||||
sErr(tr("SpkDownloadMgr: Cannot remove destination file %1 of a cancelled task")
|
||||
.arg(mDestFile.fileName()));
|
||||
SpkUi::Popup->Show(tr("The destination file of the cancelled task can't be deleted!"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -178,6 +209,9 @@ void SpkDownloadMgr::WorkerFinish()
|
||||
mScheduledWorkers.clear();
|
||||
mFailureRetryQueue.clear();
|
||||
mCurrentDownloadId = -1;
|
||||
mDownloadedBytes = 0;
|
||||
|
||||
mProgressEmitterTimer.stop();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -217,6 +251,12 @@ void SpkDownloadMgr::WorkerDownloadProgress()
|
||||
mDestFile.seek(worker.BeginOffset + worker.BytesRecvd);
|
||||
mDestFile.write(replyData);
|
||||
worker.BytesRecvd += replyData.size();
|
||||
mDownloadedBytes += replyData.size();
|
||||
}
|
||||
|
||||
void SpkDownloadMgr::ProgressTimer()
|
||||
{
|
||||
emit DownloadProgressed(mDownloadedBytes, mCurrentRemoteFileInfo.Size, mCurrentDownloadId);
|
||||
}
|
||||
|
||||
void SpkDownloadMgr::LinkReplyWithMe(QNetworkReply *reply)
|
||||
|
@ -63,6 +63,18 @@ void SpkResource::ResourceDownloaded()
|
||||
|
||||
ResourceResult ret;
|
||||
ret.status = ResourceStatus::Ready;
|
||||
|
||||
if(reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
ret.status = ResourceStatus::Failed;
|
||||
sWarn(tr("SpkResource: %1 cannot be downloaded, error code %2")
|
||||
.arg(reply->url().toString())
|
||||
.arg(reply->error()));
|
||||
// Tell ResourceContext
|
||||
if(!reply->property("outdated").toBool())
|
||||
AcquisitionFinish(id, ret);
|
||||
}
|
||||
|
||||
ret.data = reply->readAll();
|
||||
|
||||
// Save cache to disk
|
||||
@ -106,12 +118,13 @@ void SpkResource::Acquire(SpkPageBase *dest, bool stopOngoing, bool clearQueue)
|
||||
// And abort as requested.
|
||||
if(stopOngoing)
|
||||
i->abort();
|
||||
delete i;
|
||||
mWorkingRequests.remove(i);
|
||||
}
|
||||
|
||||
mWorkingRequests.clear();
|
||||
|
||||
if(stopOngoing)
|
||||
{
|
||||
mWorkingRequests.clear();
|
||||
mRequestSemaphore->release(mMaximumConcurrent); // Release all semaphore users
|
||||
}
|
||||
|
||||
@ -138,7 +151,23 @@ ResourceResult SpkResource::LocateCachedResource(const ResourceTask &task)
|
||||
|
||||
// If there is the desired file, then we return the resource in binary
|
||||
auto cacheFullPath = GetCachePath(task);
|
||||
if(list.contains(SpkUtils::CutFileName(cacheFullPath)))
|
||||
|
||||
bool isCacheHit;
|
||||
// Wildcard support
|
||||
if(task.path == "*")
|
||||
{
|
||||
cacheFullPath.chop(1);
|
||||
auto filterResult = list.filter(SpkUtils::CutFileName(cacheFullPath));
|
||||
isCacheHit = !filterResult.isEmpty();
|
||||
if(isCacheHit)
|
||||
cacheFullPath = SpkUtils::CutPath(cacheFullPath) + '/' + filterResult[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
isCacheHit = list.contains(SpkUtils::CutFileName(cacheFullPath));
|
||||
}
|
||||
|
||||
if(isCacheHit)
|
||||
{
|
||||
// qInfo() << "Cache hit:" << GetCachePath(task);
|
||||
QFile cacheFile(cacheFullPath);
|
||||
@ -198,7 +227,13 @@ void SpkResource::PurgeCachedResource(const QString &aPkgName, SpkResource::Reso
|
||||
QString SpkResource::GetCachePath(const ResourceTask &task)
|
||||
{
|
||||
return mCacheDirectory + task.pkgName + '/' + ResourceName.value(task.type) + '.' +
|
||||
task.info.toString() + '.' + SpkUtils::CutFileName(task.path);
|
||||
task.info.toString() + '.' + SpkUtils::CutFileName(task.path);
|
||||
}
|
||||
|
||||
ResourceResult SpkResource::CacheLookup(QString pkgName, ResourceType type, QVariant info)
|
||||
{
|
||||
ResourceTask task { .pkgName = pkgName, .path = "*", .type = type, .info = info, .id = -1 };
|
||||
return LocateCachedResource(task);
|
||||
}
|
||||
|
||||
const QMap<SpkResource::ResourceType, QString> SpkResource::ResourceName
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "dtk/spkdtkplugin.h"
|
||||
#include "gitver.h"
|
||||
#include "spkmainwindow.h"
|
||||
#include "spkpopup.h"
|
||||
#include "spkstore.h"
|
||||
#include "spkutils.h"
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <QDebug>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include "spkutils.h"
|
||||
|
||||
void SpkUtils::VerifySingleRequest(QPointer<QNetworkReply> aReply)
|
||||
|
Loading…
x
Reference in New Issue
Block a user