Browse Source

First implementation of context action hiding. Selection of hidden actions is not persisted to settings yet.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6412 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Martin Koníček 15 years ago
parent
commit
c81c3f73c8
  1. 81
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActionsRenderer.cs
  2. 4
      src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/AddUsing.cs
  3. 1
      src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/CacheClassAtCaret.cs
  4. 4
      src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/GenerateMember.cs
  5. 4
      src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/ImplementAbstractClass.cs
  6. 4
      src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/ImplementInterface.cs
  7. 2
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  8. 5
      src/Main/Base/Project/Src/Commands/FileTabStripCommands.cs
  9. 1
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserControl.cs
  10. 2
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextAction.cs
  11. 6
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionViewModel.cs
  12. 132
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbControl.xaml
  13. 38
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbControl.xaml.cs
  14. 24
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbPopup.cs
  15. 17
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsControl.xaml
  16. 26
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsControl.xaml.cs
  17. 20
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsHeaderedControl.xaml
  18. 42
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsHiddenViewModel.cs
  19. 22
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsProvider.cs
  20. 61
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs
  21. 2
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsViewModel.cs
  22. 1
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/IContextAction.cs
  23. 5
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/IContextActionsProvider.cs

81
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActionsRenderer.cs

@ -68,36 +68,28 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -68,36 +68,28 @@ namespace ICSharpCode.AvalonEdit.AddIn
void ContextActionsRenderer_KeyDown(object sender, KeyEventArgs e)
{
if (this.popup == null)
return;
if (e.Key == Key.T && Keyboard.Modifiers == ModifierKeys.Control)
{
if (popup != null && popup.Actions != null && popup.Actions.Actions != null && popup.Actions.Actions.Count > 0) {
if (popup.ViewModel != null && popup.ViewModel.Actions != null && popup.ViewModel.Actions.Count > 0) {
popup.IsDropdownOpen = true;
popup.Focus();
} else {
// Popup is not shown but user explicitely requests it
var popupVM = BuildPopupViewModel(this.Editor);
popupVM.LoadHiddenActions();
if (popupVM.HiddenActions.Count == 0)
return;
this.popup.ViewModel = popupVM;
this.popup.IsDropdownOpen = true;
this.popup.IsHiddenActionsExpanded = true;
this.popup.OpenAtLineStart(this.Editor);
this.popup.Focus();
}
}
}
void WorkbenchSingleton_Workbench_ViewClosed(object sender, ViewContentEventArgs e)
{
try {
// prevent memory leaks
if (e.Content.PrimaryFileName == this.Editor.FileName) {
WorkbenchSingleton.Workbench.ViewClosed -= WorkbenchSingleton_Workbench_ViewClosed;
WorkbenchSingleton.Workbench.ActiveViewContentChanged -= WorkbenchSingleton_Workbench_ActiveViewContentChanged;
}
} catch {}
}
void WorkbenchSingleton_Workbench_ActiveViewContentChanged(object sender, EventArgs e)
{
ClosePopup();
try {
// open the popup again if in current file
if (((IViewContent)WorkbenchSingleton.Workbench.ActiveContent).PrimaryFileName == this.Editor.FileName)
CaretPositionChanged(this, EventArgs.Empty);
} catch {}
}
void ScrollChanged(object sender, EventArgs e)
{
ClosePopup();
@ -109,19 +101,22 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -109,19 +101,22 @@ namespace ICSharpCode.AvalonEdit.AddIn
if (!IsEnabled)
return;
ClosePopup();
var availableActions = ContextActionsService.Instance.GetAvailableActions(this.Editor);
var availableActionsVM = new ObservableCollection<ContextActionViewModel>(
availableActions.Select(a => new ContextActionViewModel(a)));
if (availableActionsVM.Count == 0)
return;
this.popup.Actions = new ContextActionsViewModel {
//Image = ClassBrowserIconService.Class.ImageSource,
Actions = availableActionsVM
};
ContextActionsHiddenViewModel popupVM = BuildPopupViewModel(this.Editor);
//availableActionsVM.Title =
//availableActionsVM.Image =
if (popupVM.Actions.Count == 0)
return;
this.popup.ViewModel = popupVM;
this.popup.OpenAtLineStart(this.Editor);
}
ContextActionsHiddenViewModel BuildPopupViewModel(ITextEditor editor)
{
var actionsProvider = ContextActionsService.Instance.GetAvailableActions(editor);
return new ContextActionsHiddenViewModel(actionsProvider);
}
void CaretPositionChanged(object sender, EventArgs e)
{
if (this.popup.IsOpen)
@ -136,7 +131,29 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -136,7 +131,29 @@ namespace ICSharpCode.AvalonEdit.AddIn
{
this.popup.Close();
this.popup.IsDropdownOpen = false;
this.popup.Actions = null;
this.popup.IsHiddenActionsExpanded = false;
this.popup.ViewModel = null;
}
void WorkbenchSingleton_Workbench_ViewClosed(object sender, ViewContentEventArgs e)
{
try {
// prevent memory leaks
if (e.Content.PrimaryFileName == this.Editor.FileName) {
WorkbenchSingleton.Workbench.ViewClosed -= WorkbenchSingleton_Workbench_ViewClosed;
WorkbenchSingleton.Workbench.ActiveViewContentChanged -= WorkbenchSingleton_Workbench_ActiveViewContentChanged;
}
} catch {}
}
void WorkbenchSingleton_Workbench_ActiveViewContentChanged(object sender, EventArgs e)
{
ClosePopup();
try {
// open the popup again if in current file
if (((IViewContent)WorkbenchSingleton.Workbench.ActiveContent).PrimaryFileName == this.Editor.FileName)
CaretPositionChanged(this, EventArgs.Empty);
} catch {}
}
}
}

