// Copyright Epic Games, Inc. All Rights Reserved. #include "Fbx/SSceneReimportStaticMeshListView.h" #include "Modules/ModuleManager.h" #include "Widgets/SOverlay.h" #include "Textures/SlateIcon.h" #include "Framework/Commands/UIAction.h" #include "Widgets/Images/SImage.h" #include "Framework/MultiBox/MultiBoxBuilder.h" #include "Widgets/Input/SCheckBox.h" #include "EditorStyleSet.h" #include "Factories/FbxSceneImportData.h" #include "Engine/StaticMesh.h" #include "AssetData.h" #include "Styling/SlateIconFinder.h" #include "IContentBrowserSingleton.h" #include "ContentBrowserModule.h" #include "Fbx/SSceneImportNodeTreeView.h" #include "SFbxSceneOptionWindow.h" #include "FbxImporter.h" #define LOCTEXT_NAMESPACE "SFbxReimportSceneStaticMeshListView" namespace FbxSceneReimportStaticMesh { const FName CheckBoxSelectionHeaderIdName(TEXT("CheckBoxSelectionHeaderId")); const FName ClassIconHeaderIdName(TEXT("ClassIconHeaderId")); const FName AssetNameHeaderIdName(TEXT("AssetNameHeaderId")); const FName AssetStatusHeaderIdName(TEXT("AssetStatusHeaderId")); const FName ContentPathHeaderIdName(TEXT("ContentPathHeaderId")); const FName OptionNameHeaderIdName(TEXT("OptionNameHeaderId")); } // namespace FbxSceneReimportStaticMesh class SFbxMeshReimportItemTableListViewRow: public SMultiColumnTableRow { public: SLATE_BEGIN_ARGS(SFbxMeshReimportItemTableListViewRow) : _FbxMeshInfo(nullptr), _MeshStatusMap(nullptr), _GlobalImportSettings(nullptr) {} SLATE_ARGUMENT(FbxMeshInfoPtr, FbxMeshInfo) SLATE_ARGUMENT(FbxSceneReimportStatusMapPtr, MeshStatusMap) SLATE_ARGUMENT(UnFbx::FBXImportOptions*, GlobalImportSettings) SLATE_END_ARGS() /** Construct function for this widget */ void Construct(const FArguments& InArgs, const TSharedRef& InOwnerTableView) { FbxMeshInfo = InArgs._FbxMeshInfo; MeshStatusMap = InArgs._MeshStatusMap; GlobalImportSettings = InArgs._GlobalImportSettings; // This is suppose to always be valid check(FbxMeshInfo.IsValid()); check(MeshStatusMap != nullptr); check(GlobalImportSettings != nullptr); // Get item data GetItemRowData(); SMultiColumnTableRow::Construct( FSuperRowType::FArguments() .Style(FEditorStyle::Get(), "DataTableEditor.CellListViewRow"), InOwnerTableView); } // Update the data at every tick virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) { GetItemRowData(); } /** Overridden from SMultiColumnTableRow. Generates a widget for this column of the list view. */ virtual TSharedRef GenerateWidgetForColumn(const FName& ColumnName) override { if (ColumnName == FbxSceneReimportStaticMesh::CheckBoxSelectionHeaderIdName) { return SNew(SBox) .HAlign(HAlign_Center) [SNew(SCheckBox) .OnCheckStateChanged(this, &SFbxMeshReimportItemTableListViewRow::OnItemCheckChanged) .IsChecked(this, &SFbxMeshReimportItemTableListViewRow::IsItemChecked) .IsEnabled(!FbxMeshInfo->bOriginalTypeChanged)]; } else if (ColumnName == FbxSceneReimportStaticMesh::ClassIconHeaderIdName && SlateBrush != nullptr) { UClass* IconClass = FbxMeshInfo->GetType(); const FSlateBrush* ClassIcon = FSlateIconFinder::FindIconBrushForClass(IconClass); TSharedRef IconContent = SNew(SOverlay) + SOverlay::Slot().HAlign(HAlign_Right).VAlign(VAlign_Center)[SNew(SImage).Image(ClassIcon)] + SOverlay::Slot().HAlign(HAlign_Left)[SNew(SImage).Image(this, &SFbxMeshReimportItemTableListViewRow::GetIconOverlay)] + SOverlay::Slot().HAlign(HAlign_Left)[SNew(SImage).Image(this, &SFbxMeshReimportItemTableListViewRow::GetBrushForOverrideIcon)]; return IconContent; } else if (ColumnName == FbxSceneReimportStaticMesh::AssetNameHeaderIdName) { return SNew(STextBlock) .Text(FText::FromString(FbxMeshInfo->Name)) .ToolTipText(FText::FromString(FbxMeshInfo->Name)); } else if (ColumnName == FbxSceneReimportStaticMesh::AssetStatusHeaderIdName) { return SNew(STextBlock) .Text(this, &SFbxMeshReimportItemTableListViewRow::GetAssetStatus) .ToolTipText(this, &SFbxMeshReimportItemTableListViewRow::GetAssetStatusTooltip); } else if (ColumnName == FbxSceneReimportStaticMesh::ContentPathHeaderIdName) { return SNew(STextBlock) .Text(this, &SFbxMeshReimportItemTableListViewRow::GetAssetFullName) .ColorAndOpacity(this, &SFbxMeshReimportItemTableListViewRow::GetContentPathTextColor) .ToolTipText(this, &SFbxMeshReimportItemTableListViewRow::GetAssetFullName); } else if (ColumnName == FbxSceneReimportStaticMesh::OptionNameHeaderIdName) { return SNew(STextBlock) .Text(this, &SFbxMeshReimportItemTableListViewRow::GetOptionName) .ToolTipText(this, &SFbxMeshReimportItemTableListViewRow::GetOptionName); } else if (ColumnName == FbxSceneBaseListViewColumn::PivotColumnId) { return SNew(STextBlock) .Text(this, &SFbxMeshReimportItemTableListViewRow::GetAssetPivotNodeName) .ToolTipText(this, &SFbxMeshReimportItemTableListViewRow::GetAssetPivotNodeName); } return SNullWidget::NullWidget; } private: FSlateColor GetContentPathTextColor() const { return FbxMeshInfo->bOverridePath ? FLinearColor(0.75f, 0.75f, 0.0f, 1.0f) : FSlateColor::UseForeground(); } const FSlateBrush* GetIconOverlay() const { return SlateBrush; } const FSlateBrush* GetBrushForOverrideIcon() const { if (UFbxSceneImportFactory::DefaultOptionName.Compare(FbxMeshInfo->OptionName) != 0) { return FEditorStyle::GetBrush("FBXIcon.ImportOptionsOverride"); } return FEditorStyle::GetBrush("FBXIcon.ImportOptionsDefault"); } FText GetOptionName() const { return FText::FromString(FbxMeshInfo->OptionName); } FText GetAssetFullName() const { return FText::FromString(FbxMeshInfo->GetFullImportName()); } FText GetAssetStatus() const { return FText::FromString(AssetStatus); } FText GetAssetStatusTooltip() const { return FText::FromString(AssetStatusTooltip); } void GetItemRowData() { AssetStatus = LOCTEXT("SFbxMeshReimportItemTableListViewRow_NoValidStatus", "No valid status").ToString(); AssetStatusTooltip = LOCTEXT("SFbxMeshReimportItemTableListViewRow_CannotBeReimport", "This item cannot be reimport because there is no valid status").ToString(); SlateBrush = FEditorStyle::GetBrush("FBXIcon.ReimportError"); if (MeshStatusMap->Contains(FbxMeshInfo->OriginalImportPath)) { EFbxSceneReimportStatusFlags ReimportFlags = *MeshStatusMap->Find(FbxMeshInfo->OriginalImportPath); // The remove only should not be possible this is why there is no remove only case if (FbxMeshInfo->bOriginalTypeChanged) { AssetStatus = LOCTEXT("SFbxMeshReimportItemTableListViewRow_AssetTypeChanged", "Type Changed, no reimport").ToString(); AssetStatusTooltip = LOCTEXT("SFbxMeshReimportItemTableListViewRow_AssetTypeChangedTooltip", "This item type changed, we cannot reimport an asset of a different type").ToString(); } else if ((ReimportFlags & EFbxSceneReimportStatusFlags::FoundContentBrowserAsset) == EFbxSceneReimportStatusFlags::None) { if ((ReimportFlags & EFbxSceneReimportStatusFlags::Added) != EFbxSceneReimportStatusFlags::None) { SlateBrush = FEditorStyle::GetBrush("FBXIcon.ReimportAdded"); AssetStatus = LOCTEXT("SFbxMeshReimportItemTableListViewRow_AddCreateContent", "Added, create content").ToString(); AssetStatusTooltip = LOCTEXT("SFbxMeshReimportItemTableListViewRow_AddCreateContentTooltip", "This item was added to the fbx scene file, content will be create if this item is select for reimport").ToString(); } else if ((ReimportFlags & EFbxSceneReimportStatusFlags::Same) != EFbxSceneReimportStatusFlags::None) { SlateBrush = FEditorStyle::GetBrush("FBXIcon.ReimportSame"); AssetStatus = LOCTEXT("SFbxMeshReimportItemTableListViewRow_SameCreateContent", "Same, create content").ToString(); AssetStatusTooltip = LOCTEXT("SFbxMeshReimportItemTableListViewRow_SameCreateContentTooltip", "This item match the old fbx but no content was found, content will be create if this item is select for reimport").ToString(); } } else { if ((ReimportFlags & EFbxSceneReimportStatusFlags::Added) != EFbxSceneReimportStatusFlags::None) { SlateBrush = FEditorStyle::GetBrush("FBXIcon.ReimportAddedContent"); AssetStatus = LOCTEXT("SFbxMeshReimportItemTableListViewRow_AddOverrideContent", "Added, override content").ToString(); AssetStatusTooltip = LOCTEXT("SFbxMeshReimportItemTableListViewRow_AddOverrideContentTooltip", "This item was added but a content was found, content will be override if this item is select for reimport").ToString(); } else if ((ReimportFlags & EFbxSceneReimportStatusFlags::Removed) != EFbxSceneReimportStatusFlags::None) { SlateBrush = FEditorStyle::GetBrush("FBXIcon.ReimportRemovedContent"); AssetStatus = LOCTEXT("SFbxMeshReimportItemTableListViewRow_RemoveDeleteContent", "Removed, delete content").ToString(); AssetStatusTooltip = LOCTEXT("SFbxMeshReimportItemTableListViewRow_RemoveDeleteContentTooltip", "This item was deleted but a content was found, content will be delete if this item is select for reimport").ToString(); } else if ((ReimportFlags & EFbxSceneReimportStatusFlags::Same) != EFbxSceneReimportStatusFlags::None) { SlateBrush = FEditorStyle::GetBrush("FBXIcon.ReimportSameContent"); AssetStatus = LOCTEXT("SFbxMeshReimportItemTableListViewRow_SameReplaceContent", "Same, replace content").ToString(); AssetStatusTooltip = LOCTEXT("SFbxMeshReimportItemTableListViewRow_SameReplaceContentTooltip", "This item match the old fbx, content will be replace if this item is select for reimport").ToString(); } } } } void OnItemCheckChanged(ECheckBoxState CheckType) { if (!FbxMeshInfo.IsValid() || FbxMeshInfo->bOriginalTypeChanged) return; if (MeshStatusMap->Contains(FbxMeshInfo->OriginalImportPath)) { EFbxSceneReimportStatusFlags* StatusFlag = MeshStatusMap->Find(FbxMeshInfo->OriginalImportPath); if (CheckType == ECheckBoxState::Checked) { *StatusFlag = *StatusFlag | EFbxSceneReimportStatusFlags::ReimportAsset; } else { *StatusFlag = *StatusFlag & ~EFbxSceneReimportStatusFlags::ReimportAsset; } } } ECheckBoxState IsItemChecked() const { if (MeshStatusMap->Contains(FbxMeshInfo->OriginalImportPath) && !FbxMeshInfo->bOriginalTypeChanged) { return (*(MeshStatusMap->Find(FbxMeshInfo->OriginalImportPath)) & EFbxSceneReimportStatusFlags::ReimportAsset) != EFbxSceneReimportStatusFlags::None ? ECheckBoxState::Checked : ECheckBoxState::Unchecked; } return ECheckBoxState::Unchecked; } FText GetAssetPivotNodeName() const { return GlobalImportSettings->bBakePivotInVertex ? FText::FromString(FbxMeshInfo->PivotNodeName) : FText::FromString(TEXT("-")); } /** The node info to build the tree view row from. */ FbxMeshInfoPtr FbxMeshInfo; FbxSceneReimportStatusMapPtr MeshStatusMap; UnFbx::FBXImportOptions* GlobalImportSettings; // Get item data FString AssetStatus; FString AssetStatusTooltip; const FSlateBrush* SlateBrush; }; SFbxSceneStaticMeshReimportListView::~SFbxSceneStaticMeshReimportListView() { FbxMeshesArray.Empty(); SceneInfo = nullptr; SceneInfoOriginal = nullptr; GlobalImportSettings = nullptr; OverrideNameOptions = nullptr; OverrideNameOptionsMap = nullptr; SceneImportOptionsStaticMeshDisplay = nullptr; MeshStatusMap = nullptr; FilterFbxMeshesArray.Empty(); FilterAddContent = false; FilterDeleteContent = false; FilterOverwriteContent = false; FilterDiff = false; } void SFbxSceneStaticMeshReimportListView::Construct(const SFbxSceneStaticMeshReimportListView::FArguments& InArgs) { SceneInfo = InArgs._SceneInfo; SceneInfoOriginal = InArgs._SceneInfoOriginal; MeshStatusMap = InArgs._MeshStatusMap; GlobalImportSettings = InArgs._GlobalImportSettings; OverrideNameOptions = InArgs._OverrideNameOptions; OverrideNameOptionsMap = InArgs._OverrideNameOptionsMap; SceneImportOptionsStaticMeshDisplay = InArgs._SceneImportOptionsStaticMeshDisplay; check(SceneInfo.IsValid()); check(SceneInfoOriginal.IsValid()); check(MeshStatusMap != nullptr); check(GlobalImportSettings != nullptr); check(OverrideNameOptions != nullptr); check(OverrideNameOptionsMap != nullptr); check(SceneImportOptionsStaticMeshDisplay != nullptr); DefaultOptionNamePtr = MakeShareable(new FString(UFbxSceneImportFactory::DefaultOptionName)); for (auto kvp: *OverrideNameOptionsMap) { bool bNameExist = false; for (TSharedPtr OverrideName: (*OverrideNameOptions)) { if (OverrideName.Get()->Compare(kvp.Key) == 0) { bNameExist = true; break; } } if (!bNameExist) { if (kvp.Key.Compare(UFbxSceneImportFactory::DefaultOptionName) == 0) { OverrideNameOptions->Add(DefaultOptionNamePtr); SFbxSceneOptionWindow::CopyFbxOptionsToFbxOptions(kvp.Value, GlobalImportSettings); } else { OverrideNameOptions->Add(MakeShareable(new FString(kvp.Key))); } } } // Set the default options to the current global import settings GlobalImportSettings->bTransformVertexToAbsolute = false; GlobalImportSettings->StaticMeshLODGroup = NAME_None; CurrentMeshImportOptions = GlobalImportSettings; FbxMeshesArray.Empty(); FilterFbxMeshesArray.Empty(); FilterAddContent = false; FilterDeleteContent = false; FilterOverwriteContent = false; FilterDiff = false; const bool bFillSkeletalMeshStatusMap = false; SFbxSSceneBaseMeshListView::FillMeshStatusMap(MeshStatusMap, SceneInfo, SceneInfoOriginal, bFillSkeletalMeshStatusMap, &FilterFbxMeshesArray, &FbxMeshesArray); SListView::Construct( SListView::FArguments() .ListItemsSource(&FilterFbxMeshesArray) .SelectionMode(ESelectionMode::Multi) .OnGenerateRow(this, &SFbxSceneStaticMeshReimportListView::OnGenerateRowFbxSceneListView) .OnContextMenuOpening(this, &SFbxSceneStaticMeshReimportListView::OnOpenContextMenu) .HeaderRow( SNew(SHeaderRow) + SHeaderRow::Column(FbxSceneReimportStaticMesh::CheckBoxSelectionHeaderIdName) .FixedWidth(26) .DefaultLabel(FText::GetEmpty()) [SNew(SCheckBox) .HAlign(HAlign_Center) .OnCheckStateChanged(this, &SFbxSceneStaticMeshReimportListView::OnToggleSelectAll)] + SHeaderRow::Column(FbxSceneReimportStaticMesh::ClassIconHeaderIdName) .FixedWidth(20) .DefaultLabel(FText::GetEmpty()) + SHeaderRow::Column(FbxSceneReimportStaticMesh::AssetNameHeaderIdName) .FillWidth(250) .HAlignCell(EHorizontalAlignment::HAlign_Left) .DefaultLabel(LOCTEXT("AssetNameHeaderName", "Asset Name")) + SHeaderRow::Column(FbxSceneReimportStaticMesh::ContentPathHeaderIdName) .FillWidth(250) .HAlignCell(EHorizontalAlignment::HAlign_Left) .DefaultLabel(LOCTEXT("ContentPathHeaderName", "Content Path")) + SHeaderRow::Column(FbxSceneReimportStaticMesh::AssetStatusHeaderIdName) .FillWidth(160) .HAlignCell(EHorizontalAlignment::HAlign_Left) .DefaultLabel(LOCTEXT("AssetStatusHeaderName", "Asset Status")) + SHeaderRow::Column(FbxSceneReimportStaticMesh::OptionNameHeaderIdName) .FillWidth(100) .HAlignCell(EHorizontalAlignment::HAlign_Left) .DefaultLabel(LOCTEXT("AssetOptionNameHeaderName", "Option Name")))); } TSharedRef SFbxSceneStaticMeshReimportListView::OnGenerateRowFbxSceneListView(FbxMeshInfoPtr Item, const TSharedRef& OwnerTable) { TSharedRef ReturnRow = SNew(SFbxMeshReimportItemTableListViewRow, OwnerTable) .FbxMeshInfo(Item) .MeshStatusMap(MeshStatusMap) .GlobalImportSettings(GlobalImportSettings); return ReturnRow; } void SFbxSceneStaticMeshReimportListView::OnChangedOverrideOptions(TSharedPtr ItemSelected, ESelectInfo::Type SelectInfo) { check(ItemSelected.IsValid()); if (ItemSelected.Get()->Compare(UFbxSceneImportFactory::DefaultOptionName) == 0) { CurrentMeshImportOptions = GlobalImportSettings; } else if (OverrideNameOptionsMap->Contains(*(ItemSelected))) { CurrentMeshImportOptions = *OverrideNameOptionsMap->Find(*(ItemSelected)); } SFbxSceneOptionWindow::CopyFbxOptionsToStaticMeshOptions(CurrentMeshImportOptions, SceneImportOptionsStaticMeshDisplay); } void SFbxSceneStaticMeshReimportListView::OnFinishedChangingProperties(const FPropertyChangedEvent& PropertyChangedEvent) { SFbxSceneOptionWindow::CopyStaticMeshOptionsToFbxOptions(CurrentMeshImportOptions, SceneImportOptionsStaticMeshDisplay); } TSharedPtr SFbxSceneStaticMeshReimportListView::OnOpenContextMenu() { TArray SelectedFbxMeshInfos; int32 SelectCount = GetSelectedItems(SelectedFbxMeshInfos); // Build up the menu for a selection const bool bCloseAfterSelection = true; FMenuBuilder MenuBuilder(bCloseAfterSelection, TSharedPtr()); // We always create a section here, even if there is no parent so that clients can still extend the menu MenuBuilder.BeginSection("FbxScene_SM_ImportSection"); { const FSlateIcon PlusIcon(FEditorStyle::GetStyleSetName(), "Plus"); MenuBuilder.AddMenuEntry(LOCTEXT("CheckForImport", "Add Selection To Import"), FText(), PlusIcon, FUIAction(FExecuteAction::CreateSP(this, &SFbxSceneStaticMeshReimportListView::AddSelectionToImport))); const FSlateIcon MinusIcon(FEditorStyle::GetStyleSetName(), "PropertyWindow.Button_RemoveFromArray"); MenuBuilder.AddMenuEntry(LOCTEXT("UncheckForImport", "Remove Selection From Import"), FText(), MinusIcon, FUIAction(FExecuteAction::CreateSP(this, &SFbxSceneStaticMeshReimportListView::RemoveSelectionFromImport))); } MenuBuilder.EndSection(); // Build the Assign section if (SelectCount == 1 || ShowResetAssignToStaticMesh()) { MenuBuilder.BeginSection("FbxImportScene_SM_Assign", LOCTEXT("FbxScene_SM_Assign", "Assign")); { if (SelectCount == 1) { MenuBuilder.AddMenuEntry(LOCTEXT("FbxImportScene_SM_Assign", "Assign existing static mesh..."), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(this, &SFbxSceneStaticMeshReimportListView::AssignToStaticMesh))); } if (ShowResetAssignToStaticMesh()) { MenuBuilder.AddMenuEntry(LOCTEXT("FbxImportScene_SM_ResetAssign", "Reset to FBX content"), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(this, &SFbxSceneStaticMeshReimportListView::ResetAssignToStaticMesh))); } } MenuBuilder.EndSection(); } AddBakePivotMenu(MenuBuilder); bool bShowOptionMenu = false; for (FbxMeshInfoPtr MeshInfo: SelectedFbxMeshInfos) { EFbxSceneReimportStatusFlags ReimportFlags = *MeshStatusMap->Find(MeshInfo->OriginalImportPath); if ((ReimportFlags & EFbxSceneReimportStatusFlags::Removed) == EFbxSceneReimportStatusFlags::None) { bShowOptionMenu = true; } } if (bShowOptionMenu) { MenuBuilder.BeginSection("FbxScene_SM_OptionsSection", LOCTEXT("FbxScene_SM_Options", "Options:")); { for (auto OptionName: (*OverrideNameOptions)) { MenuBuilder.AddMenuEntry(FText::FromString(*OptionName.Get()), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(this, &SFbxSceneStaticMeshReimportListView::AssignToOptions, *OptionName.Get()))); } } MenuBuilder.EndSection(); } return MenuBuilder.MakeWidget(); } void SFbxSceneStaticMeshReimportListView::AssignToStaticMesh() { TArray SelectedFbxMeshInfos; int32 SelectCount = GetSelectedItems(SelectedFbxMeshInfos); if (SelectCount != 1) return; FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked("ContentBrowser"); for (FbxMeshInfoPtr ItemPtr: SelectedFbxMeshInfos) { FOpenAssetDialogConfig SelectAssetConfig; SelectAssetConfig.DialogTitleOverride = LOCTEXT("FbxChooseReimportAssetContentPath", "Choose static mesh asset for reimporting the fbx scene content"); // SelectAssetConfig.DefaultPath = ItemPtr->OriginalImportPath; SelectAssetConfig.bAllowMultipleSelection = false; SelectAssetConfig.AssetClassNames.Add(UStaticMesh::StaticClass()->GetFName()); TArray AssetData = ContentBrowserModule.Get().CreateModalOpenAssetDialog(SelectAssetConfig); if (AssetData.Num() == 1) { EFbxSceneReimportStatusFlags StatusFlag = *(MeshStatusMap->Find(ItemPtr->OriginalImportPath)); // Remove the old MeshStatusMap MeshStatusMap->Remove(ItemPtr->OriginalImportPath); // Override the MeshInfo with the new asset path ItemPtr->SetOverridePath(true); ItemPtr->OverrideImportPath = AssetData[0].PackageName.ToString(); ItemPtr->OverrideFullImportName = AssetData[0].ObjectPath.ToString(); StatusFlag |= EFbxSceneReimportStatusFlags::FoundContentBrowserAsset; // Add the new reimport status MeshStatusMap->Add(ItemPtr->OriginalImportPath, StatusFlag); } } } bool SFbxSceneStaticMeshReimportListView::ShowResetAssignToStaticMesh() { TArray SelectedFbxMeshInfos; int32 SelectCount = GetSelectedItems(SelectedFbxMeshInfos); FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked("ContentBrowser"); for (FbxMeshInfoPtr ItemPtr: SelectedFbxMeshInfos) { if (ItemPtr->bOverridePath) { return true; } } return false; } void SFbxSceneStaticMeshReimportListView::ResetAssignToStaticMesh() { TArray SelectedFbxMeshInfos; int32 SelectCount = GetSelectedItems(SelectedFbxMeshInfos); for (FbxMeshInfoPtr ItemPtr: SelectedFbxMeshInfos) { if (ItemPtr->bOverridePath) { ItemPtr->SetOverridePath(false); ItemPtr->OverrideImportPath.Empty(); ItemPtr->OverrideFullImportName.Empty(); // Get the original status flag EFbxSceneReimportStatusFlags StatusFlag = *(MeshStatusMap->Find(ItemPtr->OriginalImportPath)); MeshStatusMap->Remove(ItemPtr->OriginalImportPath); if (ItemPtr->GetContentObject() != nullptr) { StatusFlag |= EFbxSceneReimportStatusFlags::FoundContentBrowserAsset; } else { StatusFlag &= ~EFbxSceneReimportStatusFlags::FoundContentBrowserAsset; } // Add the new reimport status MeshStatusMap->Add(ItemPtr->OriginalImportPath, StatusFlag); } } } void SFbxSceneStaticMeshReimportListView::SetSelectionImportState(bool MarkForImport) { TArray SelectedFbxMeshInfos; GetSelectedItems(SelectedFbxMeshInfos); for (FbxMeshInfoPtr ItemPtr: SelectedFbxMeshInfos) { EFbxSceneReimportStatusFlags* ItemStatus = MeshStatusMap->Find(ItemPtr->OriginalImportPath); if (ItemStatus != nullptr) { *ItemStatus = MarkForImport ? *ItemStatus | EFbxSceneReimportStatusFlags::ReimportAsset : *ItemStatus & ~EFbxSceneReimportStatusFlags::ReimportAsset; } } } void SFbxSceneStaticMeshReimportListView::OnToggleSelectAll(ECheckBoxState CheckType) { for (FbxMeshInfoPtr MeshInfo: FilterFbxMeshesArray) { EFbxSceneReimportStatusFlags* ItemStatus = MeshStatusMap->Find(MeshInfo->OriginalImportPath); if (ItemStatus != nullptr) { *ItemStatus = (CheckType == ECheckBoxState::Checked) ? *ItemStatus | EFbxSceneReimportStatusFlags::ReimportAsset : *ItemStatus & ~EFbxSceneReimportStatusFlags::ReimportAsset; } } } void SFbxSceneStaticMeshReimportListView::OnToggleFilterAddContent(ECheckBoxState CheckType) { FilterAddContent = (CheckType == ECheckBoxState::Checked); UpdateFilterList(); } void SFbxSceneStaticMeshReimportListView::OnToggleFilterDeleteContent(ECheckBoxState CheckType) { FilterDeleteContent = (CheckType == ECheckBoxState::Checked); UpdateFilterList(); } void SFbxSceneStaticMeshReimportListView::OnToggleFilterOverwriteContent(ECheckBoxState CheckType) { FilterOverwriteContent = (CheckType == ECheckBoxState::Checked); UpdateFilterList(); } void SFbxSceneStaticMeshReimportListView::OnToggleFilterDiff(ECheckBoxState CheckType) { FilterDiff = (CheckType == ECheckBoxState::Checked); UpdateFilterList(); } void SFbxSceneStaticMeshReimportListView::UpdateFilterList() { FilterFbxMeshesArray.Empty(); if (FilterAddContent || FilterDeleteContent || FilterOverwriteContent || FilterDiff) { for (FbxMeshInfoPtr MeshInfo: FbxMeshesArray) { EFbxSceneReimportStatusFlags ItemStatus = *(MeshStatusMap->Find(MeshInfo->OriginalImportPath)); bool bStatusAdd = (ItemStatus & EFbxSceneReimportStatusFlags::Added) != EFbxSceneReimportStatusFlags::None; bool bStatusSame = (ItemStatus & EFbxSceneReimportStatusFlags::Same) != EFbxSceneReimportStatusFlags::None; bool bStatusRemove = (ItemStatus & EFbxSceneReimportStatusFlags::Removed) != EFbxSceneReimportStatusFlags::None; bool bStatusFoundContent = (ItemStatus & EFbxSceneReimportStatusFlags::FoundContentBrowserAsset) != EFbxSceneReimportStatusFlags::None; if (FilterAddContent && (bStatusAdd || bStatusSame) && !bStatusFoundContent) { FilterFbxMeshesArray.Add(MeshInfo); } else if (FilterDeleteContent && bStatusRemove && bStatusFoundContent) { FilterFbxMeshesArray.Add(MeshInfo); } else if (FilterOverwriteContent && (bStatusAdd || bStatusSame) && bStatusFoundContent) { FilterFbxMeshesArray.Add(MeshInfo); } else if (FilterDiff && !bStatusSame) { FilterFbxMeshesArray.Add(MeshInfo); } } } else { for (FbxMeshInfoPtr MeshInfo: FbxMeshesArray) { FilterFbxMeshesArray.Add(MeshInfo); } } this->RequestListRefresh(); } #undef LOCTEXT_NAMESPACE