Browse Source

r7440@daniel-notebook (orig r3402): daniel | 2008-08-17 16:48:17 +0200

Use svn copy when copying files/directories using the project browser.


git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3412 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
dfa4b51d2a
  1. 46
      src/AddIns/Misc/SubversionAddIn/Project/Src/Commands/AutostartCommands.cs
  2. 42
      src/AddIns/Misc/SubversionAddIn/Project/Src/SvnClientWrapper.cs
  3. 11
      src/AddIns/Misc/SubversionAddIn/Project/Src/SvnMessageView.cs
  4. 4
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/FolderNodeCommands.cs
  5. 73
      src/Main/Base/Project/Src/Services/File/FileService.cs

46
src/AddIns/Misc/SubversionAddIn/Project/Src/Commands/AutostartCommands.cs

@ -29,6 +29,7 @@ namespace ICSharpCode.Svn.Commands @@ -29,6 +29,7 @@ namespace ICSharpCode.Svn.Commands
{
FileService.FileRemoving += FileRemoving;
FileService.FileRenaming += FileRenaming;
FileService.FileCopying += FileCopying;
FileService.FileCreated += FileCreated;
ProjectService.SolutionCreated += SolutionCreated;
@ -192,7 +193,9 @@ namespace ICSharpCode.Svn.Commands @@ -192,7 +193,9 @@ namespace ICSharpCode.Svn.Commands
switch (status.TextStatus) {
case StatusKind.Unversioned:
case StatusKind.Deleted:
client.Add(fullName, Recurse.None);
using (SharpDevelop.Gui.AsynchronousWaitDialog.ShowWaitDialog("svn add")) {
client.Add(fullName, Recurse.None);
}
break;
}
}
@ -298,14 +301,51 @@ namespace ICSharpCode.Svn.Commands @@ -298,14 +301,51 @@ namespace ICSharpCode.Svn.Commands
e.Cancel = true;
return;
}
e.OperationAlreadyDone = true;
client.Delete(new string [] { fullName }, true);
}
e.OperationAlreadyDone = true;
} catch (Exception ex) {
MessageService.ShowError("File removed exception: " + ex);
}
}
void FileCopying(object sender, FileRenamingEventArgs e)
{
if (e.Cancel) return;
if (!AddInOptions.AutomaticallyRenameFiles) return;
string fullSource = Path.GetFullPath(e.SourceFile);
if (!CanBeVersionControlledFile(fullSource)) return;
try {
using (SvnClientWrapper client = new SvnClientWrapper()) {
SvnMessageView.HandleNotifications(client);
Status status = client.SingleStatus(fullSource);
switch (status.TextStatus) {
case StatusKind.Unversioned:
case StatusKind.None:
return; // nothing to do
case StatusKind.Normal:
case StatusKind.Modified:
case StatusKind.Replaced:
case StatusKind.Added:
// copy without problem
break;
default:
MessageService.ShowError("The file/directory cannot be copied because it is in subversion status '" + status.TextStatus + "'.");
e.Cancel = true;
return;
}
e.OperationAlreadyDone = true;
client.Copy(fullSource,
Revision.Working,
Path.GetFullPath(e.TargetFile)
);
}
} catch (Exception ex) {
MessageService.ShowError("File renamed exception: " + ex);
}
}
void FileRenaming(object sender, FileRenamingEventArgs e)
{
if (e.Cancel) return;
@ -332,12 +372,12 @@ namespace ICSharpCode.Svn.Commands @@ -332,12 +372,12 @@ namespace ICSharpCode.Svn.Commands
e.Cancel = true;
return;
}
e.OperationAlreadyDone = true;
client.Move(fullSource,
Path.GetFullPath(e.TargetFile),
true
);
}
e.OperationAlreadyDone = true;
} catch (Exception ex) {
MessageService.ShowError("File renamed exception: " + ex);
}