4
src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/AddUsing.cs

@ -16,9 +16,9 @@ namespace SharpRefactoring.ContextActions @@ -16,9 +16,9 @@ namespace SharpRefactoring.ContextActions
/// <summary>
/// Description of AddUsing.
/// </summary>
public class AddUsingProvider : IContextActionsProvider
public class AddUsingProvider : ContextActionsProvider
{
public IEnumerable<IContextAction> GetAvailableActions(EditorContext context)
public override IEnumerable<IContextAction> GetAvailableActions(EditorContext context)
{
var currentLineAST = context.CurrentLineAST;
if (currentLineAST == null)

1
src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/CacheClassAtCaret.cs

@ -47,6 +47,7 @@ namespace SharpRefactoring.ContextActions @@ -47,6 +47,7 @@ namespace SharpRefactoring.ContextActions
public void Initialize(EditorContext context)
{
// class at caret (either declaration of usage)
this.Class = GetClass(context.CurrentSymbol);
if (this.Class == null)
return;

4
src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/GenerateMember.cs

@ -16,9 +16,9 @@ namespace SharpRefactoring.ContextActions @@ -16,9 +16,9 @@ namespace SharpRefactoring.ContextActions
/// <summary>
/// Description of GenerateMember.
/// </summary>
public class GenerateMemberProvider : IContextActionsProvider
public class GenerateMemberProvider : ContextActionsProvider
{
public IEnumerable<IContextAction> GetAvailableActions(EditorContext context)
public override IEnumerable<IContextAction> GetAvailableActions(EditorContext context)
{
if (string.IsNullOrEmpty(context.CurrentExpression.Expression)) {
yield break;

4
src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/ImplementAbstractClass.cs

@ -19,9 +19,9 @@ namespace SharpRefactoring.ContextActions @@ -19,9 +19,9 @@ namespace SharpRefactoring.ContextActions
/// <summary>
/// Description of ImplementAbstractClass.
/// </summary>
public class ImplementAbstractClassProvider : IContextActionsProvider
public class ImplementAbstractClassProvider : ContextActionsProvider
{
public IEnumerable<IContextAction> GetAvailableActions(EditorContext editorContext)
public override IEnumerable<IContextAction> GetAvailableActions(EditorContext editorContext)
{
var ambience = AmbienceService.GetCurrentAmbience();

4
src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/ImplementInterface.cs

@ -22,9 +22,9 @@ namespace SharpRefactoring.ContextActions @@ -22,9 +22,9 @@ namespace SharpRefactoring.ContextActions
/// <summary>
/// Description of ImplementInterface.
/// </summary>
public class ImplementInterfaceProvider : IContextActionsProvider
public class ImplementInterfaceProvider : ContextActionsProvider
{
public IEnumerable<IContextAction> GetAvailableActions(EditorContext editorContext)
public override IEnumerable<IContextAction> GetAvailableActions(EditorContext editorContext)
{
// Using CurrentLineAST is basically OK, but when the "class" keyword is on different line than class name,
// parsing only one line never tells us that we are looking at TypeDeclaration

2
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -341,7 +341,9 @@ @@ -341,7 +341,9 @@
<DependentUpon>ContextActionsHeaderedControl.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Src\Services\RefactoringService\ContextActions\ContextActionsHiddenViewModel.cs" />
<Compile Include="Src\Services\RefactoringService\ContextActions\ContextActionsPopupBase.cs" />
<Compile Include="Src\Services\RefactoringService\ContextActions\ContextActionsProvider.cs" />
<Compile Include="Src\Services\RefactoringService\ContextActions\ContextActionsService.cs" />
<Compile Include="Src\Services\RefactoringService\ContextActions\EditorContext.cs" />
<Compile Include="Src\Services\RefactoringService\ContextActions\IContextAction.cs" />

5
src/Main/Base/Project/Src/Commands/FileTabStripCommands.cs

@ -84,8 +84,9 @@ namespace ICSharpCode.SharpDevelop.Commands.TabStrip @@ -84,8 +84,9 @@ namespace ICSharpCode.SharpDevelop.Commands.TabStrip
{
public override void Run()
{
var c = ProjectBrowserPad.Instance.Control as ProjectBrowserPanel;
c.ProjectBrowserControl.SelectFileAndExpand(((IWorkbenchWindow)Owner).ActiveViewContent.PrimaryFileName);
var projectBrowser = (ProjectBrowserPad.Instance.Control as ProjectBrowserPanel).ProjectBrowserControl;
projectBrowser.SelectFileAndExpand(((IWorkbenchWindow)Owner).ActiveViewContent.PrimaryFileName);
projectBrowser.Focus();
}
}

1
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserControl.cs

@ -257,7 +257,6 @@ namespace ICSharpCode.SharpDevelop.Project @@ -257,7 +257,6 @@ namespace ICSharpCode.SharpDevelop.Project
// Node for this file does not exist yet (the tree view is lazy loaded)
SelectDeepestOpenNodeForPath(fileName);
}
this.Focus();
} finally {
inSelectFile = false;
}

2
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextAction.cs

@ -16,6 +16,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -16,6 +16,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring
{
public abstract string Title { get; }
public bool IsVisible { get; set; }
public abstract bool IsAvailable(EditorContext context);
public abstract void Execute(EditorContext context);

6
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionViewModel.cs

@ -20,6 +20,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -20,6 +20,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
{
public ContextActionViewModel()
{
this.IsVisible = true;
}
public ContextActionViewModel(IContextAction action)
@ -35,6 +36,11 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -35,6 +36,11 @@ namespace ICSharpCode.SharpDevelop.Refactoring
public ImageSource Image { get; set; }
/// <summary>
/// Is this action enabled to be offered automatically?
/// </summary>
public bool IsVisible { get; set; }
public ObservableCollection<ContextActionViewModel> ChildActions { get; set; }
IContextAction action;

132
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbControl.xaml

@ -6,14 +6,137 @@ @@ -6,14 +6,137 @@
<UserControl.Resources>
<!--<BitmapImage x:Key="BulbImage" UriSource="bulb.png" />-->
<SolidColorBrush x:Key="OuterBorderBrush" Color="#436C82"></SolidColorBrush>
<BitmapImage x:Key="PencilImage" UriSource="pencil.png" />
<Geometry x:Key="DownArrowGeometry">M 0 0 L 2 3 L 4 0 Z</Geometry>
<Style x:Key="ExpanderDownHeaderStyle"
TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Control.Padding}">
<Grid>
<Border Name="headerBorder" Height="10" >
<Path Name="arrow" Data="M1,1.5L4.5,5 8,1.5" Stroke="#888" StrokeThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="False" />
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="White" Offset="0.5"></GradientStop>
<GradientStop Color="#FFE9E9E9" Offset="1"></GradientStop>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Data"
Value="M 1,4.5 L 4.5,1 L 8,4.5"
TargetName="arrow"/>
</Trigger>
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Background"
TargetName="headerBorder">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="White" Offset="0.2"></GradientStop>
<GradientStop Color="#CCEBFF" Offset="1"></GradientStop>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Stroke"
Value="#304760"
TargetName="arrow"/>
</Trigger>
<Trigger Property="IsPressed"
Value="true">
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type Expander}"
TargetType="{x:Type Expander}">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background"
Value="Transparent"/>
<Setter Property="HorizontalContentAlignment"
Value="Stretch"/>
<Setter Property="VerticalContentAlignment"
Value="Stretch"/>
<Setter Property="BorderBrush"
Value="Transparent"/>
<Setter Property="BorderThickness"
Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
CornerRadius="3"
SnapsToDevicePixels="true">
<DockPanel>
<ToggleButton x:Name="HeaderSite"
DockPanel.Dock="Top"
Margin="0"
MinWidth="0"
MinHeight="0"
Style="{StaticResource ExpanderDownHeaderStyle}"
IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
Foreground="{TemplateBinding Foreground}"
Padding="{TemplateBinding Padding}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontStyle="{TemplateBinding FontStyle}"
FontStretch="{TemplateBinding FontStretch}"
FontWeight="{TemplateBinding FontWeight}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ContentPresenter x:Name="ExpandSite"
DockPanel.Dock="Bottom"
Visibility="Collapsed"
Focusable="false"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"/>
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded"
Value="true">
<Setter Property="Visibility"
Value="Visible"
TargetName="ExpandSite"/>
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<!--<Border Padding="0 0 8 8">
<aero:SystemDropShadowChrome>
<Border BorderThickness="1" BorderBrush="{StaticResource OuterBorderBrush}" HorizontalAlignment="Stretch">-->
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
@ -37,7 +160,7 @@ @@ -37,7 +160,7 @@
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Width="12" Height="12" Stretch="Fill" Source="{StaticResource PencilImage}" />
<!-- <Path Grid.Column="1" x:Name="Arrow" Fill="Black" Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center" Data="{StaticResource DownArrowGeometry}"/>-->
<!-- <Path Grid.Column="1" x:Name="Arrow" Fill="Black" Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center" Data="{StaticResource DownArrowGeometry}"/>-->
</Grid>
<!--<Border.Style>
<Style TargetType="{x:Type Border}">
@ -51,6 +174,11 @@ @@ -51,6 +174,11 @@
</Border>
<!-- Content - TreeView -->
<local:ContextActionsControl x:Name="ActionsTreeView" Grid.Row="1" Grid.Column="0" DataContext="{Binding Actions}"></local:ContextActionsControl>
<local:ContextActionsControl x:Name="ActionsTreeView" Grid.Row="1" Grid.Column="0"
DataContext="{Binding Actions}" ActionVisibleChanged="ActionsTreeView_ActionVisibleChanged"></local:ContextActionsControl>
<Expander x:Name="HiddenActionsExpander" Expanded="Expander_Expanded" Grid.Row="2" Grid.Column="0">
<local:ContextActionsControl x:Name="HiddenActionsTreeView"
DataContext="{Binding HiddenActions}" ActionVisibleChanged="HiddenActionsTreeView_ActionVisibleChanged"></local:ContextActionsControl>
</Expander>
</Grid>
</UserControl>

38
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbControl.xaml.cs

@ -33,6 +33,12 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -33,6 +33,12 @@ namespace ICSharpCode.SharpDevelop.Refactoring
remove { this.ActionsTreeView.ActionExecuted -= value; }
}
public new ContextActionsHiddenViewModel DataContext
{
get { return (ContextActionsHiddenViewModel)base.DataContext; }
set { base.DataContext = value; }
}
bool isOpen;
public bool IsOpen {
get { return isOpen; }
@ -40,10 +46,18 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -40,10 +46,18 @@ namespace ICSharpCode.SharpDevelop.Refactoring
isOpen = value;
this.Header.Opacity = isOpen ? 1.0 : 0.7;
this.Header.BorderThickness = isOpen ? new Thickness(1, 1, 1, 0) : new Thickness(1);
this.ActionsTreeView.Visibility = isOpen ? Visibility.Visible : Visibility.Collapsed;
// Show / hide
this.ActionsTreeView.Visibility = this.HiddenActionsExpander.Visibility =
isOpen ? Visibility.Visible : Visibility.Collapsed;
}
}
public bool IsHiddenActionsExpanded
{
get { return this.HiddenActionsExpander.IsExpanded; }
set { this.HiddenActionsExpander.IsExpanded = value; }
}
public new void Focus()
{
if (this.ActionsTreeView != null)
@ -54,5 +68,27 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -54,5 +68,27 @@ namespace ICSharpCode.SharpDevelop.Refactoring
{
this.IsOpen = !this.IsOpen;
}
void ActionsTreeView_ActionVisibleChanged(object sender, ContextActionViewModelEventArgs e)
{
var clickedAction = e.Action;
this.DataContext.Model.SetVisible(clickedAction.Action, false);
// this.DataContext.Actions.Remove(clickedAction);
// this.DataContext.HiddenActions.Add(clickedAction);
}
void HiddenActionsTreeView_ActionVisibleChanged(object sender, ContextActionViewModelEventArgs e)
{
var clickedAction = e.Action;
this.DataContext.Model.SetVisible(clickedAction.Action, true);
// this.DataContext.HiddenActions.Remove(clickedAction);
// this.DataContext.Actions.Add(clickedAction);
}
void Expander_Expanded(object sender, RoutedEventArgs e)
{
this.DataContext.LoadHiddenActions();
}
}
}

24
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbPopup.cs

@ -18,30 +18,34 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -18,30 +18,34 @@ namespace ICSharpCode.SharpDevelop.Refactoring
{
this.StaysOpen = true;
this.AllowsTransparency = true;
this.ActionsControl = new ContextActionsBulbControl();
this.ChildControl = new ContextActionsBulbControl();
// Close when any action excecuted
this.ActionsControl.ActionExecuted += delegate { this.Close(); };
this.ChildControl.ActionExecuted += delegate { this.Close(); };
}
public ContextActionsBulbControl ActionsControl
private new ContextActionsBulbControl ChildControl
{
get { return (ContextActionsBulbControl)this.Child; }
set { this.Child = value; }
}
public ContextActionsViewModel Actions
public ContextActionsHiddenViewModel ViewModel
{
get { return (ContextActionsViewModel)ActionsControl.DataContext; }
set {
ActionsControl.DataContext = value;
}
get { return (ContextActionsHiddenViewModel)this.DataContext; }
set { this.DataContext = value; }
}
public bool IsDropdownOpen { get { return ActionsControl.IsOpen; } set {ActionsControl.IsOpen = value; } }
public bool IsDropdownOpen { get { return ChildControl.IsOpen; } set {ChildControl.IsOpen = value; } }
public bool IsHiddenActionsExpanded { get { return ChildControl.IsHiddenActionsExpanded; } set {ChildControl.IsHiddenActionsExpanded = value; } }
public new void Focus()
{
this.ActionsControl.Focus();
if (this.ViewModel.Actions.Count > 0) {
this.ChildControl.ActionsTreeView.Focus();
} else {
this.ChildControl.HiddenActionsTreeView.Focus();
}
}
public void OpenAtLineStart(ITextEditor editor)

17
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsControl.xaml

@ -6,11 +6,9 @@ @@ -6,11 +6,9 @@
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:aero="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
<!--ContextActionsControl accepts IEnumerable<ContextActionViewModel> as its DataContext.-->
<!--The treeview with Context actions. Accepts IEnumerable<ContextActionViewModel> as its DataContext.-->
<UserControl.Resources>
<SolidColorBrush x:Key="OuterBorderBrush" Color="#436C82"></SolidColorBrush>
<Style x:Key="ClearButton" TargetType="Button">
<Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter> <!-- Disable the dashed focus rectangle -->
<Setter Property="Template">
@ -52,9 +50,7 @@ @@ -52,9 +50,7 @@
</Style>
</UserControl.Resources>
<Border Padding="0 0 8 8">
<aero:SystemDropShadowChrome>
<Border BorderThickness="1" BorderBrush="{StaticResource OuterBorderBrush}" HorizontalAlignment="Stretch">
<TreeView ItemsSource="{Binding}" x:Name="TreeView">
<TreeView.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
@ -102,15 +98,14 @@ @@ -102,15 +98,14 @@
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding ChildActions}">
<DockPanel HorizontalAlignment="Stretch">
<DockPanel HorizontalAlignment="Stretch" LastChildFill="True">
<Image Source="{Binding Image}" Margin="3 2 4 2" />
<CheckBox IsChecked="{Binding IsVisible}" DockPanel.Dock="Right" VerticalAlignment="Center" Click="CheckBox_Click" Checked="CheckBox_Changed" Unchecked="CheckBox_Changed" />
<TextBlock Text="{Binding Comment}" Foreground="Gray" TextAlignment="Right" DockPanel.Dock="Right"/>
<TextBlock Text="{Binding Name}" Margin="0 2 20 2" />
<TextBlock Text="{Binding Comment}" Foreground="Gray" TextAlignment="Right" HorizontalAlignment="Right"/>
</DockPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Border>
</aero:SystemDropShadowChrome>
</Border>
</UserControl>

26
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsControl.xaml.cs

@ -57,5 +57,31 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -57,5 +57,31 @@ namespace ICSharpCode.SharpDevelop.Refactoring
}
return null;
}
public event EventHandler<ContextActionViewModelEventArgs> ActionVisibleChanged;
void CheckBox_Changed(object sender, RoutedEventArgs e)
{
var contextActionVM = (ContextActionViewModel)((CheckBox)sender).DataContext;
if (ActionVisibleChanged != null)
ActionVisibleChanged(sender, new ContextActionViewModelEventArgs(contextActionVM));
}
void CheckBox_Click(object sender, RoutedEventArgs e)
{
e.Handled = true;
}
}
public class ContextActionViewModelEventArgs : EventArgs
{
public ContextActionViewModel Action { get; private set; }
public ContextActionViewModelEventArgs(ContextActionViewModel action)
{
if (action == null)
throw new ArgumentNullException("action");
this.Action = action;
}
}
}

