<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Cocoa Tutorial: Wiring Undo Management Into Core Data</title>
	<atom:link href="http://www.cimgf.com/2008/04/30/cocoa-tutorial-wiring-undo-management-into-core-data/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cimgf.com/2008/04/30/cocoa-tutorial-wiring-undo-management-into-core-data/</link>
	<description>Taglines are for Windows programmers</description>
	<lastBuildDate>Mon, 26 Jul 2010 16:50:30 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
	<item>
		<title>By: wackazong</title>
		<link>http://www.cimgf.com/2008/04/30/cocoa-tutorial-wiring-undo-management-into-core-data/comment-page-1/#comment-1193</link>
		<dc:creator>wackazong</dc:creator>
		<pubDate>Wed, 22 Apr 2009 14:28:34 +0000</pubDate>
		<guid isPermaLink="false">http://www.cimgf.com/?p=115#comment-1193</guid>
		<description>&lt;p&gt;BTW: Line 15 and 16 of your snippet need to be in reverse order. I think. Otherwise you close the undo group without giving it a name, and give the name to the next undo group on the stack.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>BTW: Line 15 and 16 of your snippet need to be in reverse order. I think. Otherwise you close the undo group without giving it a name, and give the name to the next undo group on the stack.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: wackazong</title>
		<link>http://www.cimgf.com/2008/04/30/cocoa-tutorial-wiring-undo-management-into-core-data/comment-page-1/#comment-1192</link>
		<dc:creator>wackazong</dc:creator>
		<pubDate>Wed, 22 Apr 2009 11:28:47 +0000</pubDate>
		<guid isPermaLink="false">http://www.cimgf.com/?p=115#comment-1192</guid>
		<description>&lt;p&gt;I did the following: Created a NSWindow subclass that handles all that for me. All I have to do is to call it with a NSWindow*, it will open itself attached to that window, start the undo group and react on its own buttons, which are OK and Cancel in the way mentioned above. This way in the controller I can start editing with just one line:&lt;/p&gt;

&lt;p&gt;[code
]#import &lt;/p&gt;

