Re: NSTableView updating checkboxes
Hi Michael and Graham, Thank you both for your replies and time...sorry for my delay. You have been most helpful and even though I'm still working on it I believe you have given me enough info and understanding to get it to do what I need. There might be some issues with other parts of my code as well so I'm trying to clean it all up so that my Table View will be ok. I have flagged your messages for reference and I'll let you know how it works out...and I very much appreciate the help! :-) Sincerely, Rick From: Michael Vannorsdel mikev...@gmail.com To: Jo Phils jo_p...@yahoo.com Sent: Monday, March 23, 2009 10:35:31 AM Subject: Re: NSTableView updating checkboxes Just remember that every time the table view redisplays itself (for whatever reason), it will rebuild the list by asking the data source again how many rows there are by calling numberOfRowsInTableView:, then it will ask the value of each column of each row (that's visible) with tableView:objectValueForTableColumn:row:. For checkboxes you return NSNumbers with NSOnState or NSOffState. For text boxes you'd return NSStrings and image boxes NSImages. When the user edits a row and column (by checking or unchecking a box, changing text), tableView:setObjectValue:forTableColumn:row: of your data source is called with the objectValue being a new NSNumber for checkboxes with the new state, or a new NSString for the new text, ect. So you update your array with the new updated value. To initialize default values do it in the data source's init method. And whenever you change the contents of your data source always call the table view's reloadData method to let it know it needs to redisplay (and rebuild) itself at the soonest opportunity. On Mar 22, 2009, at 7:21 PM, Jo Phils wrote: Thank you Andrew (and Graham), I think i'm finally realizing that! :-) Thank you very much. Ok I still don't have it yet but it's back to work for me and hopefully the next time I post back I'll finally have it... :-) ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSTableView updating checkboxes
On 23/03/2009, at 12:21 PM, Jo Phils wrote: Thank you Andrew (and Graham), I think i'm finally realizing that! :-) Thank you very much. Ok I still don't have it yet but it's back to work for me and hopefully the next time I post back I'll finally have it... :-) Thanks again, Rick Hi Rick, I'm away on a trip right now so I have limited eMail access - but briefly make sure you implement BOTH methods I outlined, not just the second. It checks for membership of the set so manages the checkbox state as needed. If you leave in your call to always set NSOnState, well, that's what you'll get. --Graham ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSTableView updating checkboxes
On 21 Mar 09, at 04:04, Jo Phils wrote: I have taken some time to work on your suggestions...unfortunately I still can't figure out how to uncheck/recheck the checkboxes by clicking on them. :-( I understand what you're telling me about keeping 2 lists and ultimately I will get to the point where I have to do something with the items being displayed in my table. But for now I'm still stuck on the checkboxes... Right now, the method you've got coded: - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { if ([[aTableColumn identifier] isEqualToString:@column2]) { return [NSNumber numberWithInt:NSOnState]; //initializes checkbox column with boxes all checked } return [filenames objectAtIndex:rowIndex]; tells the table that every row is always checked. This method doesn't initialize the table - the table doesn't keep track of anything itself, it just asks your data source what to display. ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSTableView updating checkboxes
Thank you Andrew (and Graham), I think i'm finally realizing that! :-) Thank you very much. Ok I still don't have it yet but it's back to work for me and hopefully the next time I post back I'll finally have it... :-) Thanks again, Rick From: Andrew Farmer andf...@gmail.com To: Jo Phils jo_p...@yahoo.com Cc: Graham Cox graham@bigpond.com; cocoa-dev@lists.apple.com Sent: Sunday, March 22, 2009 3:45:12 PM Subject: Re: NSTableView updating checkboxes On 21 Mar 09, at 04:04, Jo Phils wrote: I have taken some time to work on your suggestions...unfortunately I still can't figure out how to uncheck/recheck the checkboxes by clicking on them. :-( I understand what you're telling me about keeping 2 lists and ultimately I will get to the point where I have to do something with the items being displayed in my table. But for now I'm still stuck on the checkboxes... Right now, the method you've got coded: - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { if ([[aTableColumn identifier] isEqualToString:@column2]) { return [NSNumber numberWithInt:NSOnState]; //initializes checkbox column with boxes all checked } return [filenames objectAtIndex:rowIndex]; tells the table that every row is always checked. This method doesn't initialize the table - the table doesn't keep track of anything itself, it just asks your data source what to display. ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSTableView updating checkboxes
Hi again Graham, I have taken some time to work on your suggestions...unfortunately I still can't figure out how to uncheck/recheck the checkboxes by clicking on them. :-( I understand what you're telling me about keeping 2 lists and ultimately I will get to the point where I have to do something with the items being displayed in my table. But for now I'm still stuck on the checkboxes. This was your last example code with my own variables/comments: - (void)tableView:(NSTableView*) tv setObjectValue:(id) val forTableColumn:(NSTableColumn*) aTableColumn row:(NSInteger) rowIndex { id object = [filenames objectAtIndex:rowIndex]; //filenames is my NSArray of filenames if([[aTableColumn identifier] isEqualToString:@column2]) //column2 is the identifier for my checkbox column { BOOL selected = [val boolValue]; // add or remove the object from the selection set if( selected ) //how can I uncheck the checkbox??? every method i'm trying fails... [self addToSelection:object]; else //how can I recheck the checkbox??? every method i'm trying fails... [self removeFromSelection:object]; } } In this method it's so easy: - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { if ([[aTableColumn identifier] isEqualToString:@column2]) { return [NSNumber numberWithInt:NSOnState]; //initializes checkbox column with boxes all checked } return [filenames objectAtIndex:rowIndex]; There's one more thing...in your first email you said I needed to set something in IB and at this point the only thing I have set is the column identifier for this checkbox column (column2). If there is something else I need to set in IB I'm not sure where to set it? I'm not using bindings at this time... Thank you for your patience Graham. Ultimately I would have my list of files in the first column and this would not change. Then checkboxes in the second column which would start all checked. Then the user could uncheck/recheck any boxes they choose and when it comes to processing time only the files that have a checked box will be acted upon. I might be going about it the wrong way but I was just trying to get the checkbox issue working first...thanks again! Rick From: Jo Phils jo_p...@yahoo.com To: Graham Cox graham@bigpond.com Cc: cocoa-dev@lists.apple.com Sent: Friday, March 20, 2009 11:19:46 PM Subject: Re: NSTableView updating checkboxes Thank you again Graham so much for the quick reply. Yes you're right about where I'm headed. I was just thinking that I could code it that when you click on the checkboxes the state would toggle then when I got to the processing step I would simply read the state and know how to process each item in my array. But I see what you're saying yes at this point I have no set boolean state in my array. I was able to initialize my table view with checked boxes by returning the ON state but in this method I got stuck because the return is void and that's where my problem was. Ok I will work on your suggestion and I really do appreciate all of the help... :-) I'll let you know, Rick From: Graham Cox graham@bigpond.com To: Jo Phils jo_p...@yahoo.com Cc: cocoa-dev@lists.apple.com Sent: Friday, March 20, 2009 8:56:23 PM Subject: Re: NSTableView updating checkboxes On 20/03/2009, at 8:53 PM, Jo Phils wrote: Hi Graham and thank you very much for your reply. I think I'm still a bit confused I do apologize. :-( Here's my code so far so you can see... - (int)numberOfRowsInTableView:(NSTableView *)aTableView { return [filenames count]; } - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { if ([[aTableColumn identifier] isEqualToString:@column2]) { return [NSNumber numberWithInt:NSOnState]; } return [filenames objectAtIndex:rowIndex]; - (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { // This is where I'm stuck! } And in this code I am using my variable which is a list of filenames... NSMutableArray *filenames; Other than the connections I have in IB I have given this column of checkboxes the Identifier column2 in IB. I have not set any other property key like you mentioned and I'm not sure where I would do that? I'm not using bindings in my case...I was under the impression it was not necessary? The first 2 methods seem to work fine and the 3rd method is being called but it's just I couldn't figure out the code to change the state of the checkboxes... Thank you again so much for your help, Well, I guess what isn't clear is what
Re: NSTableView updating checkboxes
Hi Graham and thank you very much for your reply. I think I'm still a bit confused I do apologize. :-( Here's my code so far so you can see... - (int)numberOfRowsInTableView:(NSTableView *)aTableView { return[filenamescount]; } - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { if([[aTableColumn identifier] isEqualToString:@column2]) { return[NSNumbernumberWithInt:NSOnState]; } return [filenames objectAtIndex:rowIndex]; - (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { // This is where I'm stuck! } And in this code I am using my variable which is a list of filenames... NSMutableArray*filenames; Other than the connections I have in IB I have given this column of checkboxes the Identifier column2 in IB. I have not set any other property key like you mentioned and I'm not sure where I would do that? I'm not using bindings in my case...I was under the impression it was not necessary? The first 2 methods seem to work fine and the 3rd method is being called but it's just I couldn't figure out the code to change the state of the checkboxes... Thank you again so much for your help, Rick From: Graham Cox graham@bigpond.com To: Jo Phils jo_p...@yahoo.com Cc: cocoa-dev@lists.apple.com Sent: Friday, March 20, 2009 1:56:36 PM Subject: Re: NSTableView updating checkboxes On 20/03/2009, at 4:43 AM, Jo Phils wrote: I am still a Cocoa beginner and looking for some help. Based on Using a Table Data Source in the Table View Programming Guide I have initiated my Table View with 2 columns...one for filenames and one for checkboxes (NSButtonCell). Everything is fine except this method: - (void)tableView:(NSTableView *)aTableView setObjectValue:anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex I can't seem to get the right syntax to tell my Table View to toggle the state. I am able to initiate my Table View with the checkboxes in the ON state (other method) but this method is where I'm stuck. My source is a NSArray *filenames and my table column is column2. If someone could help show me how to code this I would appreciate it very much not just to get me passed this point but also so I can learn what I'm doing wrong. :-) You don't actually state clearly what the problem is, but there is a minor error above: setObjectValue:anObject should be: setObjectValue:(id) anObject is that it? I believe that types left out default to id so it may not be. If your question is how do I toggle the state of something in my data model when the checkbox is changed? then this may help: - (void) tableView:(NSTableView*) tv setObjectValue:(id) objectVal forTableColumn:(NSTableColumn*) column row:(int) rowIndex { id someObject; someObject = [[self dataModel] objectAtIndex:rowIndex]; [someObject setValue:objectVal forKey:[column identifier]]; } where [column identifier] returns the string which is the property key for the boolean property of interest that the checkbox is representing. You set this in IB, e.g. @myBooleanProperty --Graham ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSTableView updating checkboxes
On 20/03/2009, at 8:53 PM, Jo Phils wrote: Hi Graham and thank you very much for your reply. I think I'm still a bit confused I do apologize. :-( Here's my code so far so you can see... - (int)numberOfRowsInTableView:(NSTableView *)aTableView { return [filenames count]; } - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { if ([[aTableColumn identifier] isEqualToString:@column2]) { return [NSNumber numberWithInt:NSOnState]; } return [filenames objectAtIndex:rowIndex]; - (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { // This is where I'm stuck! } And in this code I am using my variable which is a list of filenames... NSMutableArray *filenames; Other than the connections I have in IB I have given this column of checkboxes the Identifier column2 in IB. I have not set any other property key like you mentioned and I'm not sure where I would do that? I'm not using bindings in my case...I was under the impression it was not necessary? The first 2 methods seem to work fine and the 3rd method is being called but it's just I couldn't figure out the code to change the state of the checkboxes... Thank you again so much for your help, Well, I guess what isn't clear is what the checkboxes actually *mean*. If your data model is simply a list of strings (as it appears to be, even though they represent filenames) then what is the boolean property? If what you're after is to represent some subset of the list, i.e. all the checked filenames, then there are two basic ways to handle this. One is to define a class that has both the filename and the 'checked' state as properties, and keep an array of those. The better way (IMO) is to have two lists - the original list all filenames, and a second list those which are checked. The second approach has numerous advantages, such as being able to quickly iterate the list or pass it to other processing methods as an object in its own right (otherwise everything would have to iterate the main list looking for those objects that have the 'checked' property set - this way they can just get to work on that list as it comes). The second approach is possibly a teeny bit more work, but well worth it. Your controller will have two lists - the main list - an array of filenames, and a second list - those that are checked. I'd recommend using NSMutableSet for the second, since there's not really an inherent order to be concerned with here, and it ignores double entries, etc. If you need a sorted list, it's easy to generate one from the set on the fly. The basic idea is that when a box is checked, the object is added to the set. When unchecked, it is removed. Some example code that shows the general idea (warning, typed into mail from memory of the APIs involved) @interface MyListController : NSObject { NSArray*mainList; NSMutableSet* selectedObjects; } - (void)addToSelection:(id) object; - (void)removeFromSelection:(id) object; - (NSSet*) selection; @end //--- @implementation MyListController // much stuff glossed over, such as initialising the lists - (void)addToSelection:(id) object { [selectedObjects addObject:object]; } - (void)removeFromSelection:(id) object { [selectedObjects removeObject:object]; } - (NSSet*) selection { return selectedObjects; } // as a NSTableDataSource - (NSInteger) numberOfRowsInTableView:(NSTableView*) tv { return [mainList count]; } - (id) tableView:(NSTableView*) tv objectValueForTableColumn: (NSTableColumn*) aTableColumn row:(NSInteger) rowIndex { id object = [mainList objectAtIndex:rowIndex]; // if the object is in the set, it's checked, otherwise not if([[aTableColumn identifier] isEqualToString:@checked]) return [NSNumber numberWithBool:[selectedObjects isMember:object]]; else return object; } - (void) tableView:(NSTableView*) tv setObjectValue:(id) val forTableColumn:(NSTableColumn*) aTableColumn row:(NSInteger) rowIndex { id object = [mainList objectAtIndex:rowIndex]; if([[aTableColumn identifier] isEqualToString:@checked]) { BOOL selected = [val boolValue]; // add or remove the object from the selection set if( selected ) [self addToSelection:object]; else [self removeFromSelection:object]; } } Is that any help? If this isn't what you're trying to do, you'll need to be more explicit about what your boolean property represented
Re: NSTableView updating checkboxes
Thank you again Graham so much for the quick reply. Yes you're right about where I'm headed. I was just thinking that I could code it that when you click on the checkboxes the state would toggle then when I got to the processing step I would simply read the state and know how to process each item in my array. But I see what you're saying yes at this point I have no set boolean state in my array. I was able to initialize my table view with checked boxes by returning the ON state but in this method I got stuck because the return is void and that's where my problem was. Ok I will work on your suggestion and I really do appreciate all of the help... :-) I'll let you know, Rick From: Graham Cox graham@bigpond.com To: Jo Phils jo_p...@yahoo.com Cc: cocoa-dev@lists.apple.com Sent: Friday, March 20, 2009 8:56:23 PM Subject: Re: NSTableView updating checkboxes On 20/03/2009, at 8:53 PM, Jo Phils wrote: Hi Graham and thank you very much for your reply. I think I'm still a bit confused I do apologize. :-( Here's my code so far so you can see... - (int)numberOfRowsInTableView:(NSTableView *)aTableView { return [filenames count]; } - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { if ([[aTableColumn identifier] isEqualToString:@column2]) { return [NSNumber numberWithInt:NSOnState]; } return [filenames objectAtIndex:rowIndex]; - (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { // This is where I'm stuck! } And in this code I am using my variable which is a list of filenames... NSMutableArray *filenames; Other than the connections I have in IB I have given this column of checkboxes the Identifier column2 in IB. I have not set any other property key like you mentioned and I'm not sure where I would do that? I'm not using bindings in my case...I was under the impression it was not necessary? The first 2 methods seem to work fine and the 3rd method is being called but it's just I couldn't figure out the code to change the state of the checkboxes... Thank you again so much for your help, Well, I guess what isn't clear is what the checkboxes actually *mean*. If your data model is simply a list of strings (as it appears to be, even though they represent filenames) then what is the boolean property? If what you're after is to represent some subset of the list, i.e. all the checked filenames, then there are two basic ways to handle this. One is to define a class that has both the filename and the 'checked' state as properties, and keep an array of those. The better way (IMO) is to have two lists - the original list all filenames, and a second list those which are checked. The second approach has numerous advantages, such as being able to quickly iterate the list or pass it to other processing methods as an object in its own right (otherwise everything would have to iterate the main list looking for those objects that have the 'checked' property set - this way they can just get to work on that list as it comes). The second approach is possibly a teeny bit more work, but well worth it. Your controller will have two lists - the main list - an array of filenames, and a second list - those that are checked. I'd recommend using NSMutableSet for the second, since there's not really an inherent order to be concerned with here, and it ignores double entries, etc. If you need a sorted list, it's easy to generate one from the set on the fly. The basic idea is that when a box is checked, the object is added to the set. When unchecked, it is removed. Some example code that shows the general idea (warning, typed into mail from memory of the APIs involved) @interface MyListController : NSObject { NSArray* mainList; NSMutableSet*selectedObjects; } - (void)addToSelection:(id) object; - (void)removeFromSelection:(id) object; - (NSSet*)selection; @end //--- @implementation MyListController // much stuff glossed over, such as initialising the lists - (void)addToSelection:(id) object { [selectedObjects addObject:object]; } - (void)removeFromSelection:(id) object { [selectedObjects removeObject:object]; } - (NSSet*)selection { return selectedObjects; } // as a NSTableDataSource - (NSInteger)numberOfRowsInTableView:(NSTableView*) tv { return [mainList count]; } - (id)tableView:(NSTableView*) tv objectValueForTableColumn:(NSTableColumn*) aTableColumn row:(NSInteger) rowIndex { id object = [mainList objectAtIndex:rowIndex]; // if the object is in the set, it's checked, otherwise not if([[aTableColumn identifier] isEqualToString:@checked]) return