Hi Wofgang,

disegard my previous patch. I don't know why it did hang for me, it did only on clang/libobjc2, on another computer it worked. Still, it was buggy in concept. A resume after pause had the "progress bar" restart and jump. The fact is that most of the information of the status is held in the executor, which, on pause, we loose. Besides from the processed files, which I communicated back to the master, we also have information such about the total vs. current number of files.
On pause, we need to communicate it all back.

I added thus also the processed files in the caller, as well as adding a parameter to calculateNumFiles to skip the calculation and just resume. What do you think? does it work for me? It works for me in a simple case e.g. copying 10 files (the only operatio supported is copy right now).

What is not working? if there are "duplicated" files, that is the panel comes up, not only the check is performed again, but the total is calculated wrongly again. Ideas? One idea would be to store the operation (overwrite, copy, skip) in the caller and pass it to the executor again.

Riccardo
Index: Operation/FileOpInfo.h
===================================================================
--- Operation/FileOpInfo.h	(revision 38057)
+++ Operation/FileOpInfo.h	(working copy)
@@ -43,6 +43,8 @@
 
 - (void)sendDidChangeNotification;
 
+- (void)removeProcessedFiles;
+
 - (oneway void)endOperation;
 
 @end
@@ -60,7 +62,7 @@
 
 - (void)setOnlyOlder;
 
-- (oneway void)calculateNumFiles;
+- (oneway void)calculateNumFiles:(NSUInteger)continueFrom;
 
 - (oneway void)performOperation;
 
@@ -84,13 +86,14 @@
   NSString *type;
   NSString *source;
   NSString *destination;
-  NSArray *files;
+  NSMutableArray *files;
   NSMutableArray *dupfiles;
+  NSMutableArray *procFiles;
   int ref;
   
   NSMutableDictionary *operationDict;
   NSMutableArray *notifNames;
-  
+
   BOOL confirm;
   BOOL showwin;
   BOOL opdone;
@@ -134,6 +137,8 @@
 
 - (void)startOperation;
 
+- (void)detachOperationThread;
+
 - (NSInteger)requestUserConfirmationWithMessage:(NSString *)message 
                                     title:(NSString *)title;
 
@@ -209,8 +214,6 @@
 
 - (void)setOnlyOlder;
 
-- (void)calculateNumFiles;
-
 - (void)performOperation;
 
 - (NSData *)processedFiles;
Index: Operation/FileOpInfo.m
===================================================================
--- Operation/FileOpInfo.m	(revision 38057)
+++ Operation/FileOpInfo.m	(working copy)
@@ -46,6 +46,7 @@
   RELEASE (source);
   RELEASE (destination);
   RELEASE (files);
+  RELEASE (procFiles);
   RELEASE (dupfiles);
   RELEASE (notifNames);
   RELEASE (win);
@@ -118,7 +119,8 @@
     ASSIGN (type, tp);
     ASSIGN (source, src);
     ASSIGN (destination, dst);
-    ASSIGN (files, fls);
+    files = [[NSMutableArray arrayWithArray:fls] retain];
+    procFiles = [[NSMutableArray alloc] init];
     
     dupfiles = [NSMutableArray new];
     
