void SVisualLoggerFilters::Construct(const FArguments& InArgs, const TSharedRef<FUICommandList>& InCommandList)
{
	ChildSlot
		[
			SAssignNew(FilterBox, SWrapBox)
			.UseAllottedWidth(true)
		];

	GraphsFilterCombo =
		SNew(SComboButton)
		.ComboButtonStyle(FLogVisualizerStyle::Get(), "Filters.Style")
		.ForegroundColor(FLinearColor::White)
		.ContentPadding(0)
		.OnGetMenuContent(this, &SVisualLoggerFilters::MakeGraphsFilterMenu)
		.ToolTipText(LOCTEXT("AddFilterToolTip", "Add an asset filter."))
		.HasDownArrow(true)
		.ContentPadding(FMargin(1, 0))
		.ButtonContent()
		[
			SNew(STextBlock)
			.TextStyle(FLogVisualizerStyle::Get(), "Filters.Text")
			.Text(LOCTEXT("GraphFilters", "Graph Filters"))
		];


	FilterBox->AddSlot()
		.Padding(3, 3)
		[
			SNew(SHorizontalBox)
			+ SHorizontalBox::Slot()
			.Padding(FMargin(0))
			.AutoWidth()
			.HAlign(HAlign_Center)
			.VAlign(VAlign_Center)
			[
				SNew(SImage)
				.Visibility_Lambda([this]()->EVisibility{ return this->GraphsSearchString.Len() > 0 ? EVisibility::Visible : EVisibility::Hidden; })
				.Image(FLogVisualizerStyle::Get().GetBrush("Filters.FilterIcon"))
			]
			+ SHorizontalBox::Slot()
			.Padding(FMargin(0))
			[
				GraphsFilterCombo.ToSharedRef()
			]
		];

	for (auto& CurrentCategory : FVisualLoggerFilters::Get().Categories)
	{
		AddFilterCategory(CurrentCategory.CategoryName, (ELogVerbosity::Type)CurrentCategory.LogVerbosity, false);
	}

	GraphsFilterCombo->SetVisibility(CachedDatasPerGraph.Num() ? EVisibility::Visible : EVisibility::Collapsed);

	FVisualLoggerFilters::Get().OnFilterCategoryAdded.AddRaw(this, &SVisualLoggerFilters::OnFilterCategoryAdded);
	FVisualLoggerFilters::Get().OnFilterCategoryRemoved.AddRaw(this, &SVisualLoggerFilters::OnFilterCategoryRemoved);
	FVisualLoggerDatabase::Get().GetEvents().OnItemSelectionChanged.AddRaw(this, &SVisualLoggerFilters::OnItemsSelectionChanged);

	FVisualLoggerDatabase::Get().GetEvents().OnGraphAddedEvent.AddRaw(this, &SVisualLoggerFilters::OnGraphAddedEvent);
	FVisualLoggerDatabase::Get().GetEvents().OnGraphDataNameAddedEvent.AddRaw(this, &SVisualLoggerFilters::OnGraphDataNameAddedEvent);
}
void SVisualLoggerFilters::OnFilterCategoryAdded(FString InName, ELogVerbosity::Type InVerbosity)
{
	AddFilterCategory(InName, InVerbosity, false);
	GraphsFilterCombo->SetVisibility(CachedGraphFilters.Num() > 0 ? EVisibility::Visible : EVisibility::Collapsed);
}
void MainDialog::DisplayFullCategorySet()
{
    HRESULT hr;
    int nClasses=0;

    IEnumMoniker *pEmCat = 0;
    ICreateDevEnum *pCreateDevEnum = NULL;
	IPropertyBag *pPropBag = NULL;

    // Create the system device enumerator.
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
                          IID_ICreateDevEnum, (void**)&pCreateDevEnum);

	if (SUCCEEDED(hr))
	{
		// Use the meta-category that contains a list of all categories.
		// This emulates the behavior of GraphEdit.
		hr = pCreateDevEnum->CreateClassEnumerator(
							CLSID_ActiveMovieCategories, &pEmCat, 0);

		if (hr == S_FALSE)
		{
			// If CreateClassEnumerator returns S_OK, it means this
			// category does not exist or is empty. For the meta-category,
			// that would qualify as a failure!
			hr = E_FAIL;
		}
	}

	// Enumerate over every category and get the category CLSID and description.
    if (SUCCEEDED(hr))
    {
        IMoniker *pMCat = NULL;

        while (S_OK == pEmCat->Next(1, &pMCat, NULL))
        {
			VARIANT varCatName;
			VariantInit(&varCatName);

			VARIANT varCatClsid;
			VariantInit(&varCatClsid);

			CLSID clsidCat;

            // Associate moniker with a file
            hr = pMCat->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
			
			// Read CLSID string from property bag
			if (SUCCEEDED(hr))
			{
				hr = pPropBag->Read(L"CLSID", &varCatClsid, 0);
			}

			// Convert to a CLSID
			if (SUCCEEDED(hr))
			{
				hr = CLSIDFromString(varCatClsid.bstrVal, &clsidCat);
			}

			// Read the category name. If that fails, use the CLSID string.
			if (SUCCEEDED(hr))
			{
				HRESULT hrTmp = pPropBag->Read(L"FriendlyName", &varCatName, 0);

				// Add category name and CLSID to list box
				if(SUCCEEDED(hrTmp))
				{
					hr = AddFilterCategory(varCatName.bstrVal, clsidCat);
				}
				else
				{
					hr = AddFilterCategory(varCatClsid.bstrVal, clsidCat);
				}
				nClasses++;
			}

			SAFE_RELEASE(pMCat);
			SAFE_RELEASE(pPropBag);
			VariantClear(&varCatName);
			VariantClear(&varCatClsid);

			if (FAILED(hr))
			{
				break;
			}
        } // for loop
    }

    // Update listbox title with number of classes
	if (SUCCEEDED(hr))
	{
	    SetNumClasses(nClasses);
	}

	SAFE_RELEASE(pEmCat);
    SAFE_RELEASE(pCreateDevEnum);

}