From 8527075b41b7596ff32ddde182adb56a3cc4df81 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 15 Feb 2012 21:52:45 +0100 Subject: [PATCH] initial implementation of the ProjectBehavior-API --- .../Project/ICSharpCode.SharpDevelop.addin | 9 +- .../Project/ICSharpCode.SharpDevelop.csproj | 4 + .../Project/Src/Project/AbstractProject.cs | 38 ++--- .../Src/Project/Behaviors/ProjectBehavior.cs | 144 ++++++++++++++++++ .../Behaviors/ProjectBehaviorService.cs | 32 ++++ ...jectBehaviorSupportedConditionEvaluator.cs | 47 ++++++ 6 files changed, 255 insertions(+), 19 deletions(-) create mode 100644 src/Main/Base/Project/Src/Project/Behaviors/ProjectBehavior.cs create mode 100644 src/Main/Base/Project/Src/Project/Behaviors/ProjectBehaviorService.cs create mode 100644 src/Main/Base/Project/Src/Project/Behaviors/ProjectBehaviorSupportedConditionEvaluator.cs diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin index bbd1bd8c3a..8b67c9d3b0 100755 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin @@ -32,6 +32,7 @@ + @@ -473,14 +474,14 @@ - + - + + + + + diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index bcedbeeb4f..4209301749 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -340,6 +340,9 @@ + + + @@ -913,6 +916,7 @@ False + diff --git a/src/Main/Base/Project/Src/Project/AbstractProject.cs b/src/Main/Base/Project/Src/Project/AbstractProject.cs index 66b0cfbd30..87ac8655c7 100644 --- a/src/Main/Base/Project/Src/Project/AbstractProject.cs +++ b/src/Main/Base/Project/Src/Project/AbstractProject.cs @@ -305,7 +305,7 @@ namespace ICSharpCode.SharpDevelop.Project [Browsable(false)] public virtual ICollection AvailableFileItemTypes { get { - return ItemType.DefaultFileItems; + return GetOrCreateBehavior().AvailableFileItemTypes; } } @@ -386,7 +386,7 @@ namespace ICSharpCode.SharpDevelop.Project [Browsable(false)] public virtual bool IsStartable { get { - return false; + return GetOrCreateBehavior().IsStartable; } } @@ -399,18 +399,7 @@ namespace ICSharpCode.SharpDevelop.Project public virtual void Start(bool withDebugging) { - ProcessStartInfo psi; - try { - psi = CreateStartInfo(); - } catch (ProjectStartException ex) { - MessageService.ShowError(ex.Message); - return; - } - if (withDebugging) { - DebuggerService.CurrentDebugger.Start(psi); - } else { - DebuggerService.CurrentDebugger.StartWithoutDebugging(psi); - } + GetOrCreateBehavior().Start(withDebugging); } /// @@ -421,7 +410,7 @@ namespace ICSharpCode.SharpDevelop.Project /// Note: this can be a ProcessStartInfo with a URL as filename! public virtual ProcessStartInfo CreateStartInfo() { - throw new NotSupportedException(); + return GetOrCreateBehavior().CreateStartInfo(); } /// @@ -481,7 +470,7 @@ namespace ICSharpCode.SharpDevelop.Project /// public virtual ProjectItem CreateProjectItem(IProjectItemBackendStore item) { - return new UnknownProjectItem(this, item); + return GetOrCreateBehavior().CreateProjectItem(item); } #region Dirty @@ -513,7 +502,7 @@ namespace ICSharpCode.SharpDevelop.Project /// public virtual ItemType GetDefaultItemType(string fileName) { - return ItemType.None; + return GetOrCreateBehavior().GetDefaultItemType(fileName); } [Browsable(false)] @@ -611,6 +600,7 @@ namespace ICSharpCode.SharpDevelop.Project public virtual void ProjectCreationComplete() { + GetOrCreateBehavior().ProjectCreationComplete(); } public virtual XElement LoadProjectExtensions(string name) @@ -626,5 +616,19 @@ namespace ICSharpCode.SharpDevelop.Project public Properties ProjectSpecificProperties { get; protected set; } + + protected virtual ProjectBehavior CreateDefaultBehavior() + { + return new DefaultProjectBehavior(this); + } + + protected ProjectBehavior projectBehavior; + + protected virtual ProjectBehavior GetOrCreateBehavior() + { + if (projectBehavior == null) + projectBehavior = ProjectBehaviorService.LoadBehaviorsForProject(this, CreateDefaultBehavior()); + return projectBehavior; + } } } diff --git a/src/Main/Base/Project/Src/Project/Behaviors/ProjectBehavior.cs b/src/Main/Base/Project/Src/Project/Behaviors/ProjectBehavior.cs new file mode 100644 index 0000000000..ec23507b81 --- /dev/null +++ b/src/Main/Base/Project/Src/Project/Behaviors/ProjectBehavior.cs @@ -0,0 +1,144 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop.Debugging; + +namespace ICSharpCode.SharpDevelop.Project +{ + public abstract class ProjectBehavior + { + ProjectBehavior next; + protected IProject Project { get; private set; } + + public ProjectBehavior(IProject project, ProjectBehavior next = null) + { + if (project == null) + throw new ArgumentNullException("project"); + this.Project = project; + this.next = next; + } + + internal void SetProject(IProject project) + { + if (project == null) + throw new ArgumentNullException("project"); + this.Project = project; + } + + internal void SetNext(ProjectBehavior next) + { + if (next == null) + throw new ArgumentNullException("next"); + this.next = next; + } + + public virtual bool IsStartable { + get { + if (this.next != null) + return next.IsStartable; + return false; + } + } + + public virtual void Start(bool withDebugging) + { + if (this.next != null) + next.Start(withDebugging); + } + + public virtual ProcessStartInfo CreateStartInfo() + { + if (this.next != null) + return next.CreateStartInfo(); + return null; + } + + public virtual ItemType GetDefaultItemType(string fileName) + { + if (this.next != null) + return next.GetDefaultItemType(fileName); + return default(ItemType); + } + + public virtual ProjectItem CreateProjectItem(IProjectItemBackendStore item) + { + if (this.next != null) + return next.CreateProjectItem(item); + return null; + } + + public virtual ICollection AvailableFileItemTypes { + get { + if (this.next != null) + return next.AvailableFileItemTypes; + return null; + } + } + + public virtual void ProjectCreationComplete() + { + if (this.next != null) + next.ProjectCreationComplete(); + } + } + + sealed class DefaultProjectBehavior : ProjectBehavior + { + public DefaultProjectBehavior(IProject project) + : base(project) + { + } + + public override bool IsStartable { + get { return false; } + } + + public override void Start(bool withDebugging) + { + ProcessStartInfo psi; + try { + if (!(Project is AbstractProject)) + return; + psi = ((AbstractProject)Project).CreateStartInfo(); + } catch (ProjectStartException ex) { + MessageService.ShowError(ex.Message); + return; + } + if (withDebugging) { + DebuggerService.CurrentDebugger.Start(psi); + } else { + DebuggerService.CurrentDebugger.StartWithoutDebugging(psi); + } + } + + public override ProcessStartInfo CreateStartInfo() + { + throw new NotSupportedException(); + } + + public override ItemType GetDefaultItemType(string fileName) + { + return ItemType.None; + } + + public override ProjectItem CreateProjectItem(IProjectItemBackendStore item) + { + return new UnknownProjectItem(Project, item); + } + + public override ICollection AvailableFileItemTypes { + get { return ItemType.DefaultFileItems; } + } + + public override void ProjectCreationComplete() + { + + } + } +} diff --git a/src/Main/Base/Project/Src/Project/Behaviors/ProjectBehaviorService.cs b/src/Main/Base/Project/Src/Project/Behaviors/ProjectBehaviorService.cs new file mode 100644 index 0000000000..37c4f48b89 --- /dev/null +++ b/src/Main/Base/Project/Src/Project/Behaviors/ProjectBehaviorService.cs @@ -0,0 +1,32 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using ICSharpCode.Core; + +namespace ICSharpCode.SharpDevelop.Project +{ + public static class ProjectBehaviorService + { + const string AddInPath = "/SharpDevelop/Workbench/ProjectBehaviors"; + + public static ProjectBehavior LoadBehaviorsForProject(IProject project, ProjectBehavior defaultBehavior) + { + List behaviors = AddInTree.BuildItems(AddInPath, project, false); + ProjectBehavior first = null, current = null; + foreach (var behavior in behaviors) { + behavior.SetProject(project); + if (first == null) + first = behavior; + else + current.SetNext(behavior); + current = behavior; + } + if (current == null) + return defaultBehavior; + current.SetNext(defaultBehavior); + return first; + } + } +} diff --git a/src/Main/Base/Project/Src/Project/Behaviors/ProjectBehaviorSupportedConditionEvaluator.cs b/src/Main/Base/Project/Src/Project/Behaviors/ProjectBehaviorSupportedConditionEvaluator.cs new file mode 100644 index 0000000000..722ada79b3 --- /dev/null +++ b/src/Main/Base/Project/Src/Project/Behaviors/ProjectBehaviorSupportedConditionEvaluator.cs @@ -0,0 +1,47 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Linq; +using ICSharpCode.Core; + +namespace ICSharpCode.SharpDevelop.Project +{ + public class ProjectBehaviorSupportedConditionEvaluator : IConditionEvaluator + { + public bool IsValid(object owner, Condition condition) + { + Guid conditionGuid; + if (!Guid.TryParse(condition.Properties["guid"], out conditionGuid)) + return true; + + string guidString; + if (owner is IProject) + guidString = FindGuidInProject((IProject)owner); + else if (ProjectService.CurrentProject != null) + guidString = FindGuidInProject(ProjectService.CurrentProject); + else + return false; + + Guid result; + foreach (string guid in guidString.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { + if (Guid.TryParse(guid, out result) && conditionGuid == result) + return true; + } + + return false; + } + + string FindGuidInProject(IProject project) + { + if (project is MSBuildBasedProject) { + string guid = ((MSBuildBasedProject)project).GetEvaluatedProperty("ProjectTypeGuids"); + if (!string.IsNullOrEmpty(guid)) + return guid; + } + + return project.TypeGuid; + } + } +}