Maybe spoke too soon, as so far I’ve been unsuccessful in getting this to work 
as I wish. My code does perform the series of undos, but I can’t see the 
results until the end - the window isn’t refreshed on each pass of the runloop 
as I expected.

Here’s my code:

- (BOOL)                performUndoUntilGroup:(GCUndoGroup*) desiredTopOfStack
{
        // check if there's anything to do:
        
        if( self.undoManager.canUndo && self.undoManager.peekUndo != 
desiredTopOfStack )
        {
                // set up timer to repeatedly invoke Undo
                
                NSTimer* timer = [NSTimer 
timerWithTimeInterval:kMDABUndoHistoryUndoInvocationRate 
target:self.undoManager selector:@selector(undo) userInfo:NULL repeats:YES];
                [[NSRunLoop mainRunLoop] addTimer:timer 
forMode:MDABUndoHistoryRunLoopMode];
                
                // run loop in special custom mode until finished or times out 
(allow twice the scheduled time to finish)
                
                NSDate* maxEndDate = [NSDate distantPast];//[NSDate 
dateWithTimeIntervalSinceNow:self.undoManager.numberOfUndoActions * 
kMDABUndoHistoryUndoInvocationRate * 2];
                
                while( self.undoManager.canUndo && self.undoManager.peekUndo != 
desiredTopOfStack )
                {
                        [[NSRunLoop mainRunLoop] 
runMode:MDABUndoHistoryRunLoopMode beforeDate:maxEndDate];
                        [self.view.window displayIfNeeded];
                }
                
                // get rid of timer
                
                [timer invalidate];
                
                return YES;
        }
        return NO;
}



The ‘self.undoManager’ is not NSUndoManager but GCUndoManager, which has some 
methods that differ from NSUndoManager that make this possible - that all 
works, and is not important here. 

As you can see I’ve experimented with the end date, but seems that -distantPast 
works well enough. I’ve also tried forcing a window redisplay on each pass (as 
here) but it doesn’t appear to do anything; my understanding was that the 
runloop should take care of this anyway.

What am I missing?


—Graham






> On 21 May 2016, at 12:14 PM, Graham Cox <graham....@bigpond.com> wrote:
> 
> Great, thanks! Perfect answer,actually...
> 
> 
> —Graham
> 
> 
>> On 21 May 2016, at 1:00 AM, Jens Alfke <j...@mooseyard.com> wrote:
>> 
>> 
>>> On May 20, 2016, at 12:58 AM, Graham Cox <graham....@bigpond.com> wrote:
>>> 
>>> First question: does that even sound like a proper use for a custom 
>>> run-loop mode?
>> 
>> Yes.
>> 
>>> If the answer is yes, how do I cause the run loop to run in that mode? Do I 
>>> have to run the loop mysef until the operation is done?
>> 
>> Yes, use a `while` loop that calls -runMode:beforeDate: repeatedly until all 
>> of the actions are done.
>> 
>> —Jens
> 
> 
> _______________________________________________
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/graham.cox%40bigpond.com
> 
> This email sent to graham....@bigpond.com


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to