Merge commit '08848ac7817a704135014f222f156003c4a16832' into amzn-tommy/gitflow_211116_o3de2
This commit is contained in:
@@ -41,5 +41,6 @@
|
||||
<file>Download.svg</file>
|
||||
<file>in_progress.gif</file>
|
||||
<file>gem.svg</file>
|
||||
<file>checkmark.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="15px" height="14px" viewBox="0 0 15 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Icons / Hub / Download Copy 5</title>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Screen-1-Copy-80" transform="translate(-425.000000, -251.000000)">
|
||||
<g id="Icons-/-Hub-/-Download-Copy-5" transform="translate(424.573941, 250.098705)">
|
||||
<rect id="Icon-Background" x="0" y="0" width="16" height="16"></rect>
|
||||
<path d="M8,1.33333333 C11.6818983,1.33333333 14.6666667,4.31810167 14.6666667,8 C14.6666667,11.6818983 11.6818983,14.6666667 8,14.6666667 C4.31810167,14.6666667 1.33333333,11.6818983 1.33333333,8 C1.33333333,4.31810167 4.31810167,1.33333333 8,1.33333333 Z M12.0947571,4 L5.96649831,10.1282588 L3.60947571,7.77123617 L2.66666667,8.71404521 L5.96649831,12.0138769 L13.0375661,4.94280904 L12.0947571,4 Z" id="Combined-Shape" fill="#58BC61"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -18,7 +18,6 @@ namespace O3DE::ProjectManager
|
||||
{
|
||||
DownloadController::DownloadController(QWidget* parent)
|
||||
: QObject()
|
||||
, m_lastProgress(0)
|
||||
, m_parent(parent)
|
||||
{
|
||||
m_worker = new DownloadWorker();
|
||||
@@ -69,10 +68,9 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadController::UpdateUIProgress(int progress)
|
||||
void DownloadController::UpdateUIProgress(int bytesDownloaded, int totalBytes)
|
||||
{
|
||||
m_lastProgress = progress;
|
||||
emit GemDownloadProgress(m_gemNames.front(), progress);
|
||||
emit GemDownloadProgress(m_gemNames.front(), bytesDownloaded, totalBytes);
|
||||
}
|
||||
|
||||
void DownloadController::HandleResults(const QString& result)
|
||||
@@ -88,6 +86,7 @@ namespace O3DE::ProjectManager
|
||||
QString gemName = m_gemNames.front();
|
||||
m_gemNames.erase(m_gemNames.begin());
|
||||
emit Done(gemName, succeeded);
|
||||
emit GemDownloadRemoved(gemName);
|
||||
|
||||
if (!m_gemNames.empty())
|
||||
{
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
public slots:
|
||||
void UpdateUIProgress(int progress);
|
||||
void UpdateUIProgress(int bytesDownloaded, int totalBytes);
|
||||
void HandleResults(const QString& result);
|
||||
|
||||
signals:
|
||||
@@ -61,14 +61,12 @@ namespace O3DE::ProjectManager
|
||||
void Done(const QString& gemName, bool success = true);
|
||||
void GemDownloadAdded(const QString& gemName);
|
||||
void GemDownloadRemoved(const QString& gemName);
|
||||
void GemDownloadProgress(const QString& gemName, int percentage);
|
||||
void GemDownloadProgress(const QString& gemName, int bytesDownloaded, int totalBytes);
|
||||
|
||||
private:
|
||||
DownloadWorker* m_worker;
|
||||
QThread m_workerThread;
|
||||
QWidget* m_parent;
|
||||
AZStd::vector<QString> m_gemNames;
|
||||
|
||||
int m_lastProgress;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -20,10 +20,9 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void DownloadWorker::StartDownload()
|
||||
{
|
||||
auto gemDownloadProgress = [=](int downloadProgress)
|
||||
auto gemDownloadProgress = [=](int bytesDownloaded, int totalBytes)
|
||||
{
|
||||
m_downloadProgress = downloadProgress;
|
||||
emit UpdateProgress(downloadProgress);
|
||||
emit UpdateProgress(bytesDownloaded, totalBytes);
|
||||
};
|
||||
AZ::Outcome<void, AZStd::string> gemInfoResult = PythonBindingsInterface::Get()->DownloadGem(m_gemName, gemDownloadProgress);
|
||||
if (gemInfoResult.IsSuccess())
|
||||
|
||||
@@ -31,12 +31,11 @@ namespace O3DE::ProjectManager
|
||||
void SetGemToDownload(const QString& gemName, bool downloadNow = true);
|
||||
|
||||
signals:
|
||||
void UpdateProgress(int progress);
|
||||
void UpdateProgress(int bytesDownloaded, int totalBytes);
|
||||
void Done(QString result = "");
|
||||
|
||||
private:
|
||||
|
||||
QString m_gemName;
|
||||
int m_downloadProgress;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <QProgressBar>
|
||||
#include <TagWidget.h>
|
||||
#include <QMenu>
|
||||
#include <QLocale>
|
||||
#include <QMovie>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
@@ -224,7 +226,6 @@ namespace O3DE::ProjectManager
|
||||
connect(m_downloadController, &DownloadController::GemDownloadAdded, this, &CartOverlayWidget::GemDownloadAdded);
|
||||
connect(m_downloadController, &DownloadController::GemDownloadRemoved, this, &CartOverlayWidget::GemDownloadRemoved);
|
||||
connect(m_downloadController, &DownloadController::GemDownloadProgress, this, &CartOverlayWidget::GemDownloadProgress);
|
||||
connect(m_downloadController, &DownloadController::Done, this, &CartOverlayWidget::GemDownloadComplete);
|
||||
}
|
||||
|
||||
void CartOverlayWidget::GemDownloadAdded(const QString& gemName)
|
||||
@@ -288,29 +289,41 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
void CartOverlayWidget::GemDownloadProgress(const QString& gemName, int percentage)
|
||||
void CartOverlayWidget::GemDownloadProgress(const QString& gemName, int bytesDownloaded, int totalBytes)
|
||||
{
|
||||
QWidget* gemToUpdate = m_downloadingListWidget->findChild<QWidget*>(gemName);
|
||||
if (gemToUpdate)
|
||||
{
|
||||
QLabel* progressLabel = gemToUpdate->findChild<QLabel*>("DownloadProgressLabel");
|
||||
if (progressLabel)
|
||||
{
|
||||
progressLabel->setText(QString("%1%").arg(percentage));
|
||||
}
|
||||
QProgressBar* progressBar = gemToUpdate->findChild<QProgressBar*>("DownloadProgressBar");
|
||||
if (progressBar)
|
||||
|
||||
// totalBytes can be 0 if the server does not return a content-length for the object
|
||||
if (totalBytes != 0)
|
||||
{
|
||||
progressBar->setValue(percentage);
|
||||
int downloadPercentage = static_cast<int>((bytesDownloaded / static_cast<float>(totalBytes)) * 100);
|
||||
if (progressLabel)
|
||||
{
|
||||
progressLabel->setText(QString("%1%").arg(downloadPercentage));
|
||||
}
|
||||
if (progressBar)
|
||||
{
|
||||
progressBar->setValue(downloadPercentage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (progressLabel)
|
||||
{
|
||||
progressLabel->setText(QLocale::system().formattedDataSize(bytesDownloaded));
|
||||
}
|
||||
if (progressBar)
|
||||
{
|
||||
progressBar->setRange(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CartOverlayWidget::GemDownloadComplete(const QString& gemName, bool /*success*/)
|
||||
{
|
||||
GemDownloadRemoved(gemName); // update the list to remove the gem that has finished
|
||||
}
|
||||
|
||||
QVector<Tag> CartOverlayWidget::GetTagsFromModelIndices(const QVector<QModelIndex>& gems) const
|
||||
{
|
||||
QVector<Tag> tags;
|
||||
@@ -389,7 +402,7 @@ namespace O3DE::ProjectManager
|
||||
{
|
||||
const QVector<QModelIndex> toBeAdded = m_gemModel->GatherGemsToBeAdded(/*includeDependencies=*/true);
|
||||
const QVector<QModelIndex> toBeRemoved = m_gemModel->GatherGemsToBeRemoved(/*includeDependencies=*/true);
|
||||
if (toBeAdded.isEmpty() && toBeRemoved.isEmpty())
|
||||
if (toBeAdded.isEmpty() && toBeRemoved.isEmpty() && m_downloadController->IsDownloadQueueEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -430,6 +443,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
GemCatalogHeaderWidget::GemCatalogHeaderWidget(GemModel* gemModel, GemSortFilterProxyModel* filterProxyModel, DownloadController* downloadController, QWidget* parent)
|
||||
: QFrame(parent)
|
||||
, m_downloadController(downloadController)
|
||||
{
|
||||
QHBoxLayout* hLayout = new QHBoxLayout();
|
||||
hLayout->setAlignment(Qt::AlignLeft);
|
||||
@@ -456,8 +470,25 @@ namespace O3DE::ProjectManager
|
||||
hLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
|
||||
hLayout->addSpacerItem(new QSpacerItem(75, 0, QSizePolicy::Fixed));
|
||||
|
||||
CartButton* cartButton = new CartButton(gemModel, downloadController);
|
||||
hLayout->addWidget(cartButton);
|
||||
// spinner
|
||||
m_downloadSpinnerMovie = new QMovie(":/in_progress.gif");
|
||||
m_downloadSpinner = new QLabel(this);
|
||||
m_downloadSpinner->setScaledContents(true);
|
||||
m_downloadSpinner->setMaximumSize(16, 16);
|
||||
m_downloadSpinner->setMovie(m_downloadSpinnerMovie);
|
||||
hLayout->addWidget(m_downloadSpinner);
|
||||
hLayout->addSpacing(8);
|
||||
|
||||
// downloading label
|
||||
m_downloadLabel = new QLabel(tr("Downloading"));
|
||||
hLayout->addWidget(m_downloadLabel);
|
||||
m_downloadSpinner->hide();
|
||||
m_downloadLabel->hide();
|
||||
|
||||
hLayout->addSpacing(16);
|
||||
|
||||
m_cartButton = new CartButton(gemModel, downloadController);
|
||||
hLayout->addWidget(m_cartButton);
|
||||
hLayout->addSpacing(16);
|
||||
|
||||
// Separating line
|
||||
@@ -479,6 +510,27 @@ namespace O3DE::ProjectManager
|
||||
gemMenuButton->setIcon(QIcon(":/menu.svg"));
|
||||
gemMenuButton->setIconSize(QSize(36, 24));
|
||||
hLayout->addWidget(gemMenuButton);
|
||||
|
||||
connect(m_downloadController, &DownloadController::GemDownloadAdded, this, &GemCatalogHeaderWidget::GemDownloadAdded);
|
||||
connect(m_downloadController, &DownloadController::GemDownloadRemoved, this, &GemCatalogHeaderWidget::GemDownloadRemoved);
|
||||
}
|
||||
|
||||
void GemCatalogHeaderWidget::GemDownloadAdded(const QString& /*gemName*/)
|
||||
{
|
||||
m_downloadSpinner->show();
|
||||
m_downloadLabel->show();
|
||||
m_downloadSpinnerMovie->start();
|
||||
m_cartButton->ShowOverlay();
|
||||
}
|
||||
|
||||
void GemCatalogHeaderWidget::GemDownloadRemoved(const QString& /*gemName*/)
|
||||
{
|
||||
if (m_downloadController->IsDownloadQueueEmpty())
|
||||
{
|
||||
m_downloadSpinner->hide();
|
||||
m_downloadLabel->hide();
|
||||
m_downloadSpinnerMovie->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void GemCatalogHeaderWidget::ReinitForProject()
|
||||
|
||||
@@ -24,6 +24,7 @@ QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
|
||||
QT_FORWARD_DECLARE_CLASS(QHBoxLayout)
|
||||
QT_FORWARD_DECLARE_CLASS(QHideEvent)
|
||||
QT_FORWARD_DECLARE_CLASS(QMoveEvent)
|
||||
QT_FORWARD_DECLARE_CLASS(QMovie)
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
@@ -39,8 +40,7 @@ namespace O3DE::ProjectManager
|
||||
public slots:
|
||||
void GemDownloadAdded(const QString& gemName);
|
||||
void GemDownloadRemoved(const QString& gemName);
|
||||
void GemDownloadProgress(const QString& gemName, int percentage);
|
||||
void GemDownloadComplete(const QString& gemName, bool success);
|
||||
void GemDownloadProgress(const QString& gemName, int bytesDownloaded, int totalBytes);
|
||||
|
||||
private:
|
||||
QVector<Tag> GetTagsFromModelIndices(const QVector<QModelIndex>& gems) const;
|
||||
@@ -96,6 +96,10 @@ namespace O3DE::ProjectManager
|
||||
|
||||
void ReinitForProject();
|
||||
|
||||
public slots:
|
||||
void GemDownloadAdded(const QString& gemName);
|
||||
void GemDownloadRemoved(const QString& gemName);
|
||||
|
||||
signals:
|
||||
void AddGem();
|
||||
void OpenGemsRepo();
|
||||
@@ -103,5 +107,10 @@ namespace O3DE::ProjectManager
|
||||
private:
|
||||
AzQtComponents::SearchLineEdit* m_filterLineEdit = nullptr;
|
||||
inline constexpr static int s_height = 60;
|
||||
DownloadController* m_downloadController = nullptr;
|
||||
QLabel* m_downloadSpinner = nullptr;
|
||||
QLabel* m_downloadLabel = nullptr;
|
||||
QMovie* m_downloadSpinnerMovie = nullptr;
|
||||
CartButton* m_cartButton = nullptr;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -483,7 +483,7 @@ namespace O3DE::ProjectManager
|
||||
QModelIndex index = m_gemModel->FindIndexByNameString(gemName);
|
||||
if (index.isValid())
|
||||
{
|
||||
m_gemModel->setData(index, GemInfo::Downloaded, GemModel::RoleDownloadStatus);
|
||||
m_proxyModel->setData(m_proxyModel->mapFromSource(index), GemInfo::DownloadSuccessful, GemModel::RoleDownloadStatus);
|
||||
m_gemModel->setData(index, gemInfo.m_path, GemModel::RolePath);
|
||||
m_gemModel->setData(index, gemInfo.m_path, GemModel::RoleDirectoryLink);
|
||||
}
|
||||
@@ -493,6 +493,14 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QModelIndex index = m_gemModel->FindIndexByNameString(gemName);
|
||||
if (index.isValid())
|
||||
{
|
||||
m_proxyModel->setData(m_proxyModel->mapFromSource(index), GemInfo::DownloadFailed, GemModel::RoleDownloadStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProjectManagerScreen GemCatalogScreen::GetScreenEnum()
|
||||
|
||||
@@ -57,7 +57,9 @@ namespace O3DE::ProjectManager
|
||||
UnknownDownloadStatus = -1,
|
||||
NotDownloaded,
|
||||
Downloading,
|
||||
Downloaded,
|
||||
DownloadSuccessful,
|
||||
DownloadFailed,
|
||||
Downloaded
|
||||
};
|
||||
static QString GetDownloadStatusString(DownloadStatus status);
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace O3DE::ProjectManager
|
||||
|
||||
SetStatusIcon(m_notDownloadedPixmap, ":/Download.svg");
|
||||
SetStatusIcon(m_unknownStatusPixmap, ":/X.svg");
|
||||
SetStatusIcon(m_downloadSuccessfulPixmap, ":/checkmark.svg");
|
||||
SetStatusIcon(m_downloadFailedPixmap, ":/Warning.svg");
|
||||
|
||||
m_downloadingMovie = new QMovie(":/in_progress.gif");
|
||||
}
|
||||
@@ -480,6 +482,14 @@ namespace O3DE::ProjectManager
|
||||
currentFrame = currentFrame.scaled(s_statusIconSize, s_statusIconSize);
|
||||
statusPixmap = ¤tFrame;
|
||||
}
|
||||
else if (downloadStatus == GemInfo::DownloadStatus::DownloadSuccessful)
|
||||
{
|
||||
statusPixmap = &m_downloadSuccessfulPixmap;
|
||||
}
|
||||
else if (downloadStatus == GemInfo::DownloadStatus::DownloadFailed)
|
||||
{
|
||||
statusPixmap = &m_downloadFailedPixmap;
|
||||
}
|
||||
else if (downloadStatus == GemInfo::DownloadStatus::NotDownloaded)
|
||||
{
|
||||
statusPixmap = &m_notDownloadedPixmap;
|
||||
|
||||
@@ -97,6 +97,8 @@ namespace O3DE::ProjectManager
|
||||
|
||||
QPixmap m_unknownStatusPixmap;
|
||||
QPixmap m_notDownloadedPixmap;
|
||||
QPixmap m_downloadSuccessfulPixmap;
|
||||
QPixmap m_downloadFailedPixmap;
|
||||
QMovie* m_downloadingMovie = nullptr;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -1166,7 +1166,7 @@ namespace O3DE::ProjectManager
|
||||
return AZ::Success(AZStd::move(gemRepos));
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> PythonBindings::DownloadGem(const QString& gemName, std::function<void(int)> gemProgressCallback)
|
||||
AZ::Outcome<void, AZStd::string> PythonBindings::DownloadGem(const QString& gemName, std::function<void(int, int)> gemProgressCallback)
|
||||
{
|
||||
// This process is currently limited to download a single gem at a time.
|
||||
bool downloadSucceeded = false;
|
||||
@@ -1181,9 +1181,9 @@ namespace O3DE::ProjectManager
|
||||
false, // skip auto register
|
||||
false, // force
|
||||
pybind11::cpp_function(
|
||||
[this, gemProgressCallback](int progress)
|
||||
[this, gemProgressCallback](int bytesDownloaded, int totalBytes)
|
||||
{
|
||||
gemProgressCallback(progress);
|
||||
gemProgressCallback(bytesDownloaded, totalBytes);
|
||||
|
||||
return m_requestCancelDownload;
|
||||
}) // Callback for download progress and cancelling
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace O3DE::ProjectManager
|
||||
bool AddGemRepo(const QString& repoUri) override;
|
||||
bool RemoveGemRepo(const QString& repoUri) override;
|
||||
AZ::Outcome<QVector<GemRepoInfo>, AZStd::string> GetAllGemRepoInfos() override;
|
||||
AZ::Outcome<void, AZStd::string> DownloadGem(const QString& gemName, std::function<void(int)> gemProgressCallback) override;
|
||||
AZ::Outcome<void, AZStd::string> DownloadGem(const QString& gemName, std::function<void(int, int)> gemProgressCallback) override;
|
||||
void CancelDownload() override;
|
||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetAllGemRepoGemsInfos() override;
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace O3DE::ProjectManager
|
||||
* @param gemProgressCallback a callback function that is called with an int percentage download value
|
||||
* @return an outcome with a string error message on failure.
|
||||
*/
|
||||
virtual AZ::Outcome<void, AZStd::string> DownloadGem(const QString& gemName, std::function<void(int)> gemProgressCallback) = 0;
|
||||
virtual AZ::Outcome<void, AZStd::string> DownloadGem(const QString& gemName, std::function<void(int, int)> gemProgressCallback) = 0;
|
||||
|
||||
/**
|
||||
* Cancels the current download.
|
||||
|
||||
@@ -105,7 +105,7 @@ def download_o3de_object(object_name: str, default_folder_name: str, dest_path:
|
||||
origin_uri = downloadable_object_data['originuri']
|
||||
parsed_uri = urllib.parse.urlparse(origin_uri)
|
||||
|
||||
download_zip_result = utils.download_zip_file(parsed_uri, download_zip_path, download_progress_callback)
|
||||
download_zip_result = utils.download_zip_file(parsed_uri, download_zip_path, force_overwrite, download_progress_callback)
|
||||
if download_zip_result != 0:
|
||||
return download_zip_result
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ def backup_folder(folder: str or pathlib.Path) -> None:
|
||||
if backup_folder_name.is_dir():
|
||||
renamed = True
|
||||
|
||||
def download_file(parsed_uri, download_path: pathlib.Path, force_overwrite, download_progress_callback = None) -> int:
|
||||
def download_file(parsed_uri, download_path: pathlib.Path, force_overwrite: bool = False, download_progress_callback = None) -> int:
|
||||
"""
|
||||
:param parsed_uri: uniform resource identifier to zip file to download
|
||||
:param download_path: location path on disk to download file
|
||||
@@ -140,9 +140,9 @@ def download_file(parsed_uri, download_path: pathlib.Path, force_overwrite, down
|
||||
download_file_size = s.headers['content-length']
|
||||
except KeyError:
|
||||
pass
|
||||
def download_progress(blocks):
|
||||
if download_progress_callback and download_file_size:
|
||||
return download_progress_callback(int(blocks/int(download_file_size) * 100))
|
||||
def download_progress(downloaded_bytes):
|
||||
if download_progress_callback:
|
||||
return download_progress_callback(int(downloaded_bytes), int(download_file_size))
|
||||
return False
|
||||
with download_path.open('wb') as f:
|
||||
download_cancelled = copyfileobj(s, f, download_progress)
|
||||
@@ -157,12 +157,12 @@ def download_file(parsed_uri, download_path: pathlib.Path, force_overwrite, down
|
||||
return 0
|
||||
|
||||
|
||||
def download_zip_file(parsed_uri, download_zip_path: pathlib.Path, download_progress_callback = None) -> int:
|
||||
def download_zip_file(parsed_uri, download_zip_path: pathlib.Path, force_overwrite: bool, download_progress_callback = None) -> int:
|
||||
"""
|
||||
:param parsed_uri: uniform resource identifier to zip file to download
|
||||
:param download_zip_path: path to output zip file
|
||||
"""
|
||||
download_file_result = download_file(parsed_uri, download_zip_path, download_progress_callback)
|
||||
download_file_result = download_file(parsed_uri, download_zip_path, force_overwrite, download_progress_callback)
|
||||
if download_file_result != 0:
|
||||
return download_file_result
|
||||
|
||||
|
||||
Reference in New Issue
Block a user