Re: Problem with NSOutlineView::shouldSelectItem: and NSRunCriticalAlertPanel
Re: Problem with NSOutlineView::shouldSelectItem: and NSRunCriticalAlertPanel
- Subject: Re: Problem with NSOutlineView::shouldSelectItem: and NSRunCriticalAlertPanel
- From: Blake Hodgetts <email@hidden>
- Date: Mon, 15 Dec 2003 11:38:12 -0800
Louis:
Thanks for the response.
OK, I see how selectionShouldChangeInOutlineView: would be what I need
here, and why outlineView:shouldSelectItem: is looping.
Unfortunately this is still not easy to fix, because the determination of
whether to allow the selection change is partially dependent on which new
item the selection is changing to. If the new selection is a certain type
of item (a "sibling" at the same indentation level as the currently
selected item) then selectionShouldChange should always be YES and no
dialog should appear. If the new selection is a different parent one level
up from the currently selected item, or a subitem of some different parent
(a "cousin" rather than a sibling), then selectionShouldChange needs to
depend on the results of a dialog.
The big problem is that selectionShouldChangeInOutlineView: doesn't give
you -any- information about what the selection might be going to change to;
you can't get that information until you've already approved that
selectionShouldChange. I've gone over all the NSOutlineView methods and
there doesn't seem to be any way to get the incipient selection other than
outlineView:shouldSelectItem:. If I could find this information it would
solve the problem.
Anyone have any ideas on how I can get out of this Catch-22? I really don't
want to display the dialog asking user to confirm the selection change
unless it's needed; it will be very disruptive when it isn't needed.
The one way I can see to do it -- a little messy -- is actually to allow
the change selection, but in outlineView:shouldSelectItem:, if the
selection turns out not to be allowed, then automatically reselect the
previous selection using selectRow:byExtendingSelection:. I'd have to set
some flags to prevent certain things from happening, but it would at least
be possible. I don't want to do this unless I have to -- it seems like a
kludge -- but maybe it's actually the best way to do it?
Thanks for any ideas!
--blake
Louis Sacha responded:
>
Hello...
>
>
Note: I've never actually used an outline view in a program yet, so
>
keep that in mind when reading this.
>
>
I think the problem might be that you are using the wrong method for
>
what you are trying to do. Usually there are several delegate methods
>
for every action, with one being called before, one during, and
>
another after...
>
NSOutlineView also has the delegate method:
>
>
- (BOOL)selectionShouldChangeInOutlineView:(NSOutlineView *)outlineView
>
>
That method should be called before the selection is changed,
>
allowing you to confirm/deny the change at that point. Theoretically,
>
you could just change the method name for the code you have already
>
written to that method, and see if that works.
>
>
The way you have it set up now, I think the method
>
outlineview:shouldSelectItem: is stuck in a loop because you keep
>
returning no and the outlineview can't reselect the old row. In other
>
words, it tries to select a new row/item, you say no (assuming the
>
old row is dirty and shouldn't be discarded), and then it tries to
>
select the original row and calls the same method again to validate
>
the selection of that original row, and you are still returning no.
>
If this is the case, then your code would probably be working
>
properly if you choose to discard the changes from the alert, but not
>
working correctly if you choose to cancel the selection. If that's
>
not what's happening, then there is something else going on as well.
>
>
Anyway, I would suggest trying the
>
selectionShouldChangeInOutlineView: delegate method instead, since
>
that way you are confirming/denying the change before the outline
>
view is actually changing the selection.
>
>
Hope that helps,
>
>
Louis
>
>
>
>I am having a problem with the NSOutlineView method "shouldSelectItem:".
>
>
>
>I have a condition in my code where, within my delegate implementation of
>
>"shouldSelectItem:", I need to warn the user that certain changes to the
>
>current selection will be lost if the selection is changed. Therefore, if
a
>
>"dirty" flag is set, within shouldSelectItem I prompt the user via a
dialog
>
>to either discard the changes, or cancel the selection. Depending on the
>
>response to the dialog, I want "shouldSelectItem:" to return either "NO"
or
>
>"YES".
>
>
>
>The code looks like this ("dirty" is a class member):
>
>
>
>- (BOOL)outlineView:(NSOutlineView *)outlineView
shouldSelectItem:(id)item
>
>{
>
> if (dirty)
>
> {
>
> changeOK = (NSRunCriticalAlertPanel(@"Discard Changes?",
>
> @"Changing selections will discard changes made to the
>
>
selection.
>
> Proceed?",
>
> @"Cancel",
>
> @"Discard Changes",
>
> NIL)
>
> == NSAlertAlternateReturn);
>
> }
>
>
>
> if (changeOK)
>
> resetValues = YES;
>
> else
>
> return NO;
>
>
>
> [...]
>
> return YES;
>
>}
>
>
>
>The problem is that when this runs, it returns back through the stack to
>
>[NSOutlineView _userCanSelectRow:], then to [NSTableView
>
>-userSelectRow:byExtendingSelection:] and then to [NSTableView
mouseDown:].
>
>From there it returns to shouldSelectItem, with the same item that was
>
>selected before, causing a loop that I can't find a way to avoid,
>
>continually re-displaying the alert panel.
>
>It seems as if running the alert panel somehow prevents the mouse click
>
>that initiated the selection attempt from getting cleared off of the
event
>
>queue, so it just gets submitted over and over again.
>
>
>
>What's worse is, once this has happened, the mouseclick NEVER gets
cleared
>
>off the event queue. I tried putting in a loop catcher that would
>
>immediately return NO from shouldSelectItem: if it found that a flag was
>
>set following the alert panel. Although the alert panel runs only once,
the
>
>program loops endlessly through shouldSelectItem returning NO and the
>
>selection is never cancelled.
>
>
>
>If the alert panel is not run, then the selection cancels as expected.
>
>
>
>Any assistance is greatly appreciated.
>
>
>
>--blake
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.