&lt;p&gt;@interface CTCoreDataUndoWindow : NSWindow {&lt;/p&gt;

&lt;p&gt;&lt;pre&gt;&lt;code&gt;NSButton* _okButton;
NSButton* _cancelButton;
id _target;
SEL _ok;
SEL _cancel;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;@property (readwrite, retain) IBOutlet NSButton* okButton;
@property (readwrite, retain) IBOutlet NSButton* cancelButton;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(void)showOnWindow:(NSWindow*)w;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;@end
[/code]&lt;/p&gt;

&lt;p&gt;[code]&lt;/p&gt;

&lt;p&gt;import &quot;CTCoreDataUndoWindow.h&quot;&lt;/p&gt;

&lt;p&gt;@implementation CTCoreDataUndoWindow&lt;/p&gt;

&lt;p&gt;@synthesize okButton = _okButton;
@synthesize cancelButton = _cancelButton;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;(NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window
{
return [self undoManager];
}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(NSUndoManager*)undoManager
{
return [[self.delegate managedObjectContext] undoManager];
}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(void)showOnWindow:(NSWindow*)w
{
[[self undoManager] beginUndoGrouping];
[self.okButton setAction:@selector(okSheet:)];
[self.cancelButton setAction:@selector(cancelSheet:)];
[self.okButton setTarget:self];
[self.cancelButton setTarget:self];
[NSApp beginSheet:self modalForWindow:w modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(void)cancelSheet:(id)sender
{
[[self undoManager] endUndoGrouping];
[[self undoManager] undo];
[self orderOut:self];
[NSApp endSheet:self];
}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(void)okSheet:(id)sender
{
[[self undoManager] endUndoGrouping];
[[self undoManager] setActionName:@&quot;Object edit&quot;];
[self orderOut:self];
[NSApp endSheet:self];
}&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;@end
[/code]&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I did the following: Created a NSWindow subclass that handles all that for me. All I have to do is to call it with a NSWindow*, it will open itself attached to that window, start the undo group and react on its own buttons, which are OK and Cancel in the way mentioned above. This way in the controller I can start editing with just one line:</p>

<p>[code
]#import </p>

<p>@interface CTCoreDataUndoWindow : NSWindow {</p>

<p><pre><code>NSButton* _okButton;
NSButton* _cancelButton;
id _target;
SEL _ok;
SEL _cancel;
</code></pre></p>

<p>}</p>

<p>@property (readwrite, retain) IBOutlet NSButton* okButton;
@property (readwrite, retain) IBOutlet NSButton* cancelButton;</p>

<ul>
<li>(void)showOnWindow:(NSWindow*)w;</li>
</ul>

<p>@end
[/code]</p>

<p>[code]</p>

<p>import "CTCoreDataUndoWindow.h"</p>

<p>@implementation CTCoreDataUndoWindow</p>

<p>@synthesize okButton = _okButton;
@synthesize cancelButton = _cancelButton;</p>

<ul>
<li><p>(NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window
{
return [self undoManager];
}</p></li>
<li><p>(NSUndoManager*)undoManager
{
return [[self.delegate managedObjectContext] undoManager];
}</p></li>
<li><p>(void)showOnWindow:(NSWindow*)w
{
[[self undoManager] beginUndoGrouping];
[self.okButton setAction:@selector(okSheet:)];
[self.cancelButton setAction:@selector(cancelSheet:)];
[self.okButton setTarget:self];
[self.cancelButton setTarget:self];
[NSApp beginSheet:self modalForWindow:w modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
}</p></li>
<li><p>(void)cancelSheet:(id)sender
{
[[self undoManager] endUndoGrouping];
[[self undoManager] undo];
[self orderOut:self];
[NSApp endSheet:self];
}</p></li>
<li><p>(void)okSheet:(id)sender
{
[[self undoManager] endUndoGrouping];
[[self undoManager] setActionName:@"Object edit"];
[self orderOut:self];
[NSApp endSheet:self];
}</p></li>
</ul>

<p>@end
[/code]</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Marcus Zarra</title>
		<link>http://www.cimgf.com/2008/04/30/cocoa-tutorial-wiring-undo-management-into-core-data/comment-page-1/#comment-606</link>
		<dc:creator>Marcus Zarra</dc:creator>
		<pubDate>Thu, 22 May 2008 03:14:01 +0000</pubDate>
		<guid isPermaLink="false">http://www.cimgf.com/?p=115#comment-606</guid>
		<description>&lt;p&gt;As I have said before, just because Apple does it, does not mean it is the best solution or even a good solution.  This is especially true of their tutorials as opposed to running code.&lt;/p&gt;

&lt;p&gt;There is always more than one way to solve an issue.  As I said before I would not recommend yours as an optimal solution.  Perhaps if your context is small it would be light enough to use but I would certainly not do it that way.&lt;/p&gt;

&lt;p&gt;If it works for you then great â€” Enjoy it!&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>As I have said before, just because Apple does it, does not mean it is the best solution or even a good solution.  This is especially true of their tutorials as opposed to running code.</p>

<p>There is always more than one way to solve an issue.  As I said before I would not recommend yours as an optimal solution.  Perhaps if your context is small it would be light enough to use but I would certainly not do it that way.</p>

<p>If it works for you then great â€” Enjoy it!</p>]]></content:encoded>
	</item>
	<item>
		<title>By: mj1531</title>
		<link>http://www.cimgf.com/2008/04/30/cocoa-tutorial-wiring-undo-management-into-core-data/comment-page-1/#comment-605</link>
		<dc:creator>mj1531</dc:creator>
		<pubDate>Wed, 21 May 2008 23:22:06 +0000</pubDate>
		<guid isPermaLink="false">http://www.cimgf.com/?p=115#comment-605</guid>
		<description>&lt;p&gt;You don&#039;t have to copy all your managed objects to the sheet&#039;s context, just the one your editing.  Actually, I found a similar approach is given in the NSPersistentDocument Tutorial:&lt;/p&gt;

&lt;p&gt;http://developer.apple.com/documentation/Cocoa/Conceptual/NSPersistentDocumentTutorial/08_CreationSheet/chapter_9_section_1.html#//apple_ref/doc/uid/TP40001799-CH284-SW2&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>You don&#8217;t have to copy all your managed objects to the sheet&#8217;s context, just the one your editing.  Actually, I found a similar approach is given in the NSPersistentDocument Tutorial:</p>

<p><a href="http://developer.apple.com/documentation/Cocoa/Conceptual/NSPersistentDocumentTutorial/08_CreationSheet/chapter_9_section_1.html#//apple_ref/doc/uid/TP40001799-CH284-SW2" rel="nofollow">http://developer.apple.com/documentation/Cocoa/Conceptual/NSPersistentDocumentTutorial/08_CreationSheet/chapter_9_section_1.html#//apple_ref/doc/uid/TP40001799-CH284-SW2</a></p>]]></content:encoded>
	</item>
	<item>
		<title>By: Marcus Zarra</title>
		<link>http://www.cimgf.com/2008/04/30/cocoa-tutorial-wiring-undo-management-into-core-data/comment-page-1/#comment-604</link>
		<dc:creator>Marcus Zarra</dc:creator>
		<pubDate>Wed, 21 May 2008 00:38:56 +0000</pubDate>
		<guid isPermaLink="false">http://www.cimgf.com/?p=115#comment-604</guid>
		<description>&lt;p&gt;As a general rule I would not recommend your solution.  Also, disabiling undo management for editable sheets kind of defeats the purpose of having an undo manager in the first place.  Without an undo manager the developer would need to track all of the changes in the sheet manually so that if the user hits cancel the developer can back everything out.&lt;/p&gt;

&lt;p&gt;If the possibility of a redo is that much of an issue I would recommend creating an independent undo manager for the sheet that tracks all of the changes in that sheet.  Much cheaper than copying all of the managed objects and since the sheet is destroyed upon completion there is no chance of the redo issue.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>As a general rule I would not recommend your solution.  Also, disabiling undo management for editable sheets kind of defeats the purpose of having an undo manager in the first place.  Without an undo manager the developer would need to track all of the changes in the sheet manually so that if the user hits cancel the developer can back everything out.</p>

<p>If the possibility of a redo is that much of an issue I would recommend creating an independent undo manager for the sheet that tracks all of the changes in that sheet.  Much cheaper than copying all of the managed objects and since the sheet is destroyed upon completion there is no chance of the redo issue.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: mj1531</title>
		<link>http://www.cimgf.com/2008/04/30/cocoa-tutorial-wiring-undo-management-into-core-data/comment-page-1/#comment-603</link>
		<dc:creator>mj1531</dc:creator>
		<pubDate>Wed, 21 May 2008 00:14:55 +0000</pubDate>
		<guid isPermaLink="false">http://www.cimgf.com/?p=115#comment-603</guid>
		<description>&lt;p&gt;Actually, it&#039;s not that bad for my object model.  I created a category on NSManagedObjectContext in my app for copying model objects between contexts.&lt;/p&gt;

&lt;p&gt;There&#039;s also the easier option that if you don&#039;t want undo support in the sheet, you can disable undo registration while the sheet is running and re-enable it after the user dismisses it.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Actually, it&#8217;s not that bad for my object model.  I created a category on NSManagedObjectContext in my app for copying model objects between contexts.</p>

<p>There&#8217;s also the easier option that if you don&#8217;t want undo support in the sheet, you can disable undo registration while the sheet is running and re-enable it after the user dismisses it.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Marcus Zarra</title>
		<link>http://www.cimgf.com/2008/04/30/cocoa-tutorial-wiring-undo-management-into-core-data/comment-page-1/#comment-602</link>
		<dc:creator>Marcus Zarra</dc:creator>
		<pubDate>Tue, 20 May 2008 22:32:36 +0000</pubDate>
		<guid isPermaLink="false">http://www.cimgf.com/?p=115#comment-602</guid>
		<description>&lt;p&gt;Sounds like you are creating a bigger headache than you are solving!&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Sounds like you are creating a bigger headache than you are solving!</p>]]></content:encoded>
	</item>
	<item>
		<title>By: mj1531</title>
		<link>http://www.cimgf.com/2008/04/30/cocoa-tutorial-wiring-undo-management-into-core-data/comment-page-1/#comment-601</link>
		<dc:creator>mj1531</dc:creator>
		<pubDate>Tue, 20 May 2008 21:25:15 +0000</pubDate>
		<guid isPermaLink="false">http://www.cimgf.com/?p=115#comment-601</guid>
		<description>&lt;p&gt;When you cancel the sheet using the sample code you provided, that last undo will push the undone changes to the undo manager&#039;s redo stack and thus enable the Redo menu item in the application.&lt;/p&gt;

&lt;p&gt;This would allow the user to redo the changes in the sheet without bringing it back up if you are using the same NSManagedObjectContext for the sheet and the document window.  Unfortunately, NSUndoManager doesn&#039;t have a method for removing only the top item from either stack.&lt;/p&gt;

&lt;p&gt;What I usually end up doing is to create a new NSManagedObjectContext for the sheet (which involves non-trivial copying of the edited managed object to and from the 2 contexts).  It&#039;s non-trivial because you have to think about what copying means to relationships in your object model and there&#039;s also the whole thing about NSManagedObjectIDs not being fetchable from another context if they are temporary in the first context.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>When you cancel the sheet using the sample code you provided, that last undo will push the undone changes to the undo manager&#8217;s redo stack and thus enable the Redo menu item in the application.</p>

<p>This would allow the user to redo the changes in the sheet without bringing it back up if you are using the same NSManagedObjectContext for the sheet and the document window.  Unfortunately, NSUndoManager doesn&#8217;t have a method for removing only the top item from either stack.</p>

<p>What I usually end up doing is to create a new NSManagedObjectContext for the sheet (which involves non-trivial copying of the edited managed object to and from the 2 contexts).  It&#8217;s non-trivial because you have to think about what copying means to relationships in your object model and there&#8217;s also the whole thing about NSManagedObjectIDs not being fetchable from another context if they are temporary in the first context.</p>]]></content:encoded>
	</item>
</channel>
</rss>
