Merge commit '08848ac7817a704135014f222f156003c4a16832' into amzn-tommy/gitflow_211116_o3de2

This commit is contained in:
Tommy Walton
2021-11-16 11:41:18 -08:00
17 changed files with 136 additions and 45 deletions
@@ -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 = &currentFrame;
}
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.
+1 -1
View File
@@ -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
+6 -6
View File
@@ -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