20
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsHeaderedControl.xaml

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
<UserControl x:Class="ICSharpCode.SharpDevelop.Refactoring.ContextActionsHeaderedControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ICSharpCode.SharpDevelop.Refactoring"
xmlns:aero="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ICSharpCode.SharpDevelop.Refactoring"
xmlns:aero="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
<UserControl.Resources>
<SolidColorBrush x:Key="OuterBorderBrush" Color="#436C82"></SolidColorBrush>
@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
</Grid.ColumnDefinitions>
<!-- Header -->
<Border x:Name="Header" Grid.Row="0" Grid.Column="0" Padding="4" BorderThickness="1 1 1 0"
<Border x:Name="Header" Grid.Row="0" Grid.Column="0" Padding="4" BorderThickness="1 1 1 0"
BorderBrush="{StaticResource OuterBorderBrush}" HorizontalAlignment="Left">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
@ -32,7 +32,13 @@ @@ -32,7 +32,13 @@
</StackPanel>
</Border>
<!-- Content - TreeView -->
<local:ContextActionsControl x:Name="ActionsTreeView" Grid.Row="1" Grid.Column="0" DataContext="{Binding Actions}"></local:ContextActionsControl>
<Border Padding="0 0 8 8" Grid.Row="1" Grid.Column="0">
<aero:SystemDropShadowChrome>
<Border BorderThickness="1" BorderBrush="{StaticResource OuterBorderBrush}" HorizontalAlignment="Stretch">
<!-- Content - TreeView -->
<local:ContextActionsControl x:Name="ActionsTreeView" DataContext="{Binding Actions}"></local:ContextActionsControl>
</Border>
</aero:SystemDropShadowChrome>
</Border>
</Grid>
</UserControl>

