shellfile.c

Go to the documentation of this file.
00001 
00002 /*  $Id: shellfile.c 1260 2006-04-13 06:13:10Z sethdill $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include "cursor.h"
00032 #include "dialogs.h"
00033 #include "file.h"
00034 #include "kb.h"
00035 #include "launch.h"
00036 #ifdef MACVERSION
00037     #include "mac.h"
00038 #endif
00039 #include "memory.h"
00040 #include "resources.h"
00041 #include "strings.h"
00042 #include "frontierwindows.h"
00043 #include "zoom.h"
00044 #include "cancoon.h"
00045 #include "shell.rsrc.h"
00046 #include "shell.h"
00047 #include "shellhooks.h"
00048 #include "shellprivate.h"
00049 #include "shellundo.h"
00050 #include "lang.h"
00051 #include "langinternal.h"
00052 #include "tablestructure.h"
00053 
00054 #ifdef MACVERSION
00055     #include <uisharing.h>
00056 #endif
00057 #ifdef WIN95VERSION
00058     #include "FrontierWinMain.h"
00059 #endif
00060 
00061 #define str_desktopscript   BIGSTRING ("\x04" "ftds")
00062 #define str_normalscript    BIGSTRING ("\x04" "ftsc")
00063 #define type_desktopscript  'FTds'
00064 #define type_normalscript   'FTsc'
00065 #define type_wptext         'FTwp'
00066 #define type_plaintext      'TEXT'
00067 
00068 
00069 boolean flinhibitclosedialogs = false; /*global for close routines*/
00070 
00071 boolean flconvertingolddatabase = false; /*global for saveas operation*/
00072 
00073 boolean flshellclosingall = false; /*global for ccwindowpreclose*/
00074 
00075 
00076 typedef struct findvisitinfo {
00077     
00078     ptrfilespec fsfind;
00079 
00080     WindowPtr *wfound;
00081 
00082     boolean flhidden;
00083     } tyfindvisitinfo, *ptrfindvisitinfo;
00084 
00085 
00086 static boolean findfilevisit (WindowPtr w, ptrvoid refcon) {
00087     
00088     /*
00089     if the filespec for the given window is the one we're looking for, 
00090     select that window and stop visiting
00091     
00092     5.1b22 dmb: make sure the window is visible by calling shellbringtofront
00093     */
00094     
00095     ptrfindvisitinfo info = (ptrfindvisitinfo) refcon;
00096     tyfilespec fs;
00097     hdlwindowinfo hinfo;
00098     
00099     windowgetfspec (w, &fs);
00100     
00101     if (equalfilespecs ((*info).fsfind, &fs)) {
00102         
00103         getwindowinfo (w, &hinfo);
00104         
00105         if (!(*info).flhidden)
00106             shellbringtofront (hinfo);
00107         
00108         if ((*info).wfound != nil)
00109             *(*info).wfound = w;
00110         
00111         return (false);
00112         }
00113     
00114     return (true);
00115     } /*findfilevisit*/
00116 
00117 
00118 boolean shellopenfile (ptrfilespec fspec, boolean flhidden, WindowPtr *wnew) {
00119     
00120     /*
00121     open the specified file in a new window.
00122     
00123     dmb 8/20/90:  show window after success (window now initially invisible).
00124     
00125     dmb 8/20/90:  added resfile support.
00126     
00127     8/31/90 DW: replace setglobals calls with shellpush/popglobals.  also commented
00128     out the call to shellfrontglobals.
00129     
00130     11/8/90 dmb: push default globals so that caller doesn't have to
00131     
00132     7/29/92 dmb: moved handling of update events after loadspecial handler, so that 
00133     is can see what kind of event triggered the open
00134     
00135     8/20/92 dmb: since handling of update events can push/pop globals, we need to 
00136     re-establish default globals after calling partialeventloop
00137     
00138     2.1b3 dmb: resolve alias files
00139     
00140     3.0.2 dmb: if asked to open a file that's already open in a root window, 
00141     just bring it to the front and return true
00142 
00143     6.0a11 dmb: fixed wnew handling for already-open windows
00144     */
00145     
00146     WindowPtr w;
00147     hdlfilenum fnum;
00148     short rnum;
00149     boolean fl;
00150     OSType filetype;
00151     tyfindvisitinfo info;
00152 #ifdef MACVERSION
00153     bigstring bsext;
00154 #endif
00155 
00156     if (wnew != nil)
00157         *wnew = nil;
00158     
00159     info.fsfind = fspec;
00160     info.wfound = wnew;
00161     info.flhidden = flhidden;
00162     
00163     if (!shellvisittypedwindows (iddefaultconfig, &findfilevisit, &info))
00164         return (true);
00165     
00166     initbeachball (right);
00167     
00168     if (!fileresolvealias (fspec))
00169         return (false);
00170     
00171     if (!getfiletype (fspec, &filetype))
00172         return (false);
00173     
00174 #ifdef MACVERSION
00175 
00176     lastword (fspec->name, '.', bsext);
00177 
00178     if (equalidentifiers (bsext, "\proot"))
00179         filetype = 'TABL';
00180 #endif
00181     
00182     if (!shellpushdefaultglobals ())
00183         return (false);
00184     
00185     if (filetype != config.filetype) {
00186         
00187         fl = (*shellglobals.loadspecialroutine) (fspec, filetype);
00188         
00189         shellpopglobals ();
00190         
00191         return (fl);
00192         }
00193     
00194     shellpopglobals (); /*next statement may smash 'em*/
00195     
00196     shellpartialeventloop (updateMask); /*handle updates*/
00197     
00198     shellpushdefaultglobals (); /*set 'em back up*/
00199     
00200     w = nil;
00201     
00202     rnum = -1;
00203     
00204     if (!openfile (fspec, &fnum, false))
00205         goto error;
00206     
00207 #ifdef MACVERSION
00208     if (config.flopenresfile)
00209         if (!openresourcefile (fspec, &rnum, resourcefork)) /* 2005-09-02 creedon - added support for fork parameter, see resources.c: openresourcefile and pushresourcefile */ 
00210             goto error;
00211 #endif
00212     
00213     if (!newfilewindow (fspec, fnum, rnum, flhidden, &w))
00214         goto error;
00215     
00216     if (wnew != nil)
00217         *wnew = w;
00218     
00219     shellpushglobals (w);
00220     
00221     fl = (*shellglobals.loadroutine) (fnum, rnum);
00222     
00223     setcursortype (cursorisarrow); /*don't leave stopped beach ball lingering*/
00224     
00225     shellpopglobals ();
00226     
00227     if (!fl)
00228         goto error;
00229     
00230     zoomfilewindow (w);
00231     
00232     if (!flhidden)
00233         windowinval (w); /*be sure absolutely everything gets drawn*/
00234     
00235     shellpopglobals ();
00236     
00237     shellcallfilehooks (); /*a file was just opened or closed*/
00238     
00239     return (true);
00240     
00241     error:
00242 
00243     shellpopglobals ();
00244     
00245     disposeshellwindow (w);
00246     
00247     closefile (fnum);
00248 
00249 #ifdef MACVERSION
00250     closeresourcefile (rnum);
00251 #endif
00252     
00253     return (false);
00254     } /*shellopenfile*/
00255     
00256 
00257 static boolean clickersvisit (hdlhashnode hnode, ptrvoid refcon) {
00258     
00259     ptrsftypelist psftypes = (ptrsftypelist) refcon;
00260     bigstring bs;
00261     byte bstype [8];
00262     
00263     gethashkey (hnode, bs);
00264     
00265     if (patternmatch (BIGSTRING ("\x04type"), bs) == 1) {
00266         
00267         midstring (bs, 5, 4, bstype);
00268         
00269         stringtoostype (bstype, &(*psftypes).types [(*psftypes).cttypes++]);
00270         }
00271         
00272     return ((*psftypes).cttypes < maxsftypelist);
00273     } /*clickersvisit*/
00274 
00275 
00276 boolean shellopen (void) {
00277     
00278     /*
00279     2.1b4 dmb: option-open to show all types
00280     
00281     5.0d3 dmb: look in clickers table for types we can actually open
00282     */
00283     
00284     tyconfigrecord  lconfig;
00285     tyfilespec      fspec;
00286     tysftypelist    filetypes;
00287     ptrsftypelist   ptypes = nil;
00288     hdlhashtable    htable;
00289     bigstring bs;
00290     boolean fl;
00291     hdlwindowinfo hdummy;
00292     
00293     if (!keyboardstatus.floptionkey) { /*2.1b4*/
00294         
00295         shellgetconfig (iddefaultconfig, &lconfig);
00296         
00297         filetypes.cttypes = 1;
00298         
00299         filetypes.types [0] = lconfig.filetype;
00300         
00301     //  filetypes.types [1] = '2CLK'; // application glue files
00302         
00303         ptypes = &filetypes;
00304         }
00305     
00306     getsystemtablescript (idfrontierclickers, bs); // "Frontier.clickers.typeXXXX"
00307     
00308     disablelangerror ();
00309 
00310     fl = langexpandtodotparams (bs, &htable, bs);
00311     
00312     enablelangerror ();
00313     
00314     if (fl)
00315         hashtablevisit (htable, &clickersvisit, &filetypes);
00316     
00317     clearbytes (&fspec, sizeof (fspec));
00318     
00319     //RAB: 1/27/98  - make this look better when opening a file after the root is open
00320     if (ccfindrootwindow (&hdummy) == false)
00321         getstringlist (defaultlistnumber, startupfileprompt, bs);
00322     else
00323         getstringlist (defaultlistnumber, nonstartupfileprompt, bs);
00324     
00325     if (!sfdialog (sfgetfileverb, bs, ptypes, &fspec, 'LAND')) /* 2005-10-06 creedon - added 'LAND' */
00326         return (false);
00327     
00328     return (shellopenfile (&fspec, false, nil));
00329     } /*shellopen*/
00330 
00331 
00332 static void prepuserforwait (WindowPtr w) {
00333 #if TARGET_API_MAC_CARBON
00334 #   pragma unused(w)
00335 #endif
00336 
00337     /*
00338     4.1.1b1 dmb: call langpartialeventloop when appropriate
00339 
00340     7.0b16 PBS: Fix for Windows display glitch -- don't gray windows for save
00341     if this is Windows, it leads to the display getting messed up for the frontmost
00342     outline.
00343     */
00344     
00345     initbeachball (left);
00346     
00347     if (flscriptrunning)
00348         langpartialeventloop (updateMask);
00349     else
00350         shellpartialeventloop (updateMask);
00351 
00352 #ifdef MACVERSION /*7.0b16 PBS: only Macs get grayed windows. Fix for Windows display glitch.*/
00353     #if TARGET_API_MAC_CARBON
00354     {
00355     //only gray the front window
00356     WindowRef   frontWind = GetFrontWindowOfClass(kAllWindowClasses, false);
00357     graywindow(frontWind);
00358     }
00359     #else
00360     grayownedwindows (w); /*gray the window while saving*/
00361     #endif
00362 
00363 #endif
00364     } /*prepuserforwait*/
00365 
00366 
00367 static boolean killundovisit (WindowPtr w, ptrvoid refcon) {
00368 #pragma unused (refcon)
00369 
00370     if (shellpushglobals (w)) {
00371         
00372         killundo ();
00373         
00374         shellpopglobals ();
00375         }
00376     
00377     return (true);
00378     } /*killundovisit*/
00379 
00380 
00381 void killownedundo (WindowPtr w) {
00382     
00383     /*
00384     3/8/91 dmb: added this routine to make sure that all undos are tossed 
00385     before saving.  we'd be able to get rid of this if we made the undo 
00386     stacks part of the superglobals, and added support for file-specific 
00387     instead of window-specific undo
00388     */
00389     
00390     killundo ();
00391     
00392     visitownedwindows (w, -1, &killundovisit, nil);
00393     } /*killownedundo*/
00394 
00395 
00396 static boolean shellsavefile (WindowPtr w, ptrfilespec fspec, hdlfilenum fnum, short rnum, boolean flsaveas, boolean flrunnable) {
00397     
00398     /*
00399     this just factors out some code common to all save routines in this file
00400     */
00401     
00402     killownedundo (w);
00403     
00404     prepuserforwait (w);
00405     
00406     return ((*shellglobals.saveroutine) (fspec, fnum, rnum, flsaveas, flrunnable));
00407     } /*shellsavefile*/
00408 
00409 
00410 static boolean shelldatabasesaveas (WindowPtr wsave, ptrfilespec fspec) {
00411     
00412     /*
00413     a save-as designed for applications that work with a file that it reads
00414     and writes while the user is working.
00415     
00416     10/3/90 dmb:  rewrote
00417     
00418     7/5/91 dmb: use new copyallresources routine to handle the resource fork.
00419     
00420     this routine now actually implements a "save a copy"; the newly-saved file 
00421     does not become the current file.
00422     */
00423     
00424     register WindowPtr w = wsave;
00425     hdlfilenum fnum;
00426     short rnum;
00427     hdlwindowinfo hinfo;
00428     
00429     if (!opennewfile (fspec, config.filecreator, config.filetype, &fnum))
00430         return (false);
00431     
00432     rnum = -1;
00433 
00434 #ifdef MACVERSION
00435     if (config.flopenresfile)
00436         if (!openresourcefile (fspec, &rnum, resourcefork)) { /* 2005-09-02 creedon - added support for fork parameter, see resources.c: openresourcefile and pushresourcefile */ 
00437             
00438             closefile (fnum);
00439             
00440             return (false);
00441             }
00442 #endif
00443     
00444     getwindowinfo (w, &hinfo);
00445     
00446     /*
00447     shellbringtofront (hinfo);
00448     
00449     shellclosechildwindows (hinfo); /%Save As can't maintain these, so close them now%/
00450     */
00451     
00452     if (!shellsavefile (w, fspec, fnum, rnum, true, false)) {
00453         
00454         closefile (fnum);
00455 
00456         closeresourcefile (rnum);
00457         
00458         deletefile (fspec);
00459         
00460         return (false);
00461         }
00462     
00463     if (config.flopenresfile)
00464         copyallresources ((**hinfo).rnum, rnum);
00465 
00466 #ifndef version42orgreater
00467     shellsavewindowresource (w, fspec, rnum);
00468     
00469     shellsavefontresource (w, fspec, rnum);
00470 #endif
00471     
00472     if (!flconvertingolddatabase) { /*close new file; we're really doing a "Save a Copy"*/
00473     
00474         closefile (fnum);
00475         
00476         closeresourcefile (rnum);
00477         }
00478     else { /*close old file and re-open newly-converted file*/
00479         
00480         (*shellglobals.closeroutine) ();
00481         
00482         (*shellglobals.disposerecordroutine) ();
00483         
00484         shellclearwindowdata ();
00485 
00486         closewindowfile (w); /*close old file*/
00487         
00488         (**hinfo).flneversaved = false; /*must do after closewindowfile*/
00489         
00490         windowsetfspec (w, fspec);
00491         
00492         windowsetfnum (w, fnum);
00493         
00494         windowsetrnum (w, rnum);
00495         
00496         if (!(*shellglobals.loadroutine) (fnum, rnum)) {
00497             
00498             closewindowfile (w); /*close new file*/
00499             
00500             disposeshellwindow (w);
00501             
00502             alertdialog ((ptrstring) "\x47" "A copy of the file was successfully converted, but could not be opened.");
00503             
00504             return (false);
00505             }
00506         
00507         windowsetchanges (w, false);
00508         }
00509     
00510     flushvolumechanges (fspec, fnum); /*write changes out to disk*/
00511     
00512     return (true);
00513     } /*shelldatabasesaveas*/
00514 
00515 
00516 static boolean shellnormalsaveas (WindowPtr wsave, ptrfilespec fspec, boolean flrunnable) {
00517     
00518     /*
00519     8/20/90 dmb: added resfile support
00520     
00521     5.0.2b19 dmb: special case file type for runnable
00522     */
00523     
00524     register WindowPtr w = wsave;
00525     hdlfilenum fnum;
00526     short rnum;
00527     tyfilespec fs;
00528     OSType filetype = config.filetype;
00529     OSType type;
00530     
00531     switch (filetype) { //handle special cases
00532     
00533         case type_normalscript:
00534             if (flrunnable)
00535                 filetype = type_desktopscript;
00536             
00537             break;
00538         
00539         case type_wptext:
00540             if (windowgetfspec (w, &fs) && getfiletype (&fs, &type) && (type == type_plaintext))
00541                 filetype = type_plaintext;
00542             
00543             break;
00544         }
00545     
00546     if (!opennewfile (fspec, config.filecreator, filetype, &fnum))
00547         return (false);
00548     
00549     if (config.flopenresfile) {
00550     
00551         if (!openresourcefile (fspec, &rnum, resourcefork)) { /* 2005-09-02 creedon - added support for fork parameter, see resources.c: openresourcefile and pushresourcefile */ 
00552             
00553             closefile (fnum);
00554             
00555             return (false);
00556             }
00557         }
00558     
00559     if (shellsavefile (w, fspec, fnum, rnum, true, flrunnable)) { 
00560         
00561         (**shellwindowinfo).flneversaved = false;
00562         
00563         flushvolumechanges (fspec, fnum); /*write changes out to disk*/
00564         
00565         closefile (windowgetfnum (w));
00566         
00567     #ifdef MACVERSION
00568         closeresourcefile (windowgetrnum (w));
00569     #endif
00570     
00571         windowsetchanges (w, false);
00572         
00573         windowsetfnum (w, fnum);
00574         
00575         windowsetrnum (w, rnum);
00576         
00577         windowsetfspec (w, fspec);
00578         }
00579     
00580     return (true);
00581     } /*shellnormalsaveas*/
00582 
00583 
00584 boolean shellsaveas (WindowPtr wsave, ptrfilespec fspec, boolean flrunnable) {
00585     
00586     /*
00587     if we're given a path, save the current file to that location with no 
00588     dialog.
00589     
00590     if bspath is nil, use standard file to determine the new file location
00591     
00592     12/12/91 dmb: make sure we don't use a full path as the default file name
00593 
00594     5.0d8 dmb: pass file type to sfdialog for Win
00595     */
00596     
00597 //  #if TARGET_API_MAC_CARBON == 1 /*7.0b50 PBS: set window title icon*/
00598 //      OSStatus err = noErr;
00599 //  #endif
00600     
00601     register boolean fl;
00602     register WindowPtr w;
00603     tyfilespec fs;
00604     tysftypelist filetypes;
00605     
00606     if (!shellpushrootglobals (wsave)) /*save as only operates on root windows*/
00607         return (false);
00608     
00609     w = shellwindow; /*move into register*/
00610     
00611     if (fspec != nil) {
00612         
00613         fs = *fspec;
00614         
00615         fl = true;
00616         }
00617     else {
00618         
00619         if (!windowgetfspec (w, &fs))
00620             getdefaultfilename (fsname (&fs));
00621         
00622         filetypes.cttypes = 1;
00623 
00624         filetypes.types [0] = config.filetype;
00625 
00626         if (flrunnable) { //special case for desktop scripts.
00627             bigstring bsfile, bssuffix;
00628             
00629             getfsfile (&fs, bsfile);
00630             
00631             lastword (bsfile, '.', bssuffix);
00632             
00633             if (equalidentifiers (bssuffix, str_normalscript)) {
00634                 
00635                 replacestring (bsfile, stringlength (bsfile) - 3, 4, str_desktopscript);
00636                 
00637                 setfsfile (&fs, bsfile);
00638                 }
00639             
00640             filetypes.types [0] = type_desktopscript;
00641             }
00642         
00643         fl = sfdialog (sfputfileverb, nil, &filetypes, &fs, 'LAND'); /* 2005-10-06 creedon - added 'LAND' */
00644         }
00645     
00646     if (fl) {
00647         
00648         if (config.flcreateonnew)
00649             fl = shelldatabasesaveas (w, &fs);
00650         else
00651             fl = shellnormalsaveas (w, &fs, flrunnable);
00652             
00653 //      #if TARGET_API_MAC_CARBON == 1 /*7.0b50 PBS: set window title icon*/
00654             
00655 //          err = SetWindowProxyFSSpec (w, &fs);
00656 
00657 //      #endif
00658         }
00659 
00660     shellpopglobals ();
00661     
00662     return (fl);
00663     } /*shellsaveas*/
00664 
00665 
00666 boolean shellnewfile (ptrfilespec fspec, boolean flhidden, WindowPtr *wnew) {
00667     
00668     /*
00669     create a new file with the default config
00670     
00671     7/27/90 dmb: clean up after error.
00672     
00673     8/20/90 dmb: show window after success.  added resfile support.
00674     
00675     8/31/90 DW: eliminate setglobals calls.
00676     
00677     11/8/90 dmb: fixed globals push/pop imbalance
00678     
00679     2/6/91 dmb: take fname, vnum as parameters so verbs can call us
00680     */
00681     
00682     hdlfilenum fnum = 0;
00683     short rnum = -1;
00684     WindowPtr w = nil;
00685     boolean fl;
00686     
00687     shellpushdefaultglobals (); /*so that config is correct*/
00688     
00689     if (config.flcreateonnew) {
00690         
00691         if (!opennewfile (fspec, config.filecreator, config.filetype, &fnum))
00692             goto error;
00693 
00694     #ifdef MACVERSION
00695         if (config.flopenresfile)
00696             if (!openresourcefile (fspec, &rnum, resourcefork)) /* 2005-09-02 creedon - added support for fork parameter, see resources.c: openresourcefile and pushresourcefile */ 
00697                 goto error;
00698     #endif
00699         }
00700     
00701     if (!newfilewindow (fspec, fnum, rnum, flhidden, wnew)) 
00702         goto error;
00703     
00704     w = *wnew;
00705     
00706     shellpushglobals (w);
00707     
00708     (**shellwindowinfo).flneversaved = (boolean) config.flcreateonnew;
00709     
00710     fl = (*shellglobals.newrecordroutine) ();
00711     
00712     shellpopglobals ();
00713     
00714     if (!fl)
00715         goto error;
00716     
00717     zoomfilewindow (w);
00718     
00719     shellpopglobals ();
00720     
00721     return (true);
00722     
00723     error:
00724     
00725     disposeshellwindow (w); /*checks for nil*/
00726     
00727     if (fnum != 0) { /*we actually opened a file*/
00728         
00729         closefile (fnum);
00730         
00731         #ifdef MACVERSION       
00732             closeresourcefile (rnum);
00733         #endif      
00734         
00735         deletefile (fspec);
00736         }
00737     
00738     shellpopglobals ();
00739     
00740     return (false);
00741     } /*shellnewfile*/
00742     
00743 
00744 boolean shellnew (void) {
00745     
00746     /*
00747     new front end to shellnewfile, isolates user interface
00748 
00749     5.0d8 dmb: pass file type to sfdialog for Win
00750     */
00751     
00752     tyconfigrecord lconfig;
00753     tyfilespec fspec;
00754     tysftypelist filetypes;
00755     WindowPtr w;
00756     
00757     shellgetconfig (iddefaultconfig, &lconfig);
00758     
00759     clearbytes (&fspec, sizeof (fspec));
00760     
00761     getuntitledfilename (fsname (&fspec));
00762     
00763     if (lconfig.flcreateonnew) {
00764         
00765         filetypes.cttypes = 1;
00766 
00767         filetypes.types [0] = lconfig.filetype;
00768         
00769         if (!sfdialog (sfputfileverb, nil, &filetypes, &fspec, 'LAND')) /* 2005-10-06 creedon - added 'LAND' */ /*user canceled*/
00770             return (false);
00771         }
00772     
00773     return (shellnewfile (&fspec, false, &w));
00774     } /*shellnew*/
00775     
00776     
00777 boolean shellsave (WindowPtr wsave) {
00778     
00779     /*
00780     6/14/91 dmb: dirty window menu after successful save
00781     */
00782     
00783     register WindowPtr w;
00784     tyfilespec fspec;
00785     boolean fl;
00786     boolean flrunnable;
00787     OSType ostype;
00788     bigstring osstring;
00789 
00790     if (!shellpushrootglobals (wsave)) /*save only operates on root windows*/
00791         return (false);
00792     
00793     w = shellwindow; /*move into register*/
00794     
00795     if (config.flstoredindatabase) {
00796         
00797         windowgetfspec (w, &fspec);
00798         
00799         (*shellglobals.setdatabaseroutine) (); /*make sure db.c is ready to be called*/
00800         }
00801     
00802     else {
00803         if (!windowgetfspec (w, &fspec)) { /*no file open to save to, prompt the user for name*/
00804             
00805             shellpopglobals ();
00806             
00807             return (shellsaveas (w, nil, false));
00808             }
00809         }
00810 
00811     //RAB: 1/22/98 - set runnable if the file extension is ftds
00812     flrunnable = false;
00813 
00814     if (getfiletype (&fspec, &ostype)) {
00815         ostypetostring (ostype, osstring);
00816 
00817         //use string since the windows type can be any case
00818         if (equalidentifiers (osstring, str_desktopscript))
00819             flrunnable = true;
00820         }
00821 
00822     fl = shellsavefile (w, &fspec, windowgetfnum (w), windowgetrnum (w), false, flrunnable);
00823     
00824     if (fl) { /*no error saving*/
00825         
00826         (**shellwindowinfo).flneversaved = false;
00827         
00828         #ifndef version42orgreater //def MACVERSION
00829         
00830             shellsavewindowposition (w); 
00831             
00832             shellsavedefaultfont (w);
00833         
00834         #endif
00835 
00836         windowgetfspec (w, &fspec);
00837         
00838         flushvolumechanges (&fspec, windowgetfnum (w));
00839         
00840         windowsetchanges (w, false);
00841         
00842         shellwindowmenudirty ();
00843         }
00844     
00845     shellpopglobals ();
00846     
00847     return (fl);
00848     } /*shellsave*/
00849 
00850 
00851 boolean shellclosechildwindows (hdlwindowinfo hparent) {
00852     
00853     /*
00854     2.1b1 don't ignore childcloseroutine's return value, and pass it 
00855     along to caller
00856 
00857     5.0b12 dmb: I don't know if we can ever end up reentering a child 
00858     window's close routine, but not what the flag is in the hdlwindowinfo,
00859     let's make sure. we can't selectively skip children as coded, so we 
00860     just bail
00861     
00862     5.0.2b13 dmb: set flbeingclosed while we call childcloseroutine
00863     */
00864     
00865     while (true) {
00866         
00867         hdlwindowinfo hchild;
00868         register WindowPtr w;
00869         boolean flclosed;
00870         
00871         if (!shellfirstchildwindow (hparent, &hchild))
00872             return (true);
00873         
00874         if ((**hchild).flbeingclosed) //don't reenter
00875             return (true);
00876         
00877         (**hchild).flbeingclosed = true;
00878         
00879         shellpushglobals ((**hparent).macwindow);
00880         
00881         w = (**hchild).macwindow;
00882         
00883         flclosed = (*shellglobals.childcloseroutine) (w);
00884         
00885         shellpopglobals ();
00886         
00887         (**hchild).flbeingclosed = false;
00888         
00889         if (!flclosed)
00890             return (false);
00891         
00892         disposeshellwindow (w);
00893         } /*while*/
00894     
00895     return (true);
00896     } /*shellclosechildwindows*/
00897     
00898     
00899 boolean shellclosewindow (WindowPtr wclose) {
00900     
00901     /*
00902     close the indicated child window
00903     */
00904     
00905     register WindowPtr w = wclose;
00906     hdlwindowinfo hinfo, hparentinfo;
00907     boolean flclosed;
00908     
00909     if (w == nil) /*closing a nil window is very easy*/
00910         return (true);
00911     
00912     getwindowinfo (w, &hinfo);
00913     
00914     hparentinfo = (**hinfo).parentwindow;
00915     
00916     #ifdef version42orgreater
00917         if (hparentinfo == nil) // don't close -- hide
00918             return (shellhidewindow (hinfo));
00919     #else
00920         assert (hparentinfo != nil); /*we should be part of another window's data structure*/
00921     #endif
00922     
00923     shellpushglobals ((**hparentinfo).macwindow); /*close message goes to parent window*/
00924     
00925     flclosed = (*shellglobals.childcloseroutine) (w);
00926     
00927     shellpopglobals ();
00928     
00929     if (!flclosed)
00930         return (false);
00931     
00932     disposeshellwindow (w); 
00933     
00934     return (true);
00935     } /*shellclosewindow*/
00936 
00937 
00938 boolean shellclose (WindowPtr wclose, boolean fldialog) {
00939     
00940     /*
00941     return false if the user made changes and chooses not to discard them.
00942     
00943     dmb 9/14/90:  added killundo to release memory before close
00944     
00945     3/26/93 dmb: check result of getwindowinfo
00946     
00947     4.1b5 dmb: added shellglobals.precloseroutine for ccpreclose
00948     
00949     4.1b6 dmb: added flclosingmainshellwindow to prevent reentracy
00950 
00951     5.0b7 dmb: recently-added autosave flag is now checked right
00952 
00953     5.0b12 dmb: replaced static flclosingmainshellwindow with windowinfo's
00954     flbeingclosed
00955 
00956     5.1.5b15 dmb: wait for activates before putting up save dialog; closeall
00957     doesn't do it for us anymore.
00958     */
00959     
00960     register WindowPtr w = wclose;
00961     hdlwindowinfo hinfo;
00962     long ctbytes;
00963     
00964     if (w == nil) /*closing a nil window is very easy*/
00965         return (true);
00966 
00967 #ifdef MACVERSION   
00968     #ifdef flnewfeatures
00969     
00970     if (!isshellwindow (w)) {
00971         
00972         if (uisIsSharedWindow (w))
00973             return (uisCloseSharedWindow (w));
00974         
00975         return (false);
00976         }
00977     
00978     #endif
00979 #endif
00980     
00981     if (!getwindowinfo (w, &hinfo))
00982         return (false);
00983     
00984     if ((**hinfo).parentwindow != nil) /*part of another window's data structure*/
00985         return (shellclosewindow (w));
00986     
00987     if ((**hinfo).flbeingclosed) /*don't reenter*/
00988         return (true);
00989     
00990     (**hinfo).flbeingclosed = true;
00991     
00992     shellpushglobals (w);
00993     
00994     if (fldialog && !(*shellglobals.precloseroutine) (w))
00995         goto cancelled;
00996     
00997     if (fldialog && (**hinfo).flmadechanges) {
00998         
00999         bigstring bs;
01000         
01001         if (config.flstoredindatabase && langgetuserflag (idautosave, true)) { //5.0a23 dmb: databases save w/out confirmation
01002                 
01003                 if (!keyboardstatus.flshiftkey) // shift disables autosave
01004                     if (!shellsave (w))
01005                         goto cancelled;     
01006             }
01007         else {
01008             shellgetwindowtitle (hinfo, bs); // 7.24.97 dmb: was windowgettitle
01009             
01010             filefrompath (bs, bs);
01011             
01012             if (flscriptrunning)
01013                 langpartialeventloop (activMask);
01014             else
01015                 shellpartialeventloop (activMask); /*wait for activates*/
01016 
01017             switch (savedialog (bs)) {
01018                 
01019                 case 1: /*OK*/
01020                     if (!shellsave (w))
01021                         goto cancelled;
01022                     
01023                     break;
01024                 
01025                 case 2: /*discard changes*/
01026                     break;
01027                     
01028                 case 3: /*cancel, continue editing*/
01029                     goto cancelled;
01030                 } /*switch*/
01031             }
01032         }
01033     else { /*changes were not made*/
01034         
01035         /*
01036         if ((**hinfo).flchangedposition)
01037             shellsave (w);
01038         */
01039         }
01040     
01041     killownedundo (w);
01042     
01043     flinhibitclosedialogs = true; /*it's too late to stop the process now*/
01044     
01045     (*shellglobals.closeroutine) ();
01046     
01047     shellclosechildwindows (hinfo); /*close any windows that parent didn't close*/
01048     
01049     flinhibitclosedialogs = false; /*keep it cleared*/
01050     
01051     (*shellglobals.disposerecordroutine) ();
01052     
01053     shellclearwindowdata ();
01054     
01055     shellpopglobals ();
01056     
01057     zoomtoorigin (w);
01058     
01059     closewindowfile (w);
01060     
01061     (**hinfo).flbeingclosed = false; //it's about to be disposed, but might as well
01062     
01063     disposeshellwindow (w);
01064     
01065     shellcallfilehooks (); /*a file was just opened or closed*/
01066     
01067     ctbytes = longinfinity;
01068 
01069     hashflushcache (&ctbytes); //rab 6.0b6 free the memory
01070 
01071     return (true);
01072     
01073     cancelled:
01074     
01075         shellpopglobals ();
01076         
01077         (**hinfo).flbeingclosed = false;
01078         
01079         return (false);
01080     } /*shellclose*/
01081 
01082 
01083 static boolean shellclosefilewindowvisit (WindowPtr wclose, ptrvoid fldialog) {
01084     
01085     /*
01086     5.0.2b13 dmb: bring to front before shellclose if fldialog
01087     */
01088     
01089     hdlwindowinfo hinfo;
01090     
01091     if (!getwindowinfo (wclose, &hinfo))
01092         return (false);
01093     
01094     if ((**hinfo).parentwindow != nil)
01095         //return (shellclosewindow (wclose));
01096         return (true);
01097     
01098     if ((**hinfo).configresnum != iddefaultconfig) {
01099     
01100         if (fldialog) {
01101             
01102             shellbringtofront (hinfo);
01103             
01104             shellupdatenow ((**hinfo).macwindow);
01105             }
01106         
01107         return (shellclose (wclose, (boolean) ((long) fldialog)));
01108         }
01109     
01110     return (true);
01111     } /*shellclosefilewindowvisit*/
01112 
01113 
01114 boolean shellcloseall (WindowPtr w, boolean fldialog) {
01115     
01116     /*
01117     close all "root" windows, or ones that have a parent field equal to nil.
01118     
01119     it is the responsibility of the root window handler to close all of his
01120     subordinate windows.
01121     
01122     return false if some windows are still open on exit.
01123     
01124     10/15/90 dmb: use frontrootwindow instead of firstrootwindow, so windows peel
01125     off front to back.  also, wait for activates so globals are set cleanly
01126     
01127     3/6/91 dmb: now take window parameter.  if it's nil or is a root window, 
01128     close all as before.  however, if w is non-nil, and it's a child window, 
01129     close all the children of its root.
01130     
01131     4/20/93 dmb: wait for activates _after_ determining that there's a root window left
01132     
01133     4.16 dmb: call langpartialeventloop if a script is running.
01134     
01135     7.31.97 dmb: if a non-child window is specified, and it's not a root, 
01136     close all windows non-root windows.
01137 
01138     5.0b10 dmb: don't bring root to the front after closing all children
01139     
01140     5.0.2b12 dmb: don't ignore the result of shellvisittypedwindows
01141 
01142     5.1.5b15 dmb: don't wait for activates between closes, leave that to
01143     shellclose when we need to put up a dialog
01144     */
01145     
01146     hdlwindowinfo hinfo;
01147     boolean fl;
01148     
01149     #ifdef MACVERSION
01150         uisCloseAllSharedWindows ();
01151     #endif
01152     
01153     if (w != nil) {
01154         
01155         if (!getwindowinfo (w, &hinfo))
01156             return (false);
01157         
01158         if ((**hinfo).parentwindow != nil) { /*it's a child window; close all children*/
01159             
01160             getrootwindow (w, &hinfo);
01161             
01162             if (!shellclosechildwindows (hinfo))
01163                 return (false);
01164             
01165             #ifndef version5orgreater
01166                 shellbringtofront (hinfo);
01167             #endif
01168             
01169             return (true);
01170             }
01171         
01172         if (!shellclose (w, fldialog))
01173             return (false);
01174         
01175         if ((**hinfo).configresnum != iddefaultconfig)
01176             return (shellvisittypedwindows (-1, &shellclosefilewindowvisit, (ptrvoid) ((long) fldialog)));
01177         }
01178     
01179     if (!shellvisittypedwindows (-1, &shellclosefilewindowvisit, (ptrvoid) ((long) fldialog)))
01180         return (false);
01181     
01182     while (true) { /*close all windows*/
01183         
01184         if (!frontrootwindow (&hinfo)) /*no more root windows*/
01185             return (true);
01186         
01187         flshellclosingall = true;
01188         
01189         fl = shellclose ((**hinfo).macwindow, fldialog);
01190         
01191         flshellclosingall = false;
01192         
01193         if (!fl)
01194             return (false);
01195         
01196         //shellsetglobals (nil); /*everything is disposed; must clear for nested push/popglobals*/
01197         } /*while*/
01198     } /*shellcloseall*/
01199 
01200 
01201 boolean shellrevert (WindowPtr wrevert, boolean fldialog) {
01202     
01203     /*
01204     dmb 10/3/90:  1st implementation - pretty rough
01205     */
01206     
01207     register WindowPtr w;
01208     
01209     if (!shellpushrootglobals (wrevert)) /*revert only operates on root windows*/
01210         return (false);
01211     
01212     w = shellwindow; /*move into register*/
01213     
01214     if (fldialog) {
01215         
01216         bigstring bs;
01217         
01218         shellgetwindowtitle (shellwindowinfo, bs); // 7.24.97 dmb: was windowgettitle
01219         
01220         filefrompath (bs, bs);
01221         
01222         if (!revertdialog (bs)) {
01223             
01224             shellpopglobals ();
01225             
01226             return (false);
01227             }
01228         }
01229     
01230     killownedundo (w);
01231     
01232     shellbringtofront (shellwindowinfo);
01233     
01234     flinhibitclosedialogs = true;
01235     
01236     (*shellglobals.closeroutine) ();
01237     
01238     shellclosechildwindows (shellwindowinfo); /*close any windows that parent didn't close*/
01239     
01240     flinhibitclosedialogs = false;
01241     
01242     (*shellglobals.disposerecordroutine) ();
01243     
01244     shellclearwindowdata ();
01245     
01246     prepuserforwait (w); /*gray the window, set watch cursor while reloading*/
01247     
01248     if (!(*shellglobals.loadroutine) (windowgetfnum (w), windowgetrnum (w))) {
01249         
01250         closewindowfile (w);
01251         
01252         disposeshellwindow (w);
01253         
01254         shellpopglobals ();
01255         
01256         alertstring (reopenerrorstring);
01257         
01258         shellcallfilehooks (); /*a file was just opened or closed*/
01259         
01260         return (false);
01261         }
01262     
01263     windowsetchanges (w, false);
01264     
01265     shellpopglobals ();
01266     
01267     return (true);
01268     } /*shellrevert*/
01269 
01270 
01271 boolean shellopendefaultfile (void) {
01272     
01273     /*
01274     no files were selected to be open from the finder.  we either open a new 
01275     file, or we try to open the default startup file -- similar to autoexec.bat 
01276     from MS-DOS and System.Startup from UCSD Pascal.
01277     
01278     5/20/91 dmb: if the option key is down, just do a normal open file
01279     
01280     4/24/92 dmb: use filegetapplicationvnum rather than zero (the default volume) 
01281     when opening the default file.  otherwise, if the default volume changes later,
01282     the file info won't be adequate to locate the file.
01283     
01284     5/19/92 dmb: always return a value; explicitly return boolean
01285 
01286     7.30.97 dmb: use defaultpath instead of application filespec, 
01287     and use new setfsfile to plug in default file name
01288     */
01289     
01290     tyfilespec fs;
01291     boolean fl = false;
01292     boolean flfolder;
01293     bigstring bsdefault;
01294     
01295     if (optionkeydown ())
01296         return (shellopen ());
01297     
01298     shellpushdefaultglobals (); /*so config is correct*/
01299     
01300     if (config.flnewonlaunch)
01301         fl = shellnew ();
01302     else {
01303         getapplicationfilespec (nil, &fs); /*get our own app fspec*/
01304     //  
01305         
01306         if (getstringlist (defaultlistnumber, startupfilename, bsdefault)) {
01307             
01308             setfsfile (&fs, bsdefault);
01309 
01310             if (fileexists (&fs, &flfolder))
01311                 fl = shellopenfile (&fs, false, nil);
01312             else {
01313                 
01314                 filegetdefaultpath (&fs);
01315                 
01316                 setfsfile (&fs, bsdefault);
01317                 
01318                 if (fileexists (&fs, &flfolder))
01319                     fl = shellopenfile (&fs, false, nil);
01320                 else
01321                     fl = shellopen ();
01322                 }
01323             }
01324         }
01325     
01326     shellpopglobals ();
01327     
01328     return (fl);
01329     } /*shellopendefaultfile*/
01330 
01331 
01332 #ifdef flsystem6
01333 
01334 void shellopeninitialfiles (void) {
01335     
01336     /*
01337     if the user double-clicked on the applications with files selected,
01338     then we open the files.  otherwise we try to open the default startup
01339     file -- similar to autoexec.bat from MS-DOS and System.Startup from 
01340     UCSD Pascal.
01341     */
01342     
01343     bigstring bs;
01344     register short ctfiles;
01345     short vnum;     
01346     
01347     ctfiles = countinitialfiles ();
01348     
01349     if (ctfiles > 0) { /*one or more files selected on launch*/
01350         
01351         register short i;
01352         
01353         for (i = 1; i <= ctfiles; i++) {
01354             
01355             getinitialfile (i, bs, &vnum);
01356             
01357             shellopenfile (bs, vnum, nil);
01358             } /*for*/
01359         }
01360     
01361     else { /*zero files selected on launch*/
01362         
01363         shellopendefaultfile ();
01364         }
01365     } /*shellopeninitialfiles*/
01366 
01367 #endif
01368 
01369 
01370 #ifdef WIN95VERSION
01371 
01372 void shellopeninitialfiles (void) {
01373     /* Add command line open and drag-drop open here */
01374     if (!openwindowsparamlinefiles ())
01375         shellopendefaultfile ();
01376     } /*shellopeninitialfiles*/
01377 
01378 #endif
01379 
01380 

Generated on Wed May 31 18:20:01 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6