/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include "SourceAssetDetailsPanel.h" #include "AssetTreeFilterModel.h" #include "GoToButton.h" #include "SourceAssetTreeItemData.h" #include "SourceAssetTreeModel.h" #include <AssetDatabase/AssetDatabase.h> #include <native/ui/ui_GoToButton.h> #include <native/ui/ui_SourceAssetDetailsPanel.h> #include <QHBoxLayout> #include <QItemSelection> 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(); } SourceAssetDetailsPanel::~SourceAssetDetailsPanel() { } void SourceAssetDetailsPanel::AssetDataSelectionChanged(const QItemSelection& selected, const QItemSelection& /*deselected*/) { QItemSelection sourceSelection = m_sourceFilterModel->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); 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()); AssetDatabaseConnection assetDatabaseConnection; assetDatabaseConnection.OpenDatabase(); 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); int productCount = 0; assetDatabaseConnection.QueryProductBySourceID( sourceItemData->m_sourceInfo.m_sourceID, [&](AzToolsFramework::AssetDatabase::ProductDatabaseEntry& productEntry) { m_ui->productTable->insertRow(productCount); // Qt handles cleanup automatically, setting this as the parent means // when this panel is torn down, these widgets will be destroyed. GoToButton* rowGoToButton = new GoToButton(this); connect(rowGoToButton->m_ui->goToPushButton, &QPushButton::clicked, [=] { GoToProduct(productEntry.m_productName); }); m_ui->productTable->setCellWidget(productCount, 0, rowGoToButton); QTableWidgetItem* rowName = new QTableWidgetItem(productEntry.m_productName.c_str()); m_ui->productTable->setItem(productCount, 1, rowName); ++productCount; return true; }); m_ui->productsValueLabel->setText(QString::number(productCount)); if (productCount == 0) { m_ui->productTable->insertRow(productCount); QTableWidgetItem* rowName = new QTableWidgetItem(tr("No products")); m_ui->productTable->setItem(productCount, 1, rowName); ++productCount; } // The default list behavior is to maintain size and let you scroll within. // The entire frame is scrollable here, so the list should adjust to fit the contents. m_ui->productTable->setMinimumHeight(m_ui->productTable->rowHeight(0) * productCount + 2 * m_ui->productTable->frameWidth()); m_ui->productTable->adjustSize(); } 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_sourceName.c_str(), nullptr, 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. QModelIndex goToIndex = m_sourceTreeModel->GetIndexForSource(sourceFileDependencyEntry.m_dependsOnSource); if (goToIndex.isValid()) { // Qt handles cleanup automatically, setting this as the parent means // when this panel is torn down, these widgets will be destroyed. GoToButton* rowGoToButton = new GoToButton(this); connect(rowGoToButton->m_ui->goToPushButton, &QPushButton::clicked, [=] { GoToSource(sourceFileDependencyEntry.m_dependsOnSource); }); m_ui->outgoingSourceDependenciesTable->setCellWidget(sourceDependencyCount, 0, rowGoToButton); } QTableWidgetItem* rowName = new QTableWidgetItem(sourceFileDependencyEntry.m_dependsOnSource.c_str()); m_ui->outgoingSourceDependenciesTable->setItem(sourceDependencyCount, 1, rowName); ++sourceDependencyCount; return true; }); m_ui->outgoingSourceDependenciesValueLabel->setText(QString::number(sourceDependencyCount)); if (sourceDependencyCount == 0) { m_ui->outgoingSourceDependenciesTable->insertRow(sourceDependencyCount); QTableWidgetItem* rowName = new QTableWidgetItem(tr("No source dependencies")); m_ui->outgoingSourceDependenciesTable->setItem(sourceDependencyCount, 1, rowName); ++sourceDependencyCount; } // The default list behavior is to maintain size and let you scroll within. // The entire frame is scrollable here, so the list should adjust to fit the contents. m_ui->outgoingSourceDependenciesTable->setMinimumHeight(m_ui->outgoingSourceDependenciesTable->rowHeight(0) * sourceDependencyCount + 2 * m_ui->outgoingSourceDependenciesTable->frameWidth()); m_ui->outgoingSourceDependenciesTable->adjustSize(); } void SourceAssetDetailsPanel::BuildIncomingSourceDependencies( AssetDatabaseConnection& assetDatabaseConnection, const AZStd::shared_ptr<const SourceAssetTreeItemData> sourceItemData) { m_ui->incomingSourceDependenciesTable->setRowCount(0); int sourceDependencyCount = 0; assetDatabaseConnection.QuerySourceDependencyByDependsOnSource( sourceItemData->m_sourceInfo.m_sourceName.c_str(), nullptr, AzToolsFramework::AssetDatabase::SourceFileDependencyEntry::DEP_Any, [&](AzToolsFramework::AssetDatabase::SourceFileDependencyEntry& sourceFileDependencyEntry) { m_ui->incomingSourceDependenciesTable->insertRow(sourceDependencyCount); // Qt handles cleanup automatically, setting this as the parent means // when this panel is torn down, these widgets will be destroyed. GoToButton* rowGoToButton = new GoToButton(this); connect(rowGoToButton->m_ui->goToPushButton, &QPushButton::clicked, [=] { GoToSource(sourceFileDependencyEntry.m_source); }); m_ui->incomingSourceDependenciesTable->setCellWidget(sourceDependencyCount, 0, rowGoToButton); QTableWidgetItem* rowName = new QTableWidgetItem(sourceFileDependencyEntry.m_source.c_str()); m_ui->incomingSourceDependenciesTable->setItem(sourceDependencyCount, 1, rowName); ++sourceDependencyCount; return true; }); m_ui->incomingSourceDependenciesValueLabel->setText(QString::number(sourceDependencyCount)); if (sourceDependencyCount == 0) { m_ui->incomingSourceDependenciesTable->insertRow(sourceDependencyCount); QTableWidgetItem* rowName = new QTableWidgetItem(tr("No source dependencies")); m_ui->incomingSourceDependenciesTable->setItem(sourceDependencyCount, 1, rowName); ++sourceDependencyCount; } // The default list behavior is to maintain size and let you scroll within. // The entire frame is scrollable here, so the list should adjust to fit the contents. m_ui->incomingSourceDependenciesTable->setMinimumHeight(m_ui->incomingSourceDependenciesTable->rowHeight(0) * sourceDependencyCount + 2 * m_ui->incomingSourceDependenciesTable->frameWidth()); m_ui->incomingSourceDependenciesTable->adjustSize(); } 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->productsTitleLabel->setVisible(visible); m_ui->productsValueLabel->setVisible(visible); m_ui->productTable->setVisible(visible); m_ui->outgoingSourceDependenciesTitleLabel->setVisible(visible); m_ui->outgoingSourceDependenciesValueLabel->setVisible(visible); m_ui->outgoingSourceDependenciesTable->setVisible(visible); m_ui->incomingSourceDependenciesTitleLabel->setVisible(visible); m_ui->incomingSourceDependenciesValueLabel->setVisible(visible); m_ui->incomingSourceDependenciesTable->setVisible(visible); m_ui->DependencySeparatorLine->setVisible(visible); } } #include <native/ui/SourceAssetDetailsPanel.moc>