You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
486 lines
15 KiB
486 lines
15 KiB
// <file> |
|
// <copyright see="prj:///doc/copyright.txt"/> |
|
// <license see="prj:///doc/license.txt"/> |
|
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/> |
|
// <version>$Revision$</version> |
|
// </file> |
|
|
|
using System; |
|
using System.IO; |
|
using ICSharpCode.Core; |
|
using ICSharpCode.SharpDevelop.Gui; |
|
|
|
namespace ICSharpCode.SharpDevelop.Project |
|
{ |
|
public static class ProjectService |
|
{ |
|
static Solution openSolution; |
|
static IProject currentProject; |
|
|
|
public static Solution OpenSolution { |
|
[System.Diagnostics.DebuggerStepThrough] |
|
get { |
|
return openSolution; |
|
} |
|
} |
|
|
|
public static IProject CurrentProject { |
|
[System.Diagnostics.DebuggerStepThrough] |
|
get { |
|
return currentProject; |
|
} |
|
set { |
|
if (currentProject != value) { |
|
LoggingService.Info("CurrentProject changed to " + (value == null ? "null" : value.Name)); |
|
currentProject = value; |
|
OnCurrentProjectChanged(new ProjectEventArgs(currentProject)); |
|
} |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Gets an open project by the name of the project file. |
|
/// </summary> |
|
public static IProject GetProject(string projectFilename) |
|
{ |
|
if (openSolution == null) return null; |
|
foreach (IProject project in openSolution.Projects) { |
|
if (FileUtility.IsEqualFileName(project.FileName, projectFilename)) { |
|
return project; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
static bool initialized; |
|
|
|
public static void InitializeService() |
|
{ |
|
if (initialized) |
|
throw new InvalidOperationException("ProjectService already is initialized"); |
|
initialized = true; |
|
WorkbenchSingleton.Workbench.ActiveWorkbenchWindowChanged += ActiveWindowChanged; |
|
FileService.FileRenamed += FileServiceFileRenamed; |
|
FileService.FileRemoved += FileServiceFileRemoved; |
|
} |
|
|
|
public static IProjectLoader GetProjectLoader(string fileName) |
|
{ |
|
AddInTreeNode addinTreeNode = AddInTree.GetTreeNode("/SharpDevelop/Workbench/Combine/FileFilter"); |
|
foreach (Codon codon in addinTreeNode.Codons) { |
|
string pattern = codon.Properties.Get("extensions", ""); |
|
if (FileUtility.MatchesPattern(fileName, pattern) && codon.Properties.Contains("class")) { |
|
object binding = codon.AddIn.CreateObject(codon.Properties["class"]); |
|
return binding as IProjectLoader; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
public static void LoadSolutionOrProject(string fileName) |
|
{ |
|
IProjectLoader loader = GetProjectLoader(fileName); |
|
if (loader != null) { |
|
loader.Load(fileName); |
|
} else { |
|
MessageService.ShowError(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.InvalidProjectOrCombine}", new string[,] {{"FileName", fileName}})); |
|
} |
|
} |
|
|
|
static void FileServiceFileRenamed(object sender, FileRenameEventArgs e) |
|
{ |
|
if (OpenSolution == null) { |
|
return; |
|
} |
|
string oldName = e.SourceFile; |
|
string newName = e.TargetFile; |
|
long x = 0; |
|
foreach (ISolutionFolderContainer container in OpenSolution.SolutionFolderContainers) { |
|
foreach (SolutionItem item in container.SolutionItems.Items) { |
|
string oldFullName = Path.Combine(OpenSolution.Directory, item.Name); |
|
++x; |
|
if (FileUtility.IsBaseDirectory(oldName, oldFullName)) { |
|
string newFullName = FileUtility.RenameBaseDirectory(oldFullName, oldName, newName); |
|
item.Name = item.Location = FileUtility.GetRelativePath(OpenSolution.Directory, newFullName); |
|
} |
|
} |
|
} |
|
|
|
long y = 0; |
|
foreach (IProject project in OpenSolution.Projects) { |
|
if (FileUtility.IsBaseDirectory(project.Directory, oldName)) { |
|
foreach (ProjectItem item in project.Items) { |
|
++y; |
|
if (FileUtility.IsBaseDirectory(oldName, item.FileName)) { |
|
OnProjectItemRemoved(new ProjectItemEventArgs(project, item)); |
|
item.FileName = FileUtility.RenameBaseDirectory(item.FileName, oldName, newName); |
|
OnProjectItemAdded(new ProjectItemEventArgs(project, item)); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
static void FileServiceFileRemoved(object sender, FileEventArgs e) |
|
{ |
|
if (OpenSolution == null) { |
|
return; |
|
} |
|
string fileName = e.FileName; |
|
|
|
foreach (ISolutionFolderContainer container in OpenSolution.SolutionFolderContainers) { |
|
for (int i = 0; i < container.SolutionItems.Items.Count;) { |
|
SolutionItem item = container.SolutionItems.Items[i]; |
|
if (FileUtility.IsBaseDirectory(fileName, Path.Combine(OpenSolution.Directory, item.Name))) { |
|
container.SolutionItems.Items.RemoveAt(i); |
|
} else { |
|
++i; |
|
} |
|
} |
|
} |
|
|
|
foreach (IProject project in OpenSolution.Projects) { |
|
if (FileUtility.IsBaseDirectory(project.Directory, fileName)) { |
|
for (int i = 0; i < project.Items.Count;) { |
|
ProjectItem item =project.Items[i]; |
|
if (FileUtility.IsBaseDirectory(fileName, item.FileName)) { |
|
project.Items.RemoveAt(i); |
|
OnProjectItemRemoved(new ProjectItemEventArgs(project, item)); |
|
} else { |
|
++i; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
static void ActiveWindowChanged(object sender, EventArgs e) |
|
{ |
|
object activeContent = WorkbenchSingleton.Workbench.ActiveContent; |
|
IViewContent viewContent = activeContent as IViewContent; |
|
if (viewContent == null && activeContent is ISecondaryViewContent) { |
|
// required if one creates a new winforms app and then immediately switches to design mode |
|
// without focussing the text editor |
|
IWorkbenchWindow window = ((ISecondaryViewContent)activeContent).WorkbenchWindow; |
|
if (window == null) // workbench window is being disposed |
|
return; |
|
viewContent = window.ViewContent; |
|
} |
|
if (OpenSolution == null || viewContent == null) { |
|
return; |
|
} |
|
string fileName = viewContent.FileName; |
|
if (fileName == null) { |
|
return; |
|
} |
|
CurrentProject = OpenSolution.FindProjectContainingFile(fileName) ?? CurrentProject; |
|
} |
|
|
|
/// <summary> |
|
/// Adds a project item to the project, raising the ProjectItemAdded event. |
|
/// Make sure you call project.Save() after adding new items! |
|
/// </summary> |
|
public static void AddProjectItem(IProject project, ProjectItem item) |
|
{ |
|
if (project == null) throw new ArgumentNullException("project"); |
|
if (item == null) throw new ArgumentNullException("item"); |
|
project.Items.Add(item); |
|
OnProjectItemAdded(new ProjectItemEventArgs(project, item)); |
|
} |
|
|
|
/// <summary> |
|
/// Removes a project item from the project, raising the ProjectItemRemoved event. |
|
/// Make sure you call project.Save() after removing items! |
|
/// </summary> |
|
public static void RemoveProjectItem(IProject project, ProjectItem item) |
|
{ |
|
if (project == null) throw new ArgumentNullException("project"); |
|
if (item == null) throw new ArgumentNullException("item"); |
|
if (!project.Items.Remove(item)) { |
|
throw new ArgumentException("The item was not found in the project!"); |
|
} |
|
OnProjectItemRemoved(new ProjectItemEventArgs(project, item)); |
|
} |
|
|
|
static void BeforeLoadSolution() |
|
{ |
|
if (openSolution != null) { |
|
SaveSolutionPreferences(); |
|
WorkbenchSingleton.Workbench.CloseAllViews(); |
|
CloseSolution(); |
|
} |
|
} |
|
|
|
public static void LoadSolution(string fileName) |
|
{ |
|
BeforeLoadSolution(); |
|
openSolution = Solution.Load(fileName); |
|
if (openSolution == null) |
|
return; |
|
try { |
|
string file = GetPreferenceFileName(openSolution.FileName); |
|
if (FileUtility.IsValidFileName(file) && File.Exists(file)) { |
|
(openSolution.Preferences as IMementoCapable).SetMemento(Properties.Load(file)); |
|
} |
|
ApplyConfigurationAndReadPreferences(); |
|
} catch (Exception ex) { |
|
MessageService.ShowError(ex); |
|
} |
|
// preferences must be read before OnSolutionLoad is called to enable |
|
// the event listeners to read e.Solution.Preferences.Properties |
|
OnSolutionLoaded(new SolutionEventArgs(openSolution)); |
|
} |
|
|
|
static void ApplyConfigurationAndReadPreferences() |
|
{ |
|
openSolution.ApplySolutionConfigurationToProjects(); |
|
openSolution.ApplySolutionPlatformToProjects(); |
|
foreach (IProject project in openSolution.Projects) { |
|
string file = GetPreferenceFileName(project.FileName); |
|
if (FileUtility.IsValidFileName(file) && File.Exists(file)) { |
|
project.SetMemento(Properties.Load(file)); |
|
} |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Load a single project as solution. |
|
/// </summary> |
|
public static void LoadProject(string fileName) |
|
{ |
|
string solutionFile = Path.ChangeExtension(fileName, ".sln"); |
|
if (File.Exists(solutionFile)) { |
|
LoadSolution(solutionFile); |
|
return; |
|
} |
|
Solution solution = new Solution(); |
|
solution.Name = Path.GetFileNameWithoutExtension(fileName); |
|
ILanguageBinding binding = LanguageBindingService.GetBindingPerProjectFile(fileName); |
|
IProject project; |
|
if (binding != null) { |
|
project = LanguageBindingService.LoadProject(fileName, solution.Name); |
|
} else { |
|
MessageService.ShowError(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.InvalidProjectOrCombine}", new string[,] {{"FileName", fileName}})); |
|
return; |
|
} |
|
solution.AddFolder(project); |
|
ProjectSection configSection = solution.GetSolutionConfigurationsSection(); |
|
foreach (string configuration in project.GetConfigurationNames()) { |
|
foreach (string platform in project.GetPlatformNames()) { |
|
string key = configuration + "|" + platform; |
|
configSection.Items.Add(new SolutionItem(key, key)); |
|
} |
|
} |
|
solution.FixSolutionConfiguration(new IProject[] { project }); |
|
solution.Save(solutionFile); |
|
|
|
LoadSolution(solutionFile); |
|
} |
|
|
|
public static void SaveSolution() |
|
{ |
|
if (openSolution != null) { |
|
openSolution.Save(); |
|
foreach (IProject project in openSolution.Projects) { |
|
project.Save(); |
|
} |
|
OnSolutionSaved(new SolutionEventArgs(openSolution)); |
|
} |
|
} |
|
|
|
static string GetPreferenceFileName(string projectFileName) |
|
{ |
|
string directory = PropertyService.ConfigDirectory + "preferences"; |
|
return Path.Combine(directory, |
|
Path.GetFileName(projectFileName) |
|
+ "." + projectFileName.ToLowerInvariant().GetHashCode().ToString("x") |
|
+ ".xml"); |
|
} |
|
|
|
public static void SaveSolutionPreferences() |
|
{ |
|
if (openSolution == null) |
|
return; |
|
string directory = PropertyService.ConfigDirectory + "preferences"; |
|
if (!Directory.Exists(directory)) { |
|
Directory.CreateDirectory(directory); |
|
} |
|
|
|
if (SolutionPreferencesSaving != null) |
|
SolutionPreferencesSaving(null, new SolutionEventArgs(openSolution)); |
|
Properties memento = (openSolution.Preferences as IMementoCapable).CreateMemento(); |
|
|
|
string fullFileName = GetPreferenceFileName(openSolution.FileName); |
|
if (FileUtility.IsValidFileName(fullFileName)) { |
|
FileUtility.ObservedSave(new NamedFileOperationDelegate(memento.Save), fullFileName, FileErrorPolicy.Inform); |
|
} |
|
|
|
foreach (IProject project in OpenSolution.Projects) { |
|
memento = project.CreateMemento(); |
|
if (memento == null) continue; |
|
|
|
fullFileName = GetPreferenceFileName(project.FileName); |
|
if (FileUtility.IsValidFileName(fullFileName)) { |
|
FileUtility.ObservedSave(new NamedFileOperationDelegate(memento.Save), fullFileName, FileErrorPolicy.Inform); |
|
} |
|
} |
|
} |
|
|
|
public static void CloseSolution() |
|
{ |
|
if (openSolution != null) { |
|
CurrentProject = null; |
|
OnSolutionClosing(new SolutionEventArgs(openSolution)); |
|
|
|
openSolution.Dispose(); |
|
openSolution = null; |
|
|
|
OnSolutionClosed(EventArgs.Empty); |
|
} |
|
} |
|
|
|
public static void MarkFileDirty(string fileName) |
|
{ |
|
if (OpenSolution != null) { |
|
foreach (IProject project in OpenSolution.Projects) { |
|
if (project.IsFileInProject(fileName)) { |
|
MarkProjectDirty(project); |
|
} |
|
} |
|
} |
|
} |
|
|
|
public static void MarkProjectDirty(IProject project) |
|
{ |
|
project.IsDirty = true; |
|
} |
|
|
|
static void OnCurrentProjectChanged(ProjectEventArgs e) |
|
{ |
|
if (CurrentProjectChanged != null) { |
|
CurrentProjectChanged(null, e); |
|
} |
|
} |
|
|
|
static void OnSolutionClosed(EventArgs e) |
|
{ |
|
if (SolutionClosed != null) { |
|
SolutionClosed(null, e); |
|
} |
|
} |
|
|
|
static void OnSolutionClosing(SolutionEventArgs e) |
|
{ |
|
if (SolutionClosing != null) { |
|
SolutionClosing(null, e); |
|
} |
|
} |
|
|
|
static void OnSolutionLoaded(SolutionEventArgs e) |
|
{ |
|
ParserService.OnSolutionLoaded(); |
|
if (SolutionLoaded != null) { |
|
SolutionLoaded(null, e); |
|
} |
|
} |
|
|
|
static void OnSolutionSaved(SolutionEventArgs e) |
|
{ |
|
if (SolutionSaved != null) { |
|
SolutionSaved(null, e); |
|
} |
|
} |
|
|
|
static void OnProjectConfigurationChanged(ProjectConfigurationEventArgs e) |
|
{ |
|
if (ProjectConfigurationChanged != null) { |
|
ProjectConfigurationChanged(null, e); |
|
} |
|
} |
|
|
|
static void OnSolutionConfigurationChanged(SolutionConfigurationEventArgs e) |
|
{ |
|
if (SolutionConfigurationChanged != null) { |
|
SolutionConfigurationChanged(null, e); |
|
} |
|
} |
|
|
|
static void OnStartBuild(EventArgs e) |
|
{ |
|
if (StartBuild != null) { |
|
StartBuild(null, e); |
|
} |
|
} |
|
|
|
public static void OnEndBuild() |
|
{ |
|
OnEndBuild(new EventArgs()); |
|
} |
|
|
|
static void OnEndBuild(EventArgs e) |
|
{ |
|
if (EndBuild != null) { |
|
EndBuild(null, e); |
|
} |
|
} |
|
|
|
public static void RemoveSolutionFolder(string guid) |
|
{ |
|
if (OpenSolution == null) { |
|
return; |
|
} |
|
foreach (ISolutionFolder folder in OpenSolution.SolutionFolders) { |
|
if (folder.IdGuid == guid) { |
|
folder.Parent.RemoveFolder(folder); |
|
OnSolutionFolderRemoved(new SolutionFolderEventArgs(folder)); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
static void OnSolutionFolderRemoved(SolutionFolderEventArgs e) |
|
{ |
|
if (SolutionFolderRemoved != null) { |
|
SolutionFolderRemoved(null, e); |
|
} |
|
} |
|
|
|
static void OnProjectItemAdded(ProjectItemEventArgs e) |
|
{ |
|
if (ProjectItemAdded != null) { |
|
ProjectItemAdded(null, e); |
|
} |
|
} |
|
static void OnProjectItemRemoved(ProjectItemEventArgs e) |
|
{ |
|
if (ProjectItemRemoved != null) { |
|
ProjectItemRemoved(null, e); |
|
} |
|
} |
|
|
|
public static event SolutionFolderEventHandler SolutionFolderRemoved; |
|
|
|
public static event EventHandler StartBuild; |
|
public static event EventHandler EndBuild; |
|
|
|
public static event ProjectConfigurationEventHandler ProjectConfigurationChanged; |
|
public static event SolutionConfigurationEventHandler SolutionConfigurationChanged; |
|
|
|
public static event EventHandler<SolutionEventArgs> SolutionLoaded; |
|
public static event EventHandler<SolutionEventArgs> SolutionSaved; |
|
|
|
public static event EventHandler<SolutionEventArgs> SolutionClosing; |
|
public static event EventHandler SolutionClosed; |
|
|
|
/// <summary> |
|
/// Raised before the solution preferences are being saved. Allows you to save |
|
/// your additional properties in the solution preferences. |
|
/// </summary> |
|
public static event EventHandler<SolutionEventArgs> SolutionPreferencesSaving; |
|
|
|
public static event ProjectEventHandler CurrentProjectChanged; |
|
|
|
public static event EventHandler<ProjectItemEventArgs> ProjectItemAdded; |
|
public static event EventHandler<ProjectItemEventArgs> ProjectItemRemoved; |
|
} |
|
}
|
|
|