@@ -185,89 +187,114 @@
 
 - (void)startOperation
 {
-  NSPort *port[2];
-  NSArray *ports;
+  NSLog(@"startOperation");
+  if (confirm)
+    {    
+      NSString *title = nil;
+      NSString *msg = nil;
+      NSString *msg1 = nil;
+      NSString *msg2 = nil;
+      NSString *items;
 
-  if (confirm) {    
-    NSString *title = nil;
-    NSString *msg = nil;
-    NSString *msg1 = nil;
-    NSString *msg2 = nil;
-    NSString *items;
-
-    if ([files count] > 1) {
-      items = [NSString stringWithFormat: @"%lu %@", (unsigned long)[files count], NSLocalizedString(@"items", @"")];
-    } else {
-      items = NSLocalizedString(@"one item", @"");
-    }
+      if ([files count] > 1)
+        {
+          items = [NSString stringWithFormat: @"%lu %@", (unsigned long)[files count], NSLocalizedString(@"items", @"")];
+        }
+      else
+        {
+          items = NSLocalizedString(@"one item", @"");
+        }
     
-	  if ([type isEqual: NSWorkspaceMoveOperation]) {
-		  title = NSLocalizedString(@"Move", @"");
-      msg1 = [NSString stringWithFormat: @"%@ %@ %@: ", 
-                                            NSLocalizedString(@"Move", @""), 
-                                            items, 
-                                            NSLocalizedString(@"from", @"")];
-		  msg2 = NSLocalizedString(@"\nto: ", @"");
-		  msg = [NSString stringWithFormat: @"%@%@%@%@?", msg1, source, msg2, destination];
-    } else if ([type isEqual: NSWorkspaceCopyOperation]) {
-		  title = NSLocalizedString(@"Copy", @"");
-      msg1 = [NSString stringWithFormat: @"%@ %@ %@: ", 
-                                            NSLocalizedString(@"Copy", @""), 
-                                            items, 
-                                            NSLocalizedString(@"from", @"")];
-		  msg2 = NSLocalizedString(@"\nto: ", @"");
-		  msg = [NSString stringWithFormat: @"%@%@%@%@?", msg1, source, msg2, destination];
-	  } else if ([type isEqual: NSWorkspaceLinkOperation]) {
-		  title = NSLocalizedString(@"Link", @"");
-      msg1 = [NSString stringWithFormat: @"%@ %@ %@: ", 
-                                            NSLocalizedString(@"Link", @""), 
-                                            items, 
-                                            NSLocalizedString(@"from", @"")];
-		  msg2 = NSLocalizedString(@"\nto: ", @"");
-		  msg = [NSString stringWithFormat: @"%@%@%@%@?", msg1, source, msg2, destination];
-	  } else if ([type isEqual: NSWorkspaceRecycleOperation]) {
-		  title = NSLocalizedString(@"Recycler", @"");
-      msg1 = [NSString stringWithFormat: @"%@ %@ %@: ", 
-                                            NSLocalizedString(@"Move", @""), 
-                                            items, 
-                                            NSLocalizedString(@"from", @"")];
-		  msg2 = NSLocalizedString(@"\nto the Recycler", @"");
-		  msg = [NSString stringWithFormat: @"%@%@%@?", msg1, source, msg2];
-	  } else if ([type isEqual: @"GWorkspaceRecycleOutOperation"]) {
-		  title = NSLocalizedString(@"Recycler", @"");
-      msg1 = [NSString stringWithFormat: @"%@ %@ %@ ", 
-                                            NSLocalizedString(@"Move", @""), 
-                                            items, 
-                                            NSLocalizedString(@"from the Recycler", @"")];
-		  msg2 = NSLocalizedString(@"\nto: ", @"");
-		  msg = [NSString stringWithFormat: @"%@%@%@?", msg1, msg2, destination];
-	  } else if ([type isEqual: @"GWorkspaceEmptyRecyclerOperation"]) {
-		  title = NSLocalizedString(@"Recycler", @"");
-		  msg = NSLocalizedString(@"Empty the Recycler?", @"");
-	  } else if ([type isEqual: NSWorkspaceDestroyOperation]) {
-		  title = NSLocalizedString(@"Delete", @"");
-		  msg = NSLocalizedString(@"Delete the selected objects?", @"");
-	  } else if ([type isEqual: NSWorkspaceDuplicateOperation]) {
-		  title = NSLocalizedString(@"Duplicate", @"");
-		  msg = NSLocalizedString(@"Duplicate the selected objects?", @"");
-	  }
-        
-    if (NSRunAlertPanel(title, msg, 
-                        NSLocalizedString(@"OK", @""), 
-			NSLocalizedString(@"Cancel", @""), 
-                        nil) != NSAlertDefaultReturn) {
-      [self endOperation];
-      return;
+      if ([type isEqual: NSWorkspaceMoveOperation])
+        {
+          title = NSLocalizedString(@"Move", @"");
+          msg1 = [NSString stringWithFormat: @"%@ %@ %@: ", 
+                           NSLocalizedString(@"Move", @""), 
+                           items, 
+                           NSLocalizedString(@"from", @"")];
+          msg2 = NSLocalizedString(@"\nto: ", @"");
+          msg = [NSString stringWithFormat: @"%@%@%@%@?", msg1, source, msg2, destination];
+        }
+      else if ([type isEqual: NSWorkspaceCopyOperation])
+        {
+          title = NSLocalizedString(@"Copy", @"");
+          msg1 = [NSString stringWithFormat: @"%@ %@ %@: ", 
+                           NSLocalizedString(@"Copy", @""), 
+                           items, 
+                           NSLocalizedString(@"from", @"")];
+          msg2 = NSLocalizedString(@"\nto: ", @"");
+          msg = [NSString stringWithFormat: @"%@%@%@%@?", msg1, source, msg2, destination];
+        }
+      else if ([type isEqual: NSWorkspaceLinkOperation])
+        {
+          title = NSLocalizedString(@"Link", @"");
+          msg1 = [NSString stringWithFormat: @"%@ %@ %@: ", 
+                           NSLocalizedString(@"Link", @""), 
+                           items, 
+                           NSLocalizedString(@"from", @"")];
+          msg2 = NSLocalizedString(@"\nto: ", @"");
+          msg = [NSString stringWithFormat: @"%@%@%@%@?", msg1, source, msg2, destination];
+        }
+      else if ([type isEqual: NSWorkspaceRecycleOperation])
+        {
+          title = NSLocalizedString(@"Recycler", @"");
+          msg1 = [NSString stringWithFormat: @"%@ %@ %@: ", 
+                           NSLocalizedString(@"Move", @""), 
+                           items, 
+                           NSLocalizedString(@"from", @"")];
+          msg2 = NSLocalizedString(@"\nto the Recycler", @"");
+          msg = [NSString stringWithFormat: @"%@%@%@?", msg1, source, msg2];
+        }
+      else if ([type isEqual: @"GWorkspaceRecycleOutOperation"])
+        {
+          title = NSLocalizedString(@"Recycler", @"");
+          msg1 = [NSString stringWithFormat: @"%@ %@ %@ ", 
+                           NSLocalizedString(@"Move", @""), 
+                           items, 
+                           NSLocalizedString(@"from the Recycler", @"")];
+          msg2 = NSLocalizedString(@"\nto: ", @"");
+          msg = [NSString stringWithFormat: @"%@%@%@?", msg1, msg2, destination];
+        }
+      else if ([type isEqual: @"GWorkspaceEmptyRecyclerOperation"])
+        {
+          title = NSLocalizedString(@"Recycler", @"");
+          msg = NSLocalizedString(@"Empty the Recycler?", @"");
+        }
+      else if ([type isEqual: NSWorkspaceDestroyOperation])
+        {
+          title = NSLocalizedString(@"Delete", @"");
+          msg = NSLocalizedString(@"Delete the selected objects?", @"");
+        }
+      else if ([type isEqual: NSWorkspaceDuplicateOperation])
+        {
+          title = NSLocalizedString(@"Duplicate", @"");
+          msg = NSLocalizedString(@"Duplicate the selected objects?", @"");
+        }
+      
+      if (NSRunAlertPanel(title, msg, 
+                          NSLocalizedString(@"OK", @""), 
+                          NSLocalizedString(@"Cancel", @""), 
+                          nil) != NSAlertDefaultReturn) {
+        [self endOperation];
+        return;
+      }
     }
-  } 
+  [self detachOperationThread];
+}
 
+-(void)detachOperationThread
+{
+  NSPort *port[2];
+  NSArray *ports;
+
+  NSLog(@"detach operation thread");
   port[0] = (NSPort *)[NSPort port];
   port[1] = (NSPort *)[NSPort port];
-
+  
   ports = [NSArray arrayWithObjects: port[1], port[0], nil];
 
   execconn = [[NSConnection alloc] initWithReceivePort: port[0]
-				                                      sendPort: port[1]];
+                                              sendPort: port[1]];
   [execconn setRootObject: self];
   [execconn setDelegate: self];
   
@@ -281,6 +308,7 @@
       [NSThread detachNewThreadSelector: @selector(setPorts:)
 		                           toTarget: [FileOpExecutor class]
 		                         withObject: ports];
+      NSLog(@"thread detached");
     }
   NS_HANDLER
     {
@@ -317,6 +345,7 @@
 {
   if (paused == NO)
     {
+      NSLog(@"start pause remaining files: %d", [files count]);
       [pauseButt setTitle: NSLocalizedString(@"Continue", @"")];
       [stopButt setEnabled: NO];	
       paused = YES;
@@ -323,10 +352,12 @@
     }
   else
     {
+      NSLog(@"continue from pause");
+      [self detachOperationThread];
       [pauseButt setTitle: NSLocalizedString(@"Pause", @"")];
       [stopButt setEnabled: YES];	
       paused = NO;
-      [executor performOperation];
+      NSLog(@"performing operation....");
     }
 }
 
@@ -335,6 +366,44 @@
   stopped = YES;   
 }
 
