Browse Source

Improved support for readonly projects and solutions.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3290 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Justin Dearing 18 years ago
parent
commit
26e5311b8a
  1. 82
      AddIns/ICSharpCode.SharpDevelop.addin
  2. 2
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  3. 29
      src/Main/Base/Project/Src/Commands/FileCommands.cs
  4. 6
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ProjectNode.cs
  5. 3
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/SolutionNode.cs
  6. 1
      src/Main/Base/Project/Src/Internal/ConditionEvaluators/ProjectActiveEvaluator.cs
  7. 26
      src/Main/Base/Project/Src/Internal/ConditionEvaluators/WriteableProjectEvaluator.cs
  8. 25
      src/Main/Base/Project/Src/Internal/ConditionEvaluators/WriteableSolutionEvaluator.cs
  9. 12
      src/Main/Base/Project/Src/Project/AbstractProject.cs
  10. 13
      src/Main/Base/Project/Src/Project/IProject.cs
  11. 37
      src/Main/Base/Project/Src/Project/Solution/Solution.cs

82
AddIns/ICSharpCode.SharpDevelop.addin

@ -20,6 +20,8 @@ @@ -20,6 +20,8 @@
<ConditionEvaluator name="OpenWindowState" class="ICSharpCode.SharpDevelop.OpenWindowStateConditionEvaluator"/>
<ConditionEvaluator name="WindowActive" class="ICSharpCode.SharpDevelop.WindowActiveConditionEvaluator"/>
<ConditionEvaluator name="WindowOpen" class="ICSharpCode.SharpDevelop.WindowOpenConditionEvaluator"/>
<ConditionEvaluator name="WriteableProject" class="ICSharpCode.SharpDevelop.WriteableProjectConditionEvaluator"/>
<ConditionEvaluator name="WriteableSolution" class="ICSharpCode.SharpDevelop.WriteableSolutionConditionEvaluator"/>
<ConditionEvaluator name="ProjectActive" class="ICSharpCode.SharpDevelop.ProjectActiveConditionEvaluator"/>
<ConditionEvaluator name="TextContent" class="ICSharpCode.SharpDevelop.DefaultEditor.Conditions.TextContentConditionEvaluator"/>
<ConditionEvaluator name="BrowserLocation" class="ICSharpCode.SharpDevelop.BrowserDisplayBinding.BrowserLocationConditionEvaluator"/>
@ -29,6 +31,7 @@ @@ -29,6 +31,7 @@
<ConditionEvaluator name="CompareProjectProperty" class="ICSharpCode.SharpDevelop.CompareProjectPropertyConditionEvaluator"/>
<ConditionEvaluator name="ProjectItem" class="ICSharpCode.SharpDevelop.Project.ProjectItemConditionEvaluator"/>
<Doozer name="CustomTool" class="ICSharpCode.SharpDevelop.Project.CustomToolDoozer"/>
<Doozer name="CustomProperty" class="ICSharpCode.SharpDevelop.Project.CustomPropertyDoozer"/>
<Doozer name="DialogPanel" class="ICSharpCode.SharpDevelop.DialogPanelDoozer"/>
@ -203,23 +206,25 @@ @@ -203,23 +206,25 @@
class = "ICSharpCode.SharpDevelop.Project.Commands.Clean"/>
<MenuItem id = "CombineBuildGroupSeparator" type = "Separator"/>
<MenuItem id = "CombineAddMenu" label = "${res:ProjectComponent.ContextMenu.AddMenu}" type = "Menu">
<MenuItem id = "AddNewProjectToSolution"
label = "${res:ProjectComponent.ContextMenu.NewProject}"
icon = "Icons.16x16.NewProjectIcon"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddNewProjectToSolution"/>
<MenuItem id = "AddExitingProjectToSolution"
label = "${res:ProjectComponent.ContextMenu.ExistingProject}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddExitingProjectToSolution"/>
<MenuItem id = "Separator1" type = "Separator" />
<MenuItem id = "AddItem"
label = "${res:ProjectComponent.ContextMenu.AddItem}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddExistingItemToSolution"/>
<MenuItem id = "AddNewSolutionFolderToSolution"
icon = "ProjectBrowser.SolutionFolder.CreateNew"
label = "${res:ProjectComponent.ContextMenu.NewSolutionFolder}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddNewSolutionFolderToSolution"/>
</MenuItem>
<Condition name="WriteableSolution" action="Disable">
<MenuItem id = "CombineAddMenu" label = "${res:ProjectComponent.ContextMenu.AddMenu}" type = "Menu">
<MenuItem id = "AddNewProjectToSolution"
label = "${res:ProjectComponent.ContextMenu.NewProject}"
icon = "Icons.16x16.NewProjectIcon"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddNewProjectToSolution"/>
<MenuItem id = "AddExitingProjectToSolution"
label = "${res:ProjectComponent.ContextMenu.ExistingProject}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddExitingProjectToSolution"/>
<MenuItem id = "Separator1" type = "Separator" />
<MenuItem id = "AddItem"
label = "${res:ProjectComponent.ContextMenu.AddItem}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddExistingItemToSolution"/>
<MenuItem id = "AddNewSolutionFolderToSolution"
icon = "ProjectBrowser.SolutionFolder.CreateNew"
label = "${res:ProjectComponent.ContextMenu.NewSolutionFolder}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddNewSolutionFolderToSolution"/>
</MenuItem>
</Condition>
<MenuItem id = "AddSeparator" type = "Separator"/>
<MenuItem id = "Paste"
@ -274,26 +279,29 @@ @@ -274,26 +279,29 @@
class = "ICSharpCode.SharpDevelop.Project.Commands.PublishProject"/>-->
<MenuItem id = "CombineBuildGroupSeparator" type = "Separator"/>
<MenuItem id = "ProjectAddMenu" label = "${res:ProjectComponent.ContextMenu.AddMenu}" type = "Menu" >
<MenuItem id = "New Item"
label = "${res:ProjectComponent.ContextMenu.NewItem}"
icon = "Icons.16x16.NewDocumentIcon"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddNewItemsToProject"/>
<MenuItem id = "Existing Item"
label = "${res:ProjectComponent.ContextMenu.ExistingItem}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddExistingItemsToProject"/>
<MenuItem id = "NewFolder"
label = "${res:ProjectComponent.ContextMenu.NewFolder}"
icon = "Icons.16x16.NewFolderIcon"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddNewFolderToProject"/>
</MenuItem>
<MenuItem id = "AddReference"
label = "${res:ProjectComponent.ContextMenu.AddReference}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddReferenceToProject"/>
<MenuItem id = "AddWebReference"
label = "${res:ProjectComponent.ContextMenu.AddWebReference}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddWebReferenceToProject"/>
<MenuItem id = "AddSeparator" type = "Separator"/>
<Condition name="WriteableProject" action="Disable">
<MenuItem id = "ProjectAddMenu" label = "${res:ProjectComponent.ContextMenu.AddMenu}" type = "Menu" >
<MenuItem id = "New Item"
label = "${res:ProjectComponent.ContextMenu.NewItem}"
icon = "Icons.16x16.NewDocumentIcon"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddNewItemsToProject"/>
<MenuItem id = "Existing Item"
label = "${res:ProjectComponent.ContextMenu.ExistingItem}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddExistingItemsToProject"/>
<MenuItem id = "NewFolder"
label = "${res:ProjectComponent.ContextMenu.NewFolder}"
icon = "Icons.16x16.NewFolderIcon"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddNewFolderToProject"/>
</MenuItem>
<MenuItem id = "AddReference"
label = "${res:ProjectComponent.ContextMenu.AddReference}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddReferenceToProject"/>
<MenuItem id = "AddWebReference"
label = "${res:ProjectComponent.ContextMenu.AddWebReference}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddWebReferenceToProject"/>
<MenuItem id = "AddSeparator" type = "Separator"/>
</Condition>
<MenuItem id = "OpenProjectWith"
label = "${res:Gui.ProjectBrowser.OpenWith}"

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