42
src/AddIns/Misc/SubversionAddIn/Project/Src/SvnClientWrapper.cs

@ -266,6 +266,8 @@ namespace ICSharpCode.Svn @@ -266,6 +266,8 @@ namespace ICSharpCode.Svn
#endregion
#region Notifications
public event EventHandler<SubversionOperationEventArgs> OperationStarted;
public event EventHandler OperationFinished;
public event EventHandler<NotificationEventArgs> Notify;
void OnNotify(IntPtr baton, SvnWcNotify notify, AprPool pool)
@ -292,18 +294,22 @@ namespace ICSharpCode.Svn @@ -292,18 +294,22 @@ namespace ICSharpCode.Svn
throw new ObjectDisposedException("SvnClientWrapper");
}
void BeforeOperation()
void BeforeOperation(string operationName)
{
// before any subversion operation, ensure the object is not disposed
// and register authorization if necessary
CheckNotDisposed();
OpenAuth();
if (OperationStarted != null)
OperationStarted(this, new SubversionOperationEventArgs { Operation = operationName });
}
void AfterOperation()
{
// after any subversion operation, clear the memory pool
client.Clear();
if (OperationFinished != null)
OperationFinished(this, EventArgs.Empty);
}
public void ClearStatusCache()
@ -315,7 +321,7 @@ namespace ICSharpCode.Svn @@ -315,7 +321,7 @@ namespace ICSharpCode.Svn
public Status SingleStatus(string filename)
{
Debug("SVN: SingleStatus(" + filename + ")");
BeforeOperation();
BeforeOperation("stat");
try {
filename = FileUtility.NormalizePath(filename);
Status result;
@ -357,7 +363,7 @@ namespace ICSharpCode.Svn @@ -357,7 +363,7 @@ namespace ICSharpCode.Svn
public void Add(string filename, Recurse recurse)
{
Debug("SVN: Add(" + filename + ", " + recurse + ")");
BeforeOperation();
BeforeOperation("add");
try {
client.Add3(filename, recurse == Recurse.Full, false, false);
} catch (SvnException ex) {
@ -370,7 +376,7 @@ namespace ICSharpCode.Svn @@ -370,7 +376,7 @@ namespace ICSharpCode.Svn
public string GetPropertyValue(string fileName, string propertyName)
{
Debug("SVN: GetPropertyValue(" + fileName + ", " + propertyName + ")");
BeforeOperation();
BeforeOperation("propget");
try {
AprHash hash = client.PropGet2(propertyName, fileName,
Svn.Revision.Working, Svn.Revision.Working,
@ -393,7 +399,7 @@ namespace ICSharpCode.Svn @@ -393,7 +399,7 @@ namespace ICSharpCode.Svn
public void SetPropertyValue(string fileName, string propertyName, string newPropertyValue)
{
Debug("SVN: SetPropertyValue(" + fileName + ", " + propertyName + ", " + newPropertyValue + ")");
BeforeOperation();
BeforeOperation("propset");
try {
SvnString npv;
if (newPropertyValue != null)
@ -420,7 +426,7 @@ namespace ICSharpCode.Svn @@ -420,7 +426,7 @@ namespace ICSharpCode.Svn
public void Delete(string[] files, bool force)
{
Debug("SVN: Delete(" + string.Join(",", files) + ", " + force + ")");
BeforeOperation();
BeforeOperation("delete");
try {
client.Delete2(ToSvnPaths(files), force);
} catch (SvnException ex) {
@ -433,7 +439,7 @@ namespace ICSharpCode.Svn @@ -433,7 +439,7 @@ namespace ICSharpCode.Svn
public void Revert(string[] files, Recurse recurse)
{
Debug("SVN: Revert(" + string.Join(",", files) + ", " + recurse + ")");
BeforeOperation();
BeforeOperation("revert");
try {
client.Revert(ToSvnPaths(files), recurse == Recurse.Full);
} catch (SvnException ex) {
@ -446,7 +452,7 @@ namespace ICSharpCode.Svn @@ -446,7 +452,7 @@ namespace ICSharpCode.Svn
public void Move(string from, string to, bool force)
{
Debug("SVN: Move(" + from + ", " + to + ", " + force + ")");
BeforeOperation();
BeforeOperation("move");
try {
client.Move3(from, to, force);
} catch (SvnException ex) {
@ -456,6 +462,19 @@ namespace ICSharpCode.Svn @@ -456,6 +462,19 @@ namespace ICSharpCode.Svn
}
}
public void Copy(string from, Revision revision, string to)
{
Debug("SVN: Copy(" + from + ", " + revision + ", " + to);
BeforeOperation("copy");
try {
client.Copy2(from, revision, to);
} catch (SvnException ex) {
throw new SvnClientException(ex);
} finally {
AfterOperation();
}
}
public void AddToIgnoreList(string directory, params string[] filesToIgnore)
{
Debug("SVN: AddToIgnoreList(" + directory + ", " + string.Join(",", filesToIgnore) + ")");
@ -482,7 +501,7 @@ namespace ICSharpCode.Svn @@ -482,7 +501,7 @@ namespace ICSharpCode.Svn
{
Debug("SVN: Log({" + string.Join(",", paths) + "}, " + start + ", " + end +
", " + limit + ", " + discoverChangePaths + ", " + strictNodeHistory + ")");
BeforeOperation();
BeforeOperation("log");
try {
client.Log2(
ToSvnPaths(paths),
@ -564,6 +583,11 @@ namespace ICSharpCode.Svn @@ -564,6 +583,11 @@ namespace ICSharpCode.Svn
public string Path;
}
public class SubversionOperationEventArgs : EventArgs
{
public string Operation;
}
public class LogMessage
{
public int Revision;

11
src/AddIns/Misc/SubversionAddIn/Project/Src/SvnMessageView.cs

@ -40,6 +40,17 @@ namespace ICSharpCode.Svn @@ -40,6 +40,17 @@ namespace ICSharpCode.Svn
client.Notify += delegate(object sender, NotificationEventArgs e) {
AppendLine(e.Kind + e.Action + " " + e.Path);
};
AsynchronousWaitDialog waitDialog = null;
client.OperationStarted += delegate(object sender, SubversionOperationEventArgs e) {
if (waitDialog != null)
waitDialog = AsynchronousWaitDialog.ShowWaitDialog("svn " + e.Operation);
};
client.OperationFinished += delegate {
if (waitDialog != null) {
waitDialog.Dispose();
waitDialog = null;
}
};
}
}
}

4
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/FolderNodeCommands.cs

@ -100,7 +100,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -100,7 +100,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
}
}
FileUtility.DeepCopy(directoryName, copiedFileName, true);
FileService.CopyFile(directoryName, copiedFileName, true, false);
DirectoryNode newNode = new DirectoryNode(copiedFileName);
newNode.AddTo(node);
if (includeInProject) {
@ -123,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -123,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
{
string copiedFileName = Path.Combine(node.Directory, Path.GetFileName(fileName));
if (!FileUtility.IsEqualFileName(fileName, copiedFileName)) {
File.Copy(fileName, copiedFileName, true);
FileService.CopyFile(fileName, copiedFileName, false, true);
}
if (includeInProject) {
FileNode fileNode;

73
src/Main/Base/Project/Src/Services/File/FileService.cs

@ -127,8 +127,10 @@ namespace ICSharpCode.SharpDevelop @@ -127,8 +127,10 @@ namespace ICSharpCode.SharpDevelop
LoggingService.Debug("OpenedFileFileNameChange: " + oldName + " => " + newName);
Debug.Assert(openedFileDict[oldName] == file);
Debug.Assert(!openedFileDict.ContainsKey(newName));
if (openedFileDict[oldName] != file)
throw new ArgumentException("file must be registered as oldName");
if (openedFileDict.ContainsKey(newName))
throw new ArgumentException("there already is a file with the newName");
openedFileDict.Remove(oldName);
openedFileDict[newName] = file;
@ -137,7 +139,9 @@ namespace ICSharpCode.SharpDevelop @@ -137,7 +139,9 @@ namespace ICSharpCode.SharpDevelop
/// <summary>Called by OpenedFile.UnregisterView to update the dictionary.</summary>
internal static void OpenedFileClosed(OpenedFile file)
{
Debug.Assert(openedFileDict[file.FileName] == file);
if (openedFileDict[file.FileName] != file)
throw new ArgumentException("file must be registered");
openedFileDict.Remove(file.FileName);
LoggingService.Debug("OpenedFileClosed: " + file.FileName);
}
@ -392,6 +396,47 @@ namespace ICSharpCode.SharpDevelop @@ -392,6 +396,47 @@ namespace ICSharpCode.SharpDevelop
return true;
}
/// <summary>
/// Copies a file, raising the appropriate events. This method may show message boxes.
/// </summary>
public static bool CopyFile(string oldName, string newName, bool isDirectory, bool overwrite)
{
if (FileUtility.IsEqualFileName(oldName, newName))
return false;
FileRenamingEventArgs eargs = new FileRenamingEventArgs(oldName, newName, isDirectory);
OnFileCopying(eargs);
if (eargs.Cancel)
return false;
if (!eargs.OperationAlreadyDone) {
try {
if (isDirectory && Directory.Exists(oldName)) {
if (!overwrite && Directory.Exists(newName)) {
MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}"));
return false;
}
FileUtility.DeepCopy(oldName, newName, overwrite);
} else if (File.Exists(oldName)) {
if (!overwrite && File.Exists(newName)) {
MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}"));
return false;
}
File.Copy(oldName, newName, overwrite);
}
} catch (Exception e) {
if (isDirectory) {
MessageService.ShowError(e, "Can't copy directory " + oldName);
} else {
MessageService.ShowError(e, "Can't copy file " + oldName);
}
return false;
}
}
OnFileCopied(new FileRenameEventArgs(oldName, newName, isDirectory));
return true;
}
/// <summary>
/// Opens the specified file and jumps to the specified file position.
/// Warning: Unlike parser coordinates, line and column are 0-based.
@ -443,7 +488,7 @@ namespace ICSharpCode.SharpDevelop @@ -443,7 +488,7 @@ namespace ICSharpCode.SharpDevelop
}
#region Event Handlers
static void OnFileRemoved(FileEventArgs e)
{
if (FileRemoved != null) {
@ -471,10 +516,23 @@ namespace ICSharpCode.SharpDevelop @@ -471,10 +516,23 @@ namespace ICSharpCode.SharpDevelop
}
}
static void OnFileCopied(FileRenameEventArgs e)
{
if (FileCopied != null) {
FileCopied(null, e);
}
}
static void OnFileCopying(FileRenamingEventArgs e) {
if (FileCopying != null) {
FileCopying(null, e);
}
}
#endregion Event Handlers
#region Static event firing methods
/// <summary>
/// Fires the event handlers for a file being created.
/// </summary>
@ -516,12 +574,15 @@ namespace ICSharpCode.SharpDevelop @@ -516,12 +574,15 @@ namespace ICSharpCode.SharpDevelop
#endregion Static event firing methods
#region Events
public static event EventHandler<FileEventArgs> FileCreated;
public static event EventHandler<FileRenamingEventArgs> FileRenaming;
public static event EventHandler<FileRenameEventArgs> FileRenamed;
public static event EventHandler<FileRenamingEventArgs> FileCopying;
public static event EventHandler<FileRenameEventArgs> FileCopied;
public static event EventHandler<FileCancelEventArgs> FileRemoving;
public static event EventHandler<FileEventArgs> FileRemoved;

Loading…
Cancel
Save