+- (void)removeProcessedFiles
+{
+  NSData *pFData;
+  NSArray *pFiles;
+  NSUInteger i;
+
+
+  NSLog(@"removing processed files");
+  pFData = [executor processedFiles];
+  pFiles = [NSUnarchiver unarchiveObjectWithData: pFData];
+
+  NSLog(@"remove files: %@", pFiles);
+  for (i = 0; i < [pFiles count]; i++)
+    {
+      NSDictionary *fi;
+      NSUInteger j;
+      BOOL found;
+
+      j = 0;
+      found = NO;
+      while (j < [files count] && !found)
+        {
+          fi = [files objectAtIndex:j];
+
+          if ([[pFiles objectAtIndex:i] isEqualTo:[fi objectForKey:@"name"]])
+            found = YES;
+          else
+            i++;
+        }
+      if (found)
+        {
+          [procFiles addObject:[files objectAtIndex:j]];
+          [files removeObjectAtIndex:j];
+        }
+    }
+  NSLog(@"removeFile - remaining files... %d", [files count]);
+}
+
 - (void)showProgressWin
 {  
   if ([win isVisible] == NO) {
@@ -410,7 +479,6 @@
   [progInd setMinValue: 0.0];
   [progInd setMaxValue: n];
   [progInd setDoubleValue: 0.0];
-  [executor performOperation]; 
 }
 
 - (void)setProgIndicatorValue:(int)n
@@ -479,9 +547,9 @@
   
   if (executor) {
     NSData *data = [executor processedFiles];
-    NSArray *procFiles = [NSUnarchiver unarchiveObjectWithData: data];
+    NSArray *processedFiles = [NSUnarchiver unarchiveObjectWithData: data];
     
-    [notifObj setObject: procFiles forKey: @"files"];	
+    [notifObj setObject: processedFiles forKey: @"files"];	
     [notifObj setObject: notifNames forKey: @"origfiles"];	
   } else {
     [notifObj setObject: notifNames forKey: @"files"];
@@ -535,12 +603,11 @@
 			title = @"Recycle";
 		}
         
-    result = NSRunAlertPanel(NSLocalizedString(title, @""),
-														 NSLocalizedString(msg, @""),
-														 NSLocalizedString(@"OK", @""), 
-														 NSLocalizedString(@"Cancel", @""), 
-                             NSLocalizedString(@"Only older", @"")); 
-
+      result = NSRunAlertPanel(NSLocalizedString(title, @""),							 NSLocalizedString(msg, @""),
+                               NSLocalizedString(@"OK", @""), 
+                               NSLocalizedString(@"Cancel", @""), 
+                               NSLocalizedString(@"Only older", @"")); 
+      
 		if (result == NSAlertAlternateReturn) {  
       [controller endOfFileOperation: self];
       return;   
@@ -557,7 +624,7 @@
   
   stopped = NO;
   paused = NO;   
-  [executor calculateNumFiles];
+  [executor calculateNumFiles:[procFiles count]];
 }
 
 - (BOOL)connection:(NSConnection*)ancestor 
@@ -652,7 +719,8 @@
   NSPort *port[2];
   NSConnection *conn;
   FileOpExecutor *executor;
-                              
+
+  NSLog(@"set ports start");
   port[0] = [thePorts objectAtIndex: 0];             
   port[1] = [thePorts objectAtIndex: 1];             
 
@@ -662,6 +730,7 @@
   executor = [[self alloc] init];
   [executor setFileop: thePorts];
   [(id)[conn rootProxy] registerExecutor: executor];
+  NSLog(@"setPorts stop");
   RELEASE (executor);
   
   RELEASE (pool);
@@ -788,79 +857,91 @@
   onlyolder = YES;
 }
 