42
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsHiddenViewModel.cs

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Martin Konicek" email="martin.konicek@gmail.com"/>
// <version>$Revision: $</version>
// </file>
using System;
using System.Collections.ObjectModel;
using System.Linq;
namespace ICSharpCode.SharpDevelop.Refactoring
{
/// <summary>
/// Description of ContextActionsHiddenViewModel.
/// </summary>
public class ContextActionsHiddenViewModel : ContextActionsViewModel
{
public EditorActionsProvider Model { get; private set; }
public ObservableCollection<ContextActionViewModel> HiddenActions { get; set; }
public ContextActionsHiddenViewModel(EditorActionsProvider model)
{
this.Model = model;
this.Actions = new ObservableCollection<ContextActionViewModel>(
model.GetVisibleActions().Select(a => new ContextActionViewModel(a) { IsVisible = true } ));
this.HiddenActions = new ObservableCollection<ContextActionViewModel>();
}
bool hiddenActionsLoaded = false;
public void LoadHiddenActions()
{
if (hiddenActionsLoaded)
return;
this.HiddenActions.AddRange(
Model.GetHiddenActions().Select(a => new ContextActionViewModel(a) { IsVisible = false } ));
hiddenActionsLoaded = true;
}
}
}

22
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsProvider.cs

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Martin Konicek" email="martin.konicek@gmail.com"/>
// <version>$Revision: $</version>
// </file>
using System;
using System.Collections.Generic;
using ICSharpCode.SharpDevelop.Refactoring;
namespace ICSharpCode.SharpDevelop.Refactoring
{
/// <summary>
/// Description of ContextActionsProvider.
/// </summary>
public abstract class ContextActionsProvider : IContextActionsProvider
{
public bool IsVisible { get; set; }
public abstract IEnumerable<IContextAction> GetAvailableActions(EditorContext context);
}
}

