void UK2Node_Variable::AutowireNewNode(UEdGraphPin* FromPin) { const UEdGraphSchema_K2* K2Schema = CastChecked<UEdGraphSchema_K2>(GetSchema()); // Do some auto-connection if (FromPin != NULL) { bool bConnected = false; if(FromPin->Direction == EGPD_Output) { // If the source pin has a valid PinSubCategoryObject, we might be doing BP Comms, so check if it is a class if(FromPin->PinType.PinSubCategoryObject.IsValid() && FromPin->PinType.PinSubCategoryObject->IsA(UClass::StaticClass())) { UProperty* VariableProperty = VariableReference.ResolveMember<UProperty>(GetBlueprintClassFromNode()); if(VariableProperty) { UClass* PropertyOwner = VariableProperty->GetOwnerClass(); if (PropertyOwner != nullptr) { PropertyOwner = PropertyOwner->GetAuthoritativeClass(); } // BP Comms is highly likely at this point, if the source pin's type is a child of the variable's owner class, let's conform the "Target" pin if(FromPin->PinType.PinSubCategoryObject == PropertyOwner || dynamic_cast<UClass*>(FromPin->PinType.PinSubCategoryObject.Get())->IsChildOf(PropertyOwner)) { UEdGraphPin* TargetPin = FindPin(K2Schema->PN_Self); if (TargetPin) { TargetPin->PinType.PinSubCategoryObject = PropertyOwner; if(K2Schema->TryCreateConnection(FromPin, TargetPin)) { bConnected = true; // Setup the VariableReference correctly since it may no longer be a self member VariableReference.SetFromField<UProperty>(GetPropertyForVariable(), false); TargetPin->bHidden = false; FromPin->GetOwningNode()->NodeConnectionListChanged(); this->NodeConnectionListChanged(); } } } } } } if(!bConnected) { Super::AutowireNewNode(FromPin); } } }
void USpeedTreeImportData::SaveOptions() { int32 PortFlags = 0; for (UProperty* Property = GetClass()->PropertyLink; Property; Property = Property->PropertyLinkNext) { if (!Property->HasAnyPropertyFlags(CPF_Config)) { continue; } FString Section = TEXT("SpeedTree_Import_UI_Option_") + GetClass()->GetName(); FString Key = Property->GetName(); const bool bIsPropertyInherited = Property->GetOwnerClass() != GetClass(); UObject* SuperClassDefaultObject = GetClass()->GetSuperClass()->GetDefaultObject(); UArrayProperty* Array = dynamic_cast<UArrayProperty*>(Property); if (Array) { FConfigSection* Sec = GConfig->GetSectionPrivate(*Section, 1, 0, *GEditorPerProjectIni); check(Sec); Sec->Remove(*Key); FScriptArrayHelper_InContainer ArrayHelper(Array, this); for (int32 i = 0; i < ArrayHelper.Num(); i++) { FString Buffer; Array->Inner->ExportTextItem(Buffer, ArrayHelper.GetRawPtr(i), ArrayHelper.GetRawPtr(i), this, PortFlags); Sec->Add(*Key, *Buffer); } } else { TCHAR TempKey[MAX_SPRINTF] = TEXT(""); for (int32 Index = 0; Index < Property->ArrayDim; Index++) { if (Property->ArrayDim != 1) { FCString::Sprintf(TempKey, TEXT("%s[%i]"), *Property->GetName(), Index); Key = TempKey; } FString Value; Property->ExportText_InContainer(Index, Value, this, this, this, PortFlags); GConfig->SetString(*Section, *Key, *Value, *GEditorPerProjectIni); } } } GConfig->Flush(0); }
void USpeedTreeImportData::LoadOptions() { int32 PortFlags = 0; for (UProperty* Property = GetClass()->PropertyLink; Property; Property = Property->PropertyLinkNext) { if (!Property->HasAnyPropertyFlags(CPF_Config)) { continue; } FString Section = TEXT("SpeedTree_Import_UI_Option_") + GetClass()->GetName(); FString Key = Property->GetName(); const bool bIsPropertyInherited = Property->GetOwnerClass() != GetClass(); UObject* SuperClassDefaultObject = GetClass()->GetSuperClass()->GetDefaultObject(); const FString& PropFileName = GEditorPerProjectIni; UArrayProperty* Array = dynamic_cast<UArrayProperty*>(Property); if (Array) { FConfigSection* Sec = GConfig->GetSectionPrivate(*Section, 0, 1, *GEditorPerProjectIni); if (Sec != nullptr) { TArray<FConfigValue> List; const FName KeyName(*Key, FNAME_Find); Sec->MultiFind(KeyName, List); FScriptArrayHelper_InContainer ArrayHelper(Array, this); // Only override default properties if there is something to override them with. if (List.Num() > 0) { ArrayHelper.EmptyAndAddValues(List.Num()); for (int32 i = List.Num() - 1, c = 0; i >= 0; i--, c++) { Array->Inner->ImportText(*List[i].GetValue(), ArrayHelper.GetRawPtr(c), PortFlags, this); } } else { int32 Index = 0; const FConfigValue* ElementValue = nullptr; do { // Add array index number to end of key FString IndexedKey = FString::Printf(TEXT("%s[%i]"), *Key, Index); // Try to find value of key const FName IndexedName(*IndexedKey, FNAME_Find); if (IndexedName == NAME_None) { break; } ElementValue = Sec->Find(IndexedName); // If found, import the element if (ElementValue != nullptr) { // expand the array if necessary so that Index is a valid element ArrayHelper.ExpandForIndex(Index); Array->Inner->ImportText(*ElementValue->GetValue(), ArrayHelper.GetRawPtr(Index), PortFlags, this); } Index++; } while (ElementValue || Index < ArrayHelper.Num()); } } } else { for (int32 i = 0; i < Property->ArrayDim; i++) { if (Property->ArrayDim != 1) { Key = FString::Printf(TEXT("%s[%i]"), *Property->GetName(), i); } FString Value; bool bFoundValue = GConfig->GetString(*Section, *Key, Value, *GEditorPerProjectIni); if (bFoundValue) { if (Property->ImportText(*Value, Property->ContainerPtrToValuePtr<uint8>(this, i), PortFlags, this) == NULL) { // this should be an error as the properties from the .ini / .int file are not correctly being read in and probably are affecting things in subtle ways UE_LOG(LogSpeedTreeImportData, Error, TEXT("SpeedTree Options LoadOptions (%s): failed for %s in: %s"), *GetPathName(), *Property->GetName(), *Value); } } } } } }