mirror of
https://github.com/ONLYOFFICE/desktop-apps.git
synced 2026-02-10 18:05:16 +08:00
Merge pull request #1103 from ONLYOFFICE/feature/progress_unzipping_updates
Add feature: progress unzipping updates
This commit is contained in:
@ -66,6 +66,7 @@ enum MsgCommands {
|
||||
MSG_StartReplacingFiles,
|
||||
MSG_ClearTempFiles,
|
||||
MSG_Progress,
|
||||
MSG_UnzipProgress,
|
||||
MSG_StopDownload,
|
||||
MSG_OtherError,
|
||||
MSG_SetLanguage,
|
||||
|
||||
@ -224,6 +224,9 @@ void CSvcManager::init()
|
||||
m_pUnzip->onComplete([=](int error) {
|
||||
onCompleteUnzip(error);
|
||||
});
|
||||
m_pUnzip->onProgress([=](int percent) {
|
||||
m_socket->sendMessage(MSG_UnzipProgress, to_tstring(percent));
|
||||
});
|
||||
m_socket->onMessageReceived([=](void *data, size_t) {
|
||||
vector<tstring> params;
|
||||
if (m_socket->parseMessage(data, params) == 3) {
|
||||
|
||||
@ -34,101 +34,135 @@
|
||||
#include "platform_linux/utils.h"
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
#include <sys/stat.h>
|
||||
#include <cstring>
|
||||
|
||||
#define BLOCK_SIZE 10240
|
||||
|
||||
|
||||
int unzipArchive(const string &zipFilePath, const string &folderPath, std::atomic_bool &run, string &error)
|
||||
class CUnzip::CUnzipPrivate
|
||||
{
|
||||
if (!NS_File::fileExists(zipFilePath) || !NS_File::dirExists(folderPath)) {
|
||||
error = "Archive path is empty or dest dir not exist";
|
||||
return UNZIP_ERROR;
|
||||
}
|
||||
public:
|
||||
CUnzipPrivate()
|
||||
{}
|
||||
~CUnzipPrivate()
|
||||
{}
|
||||
|
||||
struct archive *arch = archive_read_new();
|
||||
archive_read_support_filter_xz(arch);
|
||||
archive_read_support_format_tar(arch);
|
||||
if (archive_read_open_filename(arch, zipFilePath.c_str(), BLOCK_SIZE) != ARCHIVE_OK) {
|
||||
error = "Cannot open archive";
|
||||
archive_read_free(arch);
|
||||
return UNZIP_ERROR;
|
||||
}
|
||||
int unzipArchive(const string &zipFilePath, const string &folderPath, string &error)
|
||||
{
|
||||
if (!NS_File::fileExists(zipFilePath) || !NS_File::dirExists(folderPath)) {
|
||||
error = "Archive path is empty or dest dir not exist";
|
||||
return UNZIP_ERROR;
|
||||
}
|
||||
int prev_percent = -1;
|
||||
struct stat file_stat;
|
||||
long total_size = (stat(zipFilePath.c_str(), &file_stat) == 0) ? file_stat.st_size : 0;
|
||||
|
||||
int res = ARCHIVE_OK;
|
||||
int ex_code = UNZIP_OK;
|
||||
struct archive_entry *entry;
|
||||
while ((res = archive_read_next_header(arch, &entry)) == ARCHIVE_OK) {
|
||||
if (!run) {
|
||||
ex_code = UNZIP_ABORT;
|
||||
break;
|
||||
struct archive *arch = archive_read_new();
|
||||
archive_read_support_filter_xz(arch);
|
||||
archive_read_support_format_tar(arch);
|
||||
if (archive_read_open_filename(arch, zipFilePath.c_str(), BLOCK_SIZE) != ARCHIVE_OK) {
|
||||
error = "Cannot open archive";
|
||||
archive_read_free(arch);
|
||||
return UNZIP_ERROR;
|
||||
}
|
||||
|
||||
const char *entryname = archive_entry_pathname(entry);
|
||||
if (!entryname) {
|
||||
error = "Invalid entry name";
|
||||
break;
|
||||
}
|
||||
|
||||
char outpath[1024] = {0};
|
||||
snprintf(outpath, sizeof(outpath), "%s/%s", folderPath.c_str(), entryname);
|
||||
|
||||
if (archive_entry_filetype(entry) == AE_IFREG) {
|
||||
archive_entry_set_pathname(entry, outpath);
|
||||
res = archive_read_extract(arch, entry, ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM
|
||||
| ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS
|
||||
| ARCHIVE_EXTRACT_NO_OVERWRITE);
|
||||
if (res != ARCHIVE_OK) {
|
||||
error = "Cannot extract entry";
|
||||
int res = ARCHIVE_OK;
|
||||
int ex_code = UNZIP_OK;
|
||||
struct archive_entry *entry;
|
||||
while ((res = archive_read_next_header(arch, &entry)) == ARCHIVE_OK) {
|
||||
if (!run) {
|
||||
ex_code = UNZIP_ABORT;
|
||||
break;
|
||||
}
|
||||
|
||||
const char *entryname = archive_entry_pathname(entry);
|
||||
if (!entryname) {
|
||||
error = "Invalid entry name";
|
||||
break;
|
||||
}
|
||||
|
||||
char outpath[1024] = {0};
|
||||
snprintf(outpath, sizeof(outpath), "%s/%s", folderPath.c_str(), entryname);
|
||||
|
||||
if (archive_entry_filetype(entry) == AE_IFREG) {
|
||||
archive_entry_set_pathname(entry, outpath);
|
||||
res = archive_read_extract(arch, entry, ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM
|
||||
| ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS
|
||||
| ARCHIVE_EXTRACT_NO_OVERWRITE);
|
||||
if (res != ARCHIVE_OK) {
|
||||
error = "Cannot extract entry";
|
||||
break;
|
||||
}
|
||||
if (total_size > 0 && progress_callback) {
|
||||
int percent = static_cast<int>(100.0 * ((double)archive_filter_bytes(arch, -1)/total_size));
|
||||
if (percent != prev_percent) {
|
||||
progress_callback(percent);
|
||||
prev_percent = percent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (res != ARCHIVE_EOF && ex_code != UNZIP_ABORT) {
|
||||
error = string("Error reading archive: ") + archive_error_string(arch);
|
||||
ex_code = UNZIP_ERROR;
|
||||
}
|
||||
|
||||
archive_read_close(arch);
|
||||
archive_read_free(arch);
|
||||
return ex_code;
|
||||
}
|
||||
|
||||
if (res != ARCHIVE_EOF && ex_code != UNZIP_ABORT) {
|
||||
error = string("Error reading archive: ") + archive_error_string(arch);
|
||||
ex_code = UNZIP_ERROR;
|
||||
}
|
||||
FnVoidInt complete_callback = nullptr,
|
||||
progress_callback = nullptr;
|
||||
std::atomic_bool run;
|
||||
std::future<void> future;
|
||||
};
|
||||
|
||||
archive_read_close(arch);
|
||||
archive_read_free(arch);
|
||||
return ex_code;
|
||||
}
|
||||
|
||||
CUnzip::CUnzip()
|
||||
|
||||
CUnzip::CUnzip() :
|
||||
pimpl(new CUnzipPrivate)
|
||||
{
|
||||
m_run = false;
|
||||
pimpl->run = false;
|
||||
}
|
||||
|
||||
CUnzip::~CUnzip()
|
||||
{
|
||||
m_run = false;
|
||||
if (m_future.valid())
|
||||
m_future.wait();
|
||||
pimpl->run = false;
|
||||
if (pimpl->future.valid())
|
||||
pimpl->future.wait();
|
||||
delete pimpl, pimpl = nullptr;
|
||||
}
|
||||
|
||||
void CUnzip::extractArchive(const string &zipFilePath, const string &folderPath)
|
||||
{
|
||||
m_run = false;
|
||||
if (m_future.valid())
|
||||
m_future.wait();
|
||||
m_run = true;
|
||||
m_future = std::async(std::launch::async, [=]() {
|
||||
pimpl->run = false;
|
||||
if (pimpl->future.valid())
|
||||
pimpl->future.wait();
|
||||
pimpl->run = true;
|
||||
pimpl->future = std::async(std::launch::async, [=]() {
|
||||
string error;
|
||||
int res = unzipArchive(zipFilePath, folderPath, m_run, error);
|
||||
int res = pimpl->unzipArchive(zipFilePath, folderPath, error);
|
||||
if (!error.empty())
|
||||
fprintf(stderr, "%s", error.c_str());
|
||||
if (m_complete_callback)
|
||||
m_complete_callback(res);
|
||||
if (pimpl->complete_callback)
|
||||
pimpl->complete_callback(res);
|
||||
});
|
||||
}
|
||||
|
||||
void CUnzip::stop()
|
||||
{
|
||||
m_run = false;
|
||||
pimpl->run = false;
|
||||
}
|
||||
|
||||
void CUnzip::onComplete(FnVoidInt callback)
|
||||
{
|
||||
m_complete_callback = callback;
|
||||
pimpl->complete_callback = callback;
|
||||
}
|
||||
|
||||
void CUnzip::onProgress(FnVoidInt callback)
|
||||
{
|
||||
pimpl->progress_callback = callback;
|
||||
}
|
||||
|
||||
@ -57,11 +57,11 @@ public:
|
||||
|
||||
/* callback */
|
||||
void onComplete(FnVoidInt callback);
|
||||
void onProgress(FnVoidInt callback);
|
||||
|
||||
private:
|
||||
FnVoidInt m_complete_callback = nullptr;
|
||||
std::atomic_bool m_run;
|
||||
std::future<void> m_future;
|
||||
class CUnzipPrivate;
|
||||
CUnzipPrivate *pimpl = nullptr;
|
||||
};
|
||||
|
||||
#endif // CUNZIP_H
|
||||
|
||||
@ -36,123 +36,194 @@
|
||||
#include <Shldisp.h>
|
||||
|
||||
|
||||
int extractRecursively(IShellDispatch *pISD, const CComPtr<Folder> &pSrcFolder, const wstring &destFolder, std::atomic_bool &run)
|
||||
class CUnzip::CUnzipPrivate
|
||||
{
|
||||
CComPtr<FolderItems> pItems;
|
||||
if (FAILED(pSrcFolder->Items(&pItems)))
|
||||
return UNZIP_ERROR;
|
||||
public:
|
||||
CUnzipPrivate()
|
||||
{}
|
||||
~CUnzipPrivate()
|
||||
{}
|
||||
|
||||
long itemCount = 0;
|
||||
if (FAILED(pItems->get_Count(&itemCount)))
|
||||
return UNZIP_ERROR;
|
||||
bool calcFilesCountRecursively(IShellDispatch *pISD, const CComPtr<Folder> &pSrcFolder)
|
||||
{
|
||||
CComPtr<FolderItems> pItems;
|
||||
if (FAILED(pSrcFolder->Items(&pItems)))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
if (!run)
|
||||
return UNZIP_ABORT;
|
||||
long itemCount = 0;
|
||||
if (FAILED(pItems->get_Count(&itemCount)))
|
||||
return false;
|
||||
|
||||
CComPtr<FolderItem> pItem;
|
||||
if (FAILED(pItems->Item(CComVariant(i), &pItem)))
|
||||
return UNZIP_ERROR;
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
CComPtr<FolderItem> pItem;
|
||||
if (FAILED(pItems->Item(CComVariant(i), &pItem)))
|
||||
return false;
|
||||
|
||||
VARIANT_BOOL isFolder = VARIANT_FALSE;
|
||||
if (FAILED(pItem->get_IsFolder(&isFolder)))
|
||||
return UNZIP_ERROR;
|
||||
VARIANT_BOOL isFolder = VARIANT_FALSE;
|
||||
if (FAILED(pItem->get_IsFolder(&isFolder)))
|
||||
return false;
|
||||
|
||||
if (isFolder == VARIANT_TRUE) {
|
||||
// Source path
|
||||
CComPtr<Folder> pSubFolder;
|
||||
if (FAILED(pISD->NameSpace(CComVariant(pItem), &pSubFolder)))
|
||||
return UNZIP_ERROR;
|
||||
if (isFolder == VARIANT_TRUE) {
|
||||
CComPtr<Folder> pSubFolder;
|
||||
if (FAILED(pISD->NameSpace(CComVariant(pItem), &pSubFolder)))
|
||||
return false;
|
||||
|
||||
// Dest path
|
||||
BSTR bstrName;
|
||||
if (FAILED(pItem->get_Name(&bstrName)))
|
||||
return UNZIP_ERROR;
|
||||
if (!calcFilesCountRecursively(pISD, pSubFolder))
|
||||
return false;
|
||||
|
||||
wstring targetFolder = destFolder + L"\\" + bstrName;
|
||||
SysFreeString(bstrName);
|
||||
if (CreateDirectory(targetFolder.c_str(), NULL) == 0)
|
||||
return UNZIP_ERROR;
|
||||
|
||||
int res = extractRecursively(pISD, pSubFolder, targetFolder, run);
|
||||
if (res != UNZIP_OK)
|
||||
return res;
|
||||
|
||||
} else {
|
||||
CComPtr<Folder> pDestFolder;
|
||||
if (FAILED(pISD->NameSpace(CComVariant(destFolder.c_str()), &pDestFolder)))
|
||||
return UNZIP_ERROR;
|
||||
if (FAILED(pDestFolder->CopyHere(CComVariant(pItem), CComVariant(1024 | 512 | 16 | 4))))
|
||||
return UNZIP_ERROR;
|
||||
} else {
|
||||
++total_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return UNZIP_OK;
|
||||
}
|
||||
|
||||
int unzipArchive(const wstring &zipFilePath, const wstring &folderPath, std::atomic_bool &run)
|
||||
{
|
||||
if (!NS_File::fileExists(zipFilePath) || !NS_File::dirExists(folderPath))
|
||||
return UNZIP_ERROR;
|
||||
|
||||
wstring file = NS_File::toNativeSeparators(zipFilePath);
|
||||
wstring path = NS_File::toNativeSeparators(folderPath);
|
||||
|
||||
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
if (FAILED(hr))
|
||||
return UNZIP_ERROR;
|
||||
|
||||
IShellDispatch *pShell = NULL;
|
||||
hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pShell));
|
||||
if (FAILED(hr)) {
|
||||
CoUninitialize();
|
||||
return UNZIP_ERROR;
|
||||
return true;
|
||||
}
|
||||
|
||||
CComPtr<Folder> pSrcFolder;
|
||||
if (FAILED(pShell->NameSpace(CComVariant(file.c_str()), &pSrcFolder))) {
|
||||
int extractRecursively(IShellDispatch *pISD, const CComPtr<Folder> &pSrcFolder, const wstring &destFolder)
|
||||
{
|
||||
CComPtr<FolderItems> pItems;
|
||||
if (FAILED(pSrcFolder->Items(&pItems)))
|
||||
return UNZIP_ERROR;
|
||||
|
||||
long itemCount = 0;
|
||||
if (FAILED(pItems->get_Count(&itemCount)))
|
||||
return UNZIP_ERROR;
|
||||
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
if (!run)
|
||||
return UNZIP_ABORT;
|
||||
|
||||
CComPtr<FolderItem> pItem;
|
||||
if (FAILED(pItems->Item(CComVariant(i), &pItem)))
|
||||
return UNZIP_ERROR;
|
||||
|
||||
VARIANT_BOOL isFolder = VARIANT_FALSE;
|
||||
if (FAILED(pItem->get_IsFolder(&isFolder)))
|
||||
return UNZIP_ERROR;
|
||||
|
||||
if (isFolder == VARIANT_TRUE) {
|
||||
// Source path
|
||||
CComPtr<Folder> pSubFolder;
|
||||
if (FAILED(pISD->NameSpace(CComVariant(pItem), &pSubFolder)))
|
||||
return UNZIP_ERROR;
|
||||
|
||||
// Dest path
|
||||
BSTR bstrName;
|
||||
if (FAILED(pItem->get_Name(&bstrName)))
|
||||
return UNZIP_ERROR;
|
||||
|
||||
wstring targetFolder = destFolder + L"\\" + bstrName;
|
||||
SysFreeString(bstrName);
|
||||
if (CreateDirectory(targetFolder.c_str(), NULL) == 0)
|
||||
return UNZIP_ERROR;
|
||||
|
||||
int res = extractRecursively(pISD, pSubFolder, targetFolder);
|
||||
if (res != UNZIP_OK)
|
||||
return res;
|
||||
|
||||
} else {
|
||||
CComPtr<Folder> pDestFolder;
|
||||
if (FAILED(pISD->NameSpace(CComVariant(destFolder.c_str()), &pDestFolder)))
|
||||
return UNZIP_ERROR;
|
||||
if (FAILED(pDestFolder->CopyHere(CComVariant(pItem), CComVariant(1024 | 512 | 16 | 4))))
|
||||
return UNZIP_ERROR;
|
||||
if (total_count > 0 && progress_callback) {
|
||||
++curr_count;
|
||||
int percent = static_cast<int>(100.0 * ((double)curr_count / total_count));
|
||||
if (percent != prev_percent) {
|
||||
progress_callback(percent);
|
||||
prev_percent = percent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return UNZIP_OK;
|
||||
}
|
||||
|
||||
int unzipArchive(const wstring &zipFilePath, const wstring &folderPath)
|
||||
{
|
||||
if (!NS_File::fileExists(zipFilePath) || !NS_File::dirExists(folderPath))
|
||||
return UNZIP_ERROR;
|
||||
|
||||
wstring file = NS_File::toNativeSeparators(zipFilePath);
|
||||
wstring path = NS_File::toNativeSeparators(folderPath);
|
||||
|
||||
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
if (FAILED(hr))
|
||||
return UNZIP_ERROR;
|
||||
|
||||
IShellDispatch *pShell = NULL;
|
||||
hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pShell));
|
||||
if (FAILED(hr)) {
|
||||
CoUninitialize();
|
||||
return UNZIP_ERROR;
|
||||
}
|
||||
|
||||
CComPtr<Folder> pSrcFolder;
|
||||
if (FAILED(pShell->NameSpace(CComVariant(file.c_str()), &pSrcFolder))) {
|
||||
pShell->Release();
|
||||
CoUninitialize();
|
||||
return UNZIP_ERROR;
|
||||
}
|
||||
|
||||
prev_percent = -1;
|
||||
curr_count = 0;
|
||||
total_count = 0;
|
||||
if (!calcFilesCountRecursively(pShell, pSrcFolder))
|
||||
total_count = 0;
|
||||
int res = extractRecursively(pShell, pSrcFolder, path);
|
||||
pSrcFolder.Release();
|
||||
pShell->Release();
|
||||
CoUninitialize();
|
||||
return UNZIP_ERROR;
|
||||
return res;
|
||||
}
|
||||
|
||||
int res = extractRecursively(pShell, pSrcFolder, path, run);
|
||||
pSrcFolder.Release();
|
||||
pShell->Release();
|
||||
CoUninitialize();
|
||||
return res;
|
||||
}
|
||||
FnVoidInt complete_callback = nullptr,
|
||||
progress_callback = nullptr;
|
||||
std::atomic_bool run;
|
||||
std::future<void> future;
|
||||
int curr_count = 0,
|
||||
total_count = 0,
|
||||
prev_percent = -1;
|
||||
};
|
||||
|
||||
CUnzip::CUnzip()
|
||||
CUnzip::CUnzip() :
|
||||
pimpl(new CUnzipPrivate)
|
||||
{
|
||||
m_run = false;
|
||||
pimpl->run = false;
|
||||
}
|
||||
|
||||
CUnzip::~CUnzip()
|
||||
{
|
||||
m_run = false;
|
||||
if (m_future.valid())
|
||||
m_future.wait();
|
||||
pimpl->run = false;
|
||||
if (pimpl->future.valid())
|
||||
pimpl->future.wait();
|
||||
delete pimpl, pimpl = nullptr;
|
||||
}
|
||||
|
||||
void CUnzip::extractArchive(const wstring &zipFilePath, const wstring &folderPath)
|
||||
{
|
||||
m_run = false;
|
||||
if (m_future.valid())
|
||||
m_future.wait();
|
||||
m_run = true;
|
||||
m_future = std::async(std::launch::async, [=]() {
|
||||
int res = unzipArchive(zipFilePath, folderPath, m_run);
|
||||
if (m_complete_callback)
|
||||
m_complete_callback(res);
|
||||
pimpl->run = false;
|
||||
if (pimpl->future.valid())
|
||||
pimpl->future.wait();
|
||||
pimpl->run = true;
|
||||
pimpl->future = std::async(std::launch::async, [=]() {
|
||||
int res = pimpl->unzipArchive(zipFilePath, folderPath);
|
||||
if (pimpl->complete_callback)
|
||||
pimpl->complete_callback(res);
|
||||
});
|
||||
}
|
||||
|
||||
void CUnzip::stop()
|
||||
{
|
||||
m_run = false;
|
||||
pimpl->run = false;
|
||||
}
|
||||
|
||||
void CUnzip::onComplete(FnVoidInt callback)
|
||||
{
|
||||
m_complete_callback = callback;
|
||||
pimpl->complete_callback = callback;
|
||||
}
|
||||
|
||||
void CUnzip::onProgress(FnVoidInt callback)
|
||||
{
|
||||
pimpl->progress_callback = callback;
|
||||
}
|
||||
|
||||
@ -57,11 +57,11 @@ public:
|
||||
|
||||
/* callback */
|
||||
void onComplete(FnVoidInt callback);
|
||||
void onProgress(FnVoidInt callback);
|
||||
|
||||
private:
|
||||
FnVoidInt m_complete_callback = nullptr;
|
||||
std::atomic_bool m_run;
|
||||
std::future<void> m_future;
|
||||
class CUnzipPrivate;
|
||||
CUnzipPrivate *pimpl = nullptr;
|
||||
};
|
||||
|
||||
#endif // CUNZIP_H
|
||||
|
||||
@ -91,6 +91,7 @@ const char *SVC_TXT_ERR_UNPACKING = QT_TRANSLATE_NOOP("CUpdateManager", "An er
|
||||
*TXT_AVAILABLE_UPD = QT_TRANSLATE_NOOP("CUpdateManager", "Update is available (version %1)"),
|
||||
*TXT_DOWNLOADING_UPD = QT_TRANSLATE_NOOP("CUpdateManager", "Downloading new version %1 (%2%)"),
|
||||
*TXT_PREPARING_UPD = QT_TRANSLATE_NOOP("CUpdateManager", "Preparing update..."),
|
||||
*TXT_UNZIP_UPD = QT_TRANSLATE_NOOP("CUpdateManager", "Preparing update (%1%)"),
|
||||
*TXT_RESTART_TO_UPD = QT_TRANSLATE_NOOP("CUpdateManager", "To finish updating, restart app"),
|
||||
*TXT_ERR_NOT_ALLOWED = QT_TRANSLATE_NOOP("CUpdateManager", "Updates are not allowed!"),
|
||||
*TXT_ERR_URL = QT_TRANSLATE_NOOP("CUpdateManager", "Unable to check update: URL not defined."),
|
||||
@ -351,6 +352,10 @@ void CUpdateManager::init()
|
||||
QMetaObject::invokeMethod(this, "onProgressSlot", Qt::QueuedConnection, Q_ARG(int, std::stoi(params[1])));
|
||||
break;
|
||||
|
||||
case MSG_UnzipProgress:
|
||||
QMetaObject::invokeMethod(this, "onUnzipProgressSlot", Qt::QueuedConnection, Q_ARG(int, std::stoi(params[1])));
|
||||
break;
|
||||
|
||||
case MSG_RequestContentLenght: {
|
||||
double fileSize = std::stod(params[1])/1024/1024;
|
||||
m_packageData->fileSize = (fileSize == 0) ? "--" : QString::number(fileSize, 'f', 1);
|
||||
@ -450,6 +455,11 @@ void CUpdateManager::onProgressSlot(const int percent)
|
||||
refreshStartPage({"", {TXT_DOWNLOADING_UPD, m_packageData->version, QString::number(percent)}});
|
||||
}
|
||||
|
||||
void CUpdateManager::onUnzipProgressSlot(const int percent)
|
||||
{
|
||||
refreshStartPage({"", {TXT_UNZIP_UPD, QString::number(percent)}});
|
||||
}
|
||||
|
||||
void CUpdateManager::onError(const QString &error)
|
||||
{
|
||||
const char *_error = SVC_TXT_ERR_OTHER;
|
||||
|
||||
@ -141,6 +141,7 @@ private slots:
|
||||
void onLoadUpdateFinished(const QString &filePath);
|
||||
void showStartInstallMessage(QWidget *parent);
|
||||
void onProgressSlot(const int percent);
|
||||
void onUnzipProgressSlot(const int percent);
|
||||
void onError(const QString &error);
|
||||
void criticalMsg(QWidget *parent, const QString &msg);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user