Search Results

Search found 10 results on 1 pages for 'nsundomanager'.

Page 1/1 | 1 

  • NSUndoManager with Core Data - Redo not working

    - by CJ
    I have a Core Data document-based app which support undo/redo via the built-in NSUndoManager associated with the NSManagedObjectContext. I have a few actions set up which perform numerous tasks within Core Data, wrap all these tasks into an undo group via beginUndoGrouping/endUndoGrouping, and are processed by the NSUndoManager. Undo works fine. I can perform several successive actions, and each then undo each one of them successively and my app's state is maintained correctly. However, the "Redo" menu item is never enabled. This means that the NSUndoManager is telling the menu that there are no items to redo. I am wondering why the NSUndoManager is seemingly forgetting about items once they are undone, and not allowing redos to occur? One thing I should mention is that I'm disabling undo registration after a document is opened/created. When I perform an action, I call enableUndoRegistration, beginUndoGrouping, perform the action, then call processPendingChanges, setActionName:, endUndoGrouping, and finally disableUndoRegistration. This makes sure that only specific actions are undoable, and any other data changes I make outside of these go unnoticed to the NSUndoManager. This may be a part of the issue, but if so I'm wondering why it's affecting redo? Thanks in advance.

    Read the article

  • NSUndoManager, Core Data and selective undo/redo

    - by Combat
    I'm working on a core data application that has a rather large hierarchy of managed objects similar to a tree. When a base object is created, it creates a few child objects which in turn create their own child objects and so on. Each of these child objects may gather information using NSURLConnections. Now, I'd like to support undo/redo with the undoManager in the managedObjectContext. The problem is, if a user creates a base object, then tries to undo that action, the base object is not removed. Instead, one or more of the child objects may be removed. Obviously this type of action is unpredictable and unwanted. So I tried disabling undo registration by default. I did this by calling disableUndoRegistration: before anything is modified in the managedObjectContext. Then, enabling undo registration before base operations such as creating a base object the again re-disabling registrations afterwords. Now when i try to undo, I get this error: undo: NSUndoManager 0x1026428b0 is in invalid state, undo was called with too many nested undo groups Thoughts?

    Read the article

  • How can I make NSUndoManager's undo/redo action names work properly?

    - by Gabe
    I'm learning Cocoa, and I've gotten undo to work without much trouble. But the setActionName: method is puzzling me. Here's a simple example: a toy app whose windows contain a single text label and two buttons. Press the On button and the label reads 'On'. Press the Off button and the label changes to read 'Off'. Here are the two relevant methods (the only code I wrote for the app): -(IBAction) turnOnLabel:(id)sender { [[self undoManager] registerUndoWithTarget:self selector:@selector(turnOffLabel:) object:self]; [[self undoManager] setActionName:@"Turn On Label"]; [theLabel setStringValue:@"On"]; } -(IBAction) turnOffLabel:(id)sender { [[self undoManager] registerUndoWithTarget:self selector:@selector(turnOnLabel:) object:self]; [[self undoManager] setActionName:@"Turn Off Label"]; [theLabel setStringValue:@"Off"]; } Here's what I expect: I click the On button The label changes to say 'On' In the Edit menu is the item 'Undo Turn On Label' I click that menu item The label changes to say 'Off' In the Edit menu is the item 'Redo Turn On Label' In fact, all these things work as I expect apart from the last one. The item in the Edit menu reads 'Redo Turn Off Label', not 'Redo Turn On Label'. (When I click that menu item, the label does turn to On, as I'd expect, but this makes the menu item's name even more of a mystery. What am i misunderstanding, and how can I get these menu items to display the way I want them to?

    Read the article

  • NSUndoManager grouping problem?

    - by anonymous
    I'm working on a barebones drawing app. I'm attempting to implement undo/redo capability, so I tell the view's undoManager to save the current image before updating the display. This works perfectly (yes, I understand that redrawing/saving the entire view is not incredibly efficient, but to solve this problem before attempting to optimize the code). However, as expected, when I 'undo' or 'redo', only the minute change is reflected. My goal is to have the whole finger stroke undone/redone. To do that, I told the undoManager to [beginUndoGrouping] in the [touchesBegan] method, and to [endUndoGrouping] in [touchesEnded]. That works for a bit, but after drawing a few strokes, the app crashes, and gdb exits with exc_bad_access. I'm very grateful for any insight you can give me. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { mouseDragged = YES; currentPoint = [[touches anyObject] locationInView:self]; UIGraphicsBeginImageContext(drawingImageView.bounds.size); [drawingImageView.image drawInRect:drawingImageView.bounds]; CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSetLineCap(ctx, kCGLineCapRound); CGContextSetLineWidth(ctx, drawingWidth); [drawingColor setStroke]; CGContextBeginPath(ctx); CGContextMoveToPoint(ctx, previousPoint.x, previousPoint.y); CGContextAddLineToPoint(ctx, currentPoint.x, currentPoint.y); CGContextStrokePath(ctx); [self.undoManager registerUndoWithTarget:drawingImageView selector:@selector(setImage:) object:drawingImageView.image]; drawingImageView.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); previousPoint = currentPoint; }

    Read the article

  • NSUndoManager won't undo editing of a NSMutableDictionary

    - by xon1c
    Hi, I'm experiencing problems with the undo operation. The following code won't undo an removeObjectForKey: operation but the redo operation setObject:ForKey: works. - (void) insertIntoDictionary:(NSBezierPath *)thePath { [[[window undoManager] prepareWithInvocationTarget:self] removeFromDictionary:thePath]; if(![[window undoManager] isUndoing]) [[window undoManager] setActionName:@"Save Path"]; NSLog(@"Object id is: %d and Key id is: %d", [currentPath objectAtIndex:0], thePath); [colorsForPaths setObject:[currentPath objectAtIndex:0] forKey:thePath]; } - (void) removeFromDictionary:(NSBezierPath *)thePath { [[[window undoManager] prepareWithInvocationTarget:self] insertIntoDictionary:thePath]; if(![[window undoManager] isUndoing]) [[window undoManager] setActionName:@"Delete Path"]; NSLog(@"Object id is: %d and Key id is: %d", [[colorsForPaths allKeys] objectAtIndex:0], thePath); [colorsForPaths removeObjectForKey:thePath]; } The output on the console looks like: // Before setObject:ForKey: Object id is: 1184384 and Key id is: 1530016 // Before removeObjectForKey: UNDO Object id is: 2413664 and Key id is: 1530016 I don't get why the Object id is different although the Key id remains the same. Is there some special undo/redo handling of NSMutableDictionary objects? thx xonic

    Read the article

  • Multiple undo managers for a text view

    - by Rui Pacheco
    Hi, I've a text view that gets its content from an attributed string stored in a model object. I list several of these model objects in a drawer and when the user clicks on one the text view swaps its content. I now need to also swap the undo manager for the text view. I initialise an undo manager on my model object and use undoManagerForTextView to return it to the text view, but something's not quite right. Strategically placed logging statements show me that everything's working as planned: on startup a new model object is initialised correctly and a non-null undo manager is always pulled by the text view. But when it comes to actually doing undo, I just can't get the behaviour I want. I open a window, type something and press cmd+z, and undo works. I open a window, type something, select a new model on the table, type something, go back to the first model and try to undo and all I get is a beep. Something on the documentation made me raise an eyebrow, as it would mean that I can't have undo with several model objects: The default undo and redo behavior applies to text fields and text in cells as long as the field or cell is the first responder (that is, the focus of keyboard actions). Once the insertion point leaves the field or cell, prior operations cannot be undone.

    Read the article

  • NSManagedObject relationship undo

    - by Reflog
    I have a NSManagedObject ObjA that has a many-to-many relationship with another NSManagedObject ObjB. I initialize it with [NSEntityDescription insertNewObjectForEntityForName:@"ObjA" inManagedObjectContext:app.context]; When I perform undo without performing save - the object is not added to the persistent store. But - when I add an item to the collection inside ObjA and then perform undo - the ObjA is not added, but ObjB is not, it's still lingering in the persisten store for some reason. Any ideas what am I doing wrong?

    Read the article

  • Handling undo and edit flag on window with several model objects

    - by Rui Pacheco
    Hi, I've a window that will hold several instances of a model object, listed in a table. The model object is updated using a text view. What is the best way to keep the edit flag and undo manager in synch with the content of the different model objects? I'm thinking creating an instance of the undo manager on the model object and manually set the undo manager for the text view every time the user choses a new model object. Does the undo manager also handle the edited flag?

    Read the article

  • Why doesn't the undo/redo panel appear when I start a shake gesture in iPhone Simulator?

    - by dontWatchMyProfile
    I've created an NSUndoManager for the Managed Object Context of Core Data, like this: NSUndoManager *undoManager = [[NSUndoManager alloc] init]; [undoManager setLevelsOfUndo:10]; [managedObjectContext setUndoManager:undoManager]; [undoManager release]; In the app delegate where the didFinishLaunching method is called, I did this: application.applicationSupportsShakeToEdit = YES; For some reason, I never get that undo/redo panel when I make a shake gesture in iPhone Simulator (from the menu). Must I enable undo/redo somewhere else, maybe in the Info.plist file?

    Read the article

  • Migrating Core Data to new UIManagedDocument in iOS 5

    - by samerpaul
    I have an app that has been on the store since iOS 3.1, so there is a large install base out there that still uses Core Data loaded up in my AppDelegate. In the most recent set of updates, I raised the minimum version to 4.3 but still kept the same way of loading the data. Recently, I decided it's time to make the minimum version 5.1 (especially with 6 around the corner), so I wanted to start using the new fancy UIManagedDocument way of using Core Data. The issue with this though is that the old database file is still sitting in the iOS app, so there is no migrating to the new document. You have to basically subclass UIManagedDocument with a new model class, and override a couple of methods to do it for you. Here's a tutorial on what I did for my app TimeTag.  Step One: Add a new class file in Xcode and subclass "UIManagedDocument" Go ahead and also add a method to get the managedObjectModel out of this class. It should look like:   @interface TimeTagModel : UIManagedDocument   - (NSManagedObjectModel *)managedObjectModel;   @end   Step two: Writing the methods in the implementation file (.m) I first added a shortcut method for the applicationsDocumentDirectory, which returns the URL of the app directory.  - (NSURL *)applicationDocumentsDirectory {     return [[[NSFileManagerdefaultManager] URLsForDirectory:NSDocumentDirectoryinDomains:NSUserDomainMask] lastObject]; }   The next step was to pull the managedObjectModel file itself (.momd file). In my project, it's called "minimalTime". - (NSManagedObjectModel *)managedObjectModel {     NSString *path = [[NSBundlemainBundle] pathForResource:@"minimalTime"ofType:@"momd"];     NSURL *momURL = [NSURL fileURLWithPath:path];     NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];          return managedObjectModel; }   After that, I need to check for a legacy installation and migrate it to the new UIManagedDocument file instead. This is the overridden method: - (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)storeURL ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError **)error {     // If legacy store exists, copy it to the new location     NSURL *legacyPersistentStoreURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"minimalTime.sqlite"];          NSFileManager* fileManager = [NSFileManagerdefaultManager];     if ([fileManager fileExistsAtPath:legacyPersistentStoreURL.path])     {         NSLog(@"Old db exists");         NSError* thisError = nil;         [fileManager replaceItemAtURL:storeURL withItemAtURL:legacyPersistentStoreURL backupItemName:niloptions:NSFileManagerItemReplacementUsingNewMetadataOnlyresultingItemURL:nilerror:&thisError];     }          return [superconfigurePersistentStoreCoordinatorForURL:storeURL ofType:fileType modelConfiguration:configuration storeOptions:storeOptions error:error]; }   Basically what's happening above is that it checks for the minimalTime.sqlite file inside the app's bundle on the iOS device.  If the file exists, it tells you inside the console, and then tells the fileManager to replace the storeURL (inside the method parameter) with the legacy URL. This basically gives your app access to all the existing data the user has generated (otherwise they would load into a blank app, which would be disastrous). It returns a YES if successful (by calling it's [super] method). Final step: Actually load this database Due to how my app works, I actually have to load the database at launch (instead of shortly after, which would be ideal). I call a method called loadDatabase, which looks like this: -(void)loadDatabase {     static dispatch_once_t onceToken;          // Only do this once!     dispatch_once(&onceToken, ^{         // Get the URL         // The minimalTimeDB name is just something I call it         NSURL *url = [[selfapplicationDocumentsDirectory] URLByAppendingPathComponent:@"minimalTimeDB"];         // Init the TimeTagModel (our custom class we wrote above) with the URL         self.timeTagDB = [[TimeTagModel alloc] initWithFileURL:url];           // Setup the undo manager if it's nil         if (self.timeTagDB.undoManager == nil){             NSUndoManager *undoManager = [[NSUndoManager  alloc] init];             [self.timeTagDB setUndoManager:undoManager];         }                  // You have to actually check to see if it exists already (for some reason you can't just call "open it, and if it's not there, create it")         if ([[NSFileManagerdefaultManager] fileExistsAtPath:[url path]]) {             // If it does exist, try to open it, and if it doesn't open, let the user (or at least you) know!             [self.timeTagDB openWithCompletionHandler:^(BOOL success){                 if (!success) {                     // Handle the error.                     NSLog(@"Error opening up the database");                 }                 else{                     NSLog(@"Opened the file--it already existed");                     [self refreshData];                 }             }];         }         else {             // If it doesn't exist, you need to attempt to create it             [self.timeTagDBsaveToURL:url forSaveOperation:UIDocumentSaveForCreatingcompletionHandler:^(BOOL success){                 if (!success) {                     // Handle the error.                     NSLog(@"Error opening up the database");                 }                 else{                     NSLog(@"Created the file--it did not exist");                     [self refreshData];                 }             }];         }     }); }   If you're curious what refreshData looks like, it sends out a NSNotification that the database has been loaded: -(void)refreshData {     NSNotification* refreshNotification = [NSNotificationnotificationWithName:kNotificationCenterRefreshAllDatabaseData object:self.timeTagDB.managedObjectContext  userInfo:nil];     [[NSNotificationCenter defaultCenter] postNotification:refreshNotification];     }   The kNotificationCenterRefreshAllDatabaseData is just a constant I have defined elsewhere that keeps track of all the NSNotification names I use. I pass the managedObjectContext of the newly created file so that my view controllers can have access to it, and start passing it around to one another. The reason we do this as a Notification is because this is being run in the background, so we can't know exactly when it finishes. Make sure you design your app for this! Have some kind of loading indicator, or make sure your user can't attempt to create a record before the database actually exists, because it will crash the app.

    Read the article

1