2

I have a window with multiple views (they all subclass NSView and there is always only one visible) on which i draw paths. I'd like to have an NSUndoManager for each view, but obviously they all have the same NSUndoManager, coming from the NSWindow.

Is this even possible?

Thx xonic

xon1c
  • 423
  • 5
  • 12

2 Answers2

2

Check out the NSWindowDelegate method windowWillReturnUndoManager:. You should be able to use this to return the correct undo manager for the current view.

Alex
  • 26,829
  • 3
  • 55
  • 74
  • 1
    Thanks for your reply. From the docs I understand that I can advise th delegate that the undo manager has been requested and if the delegate doesn't implement windowWillReturnUndomanager, then a new undo manager will be created for the window. Still I can't see how this can be useful for me. I need a different undo manager for each view in my window, not one for all. Is there something I just don't get? – xon1c Jul 25 '10 at 21:20
  • I don't think the undo manager is cached, so `windowWillReturnUndoManager:` should be called quite frequently, giving you an opportunity to return the "current" undo manager. – Alex Jul 25 '10 at 21:39
0

// This works for me on a NSTableView subclass with two different data sources and undo managers (in a document window)

- (void)awakeFromNib
{
    _undoManager1 = [NSUndoManager new];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(undoManagerNotification:) name:NSUndoManagerDidCloseUndoGroupNotification object:_undoManager1];
    _undoManager2 = [NSUndoManager new];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(undoManagerNotification:) name:NSUndoManagerDidCloseUndoGroupNotification object:_undoManager2];
}

- (NSDocument *)document
{
    return [NSDocumentController.sharedDocumentController documentForWindow:self.window];
}

- (void)undoManagerNotification:(NSNotification *)note
{
    // NSUndoManagerDidCloseUndoGroupNotification: we made a change
    [self.document updateChangeCount:NSChangeDone];
}

- (NSUndoManager *)undoManager
{
    if ( self.window.firstResponder != self )
        return self.window.firstResponder.undoManager;

    // returns the right undo manager depending on current data source  
    return dataSource == dataSource1 ? _undoManager1 : _undoManager2;
}

- (IBAction)undo:(id)sender
{
    [self.undoManager undo];
    [self.document updateChangeCount:NSChangeUndone];
}

- (IBAction)redo:(id)sender
{
    [self.undoManager redo];
    [self.document updateChangeCount:NSChangeDone];
}

- (void)setValue:(id)newValue
{
    [[self.undoManager prepareWithInvocationTarget:self] setValue:_myValue]; // NSUndoManager will post the NSUndoManagerDidCloseUndoGroupNotification
    _myValue = newValue;
}

- (IBAction)doChangeSomeValue:(id)sender
{
    [self setValue:someValue];
}
mixage
  • 1
  • 1