File: EditorConfigSettings\Common\SettingsViewModelBase.cs
Web Access
Project: src\src\VisualStudio\Core\Def\Microsoft.VisualStudio.LanguageServices_pxr0p0dn_wpftmp.csproj (Microsoft.VisualStudio.LanguageServices)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider;
using Microsoft.CodeAnalysis.Text;
using Microsoft.Internal.VisualStudio.Shell.TableControl;
using Microsoft.VisualStudio.Shell.TableControl;
using Microsoft.VisualStudio.Shell.TableManager;
 
namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common;
 
internal abstract partial class SettingsViewModelBase<T, TSnapshotFactory, TEntriesSnapshot> : IWpfSettingsEditorViewModel, ITableDataSource
    where TSnapshotFactory : SettingsSnapshotFactoryBase<T, TEntriesSnapshot>
    where TEntriesSnapshot : SettingsEntriesSnapshotBase<T>
{
    private readonly ISettingsProvider<T> _data;
    private readonly IWpfTableControlProvider _controlProvider;
    private readonly TSnapshotFactory _snapshotFactory;
    private readonly ITableManager _tableManager;
    private ITableEntriesSnapshot? _lastPublishedSnapshot;
 
    private List<ITableDataSink> TableSinks { get; } = [];
 
    protected SettingsViewModelBase(ISettingsProvider<T> data,
                                    IWpfTableControlProvider controlProvider,
                                    ITableManagerProvider tableMangerProvider)
    {
        _data = data;
        _controlProvider = controlProvider;
        _data.RegisterViewModel(this);
        _tableManager = tableMangerProvider.GetTableManager(Identifier);
        _snapshotFactory = CreateSnapshotFactory(_data);
        _ = _tableManager.AddSource(this);
    }
 
    public abstract string Identifier { get; }
    protected abstract TSnapshotFactory CreateSnapshotFactory(ISettingsProvider<T> data);
    protected abstract string[] GetFixedColumns();
    protected abstract IEnumerable<ColumnState2> GetInitialColumnStates();
 
    public string SourceTypeIdentifier => "EditorConfigSettings";
    public string? DisplayName => null;
 
    public void NotifyOfUpdate()
    {
        _snapshotFactory.NotifyOfUpdate();
        var snapshot = _snapshotFactory.GetCurrentSnapshot();
 
        // Notify the sinks. Generally, VS Table Control will request data 500ms after the last notification.
        foreach (var tableSink in TableSinks)
        {
            // Notify that an update is available
            tableSink.ReplaceSnapshot(snapshot, _lastPublishedSnapshot);
        }
 
        _lastPublishedSnapshot = snapshot;
    }
 
    public IDisposable Subscribe(ITableDataSink sink)
    {
        TableSinks.Add(sink);
        _snapshotFactory.NotifyOfUpdate();
        _lastPublishedSnapshot = _snapshotFactory.GetCurrentSnapshot();
        sink.AddSnapshot(_lastPublishedSnapshot);
        return new RemoveSinkWhenDisposed(TableSinks, sink);
    }
 
    public IWpfTableControl4 GetTableControl()
    {
        var initialColumnStates = GetInitialColumnStates();
        var fixedColumns = GetFixedColumns();
        var control = (IWpfTableControl4)_controlProvider.CreateControl(
                _tableManager,
                true,
                initialColumnStates,
                fixedColumns);
 
        control.KeepSelectionInView = true;
        control.DoNotLoseFocusOnBucketExpandOrCollapse();
 
        return control;
    }
 
    public void ShutDown() => _ = _tableManager.RemoveSource(this);
 
    public Task<SourceText> UpdateEditorConfigAsync(SourceText sourceText) => _data.GetChangedEditorConfigAsync(sourceText);
}