How to NOT display certain nodes in outline view? - cocoa

In Apple's Mail app, in the outline view on the left, an inbox or a folder is shown in hierarchy but the emails in the folder or email is not shown at all.
I would like to reproduce this feature.
I have an outline view connected to a tree controller. Objects (nodes) are added to the tree controller and displayed in the outline view. How can I prevent some objects from appearing? Specifically, I have folder nodes that contain instances of a custom object. Just as in Mail.app, I would like to only display the folder in the outline view and will have the custom objects displayed in another view.
Some controller code as per request; here I am adding nodes to a folderNode that is selected in the outline view:
indexPath = [treeController selectionIndexPath];
indexPath = [indexPath indexPathByAddingIndex:[[[[treeController selectedObjects] objectAtIndex:0] children] count]];//want to insert the new node at the end of the folder node's array of children
...
[treeController insertObject:customObjectNode atArrangedObjectIndexPath:indexPath];
NSLog(#"No. of items selected in tree controller/outline view is %i",[[treeController selectedNodes] count]); //if the folderNode is a leaf, this gives 0, i.e. no selection
// if the folderNode is not a leaf, the added child automatically becomes selected by NSOutlineView. In that case I keep its parent selected (the folder) so the next customObjectNode can be added
[self selectParentFromSelection];//however this method will then do nothing because at this point nothing is selected. Now this whole paragraph of code cannot be repeated because nothing is selected so the first line of code doesn't work.

Are you using any other tree controllers which need to continue on to the children?
If not, just have the folder nodes return YES to -isLeaf (and nil for the childNodes key).

Related

Xcode hanging, runs out of memory when using Bindings and IB

I have a core data model with two entities, for the sake of this post I will call them Category and Items, Category is the parent entity with a one-to-many relationship to Items.
In IB I have a NSTreeController and NSOutlineView that manages the Category entity, this works great.
I also have an ArrayController with Mode set to Entity, Entity Name set to Items, Content Set bindings set to Tree Controller with Controller Key of "selection" and Model Key Path set to the relationship.
I have tested all this works by selecting Categories in the outline view and outputting how many Items are available inside the array controller when I change selection from the tree controller using the following code:
SWIFT:
#IBOutlet var itemsArrayController: NSArrayController!
#IBAction func logResult(sender: AnyObject) {
println("Items Array has \(itemsArrayController.content?.count) records")
// Print first item to console
var anItem : Items! = itemsArrayController.content?.objectAtIndex(0) as Items
if let something : Items = anItem? {
println(something.name)
}
}
Now I want to hook up a Table View to the Array Controller that will list all the Items of the selected Category.
So If I bind Table View Cell's Value to Items Array Controller.arrangedObjects.name and click RUN xcode starts compiling and just doesnt proceed past 50%. Activity Monitor->Memory shows "ibtooid" with 5GB of memory after awhile before the entire system locks up and I have to hard reset my mac. Even if I click stop in Xcode the ibtooid continues to eat memory, The only way to stop from a hard reset is to kill that process,.
Any help would be much appreciated.
Thanks
Xcode Version 6.1 (6A1046a)
Fixed it by changing the table to Cell based rather than View Based. Will file a bug with Apple.

NSTableViews in NSOutLineViews

I have a requirement to fill the outline view with table views as shown in the image. There will be only one child table view for each nsoutlineview node. The number of table views is not static. So, I will need to implement the NSOutlineView programmatically.
![Outline view named "Command" as shown in the the image][1]
Can somebody please suggest on, how to go ahead with the requirement?
Thanks!!
The above is NOT an outline view with table views as children. It's achieved with an NSOutlineView using a root node for "Xcode Menu" and "File Menu" as root nodes and all the children as leaves. Turn on header rows (it's a header row if it's a root node) and that's that.

NSArrayController: How to programmatically clear selection?