61
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs

@ -32,32 +32,81 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -32,32 +32,81 @@ namespace ICSharpCode.SharpDevelop.Refactoring
private ContextActionsService()
{
this.providers = AddInTree.BuildItems<IContextActionsProvider>("/SharpDevelop/ViewContent/AvalonEdit/ContextActions", null, false);
foreach (var provider in providers) {
// load from configuration
provider.IsVisible = true;
}
}
public EditorActionsProvider GetAvailableActions(ITextEditor editor)
{
return new EditorActionsProvider(editor, this.providers);
}
}
public class EditorActionsProvider
{
ITextEditor editor { get; set; }
IList<IContextActionsProvider> providers { get; set; }
EditorContext context { get; set; }
public EditorActionsProvider(ITextEditor editor, IList<IContextActionsProvider> providers)
{
if (editor == null)
throw new ArgumentNullException("editor");
if (providers == null)
throw new ArgumentNullException("providers");
this.editor = editor;
this.providers = providers;
ParserService.ParseCurrentViewContent();
this.context = new EditorContext(editor);
}
public IEnumerable<IContextAction> GetVisibleActions()
{
return GetActions(this.providers.Where(p => p.IsVisible));
}
public IEnumerable<IContextAction> GetHiddenActions()
{
return GetActions(this.providers.Where(p => !p.IsVisible));
}
public void SetVisible(IContextAction action, bool isVisible)
{
IContextActionsProvider provider;
if (providerForAction.TryGetValue(action, out provider)) {
provider.IsVisible = isVisible;
}
}
Dictionary<IContextAction, IContextActionsProvider> providerForAction = new Dictionary<IContextAction, IContextActionsProvider>();
/// <summary>
/// Gets actions available for current caret position in the editor.
/// </summary>
public IEnumerable<IContextAction> GetAvailableActions(ITextEditor editor)
IEnumerable<IContextAction> GetActions(IEnumerable<IContextActionsProvider> providers)
{
if (ParserService.LoadSolutionProjectsThreadRunning)
yield break;
ParserService.ParseCurrentViewContent();
// DO NOT USE Wait on the main thread!
// causes deadlocks!
//parseTask.Wait();
var sw = new Stopwatch(); sw.Start();
var editorContext = new EditorContext(editor);
var editorContext = new EditorContext(this.editor);
long elapsedEditorContextMs = sw.ElapsedMilliseconds;
// could run providers in parallel
foreach (var provider in this.providers) {
foreach (var provider in providers) {
foreach (var action in provider.GetAvailableActions(editorContext)) {
providerForAction[action] = provider;
yield return action;
}
}
ICSharpCode.Core.LoggingService.Debug(string.Format("Context actions elapsed {0}ms ({1}ms in EditorContext)",
sw.ElapsedMilliseconds, elapsedEditorContextMs));
// ICSharpCode.Core.LoggingService.Debug(string.Format("Context actions elapsed {0}ms ({1}ms in EditorContext)",
// sw.ElapsedMilliseconds, elapsedEditorContextMs));
}
}
}

2
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsViewModel.cs

@ -20,6 +20,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -20,6 +20,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring
public string Title { get; set; }
public ObservableCollection<ContextActionViewModel> Actions { get; set; }
public ObservableCollection<ContextActionViewModel> Actions { get; set; }
}
}

1
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/IContextAction.cs

@ -15,7 +15,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -15,7 +15,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring
public interface IContextAction
{
string Title { get; }
//string Id { get; }
void Execute();
}
}

5
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/IContextActionsProvider.cs

@ -20,5 +20,10 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -20,5 +20,10 @@ namespace ICSharpCode.SharpDevelop.Refactoring
/// Gets actions available for current line of the editor.
/// </summary>
IEnumerable<IContextAction> GetAvailableActions(EditorContext context);
/// <summary>
/// Is this provider enabled by user?
/// </summary>
bool IsVisible { get; set; }
}
}

Loading…
Cancel
Save