diff --git a/Content/BP_BugPlacerPawn.uasset b/Content/BP_BugPlacerPawn.uasset index 43d9668..d3b9d68 100644 Binary files a/Content/BP_BugPlacerPawn.uasset and b/Content/BP_BugPlacerPawn.uasset differ diff --git a/Content/UI/CUI_BugCommentTextEntry.uasset b/Content/UI/CUI_BugCommentTextEntry.uasset index b0ada76..756f635 100644 Binary files a/Content/UI/CUI_BugCommentTextEntry.uasset and b/Content/UI/CUI_BugCommentTextEntry.uasset differ diff --git a/Content/UI/CUI_BugFormButton.uasset b/Content/UI/CUI_BugFormButton.uasset index f19bd3c..e110eb7 100644 Binary files a/Content/UI/CUI_BugFormButton.uasset and b/Content/UI/CUI_BugFormButton.uasset differ diff --git a/Content/UI/CUI_BugFormOptionButton.uasset b/Content/UI/CUI_BugFormOptionButton.uasset index 4f2489b..1fca1c4 100644 Binary files a/Content/UI/CUI_BugFormOptionButton.uasset and b/Content/UI/CUI_BugFormOptionButton.uasset differ diff --git a/Content/UI/CUI_BugFormTextEntryButton.uasset b/Content/UI/CUI_BugFormTextEntryButton.uasset index 36d43dd..f068cd7 100644 Binary files a/Content/UI/CUI_BugFormTextEntryButton.uasset and b/Content/UI/CUI_BugFormTextEntryButton.uasset differ diff --git a/Content/UI/CUI_BugOptionSelect.uasset b/Content/UI/CUI_BugOptionSelect.uasset new file mode 100644 index 0000000..a2c1433 Binary files /dev/null and b/Content/UI/CUI_BugOptionSelect.uasset differ diff --git a/Content/UI/CUI_BugSubmissionForm.uasset b/Content/UI/CUI_BugSubmissionForm.uasset index a037da4..8d36acb 100644 Binary files a/Content/UI/CUI_BugSubmissionForm.uasset and b/Content/UI/CUI_BugSubmissionForm.uasset differ diff --git a/Content/UI/CUI_BugSummaryTextEntry.uasset b/Content/UI/CUI_BugSummaryTextEntry.uasset index 12c834f..e52387d 100644 Binary files a/Content/UI/CUI_BugSummaryTextEntry.uasset and b/Content/UI/CUI_BugSummaryTextEntry.uasset differ diff --git a/Source/Unrealzilla/Private/BugFormTextEntryButton.cpp b/Source/Unrealzilla/Private/BugFormButton.cpp similarity index 65% rename from Source/Unrealzilla/Private/BugFormTextEntryButton.cpp rename to Source/Unrealzilla/Private/BugFormButton.cpp index 9d69538..df75147 100644 --- a/Source/Unrealzilla/Private/BugFormTextEntryButton.cpp +++ b/Source/Unrealzilla/Private/BugFormButton.cpp @@ -1,6 +1,6 @@ // ©2022 Batty Bovine Productions, LLC. All Rights Reserved. -#include "BugFormTextEntryButton.h" +#include "BugFormButton.h" diff --git a/Source/Unrealzilla/Private/BugSubmissionForm.cpp b/Source/Unrealzilla/Private/BugSubmissionForm.cpp index 0b34fc8..010f267 100644 --- a/Source/Unrealzilla/Private/BugSubmissionForm.cpp +++ b/Source/Unrealzilla/Private/BugSubmissionForm.cpp @@ -44,12 +44,23 @@ const FString FormatQueryString(const TMap &QueryData) return FString::Join(AssembledKeyValuePairs, TEXT("&")); } +const FString GetGameVersion() +{ + FString GameVersion; + GConfig->GetString(TEXT("/Script/EngineSettings.GeneralProjectSettings"), TEXT("ProjectVersion"), GameVersion, GGameIni); + if (GameVersion.IsEmpty()) + { + GameVersion = "1.0.0.0"; + } + return GameVersion; +} + void UBugSubmissionForm::NativeOnInitialized() { this->ShowProcessingOverlayLoading(); - this->ProductNameValue->SetText(FText::FromString(GetDefault()->ProductName)); + this->ProductNameValue->SetText(FText::AsCultureInvariant(GetDefault()->ProductName)); const FString FullURL = GetDefault()->SubmissionServer + "/rest.cgi"; @@ -100,7 +111,7 @@ void UBugSubmissionForm::SetMarkerData(ABugMarkerActor *BugMarker) { this->BugMarkerActor = BugMarker; - MapNameValue->SetText(FText::FromString(this->GetWorld()->GetMapName().RightChop(this->GetWorld()->StreamingLevelsPrefix.Len()))); + this->MapName = FText::AsCultureInvariant(this->GetWorld()->GetMapName().RightChop(this->GetWorld()->StreamingLevelsPrefix.Len())); const FVector MarkerLocation = this->BugMarkerActor->GetActorLocation(); FFormatNamedArguments MarkerLocationArgs; @@ -121,13 +132,13 @@ void UBugSubmissionForm::SetMarkerData(ABugMarkerActor *BugMarker) MapDataArgs.Add("MarkerUpVector", MarkerUpVectorText); const FText MapDataText = FText::Format(NSLOCTEXT("BugSubmissionForm", "MapDataFormat", "{MarkerLocation}:{MarkerUpVector}"), MapDataArgs); - this->LocationValue->SetText(MapDataText); + this->MarkerLocation = MapDataText; } void UBugSubmissionForm::ShowProcessingOverlayLoading() { - this->ProcessingRequestErrorText->SetText(FText::FromString("")); + this->ProcessingRequestErrorText->SetText(FText::AsCultureInvariant("")); this->ProcessingRequestOverlay->SetVisibility(ESlateVisibility::Visible); this->ProcessingRequestThrobber->SetVisibility(ESlateVisibility::Visible); this->ProcessingRequestErrorBox->SetVisibility(ESlateVisibility::Collapsed); @@ -135,7 +146,7 @@ void UBugSubmissionForm::ShowProcessingOverlayLoading() void UBugSubmissionForm::ShowProcessingOverlayMessage(const FString Message) { - this->ProcessingRequestErrorText->SetText(FText::FromString(Message)); + this->ProcessingRequestErrorText->SetText(FText::AsCultureInvariant(Message)); this->ProcessingRequestOverlay->SetVisibility(ESlateVisibility::Visible); this->ProcessingRequestThrobber->SetVisibility(ESlateVisibility::Collapsed); this->ProcessingRequestErrorBox->SetVisibility(ESlateVisibility::Visible); @@ -160,27 +171,52 @@ void UBugSubmissionForm::SubmitForm() const FString SummaryText = this->SummaryEntryBox->GetText().ToString(); const FString CommentText = this->CommentEntryBox->GetText().ToString(); - if (SummaryText.IsEmpty()) - { - this->ShowProcessingOverlayMessage("You must provide a summary."); - } - - //if (CommentText.IsEmpty()) - //{ - // this->ShowProcessingOverlayMessage("You must provide a description."); - //} + const FString DefaultStatus = GetDefault()->DefaultStatus; FString PostJsonString; FJSONPostBug PostData; PostData.product = GetDefault()->ProductName; - PostData.component = "Component"; - PostData.version = "unspecified"; - PostData.cf_mapname = this->MapNameValue->GetText().ToString(); - PostData.cf_location = this->LocationValue->GetText().ToString(); + PostData.version = this->VersionButton->GetText().ToString(); + PostData.platform = this->HardwareButton->GetText().ToString(); + PostData.op_sys = this->OSButton->GetText().ToString(); + PostData.component = this->ComponentButton->GetText().ToString(); + PostData.severity = this->SeverityButton->GetText().ToString(); + PostData.cf_mapname = this->MapName.ToString(); + PostData.cf_location = this->MarkerLocation.ToString(); PostData.summary = SummaryText; PostData.description = CommentText; + if (!DefaultStatus.IsEmpty()) + { + PostData.status = DefaultStatus; + } FJsonObjectConverter::UStructToJsonObjectString(PostData, PostJsonString); + if (PostData.version.IsEmpty()) + { + this->ShowProcessingOverlayMessage("You must select a version number."); + return; + } + if (PostData.platform.IsEmpty() || PostData.op_sys.IsEmpty()) + { + PostData.platform = "All"; + PostData.op_sys = "All"; + } + if (PostData.component.IsEmpty()) + { + this->ShowProcessingOverlayMessage("You must select a component."); + return; + } + if (PostData.severity.IsEmpty()) + { + this->ShowProcessingOverlayMessage("You must select a severity level."); + return; + } + if (SummaryText.IsEmpty()) + { + this->ShowProcessingOverlayMessage("You must provide a summary."); + return; + } + FHttpModule &HttpModule = FHttpModule::Get(); TSharedRef Request = HttpModule.CreateRequest(); Request->SetVerb(TEXT("POST")); @@ -247,8 +283,9 @@ void UBugSubmissionForm::ServerProductInfoResponse(FHttpRequestPtr Request, FHtt } else { - for (const FJSONProductData &ProductData : ResponseData.products) + if (!ResponseData.products.IsEmpty()) { + const FJSONProductData &ProductData = ResponseData.products[0]; if (ProductData.name == GetDefault()->ProductName) { for (const FJSONComponentData &ComponentData : ProductData.components) @@ -259,10 +296,26 @@ void UBugSubmissionForm::ServerProductInfoResponse(FHttpRequestPtr Request, FHtt { this->VersionsList.Add(VersionData.name); } - break; } } + if (this->VersionsList.Contains(GetGameVersion())) + { + this->VersionButton->SetText(FText::AsCultureInvariant(GetGameVersion())); + } + else if (this->VersionsList.Contains("unspecified")) + { + this->VersionButton->SetText(FText::AsCultureInvariant("unspecified")); + } + else if (this->VersionsList.Contains("Latest")) + { + this->VersionButton->SetText(FText::AsCultureInvariant("Latest")); + } + else if (!this->VersionsList.IsEmpty()) + { + this->VersionButton->SetText(FText::AsCultureInvariant(this->VersionsList[0])); + } + this->CheckIfAllInitialResponsesAreIn(); } } @@ -370,50 +423,41 @@ void UBugSubmissionForm::CheckIfAllInitialResponsesAreIn() if (!this->ComponentList.IsEmpty() && !this->VersionsList.IsEmpty() && !this->SeverityList.IsEmpty() && !this->PlatformsList.IsEmpty() && !this->OSList.IsEmpty()) { - if (this->PlatformsList.Contains("PC")) + // Set these as defaults in case nothing below changes this setting + this->HardwareButton->SetText(FText::AsCultureInvariant("All")); + this->OSButton->SetText(FText::AsCultureInvariant("All")); + + if (this->PlatformsList.Contains("PC")) // Try our best to auto-detect PC hardware { if (UGameplayStatics::GetPlatformName() == "Windows" && this->OSList.Contains("Windows")) { - this->ShowProcessingOverlayMessage("Windows detected"); + this->HardwareButton->SetText(FText::AsCultureInvariant("PC")); + this->OSButton->SetText(FText::AsCultureInvariant("Windows")); } else if (UGameplayStatics::GetPlatformName() == "Linux" && this->OSList.Contains("Linux")) { - this->ShowProcessingOverlayMessage("Linux on PC detected"); + this->HardwareButton->SetText(FText::AsCultureInvariant("PC")); + this->OSButton->SetText(FText::AsCultureInvariant("Linux")); } else if (UGameplayStatics::GetPlatformName() == "Mac" && this->OSList.Contains("Mac OS")) { - this->ShowProcessingOverlayMessage("This should not be possible"); - } - else - { - this->ShowProcessingOverlayMessage("Could not auto-detect operating system"); + this->HardwareButton->SetText(FText::AsCultureInvariant("All")); + this->OSButton->SetText(FText::AsCultureInvariant("Mac OS")); } } - else if (this->PlatformsList.Contains("Macintosh")) + if (UGameplayStatics::GetPlatformName() == "Mac") // Try our best to auto-detect Macintosh hardware { - if (UGameplayStatics::GetPlatformName() == "Windows" && this->OSList.Contains("Windows")) + if (this->PlatformsList.Contains("Macintosh")) { - this->ShowProcessingOverlayMessage("Windows on a Macintosh detected"); + if (this->OSList.Contains("Mac OS")) + { + this->HardwareButton->SetText(FText::AsCultureInvariant("Macintosh")); + this->OSButton->SetText(FText::AsCultureInvariant("Mac OS")); + } } - else if (UGameplayStatics::GetPlatformName() == "Linux" && this->OSList.Contains("Linux")) - { - this->ShowProcessingOverlayMessage("Linux on a Macintosh detected"); - } - else if (UGameplayStatics::GetPlatformName() == "Mac" && this->OSList.Contains("Mac OS")) - { - this->ShowProcessingOverlayMessage("macOS detected"); - } - else - { - this->ShowProcessingOverlayMessage("Could not auto-detect operating system"); - } - } - else // At this stage, don't bother trying to auto-detect; we'll just set it to All here. - { - this->ShowProcessingOverlayMessage("Can't auto-detect platform"); } - //this->HideProcessingOverlay(); + this->HideProcessingOverlay(); } } diff --git a/Source/Unrealzilla/Public/BugFormButton.h b/Source/Unrealzilla/Public/BugFormButton.h new file mode 100644 index 0000000..d080515 --- /dev/null +++ b/Source/Unrealzilla/Public/BugFormButton.h @@ -0,0 +1,36 @@ +// ©2022 Batty Bovine Productions, LLC. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "CommonButtonBase.h" +#include "CommonTextBlock.h" + +#include "BugFormButton.generated.h" + + +UCLASS() +class UNREALZILLA_API UBugFormButton : public UCommonButtonBase +{ + GENERATED_BODY() + +public: + virtual void NativeConstruct() override { this->SetText(this->CurrentText); } + + UFUNCTION(BlueprintCallable) + void SetText(const FText Text) { this->CurrentText = Text.IsEmpty() ? this->DefaultText : Text; this->TextLabel->SetText(this->CurrentText); } + UFUNCTION(BlueprintPure) + FText GetText() const { return this->TextLabel->GetText().EqualTo(this->DefaultText) ? FText::GetEmpty() : this->TextLabel->GetText(); } + +protected: + virtual void NativePreConstruct() override { this->TextLabel->SetText(this->DefaultText); } + + UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) + TObjectPtr TextLabel; + + UPROPERTY(BlueprintReadOnly, EditAnywhere) + FText DefaultText; + +private: + FText CurrentText; +}; diff --git a/Source/Unrealzilla/Public/BugFormTextEntryButton.h b/Source/Unrealzilla/Public/BugFormTextEntryButton.h deleted file mode 100644 index 741c7c5..0000000 --- a/Source/Unrealzilla/Public/BugFormTextEntryButton.h +++ /dev/null @@ -1,26 +0,0 @@ -// ©2022 Batty Bovine Productions, LLC. All Rights Reserved. - -#pragma once - -#include "CoreMinimal.h" -#include "CommonButtonBase.h" -#include "CommonTextBlock.h" - -#include "BugFormTextEntryButton.generated.h" - - -UCLASS() -class UNREALZILLA_API UBugFormTextEntryButton : public UCommonButtonBase -{ - GENERATED_BODY() - -public: - UFUNCTION(BlueprintCallable) - void SetText(const FText Text) { this->TextLabel->SetText(Text); } - UFUNCTION(BlueprintPure) - FText GetText() const { return this->TextLabel->GetText(); } - -protected: - UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) - TObjectPtr TextLabel; -}; diff --git a/Source/Unrealzilla/Public/BugSubmissionForm.h b/Source/Unrealzilla/Public/BugSubmissionForm.h index f84b623..3b03f15 100644 --- a/Source/Unrealzilla/Public/BugSubmissionForm.h +++ b/Source/Unrealzilla/Public/BugSubmissionForm.h @@ -4,7 +4,7 @@ #include "CoreMinimal.h" -#include "BugFormTextEntryButton.h" +#include "BugFormButton.h" #include "CommonActivatableWidget.h" #include "Interfaces/IHttpRequest.h" #include "Interfaces/IHttpResponse.h" @@ -22,22 +22,26 @@ struct FJSONPostBug public: UPROPERTY() FString product; - UPROPERTY() - FString component; UPROPERTY() FString version; - UPROPERTY() - FString cf_mapname; - UPROPERTY() - FString cf_location; UPROPERTY() FString platform; UPROPERTY() FString op_sys; + UPROPERTY() + FString component; + UPROPERTY() + FString severity; + UPROPERTY() + FString cf_mapname; + UPROPERTY() + FString cf_location; UPROPERTY() FString summary; UPROPERTY() FString description; + UPROPERTY() + FString status; }; USTRUCT(Blueprintable) @@ -248,14 +252,22 @@ protected: UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) TObjectPtr ProductNameValue; + UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) - TObjectPtr MapNameValue; + TObjectPtr ComponentButton; UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) - TObjectPtr LocationValue; + TObjectPtr VersionButton; UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) - TObjectPtr SummaryEntryBox; + TObjectPtr SeverityButton; UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) - TObjectPtr CommentEntryBox; + TObjectPtr HardwareButton; + UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) + TObjectPtr OSButton; + + UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) + TObjectPtr SummaryEntryBox; + UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) + TObjectPtr CommentEntryBox; UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) TObjectPtr CancelButton; @@ -271,6 +283,17 @@ protected: UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) TObjectPtr ProcessingRequestErrorText; + UPROPERTY(BlueprintReadOnly) + TArray VersionsList; + UPROPERTY(BlueprintReadOnly) + TArray PlatformsList; + UPROPERTY(BlueprintReadOnly) + TArray OSList; + UPROPERTY(BlueprintReadOnly) + TArray ComponentList; + UPROPERTY(BlueprintReadOnly) + TArray SeverityList; + private: void ServerPOSTResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success); void ServerProductInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success); @@ -295,11 +318,8 @@ private: void ServerConnectionError(const EHttpRequestStatus::Type Status); - TArray ComponentList; - TArray VersionsList; - TArray SeverityList; - TArray PlatformsList; - TArray OSList; + FText MapName; + FText MarkerLocation; TObjectPtr BugMarkerActor; }; diff --git a/Source/Unrealzilla/Public/UnrealzillaGlobalSettings.h b/Source/Unrealzilla/Public/UnrealzillaGlobalSettings.h index 0655fbc..c07ee71 100644 --- a/Source/Unrealzilla/Public/UnrealzillaGlobalSettings.h +++ b/Source/Unrealzilla/Public/UnrealzillaGlobalSettings.h @@ -8,28 +8,61 @@ /** -* Global settings for Unrealzilla classes -*/ + * Global settings for Unrealzilla classes + */ UCLASS(Config=Unrealzilla, defaultconfig, meta=(DisplayName="Unrealzilla")) class UNREALZILLA_API UUnrealzillaGlobalSettings : public UDeveloperSettingsBackedByCVars { GENERATED_BODY() public: + // The distance to send the trace out when placing bug markers in the world. UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, Category="Bug Placement", meta=(DisplayName="Precise Placement Distance")) float BugPlacementTraceDistance = 1500.0f; + // The distance to hold the bug marker when using the arbitrary placement option. UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, Category="Bug Placement", meta=(DisplayName="Arbitrary Placement Distance")) float ArbitraryBugPlacementDistance = 250.0f; - + + // The Bugzilla server where bugs will be posted. UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting") FString SubmissionServer; + // The name of the product for which bugs will be posted. UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting") FString ProductName; + // The API key to use when posting bugs. All bugs will be posted under the account of the owner of this API key. UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting", meta=(DisplayName="API Key")) FString APIKey; + // The viewport depth of the bug report interface widget. UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting") int32 BugReportWidgetDepth = 0; + // The status to use when filing a new bug. A status such as "UNCONFIRMED" is suggested. + UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking") + FString DefaultStatus; + + // Whether to show unresolved bugs when displaying bug report markers. + UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking") + bool bShowUnresolvedBugs = false; + // Whether to show in-progress bugs when displaying bug report markers. + UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking") + bool bShowInProgressBugs = false; + // Whether to show resolved bugs when displaying bug report markers. + UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking") + bool bShowResolvedBugs = false; + + // A list of bug statuses that represent unresolved bugs in your Bugzilla install. + // Generally this would be something like "UNCONFIRMED" and "CONFIRMED". + UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking") + TArray UnresolvedStatuses; + // A list of bug statuses that represent in progress bugs in your Bugzilla install. + // Generally this would include "IN_PROGRESS". + UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking") + TArray InProgressStatuses; + // A list of bug statuses that represent resolved bugs in your Bugzilla install. + // Generally this would include "RESOLVED" and "VERIFIED". + UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking") + TArray ResolvedStatuses; + public: virtual void PostInitProperties() override; virtual FName GetCategoryName() const override;