123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include "SourceAssetDetailsPanel.h"
- #include "AssetTreeFilterModel.h"
- #include "GoToButton.h"
- #include "SourceAssetTreeItemData.h"
- #include "SourceAssetTreeModel.h"
- #include <AssetBuilderSDK/AssetBuilderSDK.h>
- #include <native/ui/GoToButtonDelegate.h>
- #include <native/ui/ui_GoToButton.h>
- #include <native/ui/ui_SourceAssetDetailsPanel.h>
- #include <native/utilities/assetUtils.h>
- #include <native/utilities/IPathConversion.h>
- #include <utilities/UuidManager.h>
- namespace AssetProcessor
- {
- SourceAssetDetailsPanel::SourceAssetDetailsPanel(QWidget* parent)
- : AssetDetailsPanel(parent)
- , m_ui(new Ui::SourceAssetDetailsPanel)
- {
- m_ui->setupUi(this);
- m_ui->scrollAreaWidgetContents->setLayout(m_ui->scrollableVerticalLayout);
- ResetText();
- auto* productsDelegate = new GoToButtonDelegate(this);
- connect(
- productsDelegate,
- &GoToButtonDelegate::Clicked,
- [this](const GoToButtonData& buttonData)
- {
- GoToProduct(buttonData.m_destination);
- });
- m_ui->productTable->setItemDelegate(productsDelegate);
- auto* intermediatesDelegate = new GoToButtonDelegate(this);
- connect(
- intermediatesDelegate,
- &GoToButtonDelegate::Clicked,
- [this](const GoToButtonData& buttonData)
- {
- GoToSource(buttonData.m_destination);
- });
- m_ui->IntermediateAssetsTable->setItemDelegate(intermediatesDelegate);
- auto* outgoingDependenciesDelegate = new GoToButtonDelegate(this);
- connect(
- outgoingDependenciesDelegate,
- &GoToButtonDelegate::Clicked,
- [this](const GoToButtonData& buttonData)
- {
- GoToSource(buttonData.m_destination);
- });
- m_ui->outgoingSourceDependenciesTable->setItemDelegate(outgoingDependenciesDelegate);
- auto* incomingDependenciesDelegate = new GoToButtonDelegate(this);
- connect(
- incomingDependenciesDelegate,
- &GoToButtonDelegate::Clicked,
- [this](const GoToButtonData& buttonData)
- {
- GoToSource(buttonData.m_destination);
- });
- m_ui->incomingSourceDependenciesTable->setItemDelegate(incomingDependenciesDelegate);
- }
- SourceAssetDetailsPanel::~SourceAssetDetailsPanel()
- {
- }
- void SourceAssetDetailsPanel::AssetDataSelectionChanged(const QItemSelection& selected, const QItemSelection& /*deselected*/)
- {
- AssetTreeFilterModel* filterModel = m_isIntermediateAsset ? m_intermediateFilterModel : m_sourceFilterModel;
- QItemSelection sourceSelection = filterModel->mapSelectionToSource(selected);
- // Even if multi-select is enabled, only display the first selected item.
- if (sourceSelection.indexes().count() == 0 || !sourceSelection.indexes()[0].isValid())
- {
- ResetText();
- return;
- }
- QModelIndex sourceModelIndex = sourceSelection.indexes()[0];
- if (!sourceModelIndex.isValid())
- {
- return;
- }
- AssetTreeItem* childItem = static_cast<AssetTreeItem*>(sourceModelIndex.internalPointer());
- const AZStd::shared_ptr<const SourceAssetTreeItemData> sourceItemData =
- AZStd::rtti_pointer_cast<const SourceAssetTreeItemData>(childItem->GetData());
- m_ui->assetNameLabel->setText(childItem->GetData()->m_name);
- if (childItem->GetData()->m_isFolder || !sourceItemData)
- {
- // Folders don't have details.
- SetDetailsVisible(false);
- return;
- }
- SetDetailsVisible(true);
- AssetDatabaseConnection assetDatabaseConnection;
- assetDatabaseConnection.OpenDatabase();
- if (m_isIntermediateAsset)
- {
- // First, find the product version of this intermediate asset.
- AZStd::string intermediateProductPath = AssetUtilities::GetIntermediateAssetDatabaseName(sourceItemData->m_assetDbName.c_str());
- AzToolsFramework::AssetDatabase::SourceDatabaseEntry upstreamSource;
- assetDatabaseConnection.QueryProductByProductName(
- intermediateProductPath.c_str(),
- [&](AzToolsFramework::AssetDatabase::ProductDatabaseEntry& productEntry)
- {
- // Second, get the source that created this product.
- assetDatabaseConnection.QuerySourceByProductID(
- productEntry.m_productID,
- [&](AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry)
- {
- upstreamSource = sourceEntry;
- return true;
- });
- return true;
- });
- // Finally, populate the UI with the information on the source that output this.
- m_ui->gotoAssetButton->m_ui->goToPushButton->disconnect();
- connect(
- m_ui->gotoAssetButton->m_ui->goToPushButton,
- &QPushButton::clicked,
- [=]
- {
- GoToSource(SourceAssetReference(upstreamSource).AbsolutePath().c_str());
- });
- m_ui->sourceAssetValueLabel->setText(upstreamSource.m_sourceName.c_str());
- }
- m_ui->scanFolderValueLabel->setText(sourceItemData->m_scanFolderInfo.m_scanFolder.c_str());
- m_ui->sourceGuidValueLabel->setText(sourceItemData->m_sourceInfo.m_sourceGuid.ToString<AZStd::string>().c_str());
- BuildProducts(assetDatabaseConnection, sourceItemData);
- BuildOutgoingSourceDependencies(assetDatabaseConnection, sourceItemData);
- BuildIncomingSourceDependencies(assetDatabaseConnection, sourceItemData);
- }
- void SourceAssetDetailsPanel::BuildProducts(
- AssetDatabaseConnection& assetDatabaseConnection, const AZStd::shared_ptr<const SourceAssetTreeItemData> sourceItemData)
- {
- // Clear & ClearContents leave the table dimensions the same, so set rowCount to zero to reset it.
- m_ui->productTable->setRowCount(0);
- m_ui->IntermediateAssetsTable->setRowCount(0);
- int intermediateAssetCount = 0;
- int productCount = 0;
- assetDatabaseConnection.QueryProductBySourceID(
- sourceItemData->m_sourceInfo.m_sourceID,
- [&](AzToolsFramework::AssetDatabase::ProductDatabaseEntry& productEntry)
- {
- AZ::s64 sourcePK;
- assetDatabaseConnection.QueryJobByProductID(
- productEntry.m_productID,
- [&sourcePK](AzToolsFramework::AssetDatabase::JobDatabaseEntry& jobEntry)
- {
- sourcePK = jobEntry.m_sourcePK;
- return true;
- });
- if (IsProductOutputFlagSet(productEntry, AssetBuilderSDK::ProductOutputFlags::IntermediateAsset))
- {
- m_ui->IntermediateAssetsTable->insertRow(intermediateAssetCount);
- AZStd::string intermediateAssetSourcePath;
- assetDatabaseConnection.QuerySourceBySourceID(
- sourcePK,
- [&intermediateAssetSourcePath](AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry)
- {
- intermediateAssetSourcePath = sourceEntry.m_sourceName;
- return true;
- });
- auto productPath = AssetUtilities::ProductPath::FromDatabasePath(productEntry.m_productName);
- auto* goToWidget = new QTableWidgetItem();
- goToWidget->setData(0, QVariant::fromValue(GoToButtonData{ productPath.GetIntermediatePath() }));
- QTableWidgetItem* rowName = new QTableWidgetItem(productEntry.m_productName.c_str());
- if (IsProductOutputFlagSet(productEntry, AssetBuilderSDK::ProductOutputFlags::CachedAsset))
- {
- rowName->setIcon(QIcon(":/cached_asset_item.png"));
- }
- m_ui->IntermediateAssetsTable->setItem(intermediateAssetCount, 0, goToWidget);
- m_ui->IntermediateAssetsTable->setItem(intermediateAssetCount, 1, rowName);
- ++intermediateAssetCount;
- }
- else
- {
- m_ui->productTable->insertRow(productCount);
- QTableWidgetItem* goToWidget = new QTableWidgetItem();
- goToWidget->setData(0, QVariant::fromValue(GoToButtonData{ productEntry.m_productName }));
- QTableWidgetItem* rowName = new QTableWidgetItem(productEntry.m_productName.c_str());
- if (IsProductOutputFlagSet(productEntry, AssetBuilderSDK::ProductOutputFlags::CachedAsset))
- {
- rowName->setIcon(QIcon(":/cached_asset_item.png"));
- }
- m_ui->productTable->setItem(productCount, 0, goToWidget);
- m_ui->productTable->setItem(productCount, 1, rowName);
- ++productCount;
- }
- return true;
- });
- m_ui->SourceAssetDetailTabs->setTabText(0, tr("Products (%1)").arg(productCount));
- m_ui->SourceAssetDetailTabs->setTabVisible(0, productCount > 0);
- m_ui->SourceAssetDetailTabs->setTabText(3, tr("Intermediate Assets (%1)").arg(intermediateAssetCount));
- m_ui->SourceAssetDetailTabs->setTabVisible(3, intermediateAssetCount > 0);
- }
- void SourceAssetDetailsPanel::BuildOutgoingSourceDependencies(
- AssetDatabaseConnection& assetDatabaseConnection, const AZStd::shared_ptr<const SourceAssetTreeItemData> sourceItemData)
- {
- m_ui->outgoingSourceDependenciesTable->setRowCount(0);
- int sourceDependencyCount = 0;
- assetDatabaseConnection.QueryDependsOnSourceBySourceDependency(
- sourceItemData->m_sourceInfo.m_sourceGuid,
- AzToolsFramework::AssetDatabase::SourceFileDependencyEntry::DEP_Any,
- [&](AzToolsFramework::AssetDatabase::SourceFileDependencyEntry& sourceFileDependencyEntry)
- {
- m_ui->outgoingSourceDependenciesTable->insertRow(sourceDependencyCount);
- // Some outgoing source dependencies are wildcard, or unresolved paths.
- // Only add a button to link to rows that actually exist.
- AzToolsFramework::AssetDatabase::SourceDatabaseEntry dependencyDetails;
- AZStd::string displayString;
- if (sourceFileDependencyEntry.m_dependsOnSource.IsUuid())
- {
- assetDatabaseConnection.QuerySourceBySourceGuid(
- sourceFileDependencyEntry.m_dependsOnSource.GetUuid(),
- [&](AzToolsFramework::AssetDatabase::SourceDatabaseEntry& entry)
- {
- dependencyDetails = entry;
- displayString = dependencyDetails.m_sourceName;
- return false;
- });
- if (displayString.empty())
- {
- displayString = sourceFileDependencyEntry.m_dependsOnSource.GetUuid().ToFixedString();
- }
- }
- else
- {
- AZStd::string queryString;
- if (AZ::IO::PathView(sourceFileDependencyEntry.m_dependsOnSource.GetPath().c_str()).IsAbsolute())
- {
- SourceAssetReference sourceAsset(sourceFileDependencyEntry.m_dependsOnSource.GetPath().c_str());
- AzToolsFramework::AssetDatabase::SourceDatabaseEntry sourceEntry;
- if (assetDatabaseConnection.GetSourceBySourceNameScanFolderId(
- sourceAsset.RelativePath().c_str(), sourceAsset.ScanFolderId(), sourceEntry))
- {
- dependencyDetails = sourceEntry;
- displayString = dependencyDetails.m_sourceName;
- }
- }
- else
- {
- AzToolsFramework::AssetDatabase::SourceDatabaseEntryContainer sources;
- if (assetDatabaseConnection.GetSourcesBySourceName(
- sourceFileDependencyEntry.m_dependsOnSource.GetPath().c_str(),
- sources))
- {
- // There may be multiple sources with the same relative path
- // Pick the one in the lowest ID scanfolder, which should correspond to the highest priority folder
- AZ::s64 lowestScanfolder = sources[0].m_scanFolderPK;
- for (const auto& source : sources)
- {
- if (source.m_scanFolderPK > lowestScanfolder)
- {
- lowestScanfolder = source.m_scanFolderPK;
- dependencyDetails = source;
- }
- }
- displayString = dependencyDetails.m_sourceName;
- }
- }
- if (displayString.empty())
- {
- displayString = sourceFileDependencyEntry.m_dependsOnSource.GetPath();
- }
- }
- IPathConversion* pathConversion = AZ::Interface<IPathConversion>::Get();
- AZ_Assert(pathConversion, "IPathConversion interface is not available");
- SourceAssetTreeModel* treeModel = dependencyDetails.m_scanFolderPK == pathConversion->GetIntermediateAssetScanFolderId()
- ? m_intermediateTreeModel : m_sourceTreeModel;
- QModelIndex goToIndex = treeModel->GetIndexForSource(dependencyDetails.m_sourceName, dependencyDetails.m_scanFolderPK);
- if (goToIndex.isValid())
- {
- auto* goToWidget = new QTableWidgetItem();
- goToWidget->setData(
- 0, QVariant::fromValue(GoToButtonData{ SourceAssetReference(dependencyDetails).AbsolutePath().String() }));
- m_ui->outgoingSourceDependenciesTable->setItem(sourceDependencyCount, 0, goToWidget);
- }
- QTableWidgetItem* rowName = new QTableWidgetItem(displayString.c_str());
- m_ui->outgoingSourceDependenciesTable->setItem(sourceDependencyCount, 1, rowName);
- ++sourceDependencyCount;
- return true;
- });
- m_ui->SourceAssetDetailTabs->setTabText(1, tr("Dependencies - Out (%1)").arg(sourceDependencyCount));
- m_ui->SourceAssetDetailTabs->setTabVisible(1, sourceDependencyCount > 0);
- }
- void SourceAssetDetailsPanel::BuildIncomingSourceDependencies(
- AssetDatabaseConnection& assetDatabaseConnection, const AZStd::shared_ptr<const SourceAssetTreeItemData> sourceItemData)
- {
- m_ui->incomingSourceDependenciesTable->setRowCount(0);
- int sourceDependencyCount = 0;
- auto absolutePath = AZ::IO::Path(sourceItemData->m_scanFolderInfo.m_scanFolder) / sourceItemData->m_sourceInfo.m_sourceName;
- assetDatabaseConnection.QuerySourceDependencyByDependsOnSource(
- sourceItemData->m_sourceInfo.m_sourceGuid,
- sourceItemData->m_sourceInfo.m_sourceName.c_str(),
- absolutePath.FixedMaxPathStringAsPosix().c_str(),
- AzToolsFramework::AssetDatabase::SourceFileDependencyEntry::DEP_Any,
- [&](AzToolsFramework::AssetDatabase::SourceFileDependencyEntry& sourceFileDependencyEntry)
- {
- m_ui->incomingSourceDependenciesTable->insertRow(sourceDependencyCount);
- AZStd::string sourceName;
- AzToolsFramework::AssetDatabase::SourceDatabaseEntry sourceEntry;
- assetDatabaseConnection.QuerySourceBySourceGuid(
- sourceFileDependencyEntry.m_sourceGuid,
- [&sourceName, &sourceEntry](const auto& entry)
- {
- sourceEntry = entry;
- sourceName = entry.m_sourceName;
- return false;
- });
- if (sourceName.empty())
- {
- sourceName = AZStd::string::format("Invalid UUID - %s", sourceFileDependencyEntry.m_sourceGuid.ToFixedString().c_str());
- }
- auto* goToWidget = new QTableWidgetItem();
- goToWidget->setData(0, QVariant::fromValue(GoToButtonData{ SourceAssetReference(sourceEntry).AbsolutePath().String() }));
- m_ui->incomingSourceDependenciesTable->setItem(sourceDependencyCount, 0, goToWidget);
- QTableWidgetItem* rowName = new QTableWidgetItem(QString(sourceName.c_str()));
- m_ui->incomingSourceDependenciesTable->setItem(sourceDependencyCount, 1, rowName);
- ++sourceDependencyCount;
- return true;
- });
- m_ui->SourceAssetDetailTabs->setTabText(2, tr("Dependencies - In (%1)").arg(sourceDependencyCount));
- m_ui->SourceAssetDetailTabs->setTabVisible(2, sourceDependencyCount > 0);
- }
- void SourceAssetDetailsPanel::ResetText()
- {
- m_ui->assetNameLabel->setText(tr("Select an asset to see details"));
- SetDetailsVisible(false);
- }
- void SourceAssetDetailsPanel::SetDetailsVisible(bool visible)
- {
- // The folder selected description has opposite visibility from everything else.
- m_ui->folderSelectedDescription->setVisible(!visible);
- m_ui->scanFolderTitleLabel->setVisible(visible);
- m_ui->scanFolderValueLabel->setVisible(visible);
- m_ui->sourceGuidTitleLabel->setVisible(visible);
- m_ui->sourceGuidValueLabel->setVisible(visible);
- m_ui->sourceAssetTitleLabel->setVisible(visible && m_isIntermediateAsset);
- m_ui->gotoAssetButton->setVisible(visible && m_isIntermediateAsset);
- m_ui->sourceAssetValueLabel->setVisible(visible && m_isIntermediateAsset);
- m_ui->AssetInfoSeparatorLine->setVisible(visible);
- m_ui->SourceAssetDetailTabs->setVisible(visible);
- }
- } // namespace AssetProcessor
|