@ -111,6 +111,8 @@ @@ -111,6 +111,8 @@
<Compile Include="Src\Gui\Pads\ToolsPad.cs" />
<Compile Include="Src\Gui\Workbench\Layouts\SimpleWorkbenchLayout.cs" />
<Compile Include="Src\Gui\Workbench\SingleInstanceHelper.cs" />
<Compile Include="Src\Internal\ConditionEvaluators\WriteableProjectEvaluator.cs" />
<Compile Include="Src\Internal\ConditionEvaluators\WriteableSolutionEvaluator.cs" />
<Compile Include="Src\Internal\ExternalTool\ExternalTool.cs" />
<Compile Include="Src\Internal\Templates\CodeTemplate.cs" />
<Compile Include="Src\Internal\Templates\Project\ProjectTemplate.cs" />

29
src/Main/Base/Project/Src/Commands/FileCommands.cs

@ -22,17 +22,26 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -22,17 +22,26 @@ namespace ICSharpCode.SharpDevelop.Commands
{
public override void Run()
{
if (ProjectBrowserPad.Instance.CurrentProject != null) {
int result = MessageService.ShowCustomDialog("${res:Dialog.NewFile.AddToProjectQuestionTitle}",
"${res:Dialog.NewFile.AddToProjectQuestion}",
"${res:Dialog.NewFile.AddToProjectQuestionProject}",
"${res:Dialog.NewFile.AddToProjectQuestionStandalone}");
if (result == 0) {
ProjectBrowserPad.Instance.CurrentProject.AddNewItemsToProject();
return;
} else if (result == -1) {
return;
ProjectNode node = ProjectBrowserPad.Instance.CurrentProject;
if (node != null) {
if (node.Project.ReadOnly)
{
MessageService.ShowWarningFormatted("${res:Dialog.NewFile.ReadOnlyProjectWarning}", node.Project.FileName);
}
else
{
int result = MessageService.ShowCustomDialog("${res:Dialog.NewFile.AddToProjectQuestionTitle}",
"${res:Dialog.NewFile.AddToProjectQuestion}",
"${res:Dialog.NewFile.AddToProjectQuestionProject}",
"${res:Dialog.NewFile.AddToProjectQuestionStandalone}");
if (result == 0) {
node.AddNewItemsToProject();
return;
} else if (result == -1) {
return;
}
}
}
using (NewFileDialog nfd = new NewFileDialog(null)) {
nfd.Owner = WorkbenchSingleton.MainForm;

6
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ProjectNode.cs

@ -49,10 +49,16 @@ namespace ICSharpCode.SharpDevelop.Project @@ -49,10 +49,16 @@ namespace ICSharpCode.SharpDevelop.Project
{
sortOrder = 1;
this.ContextmenuAddinTreePath = "/SharpDevelop/Pads/ProjectBrowser/ContextMenu/ProjectNode";
this.project = project;
Text = project.Name;
if (project.ReadOnly) {
Text += StringParser.Parse(" (${res:Global.ReadOnly})");
}
autoClearNodes = false;
if (project is MissingProject) {

3
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/SolutionNode.cs

@ -73,6 +73,9 @@ namespace ICSharpCode.SharpDevelop.Project @@ -73,6 +73,9 @@ namespace ICSharpCode.SharpDevelop.Project
void UpdateText()
{
Text = ResourceService.GetString("ICSharpCode.SharpDevelop.Commands.ProjectBrowser.SolutionNodeText") + " " + solution.Name;
if (Solution.ReadOnly) {
Text += StringParser.Parse(" (${res:Global.ReadOnly})");
}
}
public void AddItem(string fileName)

1
src/Main/Base/Project/Src/Internal/ConditionEvaluators/ProjectActiveEvaluator.cs

@ -41,5 +41,4 @@ namespace ICSharpCode.SharpDevelop @@ -41,5 +41,4 @@ namespace ICSharpCode.SharpDevelop
return project != null && project.Language == activeproject;
}
}
}

26
src/Main/Base/Project/Src/Internal/ConditionEvaluators/WriteableProjectEvaluator.cs

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Justin Dearing" email="zippy1981@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop
{
/// <summary>
/// Tests if the caller project is writable. If caller is not an IProject it tests
/// Project.CurrentProject.
/// </summary>
public class WriteableProjectConditionEvaluator : IConditionEvaluator
{
public bool IsValid(object caller, Condition condition)
{
IProject project = (caller as IProject) ?? ProjectService.CurrentProject;
return !project.ReadOnly;
}
}
}

25
src/Main/Base/Project/Src/Internal/ConditionEvaluators/WriteableSolutionEvaluator.cs

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Justin Dearing" email="zippy1981@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop
{
/// <summary>
/// Description of WriteableSolutionEvaluator.
/// </summary>
public class WriteableSolutionConditionEvaluator : IConditionEvaluator
{
public bool IsValid(object caller, Condition condition)
{
Solution solution = ProjectService.OpenSolution;
return (solution != null && !solution.ReadOnly);
}
}
}

12
src/Main/Base/Project/Src/Project/AbstractProject.cs

@ -123,6 +123,18 @@ namespace ICSharpCode.SharpDevelop.Project @@ -123,6 +123,18 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
/// <summary>
/// True if the file that contains the project is readonly.
/// </summary>
[ReadOnly(true)]
public bool ReadOnly {
get
{
FileAttributes attributes = File.GetAttributes(FileName);
return ((FileAttributes.ReadOnly & attributes) == FileAttributes.ReadOnly);
}
}
/// <summary>
/// Gets the directory of the project file.
/// This is equivalent to Path.GetDirectoryName(project.FileName);

13
src/Main/Base/Project/Src/Project/IProject.cs

@ -106,6 +106,19 @@ namespace ICSharpCode.SharpDevelop.Project @@ -106,6 +106,19 @@ namespace ICSharpCode.SharpDevelop.Project
get;
}
/// <summary>
/// <para>
/// True if the project is readonly. For project based files this means
/// the project file has the readonly attribute set. For solution folder
/// based projects this means that the sln file containing the project
/// has the readonly attribute set.
/// </para>
/// <para>This member is thread-safe.</para>
/// </summary>
bool ReadOnly {
get;
}
#region MSBuild properties used inside SharpDevelop base
/// <summary>
/// Gets/Sets the assembly name of the assembly created when building this project.

37
src/Main/Base/Project/Src/Project/Solution/Solution.cs

@ -12,7 +12,7 @@ using System.IO; @@ -12,7 +12,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using SearchAndReplace;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
using MSBuild = Microsoft.Build.BuildEngine;
@ -36,8 +36,6 @@ namespace ICSharpCode.SharpDevelop.Project @@ -36,8 +36,6 @@ namespace ICSharpCode.SharpDevelop.Project
string fileName = String.Empty;
bool readOnly = false;
MSBuild.Engine buildEngine = MSBuildInternals.CreateEngine();
public Solution()
@ -211,10 +209,14 @@ namespace ICSharpCode.SharpDevelop.Project @@ -211,10 +209,14 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
/// <summary>Property to determine if the solution is readonly.</summary>
/// <summary>Returns true if the solution is readonly.</summary>
[Browsable(false)]
public bool ReadOnly {
get { return readOnly; }
get
{
FileAttributes attributes = File.GetAttributes(fileName);
return ((FileAttributes.ReadOnly & attributes) == FileAttributes.ReadOnly);
}
}
#endregion
@ -252,24 +254,17 @@ namespace ICSharpCode.SharpDevelop.Project @@ -252,24 +254,17 @@ namespace ICSharpCode.SharpDevelop.Project
Save(fileName);
return;
} catch (IOException ex) {
MessageService.ShowError("Could not save " + fileName + ":\n" + ex.Message);
MessageService.ShowErrorFormatted("${res:SharpDevelop.Solution.CannotSave.IOException}", fileName, ex.Message);
} catch (UnauthorizedAccessException ex) {
FileAttributes attributes = File.GetAttributes(fileName);
if ((FileAttributes.ReadOnly & attributes) == FileAttributes.ReadOnly) {
bool attemptOverwrite = MessageService.AskQuestionFormatted(
"Solution file {0} is marked readonly. Attempt to save anyway?",
new string [] {fileName});
if (attemptOverwrite) {
try {
attributes &= ~FileAttributes.ReadOnly;
File.SetAttributes(fileName, attributes);
Save(fileName);
return;
} catch { /* If something screws up shows the error */ }
}
MessageService.ShowErrorFormatted("${res:SharpDevelop.Solution.CannotSave.ReadOnly}", fileName);
}
else
{
MessageService.ShowErrorFormatted
("${res:SharpDevelop.Solution.CannotSave.UnauthorizedAccessException}", fileName, ex.Message);
}
this.readOnly = true;
MessageService.ShowError("Could not save " + fileName + ":\n" + ex.Message + "\n\nEnsure the file is writable.");
}
}
@ -502,8 +497,8 @@ namespace ICSharpCode.SharpDevelop.Project @@ -502,8 +497,8 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
}
if (newSolution.FixSolutionConfiguration(newSolution.Projects) || needsConversion) {
if (!newSolution.ReadOnly && (newSolution.FixSolutionConfiguration(newSolution.Projects) || needsConversion)) {
// save in new format
newSolution.Save();
}

Loading…
Cancel
Save