Module: environment-tools Synopsis: Environment tools Author: Chris Page Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND //--- cpage: 1997.09.23 We should probably add a "start-application" function // to environment-framework for symmetry with frame-exit-application. //--- cpage: 1997.09.23 We should move these default methods into // environment-framework. define generic frame-do-exitable-frames (frame :: , action :: ) => (); // Default method define method frame-do-exitable-frames (frame :: , action :: ) => () do-frames(action); end method frame-do-exitable-frames; define variable *application-exiting?* :: = #f; // Return the owned modal dialog of a frame, if any define method frame-owned-modal-dialog (frame :: ) => (dialog :: false-or()) block (return) do(method (frame :: ) => () when (frame.frame-mode ~== #"modeless") return (frame); end; end method, frame-owned-frames(frame)); #f end end method frame-owned-modal-dialog; // Default method define sideways method frame-exit-application (frame :: ) => (exit? :: ) unless (*application-exiting?*) *application-exiting?* := #t; // Exit frames until we've asked all of them, or one stops the exit. *application-exiting?* := block (return) frame-do-exitable-frames (frame, method (frame-to-exit :: ) => () // Before asking a frame whether it can exit, make sure it isn't // a modal dialog, a modal dialog owner, or disabled (which // usually means it owns a native modal dialog that doesn't have // a DUIM mirror). let owned-dialog = frame-owned-modal-dialog(frame-to-exit); let modal? :: = frame-to-exit.frame-mode ~== #"modeless"; let enabled? :: = frame-to-exit.frame-enabled?; let dialog? :: = owned-dialog ~== #f | modal? | ~enabled?; if (~dialog? & frame-can-exit?(frame-to-exit)) if (instance?(frame-to-exit, )) frame-to-exit.frame-exiting? := #t end; exit-frame(frame-to-exit); else // Clear exiting? flags since exiting has been stopped frame-do-exitable-frames (frame, method (frame-to-stop-exiting :: ) => () when (instance?(frame-to-stop-exiting, )) frame-to-stop-exiting.frame-exiting? := #f end end); // Activate the dialog or owner frame when (dialog?) // Raise a frame so the user can see what's stopping the exit. // If the exit-frame is disabled, beep in the original frame; // restoring, raising and beeping won't occur until the // exit-frame becomes enabled, which is too late to be useful. let frame-to-activate :: = case owned-dialog ~== #f => owned-dialog; ~enabled? => frame; otherwise => frame-to-exit; end; call-in-frame(frame-to-activate, method (_frame :: ) => () deiconify-frame(_frame); raise-frame(_frame); beep(_frame); end method, frame-to-activate); end when; return(#f); end; end method); #t end block; end unless; *application-exiting?* end method frame-exit-application; /// Exiting the environment // Do environment frames in a certain order define method frame-do-exitable-frames (frame :: , action :: ) => () let frames = collect-frames(); // Do editor frames. do(method (frame :: ) => () //--- cpage: 1997.09.22 Apparently, isn't visible in // this library, so we'll have to define editor frames in terms // of a negative space. ~instance?(frame, ) & ~instance?(frame, ) & action(frame) end, frames); // Do project frames. do(method (frame :: ) => () instance?(frame, ) & action(frame); end, frames); // Do the primary frame last. do(method (frame :: ) => () instance?(frame, ) & action(frame); end, frames); end method frame-do-exitable-frames; define method collect-frames () let frames = make(); do-frames(method (frame :: ) frames := add!(frames, frame); end method); frames end method collect-frames;