| 946 | } |
| 947 | |
| 948 | bool SFlowGraphEditor::CanPasteNodes() const |
| 949 | { |
| 950 | if (!CanEdit() || !IsTabFocused()) |
| 951 | { |
| 952 | return false; |
| 953 | } |
| 954 | |
| 955 | FString ClipboardContent; |
| 956 | FPlatformApplicationMisc::ClipboardPaste(ClipboardContent); |
| 957 | |
| 958 | UFlowGraph* FlowGraph = CastChecked<UFlowGraph>(FlowAsset->GetGraph()); |
| 959 | if (!ensure(IsValid(FlowGraph))) |
| 960 | { |
| 961 | // We expect to have a legal FlowGraph pointer at this point |
| 962 | return false; |
| 963 | } |
| 964 | |
| 965 | const bool bIsPastePossible = FEdGraphUtilities::CanImportNodesFromText(FlowGraph, ClipboardContent); |
| 966 | if (!bIsPastePossible) |
| 967 | { |
| 968 | return false; |
| 969 | } |
| 970 | |
| 971 | // Disallow paste when multiple target nodes are selected, and if there are subnodes involved. |
| 972 | const TArray<UFlowGraphNode*> PasteTargetNodes = DerivePasteTargetNodesFromSelectedNodes(); |
| 973 | const bool bHasSubNodes = Algo::AnyOf(PasteTargetNodes, [](const UFlowGraphNode* Node) { return Node && !Node->SubNodes.IsEmpty(); }); |
| 974 | |
| 975 | if (bHasSubNodes && PasteTargetNodes.Num() > 1) |
| 976 | { |
| 977 | // NOTE (gtaylor) It's possible we could support multi-paste, but we'd need to rework PasteNodesHere() |
| 978 | // to understand how to paste copies onto each target node. |
| 979 | return false; |
| 980 | } |
| 981 | |
| 982 | FString TextToImport; |
| 983 | const TSet<UEdGraphNode*> NodesToPaste = ImportNodesToPasteFromClipboard(*FlowGraph, TextToImport); |
| 984 | |
| 985 | if (NodesToPaste.IsEmpty()) |
| 986 | { |
| 987 | // Must have at least one node to paste |
| 988 | return false; |
| 989 | } |
| 990 | |
| 991 | ON_SCOPE_EXIT |
| 992 | { |
| 993 | // We need to clean up the nodes we built to test the paste operation |
| 994 | for (TSet<UEdGraphNode*>::TConstIterator It(NodesToPaste); It; ++It) |
| 995 | { |
| 996 | UEdGraphNode* NodeToPaste = *It; |
| 997 | if (IsValid(NodeToPaste)) |
| 998 | { |
| 999 | NodeToPaste->ClearFlags(RF_Public); |
| 1000 | NodeToPaste->SetFlags(RF_Transient); |
| 1001 | |
| 1002 | const FString NewNameStr = MakeUniqueObjectName(NodeToPaste->GetOuter(), NodeToPaste->GetClass()).ToString(); |
| 1003 | |
| 1004 | // This will remove the node from its graph |
| 1005 | NodeToPaste->DestroyNode(); |
no test coverage detected