object GetNextCommandTarget (CommandTargetRoute targetRoute, object cmdTarget, bool ignoreDelegator = false)
{
if (cmdTarget is IMultiCastCommandRouter)
cmdTarget = new MultiCastDelegator (this, (IMultiCastCommandRouter)cmdTarget, targetRoute);
if (!ignoreDelegator && cmdTarget is ICommandDelegator) {
if (cmdTarget is ICommandDelegatorRouter)
throw new InvalidOperationException ("A type can't implement both ICommandDelegator and ICommandDelegatorRouter");
object oldCmdTarget = cmdTarget;
cmdTarget = ((ICommandDelegator)oldCmdTarget).GetDelegatedCommandTarget ();
if (cmdTarget != null)
delegatorStack.Push (oldCmdTarget);
else
cmdTarget = GetNextCommandTarget (targetRoute, oldCmdTarget, true);
}
else if (cmdTarget is ICommandDelegatorRouter) {
object oldCmdTarget = cmdTarget;
cmdTarget = ((ICommandDelegatorRouter)oldCmdTarget).GetDelegatedCommandTarget ();
if (cmdTarget != null)
delegatorStack.Push (oldCmdTarget);
else
cmdTarget = ((ICommandDelegatorRouter)oldCmdTarget).GetNextCommandTarget ();
}
else if (cmdTarget is ICommandRouter)
cmdTarget = ((ICommandRouter)cmdTarget).GetNextCommandTarget ();
else if (cmdTarget is Gtk.Widget)
cmdTarget = ((Gtk.Widget)cmdTarget).Parent;
#if MAC
else if (cmdTarget is AppKit.NSView) {
var v = (AppKit.NSView) cmdTarget;
if (v.Superview != null && IsRootGdkQuartzView (v.Superview))
// FIXME: We should get here the GTK parent of the superview. Since there is no api for this
// right now, we rely on it being set by GetActiveWidget()
cmdTarget = null;
else
cmdTarget = v.Superview;
}
#endif
else
cmdTarget = null;
if (cmdTarget == null || !visitedTargets.Add (cmdTarget)) {
while (delegatorStack.Count > 0) {
var del = delegatorStack.Pop ();
if (del is ICommandDelegatorRouter)
cmdTarget = ((ICommandDelegatorRouter)del).GetNextCommandTarget ();
else
cmdTarget = GetNextCommandTarget (targetRoute, del, true);
if (cmdTarget == CommandManager.CommandRouteTerminator)
return null;
if (cmdTarget != null)
return cmdTarget;
}
return globalHandlerChain;
} else
return cmdTarget;
}