diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
index 80ef5694e7..4dd62c3ba6 100644
--- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
+++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
@@ -795,6 +795,7 @@
ICSharpCode.SharpDevelop.Widgets
True
+
\ No newline at end of file
diff --git a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
index 49c6ab0620..b5443f0a1e 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
@@ -18,7 +18,7 @@ namespace ICSharpCode.SharpDevelop.Gui
///
/// Workbench implementation using WPF and AvalonDock.
///
- sealed class WpfWorkbench : Window, IWorkbench
+ sealed partial class WpfWorkbench : Window, IWorkbench
{
const string mainMenuPath = "/SharpDevelop/Workbench/MainMenu";
const string viewContentPath = "/SharpDevelop/Workbench/Pads";
@@ -34,29 +34,29 @@ namespace ICSharpCode.SharpDevelop.Gui
public ISynchronizeInvoke SynchronizingObject { get; set; }
public Window MainWindow { get { return this; } }
- DockPanel dockPanel;
- Menu mainMenu;
- ContentControl mainContent;
+ ToolBar[] toolBars;
public WpfWorkbench()
{
- this.Title = "SharpDevelop (experimental WPF build)";
this.SynchronizingObject = new WpfSynchronizeInvoke(this.Dispatcher);
this.MainWin32Window = this.GetWin32Window();
- this.WindowStartupLocation = WindowStartupLocation.Manual;
+ InitializeComponent();
}
public void Initialize()
{
- this.Content = dockPanel = new DockPanel();
- mainMenu = new Menu() {
- ItemsSource = MenuService.CreateMenuItems(this, mainMenuPath)
- };
- DockPanel.SetDock(mainMenu, Dock.Top);
- dockPanel.Children.Add(mainMenu);
+ mainMenu.ItemsSource = MenuService.CreateMenuItems(this, mainMenuPath);
- mainContent = new ContentControl();
- dockPanel.Children.Add(mainContent);
+ toolBars = ToolBarService.CreateToolBars(this, "/SharpDevelop/Workbench/ToolBar");
+ foreach (ToolBar tb in toolBars) {
+ DockPanel.SetDock(tb, Dock.Top);
+ dockPanel.Children.Insert(1, tb);
+ }
+
+ MenuService.UpdateStatus(mainMenu.ItemsSource);
+ foreach (ToolBar tb in toolBars) {
+ ToolBarService.UpdateStatus(tb.ItemsSource);
+ }
}
public ICollection ViewContentCollection {
diff --git a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.xaml b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.xaml
new file mode 100644
index 0000000000..b894428800
--- /dev/null
+++ b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.xaml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Main/ICSharpCode.Core.Presentation/ConditionalSeparator.cs b/src/Main/ICSharpCode.Core.Presentation/ConditionalSeparator.cs
new file mode 100644
index 0000000000..9bf65f80e8
--- /dev/null
+++ b/src/Main/ICSharpCode.Core.Presentation/ConditionalSeparator.cs
@@ -0,0 +1,44 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace ICSharpCode.Core.Presentation
+{
+ ///
+ /// A Separator that is invisible when it is excluded by a condition.
+ ///
+ sealed class ConditionalSeparator : Separator, IStatusUpdate
+ {
+ readonly Codon codon;
+ readonly object caller;
+
+ public ConditionalSeparator(Codon codon, object caller, bool inToolbar)
+ {
+ this.codon = codon;
+ this.caller = caller;
+
+ if (inToolbar) {
+ SetResourceReference(FrameworkElement.StyleProperty, ToolBar.SeparatorStyleKey);
+ }
+ }
+
+ public void UpdateText()
+ {
+ }
+
+ public void UpdateStatus()
+ {
+ if (codon.GetFailedAction(caller) == ConditionFailedAction.Exclude)
+ this.Visibility = Visibility.Collapsed;
+ else
+ this.Visibility = Visibility.Visible;
+ }
+ }
+}
diff --git a/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj b/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj
index 43d9280f4f..1e24f64a6d 100644
--- a/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj
+++ b/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj
@@ -59,11 +59,16 @@
Properties\GlobalAssemblyInfo.cs
+
+
+
+
+
@@ -72,5 +77,6 @@
False
+
\ No newline at end of file
diff --git a/src/Main/ICSharpCode.Core.Presentation/IStatusUpdate.cs b/src/Main/ICSharpCode.Core.Presentation/IStatusUpdate.cs
new file mode 100644
index 0000000000..41049c3470
--- /dev/null
+++ b/src/Main/ICSharpCode.Core.Presentation/IStatusUpdate.cs
@@ -0,0 +1,17 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+namespace ICSharpCode.Core.Presentation
+{
+ public interface IStatusUpdate
+ {
+ void UpdateText();
+ void UpdateStatus();
+ }
+}
diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/CoreMenuItem.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/CoreMenuItem.cs
index c33e3c8ce9..2d226e42d1 100644
--- a/src/Main/ICSharpCode.Core.Presentation/Menu/CoreMenuItem.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/Menu/CoreMenuItem.cs
@@ -7,6 +7,7 @@
using System;
using System.Collections;
+using System.Windows;
using System.Windows.Controls;
namespace ICSharpCode.Core.Presentation
@@ -14,7 +15,7 @@ namespace ICSharpCode.Core.Presentation
///
/// A menu item representing an AddIn-Tree element.
///
- class CoreMenuItem : MenuItem
+ class CoreMenuItem : MenuItem, IStatusUpdate
{
protected readonly Codon codon;
protected readonly object caller;
@@ -27,9 +28,14 @@ namespace ICSharpCode.Core.Presentation
if (codon.Properties.Contains("shortcut")) {
InputGestureText = codon.Properties["shortcut"];
}
-
+ this.SubmenuOpened += CoreMenuItem_SubmenuOpened;
UpdateText();
}
+
+ void CoreMenuItem_SubmenuOpened(object sender, RoutedEventArgs e)
+ {
+ MenuService.UpdateStatus(this.ItemsSource);
+ }
public void UpdateText()
{
@@ -37,46 +43,25 @@ namespace ICSharpCode.Core.Presentation
Header = MenuService.ConvertLabel(StringParser.Parse(codon.Properties["label"]));
}
}
- }
-
- class MenuCommand : CoreMenuItem
- {
- ICommand menuCommand;
-
- public MenuCommand(Codon codon, object caller, bool createCommand) : base(codon, caller)
- {
- if (createCommand) {
- CreateCommand();
- }
- }
- void CreateCommand()
+ public virtual void UpdateStatus()
{
- try {
- string link = codon.Properties["link"];
- if (link != null && link.Length > 0) {
- if (MenuService.LinkCommandCreator == null)
- throw new NotSupportedException("MenuCommand.LinkCommandCreator is not set, cannot create LinkCommands.");
- menuCommand = MenuService.LinkCommandCreator(codon.Properties["link"]);
- } else {
- menuCommand = (ICommand)codon.AddIn.CreateObject(codon.Properties["class"]);
- }
- if (menuCommand != null) {
- menuCommand.Owner = caller;
- }
- } catch (Exception e) {
- MessageService.ShowError(e, "Can't create menu command : " + codon.Id);
+ this.IsEnabled = this.IsEnabledCore;
+ if (this.IsEnabled) {
+ this.Visibility = Visibility.Visible;
+ } else {
+ if (codon.GetFailedAction(caller) == ConditionFailedAction.Exclude)
+ this.Visibility = Visibility.Collapsed;
+ else
+ this.Visibility = Visibility.Visible;
}
}
- protected override void OnClick()
- {
- base.OnClick();
- if (menuCommand == null) {
- CreateCommand();
- }
- if (menuCommand != null) {
- menuCommand.Run();
+ protected override bool IsEnabledCore {
+ get {
+ ConditionFailedAction failedAction = codon.GetFailedAction(caller);
+ bool isEnabled = failedAction == ConditionFailedAction.Nothing;
+ return isEnabled;
}
}
}
diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
new file mode 100644
index 0000000000..f6ad1443e8
--- /dev/null
+++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
@@ -0,0 +1,69 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace ICSharpCode.Core.Presentation
+{
+ class MenuCommand : CoreMenuItem
+ {
+ ICommand menuCommand;
+
+ public MenuCommand(Codon codon, object caller, bool createCommand) : base(codon, caller)
+ {
+ if (createCommand) {
+ CreateCommand();
+ }
+ }
+
+ protected override bool IsEnabledCore {
+ get {
+ if (!base.IsEnabledCore)
+ return false;
+
+ if (menuCommand != null && menuCommand is IMenuCommand) {
+ return ((IMenuCommand)menuCommand).IsEnabled;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ void CreateCommand()
+ {
+ try {
+ string link = codon.Properties["link"];
+ if (link != null && link.Length > 0) {
+ if (MenuService.LinkCommandCreator == null)
+ throw new NotSupportedException("MenuCommand.LinkCommandCreator is not set, cannot create LinkCommands.");
+ menuCommand = MenuService.LinkCommandCreator(codon.Properties["link"]);
+ } else {
+ menuCommand = (ICommand)codon.AddIn.CreateObject(codon.Properties["class"]);
+ }
+ if (menuCommand != null) {
+ menuCommand.Owner = caller;
+ }
+ } catch (Exception e) {
+ MessageService.ShowError(e, "Can't create menu command : " + codon.Id);
+ }
+ }
+
+ protected override void OnClick()
+ {
+ base.OnClick();
+ if (menuCommand == null) {
+ CreateCommand();
+ }
+ if (menuCommand != null && IsEnabledCore) {
+ menuCommand.Run();
+ }
+ }
+ }
+}
diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs
index a175aae105..2c7ce9434a 100644
--- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs
@@ -17,12 +17,23 @@ namespace ICSharpCode.Core.Presentation
///
public static class MenuService
{
+ public static void UpdateStatus(IEnumerable menuItems)
+ {
+ if (menuItems == null)
+ return;
+ foreach (object o in menuItems) {
+ IStatusUpdate cmi = o as IStatusUpdate;
+ if (cmi != null)
+ cmi.UpdateStatus();
+ }
+ }
+
public static IList CreateMenuItems(object owner, string addInTreePath)
{
return CreateMenuItems(AddInTree.BuildItems(addInTreePath, owner, false));
}
- static IList CreateMenuItems(IEnumerable descriptors)
+ internal static IList CreateMenuItems(IEnumerable descriptors)
{
ArrayList result = new ArrayList();
foreach (MenuItemDescriptor descriptor in descriptors) {
@@ -45,8 +56,7 @@ namespace ICSharpCode.Core.Presentation
switch (type) {
case "Separator":
- return new Separator();
- //return new MenuSeparator(codon, descriptor.Caller);
+ return new ConditionalSeparator(codon, descriptor.Caller, false);
case "CheckBox":
return "CheckBox";
//return new MenuCheckBox(codon, descriptor.Caller);
diff --git a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs
new file mode 100644
index 0000000000..5c48bd415a
--- /dev/null
+++ b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs
@@ -0,0 +1,100 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace ICSharpCode.Core.Presentation
+{
+ ///
+ ///
+ ///
+ sealed class ToolBarButton : Button, IStatusUpdate
+ {
+ readonly Codon codon;
+ readonly object caller;
+ ICommand menuCommand;
+
+ public ToolBarButton(Codon codon, object caller, bool createCommand)
+ {
+ ToolTipService.SetShowOnDisabled(this, true);
+
+ this.codon = codon;
+ this.caller = caller;
+
+ if (createCommand) {
+ CreateCommand();
+ }
+
+ if (codon.Properties.Contains("icon")) {
+ Image image = new Image {
+ Source = PresentationResourceService.GetBitmapSource(StringParser.Parse(codon.Properties["icon"])),
+ Height = 16
+ };
+ image.SetResourceReference(StyleProperty, ToolBarService.ImageStyleKey);
+ this.Content = image;
+ }
+ UpdateText();
+
+ SetResourceReference(FrameworkElement.StyleProperty, ToolBar.ButtonStyleKey);
+ }
+
+ protected override void OnClick()
+ {
+ base.OnClick();
+ if (menuCommand == null) {
+ CreateCommand();
+ }
+ if (menuCommand != null) {
+ menuCommand.Run();
+ }
+ }
+
+ void CreateCommand()
+ {
+ menuCommand = (ICommand)codon.AddIn.CreateObject(codon.Properties["class"]);
+ if (menuCommand != null) {
+ menuCommand.Owner = caller;
+ }
+ }
+
+ public void UpdateText()
+ {
+ if (codon.Properties.Contains("label")){
+ this.Content = StringParser.Parse(codon.Properties["label"]);
+ }
+ if (codon.Properties.Contains("tooltip")) {
+ this.ToolTip = StringParser.Parse(codon.Properties["tooltip"]);
+ }
+ }
+
+ public void UpdateStatus()
+ {
+ this.IsEnabled = this.IsEnabledCore;
+ if (this.IsEnabled) {
+ this.Visibility = Visibility.Visible;
+ } else {
+ if (codon.GetFailedAction(caller) == ConditionFailedAction.Exclude)
+ this.Visibility = Visibility.Collapsed;
+ else
+ this.Visibility = Visibility.Visible;
+ }
+ }
+
+ protected override bool IsEnabledCore {
+ get {
+ ConditionFailedAction failedAction = codon.GetFailedAction(caller);
+ bool isEnabled = failedAction == ConditionFailedAction.Nothing;
+ if (isEnabled && menuCommand != null && menuCommand is IMenuCommand) {
+ isEnabled = ((IMenuCommand)menuCommand).IsEnabled;
+ }
+ return isEnabled;
+ }
+ }
+ }
+}
diff --git a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs
new file mode 100644
index 0000000000..82b4c5231b
--- /dev/null
+++ b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs
@@ -0,0 +1,117 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Windows.Controls;
+
+namespace ICSharpCode.Core.Presentation
+{
+ ///
+ /// Creates WPF toolbars from the AddIn Tree.
+ ///
+ public static class ToolBarService
+ {
+ ///
+ /// Style key used for toolbar images.
+ ///
+ public static readonly object ImageStyleKey = new object();
+
+ public static void UpdateStatus(IEnumerable toolBarItems)
+ {
+ MenuService.UpdateStatus(toolBarItems);
+ }
+
+ public static IList CreateToolBarItems(object owner, string addInTreePath)
+ {
+ return CreateToolBarItems(AddInTree.BuildItems(addInTreePath, owner, false));
+ }
+
+ static IList CreateToolBarItems(IEnumerable descriptors)
+ {
+ ArrayList result = new ArrayList();
+ foreach (ToolbarItemDescriptor descriptor in descriptors) {
+ object item = CreateToolBarItemFromDescriptor(descriptor);
+ if (item is IMenuItemBuilder) {
+ IMenuItemBuilder submenuBuilder = (IMenuItemBuilder)item;
+ result.AddRange(submenuBuilder.BuildItems(descriptor.Codon, descriptor.Caller));
+ } else {
+ result.Add(item);
+ }
+ }
+ return result;
+ }
+
+ static object CreateToolBarItemFromDescriptor(ToolbarItemDescriptor descriptor)
+ {
+ Codon codon = descriptor.Codon;
+ object caller = descriptor.Caller;
+ string type = codon.Properties.Contains("type") ? codon.Properties["type"] : "Item";
+
+ bool createCommand = codon.Properties["loadclasslazy"] == "false";
+
+ switch (type) {
+ case "Separator":
+ return new ConditionalSeparator(codon, caller, true);
+ case "CheckBox":
+ return "CheckBox";
+ //return new ToolBarCheckBox(codon, caller);
+ case "Item":
+ return new ToolBarButton(codon, caller, createCommand);
+ case "ComboBox":
+ return "ComboBox";
+ //return new ToolBarComboBox(codon, caller);
+ case "TextBox":
+ return "TextBox";
+ //return new ToolBarTextBox(codon, caller);
+ case "Label":
+ return "Label";
+ //return new ToolBarLabel(codon, caller);
+ case "DropDownButton":
+ return "DropDownButton";
+ //return new ToolBarDropDownButton(codon, caller, MenuService.CreateMenuItems(descriptor.SubItems));
+ case "SplitButton":
+ return "SplitButton";
+ //return new ToolBarSplitButton(codon, caller, MenuService.CreateMenuItems(descriptor.SubItems));
+ case "Builder":
+ return codon.AddIn.CreateObject(codon.Properties["class"]);
+ default:
+ throw new System.NotSupportedException("unsupported menu item type : " + type);
+ }
+ }
+
+ static ToolBar CreateToolBar(object owner, AddInTreeNode treeNode)
+ {
+ ToolBar tb = new ToolBar();
+ tb.ItemsSource = CreateToolBarItems(treeNode.BuildChildItems(owner));
+ UpdateStatus(tb.ItemsSource); // setting Visible is only possible after the items have been added
+ //new LanguageChangeWatcher(toolStrip);
+ return tb;
+ }
+
+ public static ToolBar CreateToolBar(object owner, string addInTreePath)
+ {
+ return CreateToolBar(owner, AddInTree.GetTreeNode(addInTreePath));
+ }
+
+ public static ToolBar[] CreateToolBars(object owner, string addInTreePath)
+ {
+ AddInTreeNode treeNode;
+ try {
+ treeNode = AddInTree.GetTreeNode(addInTreePath);
+ } catch (TreePathNotFoundException) {
+ return null;
+ }
+ List toolBars = new List();
+ foreach (AddInTreeNode childNode in treeNode.ChildNodes.Values) {
+ toolBars.Add(CreateToolBar(owner, childNode));
+ }
+ return toolBars.ToArray();
+ }
+ }
+}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Sda/ICSharpCode.SharpDevelop.Sda.csproj b/src/Main/ICSharpCode.SharpDevelop.Sda/ICSharpCode.SharpDevelop.Sda.csproj
index 4b6d7a2712..688989b111 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Sda/ICSharpCode.SharpDevelop.Sda.csproj
+++ b/src/Main/ICSharpCode.SharpDevelop.Sda/ICSharpCode.SharpDevelop.Sda.csproj
@@ -97,6 +97,11 @@
Always
+
+ {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}
+ ICSharpCode.Core.Presentation
+ False
+
{857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}
ICSharpCode.Core.WinForms
diff --git a/src/Main/ICSharpCode.SharpDevelop.Sda/Src/CallHelper.cs b/src/Main/ICSharpCode.SharpDevelop.Sda/Src/CallHelper.cs
index 154c6f18ef..9e7dbc94e8 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Sda/Src/CallHelper.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Sda/Src/CallHelper.cs
@@ -67,6 +67,7 @@ namespace ICSharpCode.SharpDevelop.Sda
ResourceService.RegisterNeutralImages(new ResourceManager("Resources.BitmapResources", exe));
MenuCommand.LinkCommandCreator = delegate(string link) { return new LinkCommand(link); };
+ Core.Presentation.MenuService.LinkCommandCreator = MenuCommand.LinkCommandCreator;
StringParser.RegisterStringTagProvider(new SharpDevelopStringTagProvider());
LoggingService.Info("Looking for AddIns...");