Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4035 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
35 changed files with 885 additions and 222 deletions
@ -0,0 +1,114 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <author name="Daniel Grunwald"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Collections.ObjectModel; |
||||||
|
using System.Collections.Specialized; |
||||||
|
using System.ComponentModel; |
||||||
|
|
||||||
|
using ICSharpCode.AvalonEdit.CodeCompletion; |
||||||
|
using ICSharpCode.SharpDevelop.Editor; |
||||||
|
|
||||||
|
namespace ICSharpCode.AvalonEdit.AddIn |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Adapter between AvalonEdit InsightWindow and SharpDevelop IInsightWindow interface.
|
||||||
|
/// </summary>
|
||||||
|
public class SharpDevelopInsightWindow : OverloadInsightWindow, IInsightWindow |
||||||
|
{ |
||||||
|
sealed class SDItemProvider : IOverloadProvider |
||||||
|
{ |
||||||
|
readonly SharpDevelopInsightWindow insightWindow; |
||||||
|
int selectedIndex; |
||||||
|
|
||||||
|
public SDItemProvider(SharpDevelopInsightWindow insightWindow) |
||||||
|
{ |
||||||
|
this.insightWindow = insightWindow; |
||||||
|
insightWindow.items.CollectionChanged += insightWindow_items_CollectionChanged; |
||||||
|
} |
||||||
|
|
||||||
|
void insightWindow_items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |
||||||
|
{ |
||||||
|
OnPropertyChanged("Count"); |
||||||
|
OnPropertyChanged("CurrentHeader"); |
||||||
|
OnPropertyChanged("CurrentContent"); |
||||||
|
OnPropertyChanged("CurrentIndexText"); |
||||||
|
} |
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged; |
||||||
|
|
||||||
|
public int SelectedIndex { |
||||||
|
get { |
||||||
|
return selectedIndex; |
||||||
|
} |
||||||
|
set { |
||||||
|
if (selectedIndex != value) { |
||||||
|
selectedIndex = value; |
||||||
|
OnPropertyChanged("SelectedIndex"); |
||||||
|
OnPropertyChanged("CurrentHeader"); |
||||||
|
OnPropertyChanged("CurrentContent"); |
||||||
|
OnPropertyChanged("CurrentIndexText"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public int Count { |
||||||
|
get { return insightWindow.Items.Count; } |
||||||
|
} |
||||||
|
|
||||||
|
public string CurrentIndexText { |
||||||
|
get { return (selectedIndex + 1).ToString() + " of " + this.Count.ToString(); } |
||||||
|
} |
||||||
|
|
||||||
|
public object CurrentHeader { |
||||||
|
get { |
||||||
|
IInsightItem item = insightWindow.SelectedItem; |
||||||
|
return item != null ? item.Header : null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public object CurrentContent { |
||||||
|
get { |
||||||
|
IInsightItem item = insightWindow.SelectedItem; |
||||||
|
return item != null ? item.Content : null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void OnPropertyChanged(string propertyName) |
||||||
|
{ |
||||||
|
if (PropertyChanged != null) { |
||||||
|
PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
readonly ObservableCollection<IInsightItem> items = new ObservableCollection<IInsightItem>(); |
||||||
|
|
||||||
|
public SharpDevelopInsightWindow(TextArea textArea) : base(textArea) |
||||||
|
{ |
||||||
|
this.Provider = new SDItemProvider(this); |
||||||
|
} |
||||||
|
|
||||||
|
public IList<IInsightItem> Items { |
||||||
|
get { return items; } |
||||||
|
} |
||||||
|
|
||||||
|
public IInsightItem SelectedItem { |
||||||
|
get { |
||||||
|
int index = this.Provider.SelectedIndex; |
||||||
|
if (index < 0 || index >= items.Count) |
||||||
|
return null; |
||||||
|
else |
||||||
|
return items[index]; |
||||||
|
} |
||||||
|
set { |
||||||
|
this.Provider.SelectedIndex = items.IndexOf(value); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <author name="Daniel Grunwald"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.ObjectModel; |
||||||
|
using System.ComponentModel; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
|
||||||
|
namespace ICSharpCode.AvalonEdit.CodeCompletion |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Provides the items for the OverloadViewer.
|
||||||
|
/// </summary>
|
||||||
|
public interface IOverloadProvider : INotifyPropertyChanged |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Gets/Sets the selected index.
|
||||||
|
/// </summary>
|
||||||
|
int SelectedIndex { get; set; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of overloads.
|
||||||
|
/// </summary>
|
||||||
|
int Count { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the text 'SelectedIndex of Count'.
|
||||||
|
/// </summary>
|
||||||
|
string CurrentIndexText { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current header.
|
||||||
|
/// </summary>
|
||||||
|
object CurrentHeader { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current content.
|
||||||
|
/// </summary>
|
||||||
|
object CurrentContent { get; } |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,112 @@ |
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||||
|
xmlns:cc="clr-namespace:ICSharpCode.AvalonEdit.CodeCompletion" |
||||||
|
> |
||||||
|
<!-- Template for InsightWindow. Based on the template for ToolTip. --> |
||||||
|
<Style TargetType="{x:Type cc:InsightWindow}"> |
||||||
|
<Setter Property="SizeToContent" Value="WidthAndHeight" /> |
||||||
|
|
||||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" /> |
||||||
|
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.InfoBrushKey}}" /> |
||||||
|
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InfoTextBrushKey}}" /> |
||||||
|
<Setter Property="FontFamily" Value="{DynamicResource {x:Static SystemFonts.StatusFontFamilyKey}}" /> |
||||||
|
<Setter Property="FontSize" Value="{DynamicResource {x:Static SystemFonts.StatusFontSizeKey}}" /> |
||||||
|
<Setter Property="FontStyle" Value="{DynamicResource {x:Static SystemFonts.StatusFontStyleKey}}" /> |
||||||
|
<Setter Property="FontWeight" Value="{DynamicResource {x:Static SystemFonts.StatusFontWeightKey}}" /> |
||||||
|
<Setter Property="Padding" Value="1,1,3,1" /> |
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Left" /> |
||||||
|
<Setter Property="VerticalContentAlignment" Value="Center" /> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="{x:Type cc:InsightWindow}"> |
||||||
|
<Border BorderThickness="{TemplateBinding Border.BorderThickness}" |
||||||
|
Padding="{TemplateBinding Control.Padding}" |
||||||
|
CornerRadius="2,2,2,2" |
||||||
|
BorderBrush="{TemplateBinding Border.BorderBrush}" |
||||||
|
Background="{TemplateBinding Panel.Background}"> |
||||||
|
<AdornerDecorator> |
||||||
|
<ContentPresenter |
||||||
|
Content="{TemplateBinding ContentControl.Content}" |
||||||
|
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" |
||||||
|
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" |
||||||
|
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" |
||||||
|
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" |
||||||
|
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> |
||||||
|
</AdornerDecorator> |
||||||
|
</Border> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
|
||||||
|
<!-- Template for OverloadViewer. --> |
||||||
|
<Style TargetType="{x:Type cc:OverloadViewer}"> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="{x:Type cc:OverloadViewer}"> |
||||||
|
<Grid> |
||||||
|
<Grid.Resources> |
||||||
|
<cc:CollapseIfSingleOverloadConverter x:Key="collapseIfSingleOverloadConverter"/> |
||||||
|
|
||||||
|
<!-- Style of the UpDownButton --> |
||||||
|
<Style TargetType="{x:Type Button}" x:Key="upDownButtonStyle"> |
||||||
|
<Style.Setters> |
||||||
|
<Setter Property="Background" Value="LightGray"/> |
||||||
|
<Setter Property="Padding" Value="2,2,2,2"/> |
||||||
|
<Setter Property="Width" Value="9"/> |
||||||
|
<Setter Property="Height" Value="9"/> |
||||||
|
<Setter Property="SnapsToDevicePixels" Value="True"/> |
||||||
|
<Setter Property="OverridesDefaultStyle" Value="True"/> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="{x:Type Button}"> |
||||||
|
<Border Name="bd" |
||||||
|
Background="{TemplateBinding Background}" CornerRadius="2"> |
||||||
|
<ContentControl Margin="{TemplateBinding Padding}" |
||||||
|
Content="{TemplateBinding Content}"/> |
||||||
|
</Border> |
||||||
|
<ControlTemplate.Triggers> |
||||||
|
<Trigger Property="IsMouseOver" Value="true"> |
||||||
|
<Setter TargetName="bd" Property="Background" Value="LightBlue"/> |
||||||
|
</Trigger> |
||||||
|
</ControlTemplate.Triggers> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style.Setters> |
||||||
|
</Style> |
||||||
|
</Grid.Resources> |
||||||
|
|
||||||
|
<Grid.ColumnDefinitions> |
||||||
|
<ColumnDefinition Width="Auto"/> |
||||||
|
<ColumnDefinition Width="1*"/> |
||||||
|
</Grid.ColumnDefinitions> |
||||||
|
<Grid.RowDefinitions> |
||||||
|
<RowDefinition Height="Auto"/> |
||||||
|
<RowDefinition Height="1*"/> |
||||||
|
</Grid.RowDefinitions> |
||||||
|
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="0" |
||||||
|
Margin="0,0,4,0" |
||||||
|
Orientation="Horizontal" |
||||||
|
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Provider.Count, Converter={StaticResource collapseIfSingleOverloadConverter}}"> |
||||||
|
<Button Name="PART_UP" Style="{StaticResource upDownButtonStyle}"> |
||||||
|
<Path Stroke="Black" Fill="Black" Data="M 0,0.866 L 1,0.866 L 0.5,0 Z" Stretch="UniformToFill" /> |
||||||
|
</Button> |
||||||
|
<TextBlock Margin="2,0,2,0" |
||||||
|
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Provider.CurrentIndexText}"/> |
||||||
|
<Button Name="PART_DOWN" Style="{StaticResource upDownButtonStyle}"> |
||||||
|
<Path Stroke="Black" Fill="Black" Data="M 0,0 L 1,0 L 0.5,0.866 Z" Stretch="UniformToFill" /> |
||||||
|
</Button> |
||||||
|
</StackPanel> |
||||||
|
<ContentControl Grid.Row="0" Grid.Column="1" |
||||||
|
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Provider.CurrentHeader}"/> |
||||||
|
<ContentControl Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" |
||||||
|
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Provider.CurrentContent}"/> |
||||||
|
</Grid> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
</ResourceDictionary> |
@ -0,0 +1,56 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <author name="Daniel Grunwald"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Input; |
||||||
|
|
||||||
|
namespace ICSharpCode.AvalonEdit.CodeCompletion |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Insight window that shows an OverloadViewer.
|
||||||
|
/// </summary>
|
||||||
|
public class OverloadInsightWindow : InsightWindow |
||||||
|
{ |
||||||
|
OverloadViewer overloadViewer = new OverloadViewer(); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new OverloadInsightWindow.
|
||||||
|
/// </summary>
|
||||||
|
public OverloadInsightWindow(TextArea textArea) : base(textArea) |
||||||
|
{ |
||||||
|
overloadViewer.Margin = new Thickness(2,0,0,0); |
||||||
|
this.Content = overloadViewer; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets/Sets the item provider.
|
||||||
|
/// </summary>
|
||||||
|
public IOverloadProvider Provider { |
||||||
|
get { return overloadViewer.Provider; } |
||||||
|
set { overloadViewer.Provider = value; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
protected override void OnKeyDown(KeyEventArgs e) |
||||||
|
{ |
||||||
|
base.OnKeyDown(e); |
||||||
|
if (!e.Handled && this.Provider.Count > 1) { |
||||||
|
switch (e.Key) { |
||||||
|
case Key.Up: |
||||||
|
e.Handled = true; |
||||||
|
overloadViewer.ChangeIndex(-1); |
||||||
|
break; |
||||||
|
case Key.Down: |
||||||
|
e.Handled = true; |
||||||
|
overloadViewer.ChangeIndex(+1); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,105 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <author name="Daniel Grunwald"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.ObjectModel; |
||||||
|
using System.ComponentModel; |
||||||
|
using System.Globalization; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
|
||||||
|
namespace ICSharpCode.AvalonEdit.CodeCompletion |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Represents a text between "Up" and "Down" buttons.
|
||||||
|
/// </summary>
|
||||||
|
public class OverloadViewer : Control |
||||||
|
{ |
||||||
|
static OverloadViewer() |
||||||
|
{ |
||||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(OverloadViewer), |
||||||
|
new FrameworkPropertyMetadata(typeof(OverloadViewer))); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The text property.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty TextProperty = |
||||||
|
DependencyProperty.Register("Text", typeof(string), typeof(OverloadViewer)); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets/Sets the text between the Up and Down buttons.
|
||||||
|
/// </summary>
|
||||||
|
public string Text { |
||||||
|
get { return (string)GetValue(TextProperty); } |
||||||
|
set { SetValue(TextProperty, value); } |
||||||
|
} |
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void OnApplyTemplate() |
||||||
|
{ |
||||||
|
base.OnApplyTemplate(); |
||||||
|
|
||||||
|
Button upButton = (Button)this.Template.FindName("PART_UP", this); |
||||||
|
upButton.Click += (sender, e) => { |
||||||
|
e.Handled = true; |
||||||
|
ChangeIndex(-1); |
||||||
|
}; |
||||||
|
|
||||||
|
Button downButton = (Button)this.Template.FindName("PART_DOWN", this); |
||||||
|
downButton.Click += (sender, e) => { |
||||||
|
e.Handled = true; |
||||||
|
ChangeIndex(+1); |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ItemProvider property.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty ProviderProperty = |
||||||
|
DependencyProperty.Register("Provider", typeof(IOverloadProvider), typeof(OverloadViewer)); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets/Sets the item provider.
|
||||||
|
/// </summary>
|
||||||
|
public IOverloadProvider Provider { |
||||||
|
get { return (IOverloadProvider)GetValue(ProviderProperty); } |
||||||
|
set { SetValue(ProviderProperty, value); } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes the selected index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="relativeIndexChange">The relative index change - usual values are +1 or -1.</param>
|
||||||
|
public void ChangeIndex(int relativeIndexChange) |
||||||
|
{ |
||||||
|
IOverloadProvider p = this.Provider; |
||||||
|
if (p != null) { |
||||||
|
int newIndex = p.SelectedIndex + relativeIndexChange; |
||||||
|
if (newIndex < 0) |
||||||
|
newIndex = p.Count - 1; |
||||||
|
if (newIndex >= p.Count) |
||||||
|
newIndex = 0; |
||||||
|
p.SelectedIndex = newIndex; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
sealed class CollapseIfSingleOverloadConverter : IValueConverter |
||||||
|
{ |
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
||||||
|
{ |
||||||
|
return ((int)value < 2) ? Visibility.Collapsed : Visibility.Visible; |
||||||
|
} |
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
||||||
|
{ |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,38 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using ICSharpCode.AvalonEdit; |
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Collections.ObjectModel; |
|
||||||
using ICSharpCode.AvalonEdit.CodeCompletion; |
|
||||||
|
|
||||||
namespace ICSharpCode.SharpDevelop.Editor |
|
||||||
{ |
|
||||||
public class AvalonEditInsightWindow : InsightWindow, IInsightWindow |
|
||||||
{ |
|
||||||
public AvalonEditInsightWindow(TextArea textArea) : base(textArea) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
ObservableCollection<IInsightItem> items = new ObservableCollection<IInsightItem>(); |
|
||||||
|
|
||||||
public IList<IInsightItem> Items { |
|
||||||
get { return items; } |
|
||||||
} |
|
||||||
|
|
||||||
public IInsightItem SelectedItem { |
|
||||||
get { |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
set { |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,55 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <author name="Daniel Grunwald"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using System; |
||||||
|
|
||||||
|
namespace ICSharpCode.SharpDevelop.Editor |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// An insight item that represents an entity.
|
||||||
|
/// </summary>
|
||||||
|
public class MethodInsightItem : IInsightItem |
||||||
|
{ |
||||||
|
IEntity entity; |
||||||
|
|
||||||
|
public MethodInsightItem(IEntity entity) |
||||||
|
{ |
||||||
|
if (entity == null) |
||||||
|
throw new ArgumentNullException("entity"); |
||||||
|
this.entity = entity; |
||||||
|
} |
||||||
|
|
||||||
|
string headerText; |
||||||
|
bool descriptionCreated; |
||||||
|
string description; |
||||||
|
|
||||||
|
public object Header { |
||||||
|
get { |
||||||
|
if (headerText == null) { |
||||||
|
IAmbience ambience = AmbienceService.GetCurrentAmbience(); |
||||||
|
ambience.ConversionFlags = ConversionFlags.StandardConversionFlags; |
||||||
|
headerText = ambience.Convert(entity); |
||||||
|
} |
||||||
|
return headerText; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public object Content { |
||||||
|
get { |
||||||
|
if (!descriptionCreated) { |
||||||
|
string entityDoc = entity.Documentation; |
||||||
|
if (!string.IsNullOrEmpty(entityDoc)) { |
||||||
|
description = ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.CodeCompletionData.ConvertDocumentation(entityDoc); |
||||||
|
} |
||||||
|
descriptionCreated = true; |
||||||
|
} |
||||||
|
return description; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,141 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <author name="Daniel Grunwald"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
|
||||||
|
using ICSharpCode.Core; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
|
||||||
|
namespace ICSharpCode.SharpDevelop.Editor |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Description of MethodInsightProvider.
|
||||||
|
/// </summary>
|
||||||
|
public class MethodInsightProvider |
||||||
|
{ |
||||||
|
public int LookupOffset { get; set; } |
||||||
|
|
||||||
|
public MethodInsightProvider() |
||||||
|
{ |
||||||
|
this.LookupOffset = -1; |
||||||
|
} |
||||||
|
|
||||||
|
public IInsightItem[] ProvideInsight(ITextEditor editor) |
||||||
|
{ |
||||||
|
if (editor == null) |
||||||
|
throw new ArgumentNullException("editor"); |
||||||
|
|
||||||
|
IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(editor.FileName); |
||||||
|
if (expressionFinder == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
IDocument document = editor.Document; |
||||||
|
int useOffset = (this.LookupOffset < 0) ? editor.Caret.Offset : this.LookupOffset; |
||||||
|
ExpressionResult expressionResult = expressionFinder.FindExpression(document.Text, useOffset); |
||||||
|
|
||||||
|
if (expressionResult.Expression == null) // expression is null when cursor is in string/comment
|
||||||
|
return null; |
||||||
|
|
||||||
|
if (LoggingService.IsDebugEnabled) { |
||||||
|
if (expressionResult.Context == ExpressionContext.Default) |
||||||
|
LoggingService.DebugFormatted("ShowInsight for >>{0}<<", expressionResult.Expression); |
||||||
|
else |
||||||
|
LoggingService.DebugFormatted("ShowInsight for >>{0}<<, context={1}", expressionResult.Expression, expressionResult.Context); |
||||||
|
} |
||||||
|
|
||||||
|
var position = document.OffsetToPosition(useOffset); |
||||||
|
ResolveResult rr = ParserService.Resolve(expressionResult, position.Line, position.Column, editor.FileName, document.Text); |
||||||
|
return ProvideInsight(expressionResult, rr); |
||||||
|
} |
||||||
|
|
||||||
|
public virtual IInsightItem[] ProvideInsight(ExpressionResult expressionResult, ResolveResult result) |
||||||
|
{ |
||||||
|
if (result == null) |
||||||
|
return null; |
||||||
|
|
||||||
|
bool constructorInsight = false; |
||||||
|
if (expressionResult.Context == ExpressionContext.Attribute) { |
||||||
|
constructorInsight = true; |
||||||
|
} else if (expressionResult.Context.IsObjectCreation) { |
||||||
|
constructorInsight = true; |
||||||
|
expressionResult.Context = ExpressionContext.Type; |
||||||
|
} else if (expressionResult.Context == ExpressionContext.BaseConstructorCall) { |
||||||
|
constructorInsight = true; |
||||||
|
} |
||||||
|
|
||||||
|
LanguageProperties language; |
||||||
|
if (result.CallingClass != null) |
||||||
|
language = result.CallingClass.CompilationUnit.Language; |
||||||
|
else |
||||||
|
language = ParserService.CurrentProjectContent.Language; |
||||||
|
|
||||||
|
TypeResolveResult trr = result as TypeResolveResult; |
||||||
|
if (trr == null && language.AllowObjectConstructionOutsideContext) { |
||||||
|
if (result is MixedResolveResult) |
||||||
|
trr = (result as MixedResolveResult).TypeResult; |
||||||
|
} |
||||||
|
if (trr != null && !constructorInsight) { |
||||||
|
if (language.AllowObjectConstructionOutsideContext) |
||||||
|
constructorInsight = true; |
||||||
|
} |
||||||
|
|
||||||
|
List<IMethod> methods = new List<IMethod>(); |
||||||
|
if (constructorInsight) { |
||||||
|
if (trr != null || expressionResult.Context == ExpressionContext.BaseConstructorCall) { |
||||||
|
if (result.ResolvedType != null) { |
||||||
|
methods.AddRange(GetConstructors(result.ResolvedType)); |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
MethodGroupResolveResult mgrr = result as MethodGroupResolveResult; |
||||||
|
if (mgrr == null) |
||||||
|
return null; |
||||||
|
bool classIsInInheritanceTree = false; |
||||||
|
if (result.CallingClass != null) |
||||||
|
classIsInInheritanceTree = result.CallingClass.IsTypeInInheritanceTree(mgrr.ContainingType.GetUnderlyingClass()); |
||||||
|
|
||||||
|
foreach (IMethod method in mgrr.ContainingType.GetMethods()) { |
||||||
|
if (language.NameComparer.Equals(method.Name, mgrr.Name)) { |
||||||
|
if (method.IsAccessible(result.CallingClass, classIsInInheritanceTree)) { |
||||||
|
methods.Add(method); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (methods.Count == 0 && result.CallingClass != null && language.SupportsExtensionMethods) { |
||||||
|
ArrayList list = new ArrayList(); |
||||||
|
ResolveResult.AddExtensions(language, list, result.CallingClass, mgrr.ContainingType); |
||||||
|
foreach (IMethodOrProperty mp in list) { |
||||||
|
if (language.NameComparer.Equals(mp.Name, mgrr.Name) && mp is IMethod) { |
||||||
|
DefaultMethod m = (DefaultMethod)mp.CreateSpecializedMember(); |
||||||
|
// for the insight window, remove first parameter and mark the
|
||||||
|
// method as normal - this is required to show the list of
|
||||||
|
// parameters the method expects.
|
||||||
|
m.IsExtensionMethod = false; |
||||||
|
m.Parameters.RemoveAt(0); |
||||||
|
methods.Add(m); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return methods.Select(m => new MethodInsightItem(m)).ToArray(); |
||||||
|
} |
||||||
|
|
||||||
|
IEnumerable<IMethod> GetConstructors(IReturnType rt) |
||||||
|
{ |
||||||
|
// no need to add default constructor here:
|
||||||
|
// default constructors should already be present in rt.GetMethods()
|
||||||
|
if (rt == null) |
||||||
|
return Enumerable.Empty<IMethod>(); |
||||||
|
else |
||||||
|
return rt.GetMethods().Where(m => m.IsConstructor && !m.IsStatic); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue