// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Logging/LogVerbosity.h" #include "Misc/ScopeLock.h" #include "SlateFwd.h" #include "Templates/UniquePtr.h" #include "Widgets/DeclarativeSyntaxSupport.h" #include "Widgets/Input/SSearchBox.h" #include "Widgets/SCompoundWidget.h" #include "Widgets/Views/SListView.h" // Insights #include "Insights/Common/Stopwatch.h" #include "Insights/ViewModels/LogFilter.h" #include "Insights/ViewModels/LogMessage.h" class FMenuBuilder; //////////////////////////////////////////////////////////////////////////////////////////////////// namespace LogViewColumns { static const FName IdColumnName(TEXT("Id")); static const FName TimeColumnName(TEXT("Time")); static const FName VerbosityColumnName(TEXT("Verbosity")); static const FName CategoryColumnName(TEXT("Category")); static const FName MessageColumnName(TEXT("Message")); static const FName FileColumnName(TEXT("File")); static const FName LineColumnName(TEXT("Line")); } // namespace LogViewColumns //////////////////////////////////////////////////////////////////////////////////////////////////// /** * Trace log window. */ class SLogView: public SCompoundWidget { public: /** Default constructor. */ SLogView(); /** Virtual destructor. */ virtual ~SLogView(); void Reset(); SLATE_BEGIN_ARGS(SLogView) {} SLATE_END_ARGS() /** * Construct this widget. * @param InArgs - The declaration data for this widget */ void Construct(const FArguments& InArgs); /** * Ticks this widget. Override in derived classes, but always call the parent implementation. * * @param AllottedGeometry - The space allotted for this widget * @param InCurrentTime - Current absolute real time * @param InDeltaTime - Real time passed since last tick */ virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override; FLogMessageCache& GetCache() { return Cache; } TSharedPtr GetSelectedLogMessage() const; void SelectedLogMessageByLogIndex(int32 LogIndex); FText GetFilterText() const { return FilterTextBox->GetText(); } bool IsFilteringAsyncTaskCancelRequested() const { return bIsFilteringAsyncTaskCancelRequested; } protected: /** Generate a new list view row. */ TSharedRef OnGenerateRow(TSharedPtr InLogMessage, const TSharedRef& OwnerTable); void SelectLogMessage(TSharedPtr LogMessage); void OnMouseButtonClick(TSharedPtr LogMessage); void OnSelectionChanged(TSharedPtr LogMessage, ESelectInfo::Type SelectInfo); void FilterTextBox_OnTextChanged(const FText& InFilterText); void OnFilterChanged(); void UpdateStatsText(); FText GetStatsText() const; FSlateColor GetStatsTextColor() const; TSharedPtr ListView_GetContextMenu(); TSharedRef MakeVerbosityThresholdMenu(); void CreateVerbosityThresholdMenuSection(FMenuBuilder& MenuBuilder); TSharedRef MakeCategoryFilterMenu(); void CreateCategoriesFilterMenuSection(FMenuBuilder& MenuBuilder); bool VerbosityThreshold_IsChecked(ELogVerbosity::Type Verbosity) const; void VerbosityThreshold_Execute(ELogVerbosity::Type Verbosity); FText VerbosityThreshold_GetSuffixGlyph(ELogVerbosity::Type Verbosity) const; FSlateColor VerbosityThreshold_GetSuffixColor(ELogVerbosity::Type Verbosity) const; bool ShowHideAllCategories_IsChecked() const; void ShowHideAllCategories_Execute(); void ShowAllCategories_Execute(); void ShowOnlyCategory_Execute(FName InName); bool ToggleCategory_IsChecked(FName InName) const; void ToggleCategory_Execute(FName InName); protected: /** The list view widget. */ TSharedPtr>> ListView; /** External scrollbar used to synchronize tree view position. */ TSharedPtr ExternalScrollbar; /** The search box widget used to filter logs by message text. */ TSharedPtr FilterTextBox; FLogFilter Filter; uint64 FilterChangeNumber; int32 FilteringStartIndex; // Start index (of the range of log messages to filter) currenly used by the async task int32 FilteringEndIndex; // End index (of the range of log messages to filter) currenly used by the async task uint64 FilteringChangeNumber; // Change number of the filter currenly used by the async task TUniquePtr> FilteringAsyncTask; // The async task to filter log messages on a worker thread mutable volatile bool bIsFilteringAsyncTaskCancelRequested; // true if we want the async task to finish asap /** Stopwatch used to measure how long it takes to filter the message list. */ mutable FStopwatch FilteringStopwatch; int32 TotalNumCategories; /** Total number of log messages processed, from the source Trace session. Used to detect when new log messages are added in the source Trace session. */ int32 TotalNumMessages; /** true if the list of messages is not yet updated (the filter has changed and/or the source trace messages have changed) */ bool bIsDirty; /** Stopwatch used to measure the time since the list of messages has become dirty. */ mutable FStopwatch DirtyStopwatch; /** Stats */ FText StatsText; /** Cached log messages. */ FLogMessageCache Cache; /** List of trace log messages to show in list view (i.e. filtered). */ TArray> Messages; // TODO: this needs virtualisation (an a new SListView) }; ////////////////////////////////////////////////////////////////////////////////////////////////////