Commits

Alessandro Bahgat committed 3eb6e07

Added a notification when removing files with local modifications. The user is now given the possibility to move local files to the Trash instead or to delete them.

This may solve issue #157

Comments (0)

Files changed (4)

English.lproj/Localizable.strings

 /* Revision 'number' displayed for current revision in table */
 "current" = "current";
 
+/* Button */
+"Delete" = "Delete";
+
 /* Default button of Discard alert */
 "Discard" = "Discard";
 
 /* Alternate button of post-pull merge alert */
 "Don't Merge" = "Don't Merge";
 
+/* Body of Trash or Delete files dialog */
+"If you choose to delete them, all the changes will be lost." = "If you choose to delete them, all the changes will be lost.";
+
 /* Title of merge-conflicts sheet */
 "Merge Conflicts Remain" = "Merge Conflicts Remain";
 
 /* Error message for hg commit */
 "Missing commit message" = "Missing commit message";
 
+/* Button in remove modified files dialogs */
+"Move to Trash" = "Move to Trash";
+
 /* Error message from Open command */
 "No such directory %@" = "No such directory %@";
 
 /* Title of conflicts alert from Commit command */
 "Some files still have merge conflicts" = "Some files still have merge conflicts";
 
+/* Trash or Delete files dialog */
+"Some of the files you are about to remove have local modifications. Do you want to move them to the Trash, or delete them?" = "Some of the files you are about to remove have local modifications. Do you want to move them to the Trash, or delete them?";
+
 /* Button in fatal error alert */
 "Sorry" = "Sorry";
 

Source/HgUncommittedRevision.h

 
 - (BOOL) addRemoveWithError:(NSError**)outError;
 - (BOOL) addFiles: (NSArray*)files error: (NSError**)outError;
-- (BOOL) removeFiles: (NSArray*)files error: (NSError**)outError;
+- (BOOL) removeFiles: (NSArray*)files
+       trashModified: (BOOL)trashModified
+               error: (NSError**)outError;
+
 - (BOOL) revertFiles: (NSArray*)files
               backup: (BOOL)backup
                error: (NSError**)outError;

Source/HgUncommittedRevision.m

 //  Copyright 2008-2009 Jens Alfke. All rights reserved.
 //
 
+#import <CoreServices/CoreServices.h>
+
 #import "HgUncommittedRevision.h"
 #import "HgDir.h"
 #import "HgRepository.h"
 #import "HgOperation.h"
 
+static BOOL moveFileToTrash(HgFile* file)
+{
+    FSRef f;
+    OSStatus os_status = FSPathMakeRef((const UInt8 *)[file.absolutePath fileSystemRepresentation], &f, NULL);
+    
+    if ( os_status == noErr ) {
+        OSStatus tr_status = FSMoveObjectToTrashSync(&f, nil, kFSFileOperationOverwrite);
+        if ( tr_status  == noErr ) {
+            return YES;
+        } else {
+            // it was not possible to move the file to trash
+            return NO;
+        }
+    } else {
+        // it was not possible to create a path for the file
+        return NO;
+    }
+}
+
 
 @implementation HgUncommittedRevision
 
     return [self applyCommand: @"add" arguments: nil toFiles: files error: outError];
 }
 
-- (BOOL) removeFiles: (NSArray*)files error: (NSError**)outError
+- (BOOL) removeFiles: (NSArray*)files trashModified: (BOOL)trashModified error: (NSError**)outError
 {
     Assert(files);
     NSMutableArray *realFiles = [NSMutableArray array], *missingFiles = [NSMutableArray array];
             case kDeleted:
                 [missingFiles addObject: file];
                 break;
+            case kModified:
+                if ( trashModified ) {
+                    BOOL trashSuccess = moveFileToTrash(file);
+                    if ( trashSuccess ) {
+                        [missingFiles addObject: file];
+                    } else {
+                        // it was not possible to move the file to trash
+                        return NO;
+                    }
+                } else {
+                    [realFiles addObject: file];
+                }
+                break;
             default:
                 [realFiles addObject: file];
                 break;

Source/RepoController_Actions.m

 {
     [sheet orderOut: self];
     if( returnCode == NSOKButton ) {
+        // check if there is any locally modified file
+        if ( context ) {
+            NSArray *files = (NSArray*) context;
+            BOOL modified = NO;
+            for( HgFile *file in files ) {
+                if ( file.status == kModified ) {
+                    modified = YES;
+                    break;
+                }
+            }
+            
+            if ( ! modified ) {
+                NSError *error = nil;
+                if( ! [_repo.uncommittedRevision removeFiles: (NSArray*)context trashModified: NO error: &error] ) {
+                    [self presentError: error];
+                }
+            } else {
+                NSBeginCriticalAlertSheet(NSLocalizedString(@"Some of the files you are about to remove have local modifications. Do you want to move them to the Trash, or delete them?", @"Trash or Delete files dialog"),
+                                          NSLocalizedString(@"Move to Trash", @"Button in remove modified files dialogs"),
+                                          NSLocalizedString(@"Cancel", @"Button"),
+                                          NSLocalizedString(@"Delete", @"Button"),
+                                          self.window,self,
+                                          @selector(_removeSheetWithModificationsEnd:returnCode:context:), NULL, files,
+                                          NSLocalizedString(@"If you choose to delete them, all the changes will be lost.", 
+                                                            @"Body of Trash or Delete files dialog"));
+            }
+        }
+    }
+}
+
+- (void) _removeSheetWithModificationsEnd: (NSPanel*)sheet returnCode: (int)returnCode context: (void*)context
+{
+    [sheet orderOut: self];
+    if( returnCode == NSAlertDefaultReturn || returnCode == NSAlertOtherReturn) {
+        BOOL trashFiles = returnCode == NSAlertDefaultReturn;
         NSError *error = nil;
-        if( ! [_repo.uncommittedRevision removeFiles: (NSArray*)context error: &error] ) {
+        if( ! [_repo.uncommittedRevision removeFiles: (NSArray*)context trashModified: trashFiles error: &error] ) {
             [self presentError: error];
         }
     }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.