-- (oneway void)calculateNumFiles
+- (oneway void)calculateNumFiles:(NSUInteger)continueFrom
 {
   NSUInteger i;
   NSUInteger fnum = 0;
 
-  for (i = 0; i < [files count]; i++)
+  if (continueFrom == 0)
     {
-      CREATE_AUTORELEASE_POOL (arp);
-      NSDictionary *dict = [files objectAtIndex: i];
-      NSString *name = [dict objectForKey: @"name"]; 
-      NSString *path = [source stringByAppendingPathComponent: name];       
-      BOOL isDir = NO;
-    
-      [fm fileExistsAtPath: path isDirectory: &isDir];
-      
-      if (isDir)
+      NSLog(@"calculating num files");
+      for (i = 0; i < [files count]; i++)
         {
-          NSDirectoryEnumerator *enumerator = [fm enumeratorAtPath: path];
+          CREATE_AUTORELEASE_POOL (arp);
+          NSDictionary *dict = [files objectAtIndex: i];
+          NSString *name = [dict objectForKey: @"name"]; 
+          NSString *path = [source stringByAppendingPathComponent: name];       
+          BOOL isDir = NO;
           
-          while (1)
+          [fm fileExistsAtPath: path isDirectory: &isDir];
+          
+          if (isDir)
             {
-              CREATE_AUTORELEASE_POOL (arp2);
-              NSString *dirEntry = [enumerator nextObject];
+              NSDirectoryEnumerator *enumerator = [fm enumeratorAtPath: path];
               
-              if (dirEntry)
+              while (1)
                 {
-                  if (stopped)
+                  CREATE_AUTORELEASE_POOL (arp2);
+                  NSString *dirEntry = [enumerator nextObject];
+                  
+                  if (dirEntry)
                     {
+                      if (stopped)
+                        {
+                          RELEASE (arp2);
+                          break;
+                        }
+                      fnum++;
+                    }
+                  else
+                    {
                       RELEASE (arp2);
                       break;
                     }
-                  fnum++;
-                }
-              else
-                {
                   RELEASE (arp2);
-                  break;
                 }
-              RELEASE (arp2);
             }
+          else
+            {
+              fnum++;
+            }
+          
+          if (stopped)
+            {
+              RELEASE (arp);
+              break;
+            }
+          RELEASE (arp);
         }
-      else
-        {
-          fnum++;
-        }
       
       if (stopped)
+        [self done];
+      
+      fcount = 0;
+      stepcount = 0;
+      
+      if (fnum < PROGR_STEPS)
         {
-          RELEASE (arp);
-          break;
+          progstep = 1.0;
         }
-      RELEASE (arp);
+      else
+        {
+          progstep = fnum / PROGR_STEPS;
+        }
+      [fileOp setNumFiles: fnum];
     }
-
-  if (stopped)
-    [self done];
-
-  fcount = 0;
-  stepcount = 0;
-  
-  if (fnum < PROGR_STEPS) {
-    progstep = 1.0;
-  } else {
-    progstep = fnum / PROGR_STEPS;
-  }
-  
-  [fileOp setNumFiles: fnum];
+  else
+    {
+      fcount = continueFrom;
+      stepcount = continueFrom;
+    }
+  [self performOperation];
 }
 
 - (oneway void)performOperation
 {
   canupdate = YES; 
-  
+  NSLog(@"performOperation: %@", operation);  
   if ([operation isEqual: NSWorkspaceMoveOperation]
       || [operation isEqual: @"GWorkspaceRecycleOutOperation"])
     {
@@ -954,10 +1035,12 @@
 
 - (void)doCopy
 {
+  NSLog(@"start files... %d", [files count]);
   while (1)
     {
       CHECK_DONE;	
       GET_FILENAME;
+      sleep(1);
       
       if ((samename == NO) || (samename && [self removeExisting: fileinfo]))
         {
@@ -968,7 +1051,8 @@
               [procfiles addObject: filename];	
             }
         }
-      [files removeObject: fileinfo];	
+      [files removeObject: fileinfo];
+      NSLog(@"files... %d", [files count]);
       RELEASE (fileinfo); 
     }
   
@@ -975,7 +1059,12 @@
   if (([files count] == 0) || stopped)
     {
       [self done];
-    }                                          
+    }
+  else if (paused)
+    {
+      NSLog(@"paused, communicating back that we processed: %d", [procfiles count]);
+      [fileOp removeProcessedFiles];
+    }
 }
 
 - (void)doLink
_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@gnu.org
https://lists.gnu.org/mailman/listinfo/gnustep-dev

Reply via email to