Very simple question that's driving me crazy: What's the proper way to clear the selection of an NSArrayController programmatically?
I'm designing a view with the following components:
NSArrayController *controller1: Bound to an array of objects
NSPopUpView view1: Content bound to controller1.arrangedObjects; Value bound to controller1.selection; "Inserts Null Placeholder" selected
NSArrayController *controller2: Bound to an array stored in controller1.selection
NSPopupView view2: Content bound to controller2.arrangedObjects; value bound to controller2.selection; "Inserts Null Placeholder" selected
Initially, view1's content is populated; controller1 and controller2 have nil selection values; and view1 and view2 display null placeholders. Selection of controller1 causes controller1's selection to change and view2's content to populate. All good.
I'd like to implement a Clear button that clears the selection of controller1, which, thanks to bindings, should also clear the selection of controller2 and reset view1 and view2 to the null placeholder. For the life of me, I can't figure out the proper code for this very simple function. Altering the selection of controller1 fails to update the value shown in view1. Worse, altering the controller1 selection programatically causes weird things to happen in controller2: further selection of values in view1 fails to have any effect on view2.
Things I've tried:
Calling the SetSelectedObjects method of controller1 with an [NSArray new].
Calling the SetSelectedObjects method of controller1 with null.
Calling the SetSelectedIndex method of controller1 with NSNotFound.
Calling the RemoveSelectedIndex method of controller1 with the SelectedIndex property of controller1.
Looking in the Cocoa NSArrayController documentation for any class method or suggestion for clearing the selection value. Nothing there - not even any mention of this being desirable, let alone how to accomplish it.
Any ideas? Thanks...
According to Apples Developer documentation this can be done using setSelectionIndexes:
To deselect all indexes, pass an empty index set.
Objective-C:
[arrayController setSelectionIndexes:[NSIndexSet indexSet]];
Swift:
arrayController.setSelectionIndexes( NSIndexSet() )
Try controller1.selectionIndex = NSIntegerMax; and see if that works. I did a simple test with a label bound to the array controller's selection, and when I set the selectionIndex to NSIntegerMax, the no selection placeholder was displayed in the label.
As it turns out, the NSArrayController page does include a single recommendation for clearing the selection:
setSelectionIndexes:
Sets the receiver’s selection indexes and returns a Boolean value that indicates whether the selection changed.
(BOOL) setSelectionIndexes: (NSIndexSet *) indexes
Discussion
Attempting to change the selection may cause a commitEditing message which fails, thus denying the selection change.
To select all the receiver’s objects, indexes should be an index set with indexes [0...count -1]. To deselect all indexes, pass an empty index set.
However, I had actually tried that, and it still left me with a problem.
To generalize:
Create two classes, A and B, where A contains a property "NSArray *b_list" that contains a list of instances of B's.
Create an application with a property "NSArray *a_list". Populate it with some instances of A, and populate the b_list of each A instance with some B instances.
Create a window with two array controllers, Controller_A (bound to a_list) and Controller_B (bound to Controller_A.selection.b_list).
Create two pop-up buttons in the window, Popup_A (bound to Controller_A.arrangedObjects) and Popup_B (bound to Controller_B.arrangedObjects).
Create a "Clear" button with some logic to clear the selection of Controller_A. ("Some logic" is either the method recommended in the Apple documentation, or any other method.)
Run the application. Select an entry in Popup_A. Notice that Popup_B populates with the instances of Controller_A.selection.b_list, as it should.
Now hit the Clear button.
ERROR: Note that while the content and selection of Popup_A correctly become null, the same doesn't happen in Popup_B: it presents a blank entry with a single selected (blank) item. Note also that the selection properties of Controller_B indicates that there is a selection, but its properties are weird: selectedIndex points to 0 instead of NSNotFound, and selectedIndexes includes a non-empty selection integer range.
This is clearly an error with the binding logic that can definitely cause some exceptions and logical errors. For example, if there's any sort of binding attached to B_controller.selection, clearing A_controller will raise an exception relating to the selection value in B_controller, since it indicates a selection but points to garbage.
My workaround is not to bind anything directly to the B_controller selection. Instead, access B_controller programmatically, and in view of the selection value of A_controller, like this:
// setting some property c to the value of b_controller:
if ((B_controller.selectedIndex == NSNotFound) || A_controller.selectedIndex == NSNotFound))
c = nil;
else
c = [B_controller objectAtIndex: [B_controller.selectedIndex]];
I'm also submitting a bug report to Apple with this info.
Answer to a very old question but still.
I just needed the same thing, and for me this worked:
[arrayController setAvoidsEmptySelection:NO];
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:
NSMakeRange(NSNotFound, 0)];
[arrayController setSelectionIndexes:indexes];

Jqgrid tree grid - displaying radio off icon for last child node

I am loading data for child nodes from server side on expanding the row. I wanted to display the 'ui-icon-radio-off' icon for children at the last level, currently it is displaying downward triangle as I set loaded: true, expanded: true. Is it possible to change this icon to 'ui-icon-radio-off' as shown in the attachment below...
I suppose that the problem is the data which you used to fill the tree grid. The data should include the values of hidden columns. The column isLeaf defines whether the row is a tree node or a leaf. The rows which has isLeaf: true will be displayed with 'ui-icon-radio-off' icon.
You can find more details and example here, here, here or for example here.

Trying to use NSManagedObjectModel through NSTreeController and NSBrowser

I'm trying to use NSManagedObjectModel through NSTreeController and NSBrowser. I found some simple tutorials on the Net but they don't solve all my problems. Right now I can: add nodes (except in the leaf); to show children's nodes selecting the parent. My model is heterogeneous, all entities are different, but have the same properties: "name"; "children" (except the leaf); "parent (except the root). My model is all generated by the XCode. I don't have entered any code and don't have changed anything, all is generated by the XCode and Interface Builder.
I have 3 questions:
(1) How can I avoid the "children key error" when I reach the leaf entity?
(2) How can I avoid the creation of a children in the column of a parent?
(3) How can I disable the add children button if no one parent is selected?
(Thanks about some help. :D )
With regard to question 1: I have all my nodes implement all methods, but the leaf entities return nil for the children getter method, for example, and the root returns nil for parent.
Unfortunately, I haven't used NSBrowser, I use this technique for NSOutlineView and NSTreeController, so I can't help with questions 2 & 3.

Resources