// Purges any objects marked pending kill from the object list void FObjectPropertyNode::PurgeKilledObjects() { // Purge any objects that are marked pending kill from the object list for (int32 Index = 0; Index < Objects.Num(); ) { TWeakObjectPtr<UObject> Object = Objects[Index]; if ( !Object.IsValid() || Object->HasAnyFlags(RF_PendingKill) ) { Objects.RemoveAt(Index, 1); } else { ++Index; } } }
void SDetailsView::SetObjectArrayPrivate(const TArray< TWeakObjectPtr< UObject > >& InObjects) { double StartTime = FPlatformTime::Seconds(); PreSetObject(InObjects.Num()); // Selected actors for building SelectedActorInfo TArray<AActor*> SelectedRawActors; bViewingClassDefaultObject = InObjects.Num() > 0 ? true : false; bool bOwnedByLockedLevel = false; for( int32 ObjectIndex = 0 ; ObjectIndex < InObjects.Num(); ++ObjectIndex ) { TWeakObjectPtr< UObject > Object = InObjects[ObjectIndex]; if( Object.IsValid() ) { bViewingClassDefaultObject &= Object->HasAnyFlags( RF_ClassDefaultObject ); if(DetailsViewArgs.bAllowMultipleTopLevelObjects) { check(RootPropertyNodes.Num() == InObjects.Num()); RootPropertyNodes[ObjectIndex]->AsObjectNode()->AddObject( Object.Get() ); } else { RootPropertyNodes[0]->AsObjectNode()->AddObject( Object.Get() ); } SelectedObjects.Add( Object ); AActor* Actor = Cast<AActor>( Object.Get() ); if( Actor ) { SelectedActors.Add( Actor ); SelectedRawActors.Add( Actor ); } } } if( InObjects.Num() == 0 ) { // Unlock the view automatically if we are viewing nothing bIsLocked = false; } // Selection changed, refresh the detail area if ( DetailsViewArgs.NameAreaSettings != FDetailsViewArgs::ActorsUseNameArea && DetailsViewArgs.NameAreaSettings != FDetailsViewArgs::ComponentsAndActorsUseNameArea ) { NameArea->Refresh( SelectedObjects ); } else { NameArea->Refresh( SelectedActors, SelectedObjects, DetailsViewArgs.NameAreaSettings ); } // When selection changes rebuild information about the selection SelectedActorInfo = AssetSelectionUtils::BuildSelectedActorInfo( SelectedRawActors ); // @todo Slate Property Window //SetFlags(EPropertyWindowFlags::ReadOnly, bOwnedByLockedLevel); PostSetObject(); // Set the title of the window based on the objects we are viewing // Or call the delegate for handling when the title changed FString Title; if( GetNumObjects() == 0 ) { Title = NSLOCTEXT("PropertyView", "NothingSelectedTitle", "Nothing selected").ToString(); } else if( GetNumObjects() == 1 && RootPropertyNodes[0]->AsObjectNode()->GetNumObjects() > 0) { // if the object is the default metaobject for a UClass, use the UClass's name instead UObject* Object = RootPropertyNodes[0]->AsObjectNode()->GetUObject(0); FString ObjectName = Object->GetName(); if ( Object->GetClass()->GetDefaultObject() == Object ) { ObjectName = Object->GetClass()->GetName(); } else { // Is this an actor? If so, it might have a friendly name to display const AActor* Actor = Cast<const AActor >( Object ); if( Actor != nullptr) { // Use the friendly label for this actor ObjectName = Actor->GetActorLabel(); } } Title = ObjectName; } else if(DetailsViewArgs.bAllowMultipleTopLevelObjects) { Title = FString::Printf(*NSLOCTEXT("PropertyView", "MultipleToLevelObjectsSelected", "%i selected").ToString(), GetNumObjects()); } else { FObjectPropertyNode* RootPropertyNode = RootPropertyNodes[0]->AsObjectNode(); Title = FString::Printf( *NSLOCTEXT("PropertyView", "MultipleSelected", "%s (%i selected)").ToString(), *RootPropertyNode->GetObjectBaseClass()->GetName(), RootPropertyNode->GetNumObjects() ); } OnObjectArrayChanged.ExecuteIfBound(Title, InObjects); double ElapsedTime = FPlatformTime::Seconds() - StartTime; }