|
// 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.Threading;
using Microsoft.CodeAnalysis.Navigation;
using Microsoft.VisualStudio.Shell.TableControl;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource
{
internal abstract class AbstractTableControlEventProcessorProvider<TItem> : ITableControlEventProcessorProvider
where TItem : TableItem
{
public ITableControlEventProcessor GetAssociatedEventProcessor(IWpfTableControl tableControl)
=> CreateEventProcessor();
protected virtual EventProcessor CreateEventProcessor()
=> new();
protected class EventProcessor : TableControlEventProcessorBase
{
protected static AbstractTableEntriesSnapshot<TItem>? GetEntriesSnapshot(ITableEntryHandle entryHandle)
=> GetEntriesSnapshot(entryHandle, out _);
protected static AbstractTableEntriesSnapshot<TItem>? GetEntriesSnapshot(ITableEntryHandle entryHandle, out int index)
{
if (!entryHandle.TryGetSnapshot(out var snapshot, out index))
{
return null;
}
return snapshot as AbstractTableEntriesSnapshot<TItem>;
}
public override void PreprocessNavigate(ITableEntryHandle entryHandle, TableEntryNavigateEventArgs e)
{
var roslynSnapshot = GetEntriesSnapshot(entryHandle, out var index);
if (roslynSnapshot == null)
{
return;
}
// don't be too strict on navigation on our item. if we can't handle the item,
// let default handler to handle it at least.
// we might fail to navigate if we don't see the document in our solution anymore.
// that can happen if error is staled build error or user used #line pragma in C#
// to point to some random file in error or more.
// TODO: Use a threaded-wait-dialog here so we can cancel navigation.
var options = new NavigationOptions(PreferProvisionalTab: e.IsPreview, ActivateTab: e.ShouldActivate);
e.Handled = roslynSnapshot.TryNavigateTo(index, options, CancellationToken.None);
}
}
}
}
|