home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / DocShell / RlShell.cpp < prev    next >
Encoding:
Text File  |  1996-04-22  |  146.3 KB  |  4,784 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        RlShell.cpp
  3.  
  4.     Contains:    Shell implementation
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <12>      4/4/96    NP        1338241: If shell is in infinite loop,
  13.                                     quit.
  14.         <11>      4/2/96    RA        1320667: Call
  15.                                     Activate/DeactivateFrontWindows around
  16.                                     ShowAboutScreen modal dialog call
  17.         <10>     3/29/96    DM        1334273: propagate fatal Bento errors and
  18.                                     show low mem alert and quit when
  19.                                     out-of-memory err occurs while trying to
  20.                                     show low memory alert (solving infinite
  21.                                     loop).
  22.          <9>     3/22/96    CC        1307182: UpdateMenus: Check for null edit
  23.                                     menu.
  24.          <8>    .03.1996    NP        1307182: Stuff for caching shell menu
  25.                                     items.
  26.          <7>     3/20/96    EL        1331460 Save a Copy does not include the
  27.                                     resources in parent document (e.g.
  28.                                     preferred memory size)
  29.          <6>     3/14/96    NP        1287354: Hide invisible files in the Open
  30.                                     Document dialog.
  31.          <5>    .03.1996    NP        1223399: Don't show error dialog while
  32.                                     suspending.
  33.          <4>    .03.1996    NP        1304875,1317218: Fix can't-cancel problem
  34.                                     on receipt of quit event.
  35.          <3>      3/1/96    JP        1314798: Made new documents run from temp
  36.                                     file
  37.          <2>      1/4/96    eeh        1302569: handle fat plugins
  38.        <208>    10/26/95    TÇ        1296574 GM:Cannot set default memory
  39.                                     partition size.
  40.        <207>    10/25/95    TÇ        1295281 GM:  Stationery not behaving
  41.                                     properly.
  42.        <206>    10/24/95    jpa        1293441: Beefed up error dialog and fg/bg
  43.                                     detection. Moved mem stuff to new
  44.                                     ShellMem.cpp.
  45.        <205>    10/22/95    TÇ        1291419 GM: File type set incorrectly for
  46.                                     Old Mac data dragged to Finder from
  47.                                     OpenDoc.
  48.        <204>    10/18/95    CC        GM 1290956: Do not display alert if
  49.                                     ExportClipboard fails during suspend event.
  50.        <203>    10/18/95    eeh        1287095: exception safety
  51.        <202>    10/16/95    CC        GM 1292157: GetThisKindFromList returns
  52.                                     ODType instead of void.
  53.        <201>    10/13/95    TÇ        1284461 GM: Parts that are created in a
  54.                                     document should not automatically be given
  55.                                     names
  56.        <200>     10/4/95    jpa        Don't throw exceptions from ExceptionAlert,
  57.                                     and don't check low memory on suspend evt
  58.                                     [1289074]
  59.        <199>     10/3/95    TJ        Added Includes so it compiles
  60.        <198>     9/29/95    eeh        1287262: use ShellDef.h
  61.        <197>     9/28/95    JP        1287110: Made Save As dialog Stationery
  62.                                     button work correctly
  63.        <196>     9/27/95    TÇ        1287338 GM: ODOpenDraft returns with
  64.                                     incorrect refcount on draft if it's not
  65.                                     read-only
  66.        <195>     9/27/95    eeh        1284464: use ClipStringToBytes; 1284893:
  67.                                     fix capitalization
  68.        <194>     9/26/95    TÇ        1287296 GM:Refcount error and eventual
  69.                                     crash saving across volumes
  70.        <193>     9/26/95    eeh        1284893: add and use BITTEST
  71.        <192>     9/20/95    TÇ        1284568 GM: Choosing cancel in Save As...
  72.                                     dlg closes doc.
  73.        <191>     9/20/95    eeh        1284893: need TRY around SetErrorCode
  74.        <190>     9/19/95    eeh        1284893: don't close connection to plugin
  75.                                     unless told to
  76.        <189>     9/13/95    VL        1283523: Dragging parts between Documents &
  77.                                     Finder needs to reflect new behavior
  78.        <188>     9/13/95    TJ        Removed the #include for the Shell
  79.                                     Plugins.xh
  80.        <187>     9/13/95    TÇ        1280629 FB1:  *OpenDoc crashes allocating
  81.                                     memory to display alert for out of memory!
  82.        <186>     9/12/95    JBS        1282526 Status message needed during "Save
  83.                                     Doc to another volume"
  84.        <185>     9/12/95    eeh        1283557: don't call IsCommandRegistered
  85.        <184>     9/12/95    TÇ        1270499 FB1:  OpenDoc launcher creates
  86.                                     bogus document for old style documents
  87.        <183>     9/12/95    eeh        1253309: change name of symbol sought to
  88.                                     ODShellPluginInstall
  89.        <182>     9/12/95    eeh        1283557: call IsCommandRegistered; 1253309:
  90.                                     ScanShellPlugInsFldr changes for plugins
  91.        <181>     9/11/95    TÇ        1252120 FB1: New documents saved w/ StdFile
  92.                                     & trashed if closed w/o saving
  93.        <180>     9/11/95    NP        1272294: Messaging code cleanup.
  94.        <179>      9/8/95    TÇ        1252120 FB1: New documents saved w/ StdFile
  95.                                     & trashed if closed w/o saving
  96.        <178>      9/8/95    jpa        Don't display error kODErrAlreadyNotified.
  97.                                     [1278813]
  98.        <177>      9/8/95    TÇ        1281096 FB2:Many constants in ODTypesB
  99.                                     without kOD prefix!
  100.        <176>      9/8/95    TÇ        1282092 FB2: Shell must check nil after SOM
  101.                                     new
  102.        <175>      9/7/95    eeh        1278987: use UniquifyName
  103.        <174>      9/7/95    CG        #1270499 FB1:OpenDoc launcher creates bogus
  104.                                     document
  105.        <173>      9/7/95    EL        1281410: Window for draft just above a
  106.                                     deleted draft will not be automatically
  107.                                     closed when that draft is deleted.
  108.        <172>      9/6/95    VL        Fixed build for MW.
  109.        <171>      9/6/95    TJ        Fixed build for scpp.
  110.        <170>      9/5/95    TÇ        1280334 Shell's Save menu item available
  111.                                     even on locked documents, 1276297 FB1:
  112.                                     Save As dialog's Kind popup doesn't handle
  113.                                     Translate To correctly, FBs: 1266428,
  114.                                     1274419, 1274421, 1274423, 1274429, 1274435
  115.                                     Fixed the Shell to handle multiple
  116.                                     documents in a process. Needed for
  117.                                     CyberDog.
  118.        <169>     8/31/95    DM        1273863, 1275336: ODClipboard::DraftSaved
  119.        <168>     8/26/95    TÇ        1273606 FB: SemtIntf should delete
  120.                                     _fHelper,1279063 FB3:  must check results
  121.                                     of SOM operator new
  122.        <167>     8/25/95    JP        1262410: Update comments on Open &
  123.                                     ODGetIconFamily takes frame
  124.        <166>     8/25/95    eeh        1263528: revert to using
  125.                                     fOptionKeyDownOnMenuBarClick
  126.        <165>     8/22/95    eeh        1276821; 1276281: menu changes; 1263528:
  127.                                     handle cmd-option-keys; 1267136: change
  128.                                     menu ids
  129.        <164>     8/17/95    eeh        1272319: in RealShell::Open, don't null out
  130.                                     fDraft and release rootPart
  131.        <163>     8/15/95    TÇ        1261899 DocUtils getters should be renamed
  132.                                     Acquire___ , 1262179 FB: Shell calls
  133.                                     BlockMove() in many places , 1256049 FB:
  134.                                     Silent quit caused by exception in
  135.                                     RlShell::Open, 1260378 MouseEvents in
  136.                                     non-OpenDoc windows do not get dispatched
  137.                                     if...
  138.        <162>     8/15/95    CC        1275241: Added #include of Editons.h.
  139.        <161>     8/13/95    TÇ        1259154 FB: Extra &'s in
  140.                                     ScanShellPlugInsFolder function in
  141.                                     RlShell.cpp
  142.        <160>     8/12/95    TÇ        1276812 Need to use TempObjs and TempRefs
  143.                                     for exception safety and to avoid TRY
  144.                                     blocks, 1276807 Opt./Bug: use StdTypIO
  145.                                     routines for portable streaming & smaller
  146.                                     footprint
  147.        <159>      8/8/95    TJ        Declared FindObjsProc extern C
  148.        <158>      8/8/95    jpa        Document file synchronization &
  149.                                     notification support [1259401]. Display app
  150.                                     heap info in addition to OD heap; remove
  151.                                     system heap [1262722]
  152.        <157>      8/7/95    TJ        Typecast &FindObjsProc to (MMBlockInfoProc)
  153.                                     for the MMWalkHeap call so it will compile
  154.                                     with SCpp.
  155.        <156>      8/4/95    DM        1270320: mem leaks, 1267956: leak-detect
  156.                                     tool; new menu items for tracking stack
  157.                                     crawls, dumping tracked blocks, dumping on
  158.                                     close; watch keyboard on launch (and during
  159.                                     dump) to enable tracking (and filter out
  160.                                     NewClass); consolidate crawls in dump
  161.        <155>      8/2/95    VL        1270320: Release baseMenuBar after creating
  162.                                     it.
  163.        <154>     7/28/95    VL        1270320: Don't call DraftSaved when the
  164.                                     draft is not opened. Use TempPlatformFile
  165.                                     in SaveACopy. Dispose of fSaveCopyData
  166.                                     fields and editorID in AskUserWhereToPutIt.
  167.        <153>     7/25/95    DM        #1270320: Memory leak fixes.
  168.        <152>     7/25/95    VL        1270320: Dispose rootPartType in New.
  169.        <151>     7/24/95    CG        #1270320: Memory leak fixes.
  170.        <150>     6/30/95    TÇ        1264094 BB:Custom document size cannot be
  171.                                     attached to a stationery.
  172.        <149>     6/29/95    eeh        1263784: add and use SendFinderODOCEvent
  173.        <148>     6/28/95    RR        1242642 BB Mostly ref counting
  174.        <147>     6/28/95    CG        1263107 BB: No more crash when closing a
  175.                                     NoPart document.
  176.        <146>     6/25/95    TÇ        1242642 BB: Turn on ODDebug warning if
  177.                                     refcount is wrong in
  178.                                     ODRefCntObjectsomUninit.
  179.        <145>     6/21/95    JBS        turn on mem validation
  180.        <144>     6/21/95    CC        1260937: BB: ODTypeListIterator must return
  181.                                     copies of ODType values.
  182.        <143>     6/20/95    TÇ        1217754 BB: Delete Document command 1234877
  183.                                     BB: OpenDoc creates a bad document if
  184.                                     stationary launch fails.
  185.        <142>     6/16/95    CC        1257141: InitKindsPopup:  Pass kODNULL as
  186.                                     translateFromList parameter to
  187.                                     GetDestinationKindsList.
  188.        <141>     6/15/95    NP        1237542: Fix CORBA memory stuf
  189.        <140>     6/15/95    RR        #1256879 Get->AcquireCurrentMenuBar
  190.        <139>      6/8/95    RR        #1257260 Collapse base classes. #1214898
  191.                                     StdTypes.r -> ODTypes.r
  192.        <138>      6/7/95    TÇ        1241521 Save a Copy of read only document
  193.                                     ends up in temp folder.  Fixed for newly
  194.                                     created documents as well.
  195.        <137>      6/2/95    TÇ        1253327 BB: Creating Stationery will drop
  196.                                     it onto desktop.  Now created in proper
  197.                                     location
  198.        <136>      6/2/95    TÇ        1216915 BB:Trying to open a document that
  199.                                     is already open causes an error.
  200.        <135>      6/1/95    jpa        ExceptionAlert displays msg in programmer
  201.                                     alert box. [1242839]
  202.        <134>     5/26/95    RR        #1251403: Multithreading naming support
  203.        <133>     5/25/95    jpa        Fixed GetKeys call for univ hdrs 2.0
  204.                                     [1241078, 1253324]
  205.        <132>     5/21/95    TÇ        1249149 BB: Crash when opening huge
  206.                                     document
  207.        <131>     5/20/95    TÇ        1211170 Two launches to open.  Fixed
  208.                                     Stationery creation so that it creates
  209.                                     stationery on the desktop if you have no
  210.                                     Stationery folder.
  211.        <130>     5/19/95    TÇ        1155852 BB: String constants need to be
  212.                                     moved to resource for Localization, 1249396
  213.                                     (was BB) OpenDoc shell should serialize
  214.                                     stationery creation., 1234877 BB: OpenDoc
  215.                                     creates a bad document if stationary launch
  216.                                     fails., 1211170 Two launches to open
  217.                                     stationery
  218.        <129>     5/18/95    eeh        1236414: pass hasWriteAccess to
  219.                                     DraftWindow::Drafts()
  220.        <128>     5/18/95    CG        #1249263    BB: BndNSUtl.cpp does not compile
  221.                                     standalone.
  222.        <127>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  223.                                     refcount
  224.        <126>     5/16/95    TÇ        1249181 Init methods should be private,
  225.                                     Shell shouldn't call InitTypeList
  226.        <125>     5/10/95    eeh        1232095: used DraftSaved; 1239830 :respond
  227.                                     to kDraftWinLowMemAbort
  228.        <124>      5/7/95    TÇ        1155852 BB: String constants need to be
  229.                                     moved to resource for Localization (mostly
  230.                                     done), 1246777 BB: Shell Plugin install
  231.                                     method needs to pass fDraft not draft.,
  232.                                     1246539 Shell calls private window methods
  233.        <123>      5/5/95    TJ        ODDialogBegin is now passed the current
  234.                                     Menu bar.
  235.        <122>      5/4/95    eeh        1232095: set create date when saving (temp)
  236.        <121>      5/4/95    jpa        Check for low memory in event loop. Alert
  237.                                     user [1235657] and call Purge [1221904].
  238.        <120>      5/1/95    CG        #1240845    BB: Kinds popups need to include
  239.                                     all kinds that an editor can edit.
  240.        <119>      5/1/95    CL        Dialog fixes [1224714, 1228662, 1228678,
  241.                                     1229912].
  242.        <118>     4/30/95    TÇ        1242084 BB - Operations should not be
  243.                                     undoable across Save's
  244.        <117>     4/29/95    TÇ        1216130 BB: Shell should open top draft
  245.                                     upon receipt of open document Apple event
  246.        <116>     4/28/95    NP        1236303: Remove ODGetSystemHeap and
  247.                                     gSystemHeap.
  248.        <115>     4/28/95    eeh        1240648: use AcquireActiveWindow in
  249.                                     GetFrontDraft
  250.        <114>     4/27/95    TÇ        1241327 BB: Bad problems option-closing
  251.                                     child window (Not finished)
  252.        <113>     4/27/95    eeh        1240648: add ODDraft* param to
  253.                                     AskUserWhereToPutIt and SaveACopyAs; added
  254.                                     GetFrontDraft
  255.        <112>     4/27/95    CC        1243813: Removed MacAppAlert; use ShowAlert
  256.                                     in DlogUtil instead.
  257.        <111>     4/19/95    TÇ        #1241116 DR/BB: Shell should externalize
  258.                                     newdraft before getting root part kind.
  259.        <110>     4/15/95    TÇ        #1216915 DR/BB:Trying to open a document
  260.                                     that is already open causes an error.
  261.        <109>     4/14/95    TÇ        #1186294    DR/BB: Binding for editor also
  262.                                     affect making stationary
  263.                                     #1239463 Save a copy does not work
  264.                                     #1239933 BB: Save A Copy of a Read only
  265.                                     document fails
  266.        <108>     4/14/95    TÇ        #1237984 RealShell::()  UpdateMenus
  267.                                     defaults part info menu item to wrong text
  268.                                     #1235279 BB: InfoUtil & StdTypIO functions
  269.                                     should take Environment* and SU* when
  270.                                     possible
  271.        <107>     4/14/95    NP        1237538: Don't call SetMenuItemScript
  272.                                     anymore.
  273.        <106>     4/13/95    CG        #1221869 BB:  Shell now looks for Shell
  274.                                     Plug-Ins in the Shell Plug-Ins folder.
  275.        <105>     4/13/95    TJ        68K Opening Stationary causes crash.  Stack
  276.                                     was getting corrupted.  Fixed by JA
  277.        <104>     4/10/95    TÇ        #1234877    BB: OpenDoc creates a bad document
  278.                                     if stationary launch fails.
  279.                                     #1236210    BB: "Show Parts Bin" menu item
  280.                                     must be removed from the Edit menu
  281.                                     #1222541    BB: New document name
  282.                                     #1226675    Option-Close does not close all
  283.                                     Windows
  284.        <103>      4/7/95    RR        #1211085 Removed call to display base menu
  285.                                     bar in OpenDraft
  286.        <102>      4/7/95    eeh        1221297: added fPrintingOnly
  287.        <101>      4/5/95    CG        #1216169 BB, #1221135: When Editors folder
  288.                                     or OpenDoc Libraries folder is missing,
  289.                                     OpenDoc quits and displays error.
  290.        <100>      4/4/95    RR        #1226493 Call DisposeIText in UpdateMenus.
  291.         <99>     3/31/95    TÇ        1196067 BB: Can resize a window so small
  292.                                     that it disappears (Mostly fixed)
  293.                                     1204755 BB: Canceling save dialog when
  294.                                     Restart is chosen doesn't work correctly
  295.                                     1223465 BB: Opening and creating documents
  296.                                     under low disk space. (Creating documents
  297.                                     under low disk space part fixed).
  298.                                     1211032 BB: Invalid Permissions error
  299.                                     opening locked document
  300.         <98>     3/29/95    NP        1233490: Use Mac system constant for
  301.                                     international text stuff.
  302.         <97>     3/28/95    CG        #1221901 BB:  Shell can now open
  303.                                     non-OpenDoc documents.
  304.         <96>     3/24/95    eeh        1229961: pass ev to some draftwindow
  305.                                     methods
  306.         <95>     3/24/95    CG        #1221473 is really the bug number.
  307.         <94>     3/24/95    CG        #122143: Part API change for Doc/Part Info
  308.                                     dialogs for viewers or readonly docs.
  309.         <93>     3/22/95    RR        #1225420, 122793 Fixed CloseWindow
  310.                                     OpenDraft only calls OpenWindows if not
  311.                                     already internalized. WindowList became
  312.                                     RootFrameList
  313.         <92>     3/21/95    TÇ        Changed the rest of the #ifdef ODDebug to
  314.                                     #if  ODDebug.  Also fixed #1227362
  315.                                     Incorrect use of ODFinalReleaseObject.
  316.         <91>     3/20/95    TJ        Changed #ifdef ODDebug to #if ODDebug, and
  317.                                     included "MemDebg.h".
  318.         <90>     3/16/95    TÇ        Also, #1190903 DocShell calls
  319.                                     ODLinkManager::DraftSaved on Save a Copy..
  320.         <89>     3/16/95    TÇ        #1226090 BB: NonDebug DebugStrs in RlShell
  321.                                     #1226375 Should not call NewRgn
  322.         <88>     3/15/95    eeh        1194180: removed parameter from
  323.                                     CloseDraft()
  324.         <87>     3/10/95    CC        1225050: Call ODClipboard::DraftClosing
  325.                                     instead of ExportClipboard when draft is
  326.                                     closed; Call ExportClipboard from
  327.                                     destructor.
  328.                                     1194180: CloseDraft shouldn't remove draft
  329.                                     during iteration. [for eeh]
  330.         <86>      3/7/95    RR        # 1151165 Cleaned up UpdateMenus a bit
  331.         <85>      3/6/95    jpa        Use dialog utilities (ODGetNewDialog,
  332.                                     ODDialogFilterProc). [1218957]
  333.         <84>      3/1/95    RR        #1205622 && #1164863 .CloseDraft removes
  334.                                     draft from OpenDrafts list. Close open
  335.                                     drafts in ::Close. OpenDraft doesn't call
  336.                                     WS:Internalize if draft is open
  337.                                     Register commands for shell menus (not
  338.                                     items) Use private constants for
  339.                                     Apple/Doc/Edit menu ids, since they're no
  340.                                     longer in CmdDefs.idl
  341.         <83>     2/23/95    EL        1220392: checking read only fails on file
  342.                                     share volumes.
  343.         <82>     2/20/95    TÇ        #1210979 BB: 5-$ Bugs need to be evaluated
  344.                                     and removed from Shell
  345.                                     #1221861 BB: Incomplete AOCE support needs
  346.                                     to be removed from OpenDoc
  347.         <81>     2/16/95    TÇ        #1210979 BB: 5-$ Bugs need to be evaluated
  348.                                     in Shell.  Fixed most of them, changed some
  349.                                     to bug #'s.
  350.                                     #1220906 Need ODFinalReleaseObject.
  351.         <80>     2/15/95    NP        1220650: Use kOnSystemDisk to call to
  352.                                     FindFolder.
  353.         <79>     2/13/95    TÇ        1193359: BB: Opening stationery on other
  354.                                     volume causes bus error in Messaging code
  355.                                     1211032: BB: Invalid Permissions Error
  356.                                     opening locked document
  357.         <78>     2/10/95    RR        #1211187 Fixed bug in CloseWindow to
  358.                                     support View In Window
  359.         <77>      2/2/95    CG        #1195019:  ValueNameSpace entries are now
  360.                                     copied in and out instead of pointers being
  361.                                     passed around.
  362.         <76>     1/27/95    TÇ        1196779    BB: Save a Copy with same name
  363.                                     produces a program error
  364.                                     1207898    BB: DocShell exits on exception
  365.                                     while processing OpenDoc apple event
  366.                                     1209735    Resolve 5-$ comments in
  367.                                     PlfmFile.cpp
  368.         <75>     1/26/95    eeh        1213354: ODActionData now an ODByteArray.
  369.         <74>     1/25/95    jpa        ODIText fixes. [1212619]
  370.         <73>     1/25/95    RR        #1211853 Removed session parameter from
  371.                                     ODWindowState::CreateMenuBar
  372.         <72>     1/23/95    CG        #1195019: ValueNameSpace methods now take
  373.                                     ODByteArray parameter instead of ODPtr.
  374.         <71>     1/23/95    RR        # 1211853 Use CreateMenuBar factory method
  375.         <70>     1/19/95    TÇ        #1209480 DocShell should change cursor when
  376.                                     putting up dialogs
  377.                                     #1210210 BB: API: ODShellPlugin::Install
  378.                                     should take ODDraft*
  379.         <69>     1/12/95    jpa        Don't use obsolete Toolbox names. [1211211]
  380.                                     Took out SCpp Pascal string workaround
  381.                                     [1193085]
  382.         <68>      1/4/95    eeh        1209163: enable menu commands in
  383.                                     RealShell::UpdateMenus
  384.         <67>    12/25/94    TÇ        1191189 Eliminate duplicate Def.h, Def.xh
  385.                                     files
  386.                                     1187709 More frequent, robust and earlier
  387.                                     error detection and reporting in the Shell
  388.         <66>    12/21/94    eeh        #1191567: release non-current draft when
  389.                                     window closed; 1192626: force save after
  390.                                     creating new draft
  391.         <65>    12/20/94    VL        1195012: Make Storage calls be
  392.                                     marshallable.
  393.         <64>    12/19/94    eeh        1192626: DraftIsOpen and fOpenDrafts;
  394.                                     change use of DraftWindow::Drafts()
  395.         <63>     12/5/94    jpa        Catch CFM errors opening new documents.
  396.                                     [1158966]
  397.         <62>    11/15/94    NP        Added kludge to allow Object Master
  398.                                     parsing.
  399.         <61>    11/14/94    VL        1155887: Used new pos code for top draft.
  400.         <60>     11/2/94    eeh        #1154961: set document name in OpenFile.
  401.         <59>    10/27/94    RR        #1192168 Added CheckMenuBar to reinstall
  402.                                     base menu bar when no part has the menu
  403.                                     focus
  404.         <58>    10/24/94    jpa        Worked around scpp bug in InstallMenuBar.
  405.                                     [1193085]
  406.         <57>    10/11/94    eeh        #1186849: change kODFileMenuID to
  407.                                     kODDocumentMenuID
  408.         <56>    10/10/94    NP        1192021-added new menu item.
  409.         <55>    10/10/94    CC        1191567 - Release draft if root window of
  410.                                     non-current draft is closed.
  411.         <54>     10/7/94    TÇ        #1187826 Document Info functionality &
  412.                                     fixed saving/reverting/opening to use
  413.                                     watch/arrow cursors correctly.
  414.         <53>     9/29/94    RA        1189812: Mods for 68K build.
  415.         <52>     9/26/94    TÇ        #1188679 Save A Copy As Stationery
  416.         <51>     9/23/94    VL        1155579, 1184272: Use StorUtil to
  417.                                     create/get container and its file.
  418.         <50>     9/22/94    NP        1187682: Added call to UseInputWindow.
  419.         <49>     9/21/94    CG        #1188048: Added check for NoPart.
  420.         <48>     9/20/94    NP        1187682: Initial TSM support.
  421.         <47>     9/19/94    TÇ        #1176047 Multiple Windows (i.e. floating
  422.                                     windows) are not deactivated when closing
  423.         <46>     9/16/94    eeh        #1186754: use a single document menu for
  424.                                     OCE/no OCE cases
  425.         <45>     9/15/94    TÇ        #1183572 implement OpenDoc Shell PlugIns,
  426.                                     and changes to support creating & opening
  427.                                     stationery with ODTestMain by dropping
  428.                                     editor library files on ODTestMain
  429.         <44>     9/14/94    jpa        Use new MemDebg API calls (OD-->MM)
  430.                                     [1186692]
  431.         <43>      9/9/94    jpa        Fixed missing-prototype probs [1185658]
  432.         <42>      9/8/94    eeh        #1185443: changes to account for read-only
  433.                                     files.
  434.         <41>      9/2/94    eeh        1184782 Added check in ::New for container
  435.                                     in tmp items folder
  436.         <40>      9/2/94    eeh        moved mailer-specific stuff to RlShlMlr.cpp
  437.                                     in the process of fixing 1150934 and
  438.                                     1167302
  439.         <39>     8/31/94    TÇ        #1183129, #1183116, #1183119, #1183111:
  440.                                     Lots of ErrorCode cleanup.
  441.         <38>     8/29/94    TÇ        #1183553 Need to reduce usage of ODFileSpec
  442.                                     in RlShell
  443.         <37>     8/26/94    TÇ        #1158958 Watch cursor while saving
  444.                                     #1181761 rename obsolete kOD IDs to correct
  445.                                     kODStrong/WeakStorageUnitRefs
  446.                                     #1155850 Can't resize a document large on
  447.                                     larger monitors
  448.                                     #1149697 Resize window to titlebar, move
  449.                                     titlebar, window disappears
  450.         <36>     8/26/94    VL        1183174: GetStorageUnitRef takes
  451.                                     ODStorageUnitID now.
  452.         <35>     8/25/94    TÇ        #1183223 Enabled launching of documents in
  453.                                     folders other than that of the OpenDoc
  454.                                     libraries.  Disabled WASSERT if System
  455.                                     Process does not launch.
  456.         <34>     8/22/94    TÇ        #1182448 System Process quits when no
  457.                                     OpenDoc documents are running
  458.         <33>     8/19/94    jpa        Stop calling ODInitMemory [1182106]
  459.         <32>     8/19/94    TÇ        #1180922 Need to Stop using obsolete types
  460.                                     (kOD ID)
  461.         <31>     8/17/94    jpa        Added "Dump Objects" command to the debug
  462.                                     menu, and enhanced the "Mem Info" dialog.
  463.                                     [1179567]
  464.         <30>     8/15/94    JBS        1181156: UI API Cleanup
  465.         <29>     8/15/94    TÇ        #1180922 Removed most obsolete types from
  466.                                     StdTypes.idl
  467.         <28>     8/12/94    NP        1180762-session->close to delete session.
  468.         <27>     8/11/94    eeh        add ShellMain function
  469.         <26>     8/10/94    JBS        1179919: coordinate system bias changes
  470.         <25>      8/8/94    jpa        Added "Heap Info" cmd to ODDebug menu.
  471.                                     [1179567]
  472.         <24>      8/3/94    VL        Temporarily commented out system process
  473.                                     stuff.
  474.         <23>      8/3/94    CC        ExportClipboard() - removed calls to lock
  475.                                     and unlock; MUST FIX TO REQUEST CLIPBOARD
  476.                                     FOCUS (currently a frame is required but
  477.                                     none is available).
  478.         <22>      8/3/94    VL        1153123: Storage to ODStor.
  479.         <21>      8/2/94    jpa        Added "Break on THROW" to ODDebug menu.
  480.         <20>      8/2/94    TÇ        #1178167 Enabled code to launch System
  481.                                     Process if it had not already been
  482.                                     launched.
  483.         <19>      8/1/94    TÇ        cleaned up launcher code, added code to
  484.                                     check for and launch System Process
  485.         <18>     7/29/94    CG        NameSpace API changes.
  486.         <17>     7/28/94    TÇ        fixed a comment
  487.         <16>     7/27/94    jpa        Added the ODDebug menu.
  488.         <15>     7/27/94    NP        Fixed Undo and About menu code.
  489.         <14>     7/26/94    jpa        Took out old commented-out memory
  490.                                     validation calls; moved these to Shell.cpp.
  491.         <13>     7/26/94    eeh        Pass Point to ODWindow::Drag by reference
  492.         <12>     7/21/94    TÇ        fixed New to workaround lack of binding
  493.                                     implementation, eliminated another
  494.                                     STATICBUILD reference, fixed Open to set
  495.                                     the name of the root part correctly
  496.         <11>     7/21/94    eeh        fix installation of AOCE menu
  497.         <10>     7/21/94    TÇ        took out STATICBUILD, DONTOPENANOTHERFILE
  498.                                     symbols, put in special case code for
  499.                                     ODTestMain to use a single process instead
  500.                                     of launching another one when opening
  501.                                     stationery, moved SOM_Trace enablement to
  502.                                     the about box.
  503.          <9>     7/19/94    TÇ        properly disabled OpenAnotherFile for now
  504.          <8>     7/14/94    TÇ        added DetachResource(appleMenu);
  505.          <7>     7/14/94    TÇ        use document->Exists(fDraft) instead of
  506.                                     TRY/CATCH with AcquireDraft
  507.          <6>     7/14/94    TÇ        removed references to ASLMBILD
  508.          <5>     7/13/94    TÇ        removed some XMPs
  509.          <4>     7/11/94    TÇ        enabled calls to InfoUtil functions
  510.          <2>     6/27/94    TÇ        fixed includes
  511.          <1>     6/27/94    TÇ        first checked in
  512.          <0>     6/17/94    SV        SOMverted
  513.         <35>     5/27/94    jpa        New exception support [1165267]
  514.         <34>     5/10/94    TÇ        #1162405 Removed explicit ASLM dependency
  515.                                     for using resources
  516.         <33>      5/9/94    MB        #1162181: Changes necessary to install MMM.
  517.         <32>     4/27/94    TÇ        #1159972: Fixed setting the FInfo type of
  518.                                     OpenDoc Documents
  519.         <31>     4/19/94    TÇ        #1158391: Editor Setup part didn't always
  520.                                     open.  Whenever there is an empty
  521.                                     windowstate, this fix explicitly tells the
  522.                                     root part to open.
  523.         <30>     4/18/94    TÇ        #1157689: Clicking Zoom box was crashing
  524.                                     due to not setting the port correctly.
  525.         <29>     4/18/94    TÇ        #1144379 Stationery model & generation have
  526.                                     been fixed to enable dragging & dropping of
  527.                                     stationery onto open documents.
  528.         <28>     4/11/94    TÇ        #1155854 Use CustomPutFile for Save A Copy.
  529.         <27>      4/7/94    TÇ        fixed #1155956
  530.         <26>      4/1/94    TÇ        #1154941: Get OpenDoc source to actually
  531.                                     compile for PowerPC
  532.         <25>     3/31/94    eeh        bug #1154688: add !fAOCEFile test before
  533.                                     Save() call in Open()
  534.         <24>     3/28/94    CG        1153547: Renamed XMPSessn.h to XMPSessM.h
  535.         <23>     3/27/94    TÇ        #1153527 sync name of document & name of
  536.                                     rootpart. enable renaming of document by
  537.                                     changing name of root part in Part Info
  538.                                     dialog.
  539.         <22>     3/25/94    CC        PPCNative: Removed inline assembly (for
  540.                                     Tantek) (1153053); Change name of included
  541.                                     file to <LinkMgr.xh>. (1153348)
  542.         <21>     3/25/94    JA        Hide some ODUnused calls from Metrowerks
  543.                                     since they were causing problems for the
  544.                                     compiler. (1153437)
  545.         <20>     3/25/94    MB        Symantec ASLM fixes. #1150864
  546.         <19>     3/24/94    TÇ        (no bug# yet) Stationery now just tears off
  547.                                     instead of tearing off and opening.
  548.                                     Cleaned & removed fIsNew flag, SaveAs()
  549.                                     code, and someother #ifdef TO_BE_DELETD
  550.                                     stuff
  551.         <18>     3/17/94    CG        #1151392: Moved kOpenDocShellSignature from
  552.                                     ContsDef.h to StdDefs.h
  553.         <17>     3/16/94    RR        #1144764 Close doesn't close floaters
  554.                                     anymore.
  555.         <16>     3/16/94    eeh        bug #1149649: added params to
  556.                                     OpenAnotherFile; fleshed out ReplyToMail
  557.         <15>     3/15/94    MB        Changes to support SCpp/ASLM builds,
  558.                                     #1150864.
  559.         <14>     3/10/94    eeh        bug #1149754: kHighLevelEvent case in
  560.                                     DispatchEvent; #1149649: implement
  561.                                     ForwardMail
  562.         <13>      3/3/94    TÇ        fix #1148389
  563.         <12>      3/2/94    TÇ        fixed #1147894
  564.         <11>     2/28/94    CG        TC: fixed crash in static build when
  565.                                     opening a new stationary file.
  566.         <10>     2/25/94    TÇ        comment out the XMPMemValidation stuff
  567.          <9>     2/24/94    TÇ        fix #1145435.  Save and Revert to Saved
  568.                                     menu items are now enabled properly (only
  569.                                     when there are changes to a draft)  brand
  570.                                     new documents which have never been saved
  571.                                     are deleted when closed.  cleaned up a few
  572.                                     more comments.
  573.          <8>     2/23/94    VL        Moved memory error handling code from
  574.                                     Main.cpp to ::go.
  575.          <7>     2/17/94    TÇ        fix to help #1144379, enable opening
  576.                                     documents which were created by dragging
  577.                                     from an OpenDoc document to the desktop.
  578.                                     Make sure that a reference to the rootpart
  579.                                     is written to the draft properties
  580.                                     storageunit when the rootpart is created.
  581.                                     Set the TYPE of stationery which is created
  582.                                     by ODTestShell correctly.
  583.          <6>     2/17/94    TÇ        fix #1144404,#1144410, set stationery bit
  584.                                     when creating stationery in ODTestShell,
  585.                                     cleaned up SSREMOVEWORKAROUND
  586.          <5>     2/16/94    TÇ        fix #1144026
  587.          <4>     2/16/94    JA        Made SystemSupportsAOCE a static function.
  588.                                     Include new AltPoint.h.
  589.          <3>     2/16/94    TÇ        #1144029 and remove some unnecessary
  590.                                     #includes
  591.          <2>     2/15/94    TÇ        fix #1144029 and some cleanup
  592.        <112>      2/8/94    TÇ        Throw -> THROW & some code clean up
  593.        <111>      2/7/94    JA        Utilities.h --> XMPUtils.h
  594.        <110>      2/7/94    TÇ        more fixes to compile with PPC Headers
  595.        <109>      2/4/94    TÇ        fixes to compile with PPC Universal headers
  596.        <108>      2/2/94    RR        Call SetDefaultWindowTitles in ::Open
  597.        <107>      2/2/94    TÇ        added CreateUntitledContainer, changes to
  598.                                     ::New and ::Open and ::OpenFile to enable
  599.                                     proper creation of staionery in the static
  600.                                     build, and proper opening of stationery in
  601.                                     the dynamic build.
  602.        <106>     1/31/94    NP        Made coercion handler conform to new
  603.                                     interface.
  604.        <105>     1/28/94    RR        Reorganized CloseWindow for multiple drafts
  605.        <104>     1/28/94    TÇ        got rid of a warning
  606.        <103>     1/27/94    RR        Disabled flag, so that parts now create
  607.                                     initial window
  608.        <102>     1/25/94    EL        ISOStr includes the zero terminator.
  609.        <101>     1/25/94    RR        Create window invisible
  610.        <100>     1/25/94    NP        TÇ: added support for Draft Dialog, Create,
  611.                                     Remove, Open Drafts.  Fix for ASLM: error
  612.                                     strings in exception dialog were not being
  613.                                     displayed. NP: Implemented error catching
  614.                                     for opendocs and openapp handlers.
  615.         <99>     1/24/94    SS        Docs created now have correct filetype
  616.         <98>     1/24/94    NP        Made dismissal of About Box work better.
  617.         <97>     1/22/94    CC        CloseWindow: Call ExortClipboard() before
  618.                                     CloseDraft() to avoid potential problem;
  619.                                     this sometimes avoids crashing but not
  620.                                     always.
  621.         <96>     1/21/94    eeh        cleanup, part of which fixes mailer saves
  622.         <95>     1/21/94    RR        Added shouldSave to CreateWindow. Restored
  623.                                     Dispatch() signature
  624.         <94>     1/21/94    CC        Added calls to ODLinkManager::DraftOpened,
  625.                                     ::DraftSaved, and ::DraftClosing; conform
  626.                                     to clipboard locking interface.
  627.         <93>     1/21/94    CG        Changed kPlatformFileContainer to
  628.                                     kODDefaultFileContainer.
  629.         <92>     1/20/94    SS        Documents are now created/saved with the
  630.                                     right file type/creator
  631.         <91>     1/20/94    RR        Moved AOCE Mailer stuff to StdDisp and
  632.                                     WinState
  633.         <90>     1/20/94    TÇ        Added selection of rootpart in static
  634.                                     build, fixed references to name of document
  635.                                     in Revert and Close dialogs.
  636.         <89>     1/19/94    NP        Added call to ClearActionHistory when
  637.                                     document is reverted or closed.
  638.         <88>     1/19/94    eeh        added Open Document menu item
  639.         <87>     1/18/94    CG        Changed kODBentoFileContainer to
  640.                                     kPlatformFileContainer, include StorgDef.h.
  641.         <86>     1/18/94    TÇ        use kOpenDocShellSignature, and get rid of
  642.                                     some obsolete constants
  643.         <85>     1/17/94    NP        Semantic Events callbacks API changes.
  644.         <84>     1/15/94    RR        WinState.h->WinStat.h,
  645.                                     Dispatch.h->Disptch.h
  646.         <83>     1/15/94    RR        Updated HandleMenuEvent (command no. is no
  647.                                     longer in event)
  648.         <82>     1/14/94    TÇ        implemented calls to DraftWindow to show
  649.                                     Drafts Dialog, and to initialize the draft
  650.                                     properties of a newly created draft
  651.         <81>     1/14/94    CC        ExportClipboard(): Use clipboard keys.
  652.         <80>     1/13/94    eeh        integrate AOCEObj; cosmetic changes
  653.         <79>     1/13/94    NP        Mods for Undo menu.
  654.         <78>     1/12/94    CG        Removed ODNewPtrClear - it's in ODMemory.cp.
  655.         <77>     1/12/94    RR        Call window->CloseAndRemove
  656.         <76>     1/11/94    eeh        fix user cancel exceptions and make mailer
  657.                                     menu heierarchical
  658.         <75>     1/10/94    NP        Mods for the Undo and Redo menu items.
  659.         <74>      1/6/94    TÇ        commented out a few ODDisposePtr where a
  660.                                     ptr allocated using NewPtrClear was being
  661.                                     improperly disposed.
  662.         <73>    12/22/93    RR        Call Activate/DeactivateFrontWindows around
  663.                                     modal dialog calls
  664.         <72>    12/21/93    VL        Changed ODStorageUnit::GetValueSize to
  665.                                     StorageUnit::GetSize.
  666.         <71>    12/21/93    JBS        create frames with viewType and
  667.                                     presentation
  668.         <70>    12/20/93    VL        Used WindowState to CreateWindow.
  669.         <69>    12/20/93    RR        Use new Init method for menu bar
  670.         <68>    12/17/93    TÇ        add some code for New and Open...
  671.         <67>    12/17/93    TÇ        remove Pre & Postflight around the main
  672.                                     entry point (fEV,::go) and put them only where
  673.                                     necessary around calls to GetResource or
  674.                                     calls which call GetResource.  Enable
  675.                                     Multiple documents to be opened in the
  676.                                     dynamically linked build.
  677.         <66>    12/16/93    TÇ        CreatePart changes, write out current
  678.                                     Editor when user chooses New, read it in
  679.                                     when opening a New'd document.
  680.         <65>    12/13/93    RR        Register command for About…. Set Item
  681.                                     string to "About OpenDoc" in UpdateMenus in
  682.                                     case active part doesn't
  683.         <64>    12/12/93    TÇ        added failure handling around Initialize
  684.         <63>     12/9/93    eeh        added params to Save, Close and others to
  685.                                     support AppleEvents.
  686.         <62>     12/9/93    VL        Used ODQDGlobals instead of qd. Now we
  687.                                     can drag windows around!
  688.         <61>     12/3/93    CC        Call ODClipboard::ExportClipboard on
  689.                                     suspend events and when document is closed.
  690.         <60>     12/1/93    VL        Used new ODWindow calls that support
  691.                                     floating windows.
  692.         <59>    11/22/93    SS        Added typecasts for latest headers
  693.         <58>    11/19/93    RR        Let dispatcher deal with plain command keys
  694.                                     (i.e. no option, shift etc.)
  695.         <57>    11/18/93    eeh        fixed CreateTempFileSpec to avoid dup file
  696.                                     names
  697.         <56>    11/16/93    RR        Call windowstate::AdjustPartMenus
  698.         <55>    11/16/93    EL        Use OpenDoc instead of Amber.
  699.         <54>    11/16/93    RR        Completely reorganized event-handling
  700.         <53>    11/15/93    eeh        changed SaveAs to just moveandrename the
  701.                                     temp file, and added ManageMailerSave()
  702.         <52>    10/29/93    RR        MenuBar: EnDisable -> Enable
  703.         <51>    10/28/93    TÇ        added code to use the resource fork of
  704.                                     ShellLibASLM in ASLM builds
  705.         <50>    10/27/93    eeh        rewrote CopyFiles not to use exceptions
  706.         <49>    10/27/93    eeh        More widespread changes to enable opening
  707.                                     amber letters, particularly in
  708.                                     GetFSSpecFromLetter() and CopyFile().
  709.         <48>    10/26/93    PH        Ignore error from FSpGetInfo in AECoerce
  710.                                     handler
  711.         <47>    10/22/93    PH        Move manager inits to main
  712.         <46>    10/21/93    RR        CloseWindow uses new WindowState calls to
  713.                                     detect "last" window. CreateWindow takes
  714.                                     new flags
  715.         <45>    10/21/93    TÇ        fix CloseDraft() to NOT call
  716.                                     WindowState->Externalize and
  717.                                     fDraft->SaveToPrev
  718.         <44>    10/20/93    eeh        fixed problems with non-AOCE machines
  719.         <43>    10/20/93    eeh        Added coercion handler for incomming AOCE
  720.                                     documents (fEV,alias->FFSpec).  Incomplete.
  721.         <42>    10/18/93    TÇ        moved call to InitLibraryManager() from
  722.                                     RealShell::Intialize to main(), reduced
  723.                                     entrypoints into RealShell object to one.
  724.         <41>    10/14/93    RR        Use command numbers from CmdDefs.h
  725.         <40>    10/14/93    JA        ODShape fu: No longer returns copies from
  726.                                     GetPlatformShape. Deal w/it.
  727.         <39>    10/12/93    eeh        More mailer support, and fixed problem with
  728.                                     menu installation.
  729.         <38>     10/8/93    TÇ        fixed MPW compiler problems
  730.         <36>     10/8/93    VL        Call Release on ODPersistentObjects and
  731.                                     ODStorageUnits.
  732.         <35>     10/8/93    TÇ        fixed Save A Copy to externalize only if
  733.                                     there are changes
  734.         <34>     10/8/93    RR        Use IsODWindow
  735.         <33>     10/8/93    TÇ        bifurcated Document menu into normal and
  736.                                     AOCE versions
  737.         <32>     10/7/93    RR        Remove call to CloseWindows for now because
  738.                                     we can't delete while iterating
  739.         <31>     10/7/93    RR        Call WindowState::CloseWindows and
  740.                                     Draft::CreateWindow
  741.         <30>     10/7/93    TÇ        Save A Copy uses name of file, comment out
  742.                                     RemoveAOCEMailer call until it is moved to
  743.                                     ODWindow::Close, fix size/location of
  744.                                     window creation (copied some code from
  745.                                     TeachText)
  746.         <29>     10/7/93    eeh        Various changes related to adding Mailer
  747.                                     support, with more to come.
  748.         <28>     10/4/93    TÇ        added #ifdef SSREMOVEWORKAROUND until
  749.                                     su->Remove(ev) is fixed
  750.         <27>     10/4/93    RR        Added hard-coded document title
  751.         <26>     10/1/93    TÇ        fixed file corruption
  752.         <25>     10/1/93    TÇ        fixed ErrRecord definition to use ODError
  753.                                     and ODULong
  754.         <24>     9/30/93    TÇ        fixed smashing memory bug in New(), and
  755.                                     Close/SaveAs() interaction bug
  756.         <23>     9/29/93    TÇ        got Revert() to work, auto New() on OAPP
  757.                                     for now
  758.         <22>     9/24/93    TÇ        Integrated Storage System draft calls,
  759.                                     enabled real implementation of Save, Close.
  760.                                     With help from RCR: integrated the
  761.                                     ODMenuBar object into the shell.
  762.         <21>     9/24/93    JA        Minor syntactic tweaks for THINK C++.
  763.         <20>     9/23/93    TÇ        fixed Error handling code so that it
  764.                                     doesn't crash if there is no window
  765.         <19>     9/22/93    NP        Integrated Semantic Events into the
  766.                                     DocShell.
  767.         <18>     9/22/93    RR        menuBar::Add -> AddLast(). Still need to
  768.                                     modify menu handling code to  use
  769.                                     registered commands.
  770.         <17>     9/15/93    TÇ        implemented Error Handling
  771.         <16>     9/10/93    RR        Use new ODMenuBar interface
  772.         <15>     8/27/93    TÇ        implemented updated New, Open..., Open
  773.                                     stationery, About...
  774.         <14>     8/24/93    TÇ        integrated with partial storage
  775.                                     implementation, enabled readwrite access
  776.         <13>     8/20/93    TÇ        integrated with Prototype Window, Layout,
  777.                                     Imaging and parts.
  778.         <12>     8/19/93    TÇ        release document & container when closing
  779.         <11>     8/19/93    TÇ        SS Integration: doc/window opens, closes &
  780.                                     quits
  781.         <10>     8/19/93    TÇ        SS integration: got windowstate to
  782.                                     internalize
  783.          <9>      8/9/93    TÇ        with help from CG: implement/integrate ODOC
  784.          <8>     7/21/93    TÇ        with help from CG: implement/integrate OAPP
  785.                                     & QUIT AppleEvent handlers
  786.          <7>      7/6/93    TÇ        implement Draft Interface
  787.          <6>     5/24/93    TÇ        finish implementing methods for open, save,
  788.                                     close, save as, revert
  789.          <5>     4/30/93    TÇ        implement Open
  790.          <4>     4/29/93    TÇ        change names of includefiles
  791.          <3>     4/28/93    TÇ        implement more Event Loop
  792.          <2>     4/27/93    TÇ        implemented Initialization, bare bones Main
  793.                                     Event Loop
  794.          <1>     4/14/93    TÇ        first checked in
  795.          
  796.     In Progress:
  797.         
  798. */
  799.  
  800. #ifndef _PLFMDEF_
  801. #include <PlfmDef.h>
  802. #endif
  803.  
  804. #ifndef _SHELLDEF_
  805. #include "ShellDef.h"
  806. #endif
  807.  
  808. #ifndef _SHLMAIN_
  809. #include "ShlMain.h"
  810. #endif
  811.  
  812. #ifndef _DOCUTILS_
  813. #include "DocUtils.h"
  814. #endif
  815.  
  816. #ifndef _UTILDEFS_
  817. #include "UtilDefs.h"
  818. #endif
  819.  
  820. #ifndef _RLSHELL_
  821. #include "RlShell.h"
  822. #endif
  823.  
  824. #ifndef _SHPLUGIN_
  825. #include "ShPlugIn.h"
  826. #endif
  827.  
  828. #ifndef _USERSRCM_
  829. #include <UseRsrcM.h>
  830. #endif
  831.  
  832. #ifndef _EXCEPT_
  833. #include <Except.h>
  834. #endif
  835.  
  836. #ifndef SOM_Module_OpenDoc_Commands_defined
  837. #include <CmdDefs.xh>
  838. #endif
  839.  
  840. #ifndef _ODUTILS_
  841. #include <ODUtils.h>
  842. #endif
  843.  
  844. #ifndef _BINDNGH_
  845. #include <BindngH.h>
  846. #endif
  847.  
  848. #ifndef _BNDNSUTL_
  849. #include <BndNSUtl.h>
  850. #endif
  851.  
  852. #ifndef _TEMPOBJ_
  853. #include "TempObj.h"
  854. #endif
  855.  
  856. #ifndef _TEMPITER_
  857. #include "TempIter.h"
  858. #endif
  859.  
  860. #ifndef _ODMEMORY_
  861. #include <ODMemory.h>
  862. #endif
  863.  
  864. #ifndef _BARRAY_
  865. #include <BArray.h>
  866. #endif
  867.  
  868. #ifndef SOM_ODDispatcher_xh
  869. #include <Disptch.xh>
  870. #endif
  871.  
  872. #ifndef SOM_ODWindowState_xh
  873. #include <WinStat.xh>
  874. #endif
  875.  
  876. #ifndef SOM_ODWindowIterator_xh
  877. #include <WinIter.xh>
  878. #endif
  879.  
  880. #ifndef SOM_ODWindow_xh
  881. #include <Window.xh>
  882. #endif
  883.  
  884. #ifndef SOM_ODMenuBar_xh
  885. #include <MenuBar.xh>
  886. #endif
  887.  
  888. #ifndef _ORDCOLL_
  889. #include "OrdColl.h"
  890. #endif
  891.  
  892. #ifndef SOM_ODFrame_xh
  893. #include <Frame.xh>
  894. #endif
  895.  
  896. #ifndef SOM_ODFrameFacetIterator_xh
  897. #include <FrFaItr.xh>
  898. #endif
  899.  
  900. #ifndef SOM_Module_Apple_defined
  901. #include <Part.xh>
  902. #endif
  903.  
  904. #ifndef SOM_ODArbitrator_xh
  905. #include <Arbitrat.xh>
  906. #endif
  907.  
  908. #ifndef SOM_Module_OpenDoc_Foci_defined
  909. #include "Foci.xh"
  910. #endif
  911.  
  912. #ifndef SOM_ODSession_xh
  913. #include <ODSessn.xh>
  914. #endif
  915.  
  916. #ifndef SOM_ODLinkManager_xh
  917. #include <LinkMgr.xh>
  918. #endif
  919.  
  920. #ifndef SOM_ODStorageSystem_xh
  921. #include <ODStor.xh>
  922. #endif
  923.  
  924. #ifndef SOM_ODStorageUnit_xh
  925. #include <StorageU.xh>
  926. #endif
  927.  
  928. #ifndef SOM_ODDocument_xh
  929. #include <Document.xh>
  930. #endif
  931.  
  932. #ifndef SOM_ODContainer_xh
  933. #include <ODCtr.xh>
  934. #endif
  935.  
  936. #ifndef SOM_ODClipboard_xh
  937. #include <Clipbd.xh>
  938. #endif
  939.  
  940. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  941. #include <StdTypes.xh>
  942. #endif
  943.  
  944. #ifndef SOM_Module_OpenDoc_StdProps_defined
  945. #include <StdProps.xh>
  946. #endif
  947.  
  948. #ifndef _ITEXT_
  949. #include <IText.h>
  950. #endif
  951.  
  952. #ifndef _ISOSTR_
  953. #include <ISOStr.h>
  954. #endif
  955.  
  956. #ifndef _PASCLSTR_
  957. #include <PasclStr.h>
  958. #endif
  959.  
  960. #ifndef _STORUTIL_
  961. #include <StorUtil.h>
  962. #endif
  963.  
  964. #ifndef SOM_ODUndo_xh
  965. #include <Undo.xh>
  966. #endif
  967.  
  968. #ifndef SOM_ODInfo_xh
  969. #include <Info.xh>
  970. #endif
  971.  
  972. #ifndef _DRAFTWN_
  973. #include "DraftWn.h"
  974. #endif
  975.  
  976. #ifndef _ODPRCS_
  977. #include "ODPrcs.h"
  978. #endif
  979.  
  980. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  981. #include <StdDefs.xh>
  982. #endif
  983.  
  984. #ifndef _INFOUTIL_
  985. #include <InfoUtil.h>
  986. #endif
  987.  
  988. #ifndef SOM_Module_OpenDoc_StandardExtensions_defined
  989. #include <StdExts.xh>
  990. #endif
  991.  
  992. #ifndef _STDTYPIO_
  993. #include <StdTypIO.h>
  994. #endif
  995.  
  996. #ifndef _DLOGUTIL_
  997. #include <DlogUtil.h>
  998. #endif
  999.  
  1000. #ifndef _MEMMGR_
  1001. #include <MemMgr.h>
  1002. #endif
  1003.  
  1004. #if ODDebug
  1005. #ifndef _MEMDEBG_
  1006. #include <MemDebg.h>
  1007. #endif
  1008. #endif
  1009.  
  1010. #ifndef __QUICKDRAW__
  1011. #include <QuickDraw.h>
  1012. #endif
  1013.  
  1014. #ifndef __STANDARDFILE__
  1015. #include <StandardFile.h>
  1016. #endif
  1017.  
  1018. #ifndef __FOLDERS__
  1019. #include <Folders.h>
  1020. #endif
  1021.  
  1022. #ifndef __FONTS__
  1023. #include <Fonts.h>
  1024. #endif
  1025.  
  1026. #ifndef __MENUS__
  1027. #include <Menus.h>
  1028. #endif
  1029.  
  1030. #ifndef __OSEVENTS__
  1031. #include <OSEvents.h>
  1032. #endif
  1033.  
  1034. #ifndef __DIALOGS__
  1035. #include <Dialogs.h>
  1036. #endif
  1037.  
  1038. #ifndef __PACKAGES__
  1039. #include <Packages.h>
  1040. #endif
  1041.  
  1042. #ifndef __TOOLUTILS__
  1043. #include <ToolUtils.h>
  1044. #endif
  1045.  
  1046. #ifndef __DESK__
  1047. #include <Desk.h>
  1048. #endif
  1049.  
  1050. #ifndef __RESOURCES__
  1051. #include <Resources.h>
  1052. #endif
  1053.  
  1054. #ifndef __LOWMEM__
  1055. #include <LowMem.h>
  1056. #endif
  1057.  
  1058. #ifndef __GESTALTEQU__
  1059. #include <GestaltEqu.h>
  1060. #endif
  1061.  
  1062. #ifndef __SCRIPT__
  1063. #include <Script.h>
  1064. #endif
  1065.  
  1066. #ifndef __FINDER__
  1067. #include <Finder.h>
  1068. #endif
  1069.  
  1070. #ifndef __FILES__
  1071. #include <Files.h>
  1072. #endif
  1073.  
  1074. #ifndef __ICONS__
  1075. #include <Icons.h>
  1076. #endif
  1077.  
  1078. #ifndef __ALIASES__
  1079. #include <Aliases.h>
  1080. #endif
  1081.  
  1082. #ifndef __TEXTSERVICES__
  1083. #include <TextServices.h>
  1084. #endif
  1085.  
  1086. #ifndef __LIMITS__
  1087. #include <limits.h>
  1088. #endif
  1089.  
  1090. #ifndef __STRING__
  1091. #include <string.h>
  1092. #endif
  1093.  
  1094. #ifndef SOM_ODPartWrapper_xh
  1095. #include "PartWrap.xh"
  1096. #endif
  1097.  
  1098. #ifndef __STDIO__
  1099. #include <stdio.h>
  1100. #endif
  1101.  
  1102. #ifndef __SEGLOAD__
  1103. #include "SegLoad.h"
  1104. #endif
  1105.  
  1106. #ifndef _ODDEBUG_
  1107. #include "ODDebug.h"
  1108. #endif
  1109.  
  1110. #ifndef _MEMMGR_
  1111. #include "MemMgr.h"
  1112. #endif
  1113.  
  1114. #ifndef _MEMDEBG_
  1115. #include "MemDebg.h"
  1116. #endif
  1117.  
  1118. #ifndef _STORUTIL_
  1119. #include <StorUtil.h>
  1120. #endif
  1121.  
  1122. #ifndef _NMSPCUTL_
  1123. #include <NmSpcUtl.h>
  1124. #endif
  1125.  
  1126. #ifndef SOM_ODBinding_xh
  1127. #include <ODBindng.xh>
  1128. #endif
  1129.  
  1130. #ifndef SOM_ODTranslation_xh
  1131. #include <Translt.xh>
  1132. #endif
  1133.  
  1134. #ifndef SOM_ODTypeList_xh
  1135. #include <TypeList.xh>
  1136. #endif
  1137.  
  1138. #ifndef SOM_ODTypeListIterator_xh
  1139. #include <TypLsItr.xh>
  1140. #endif
  1141.  
  1142. #ifndef _SIHELPER_
  1143. #include <SIHelper.h>
  1144. #endif
  1145.  
  1146. #ifndef _EDITRSET_
  1147. #include <EditrSet.h>
  1148. #endif
  1149.  
  1150. #ifndef _TRANSUTL_
  1151. #include <TransUtl.h>
  1152. #endif
  1153.  
  1154. #ifndef _CRAWL_
  1155. #include <Crawl.h>
  1156. #endif
  1157.  
  1158. #ifndef _SEUTILS_
  1159. #include "SEUtils.h"
  1160. #endif
  1161.  
  1162. #ifndef __EDITIONS__
  1163. #include <Editions.h>
  1164. #endif
  1165.  
  1166. #ifndef __CODEFRAGMENTS__
  1167. #include <CodeFragments.h>
  1168. #endif
  1169.  
  1170. #ifndef _CONSTDEF_
  1171. #include <ConstDef.h>
  1172. #endif
  1173.  
  1174. #ifndef _SHELLMEM_
  1175. #include <ShellMem.h>
  1176. #endif
  1177.  
  1178. #pragma segment RealShell
  1179.  
  1180. #if ODDebug
  1181. //==============================================================================
  1182. // Debugging #Defines
  1183. //==============================================================================
  1184.  
  1185. #endif
  1186.  
  1187. //==============================================================================
  1188. // Constants
  1189. //==============================================================================
  1190.  
  1191. // <eeh> this should be defined elsewhere, so that parts like EditorSetup can
  1192. // use it rather than risk choosing another constant.
  1193. const  ODMenuID  kODAppleMenuID  = 255;
  1194. const  ODMenuID  kODDocumentMenuID  = 256;
  1195. const  ODMenuID  kODEditMenuID    = 257;
  1196. const  ODOSType  kODDASMenuRsrc    = 0x44525652; // 'DRVR';
  1197.  
  1198. const ODSLong    kMaxTimeBetweenLocationChecks = 3 * 60L;    // Background file check delay
  1199.  
  1200. const short kMaxUniqueNameTries = 100;
  1201.  
  1202.  
  1203. const ODSShort    kUseSpecificScript = 0x1c;
  1204.  
  1205. #define kMaxNumberSuffixLength 11
  1206.  
  1207. // For window resizing
  1208. #define kMinWindowWidth  192
  1209. #define kMinWindowHeight 64
  1210. #define kMaxWindowWidth  16384
  1211. #define kMaxWindowHeight 16384
  1212.  
  1213. // from DrawDef.h
  1214. #define kODKindTestDraw "Apple:Kind:TestDraw"
  1215.  
  1216. // Local error codes:
  1217.  
  1218. #define        kODErrClosingNonODWindow    5001
  1219.  
  1220.  
  1221. #define ODDebugMenu ODDebug        /* Use Debug menu if debug build */
  1222.  
  1223.  
  1224. #if ODDebugMenu
  1225. const ODMenuID kDebugMenuID = 100;
  1226. // Command IDs for the debugging menu:
  1227. enum {
  1228.     kODCommandDBHeapInfo = 980,
  1229.     kODCommandDBDumpObjects,
  1230.     kODCommandDBDumpBlocks,
  1231.     kODCommandDBMemValidation,
  1232.     kODCommandDBHeapChecking,
  1233.     kODCommandDBLeakChecking,
  1234.     kODCommandDBDumpBlocksOnClose,
  1235.     kODCommandDBTrackStackCrawls,
  1236.     kODCommandDBLogStdout,
  1237.     kODCommandDBLogDebugWindow,
  1238.     kODCommandDBLogDebugStr,
  1239.     kODCommandDBSOMTrace,
  1240.     kODCommandDBBreakOnThrow,
  1241.     kODCommandDBEatMemory,
  1242.     kODCommandDBPurge
  1243. };
  1244.  
  1245. const short kODHeapInfoAlert = 980;
  1246. #endif
  1247.  
  1248. const StringPtr kODEmptyPString = "\p";
  1249.  
  1250. //==============================================================================
  1251. // Local Macros
  1252. //==============================================================================
  1253.  
  1254. #if ODDebug
  1255. #define SHLDebugStr(x)        DebugStr(x)
  1256. #else
  1257. #define SHLDebugStr(x)
  1258. #endif
  1259.  
  1260. #define BITTEST( codes, thisCode )                                            \
  1261.         (((codes) & (thisCode)) != 0L)
  1262.  
  1263. //#define SHLHeapDebug
  1264. //#define SHLTestSessionOverhead
  1265. //#define SHLTestErrorDialogUsage
  1266.  
  1267. //==============================================================================
  1268. // Static variables
  1269. //==============================================================================
  1270.  
  1271. #if ODDebug
  1272. static ODBoolean gMemValidation = kODFalse;
  1273. static ODBoolean gHeapChecking    = kODFalse;
  1274. static ODBoolean gLeakChecking  = kODFalse;
  1275. static ODBoolean gDumpBlocksOnClose      = kODFalse;
  1276. static ODBoolean gTrackStackCrawls  = kODFalse;
  1277. #endif
  1278.  
  1279. #ifndef __MWERKS__
  1280. QDGlobals qd;
  1281. #endif            
  1282. // Need to declare 'qd' ourselves because even though 'qd' is already 
  1283. // in Startup.c in the Metrowerks libraries, it is NOT necessarily in the
  1284. // libraries for other compilers, e.g the compilers for CFM68K. -TÇ
  1285.  
  1286. //==============================================================================
  1287. // Local Classes
  1288. //==============================================================================
  1289.  
  1290. struct ErrRecord
  1291. {
  1292.     ODError lowErr, highErr;
  1293.     ODULong index;
  1294. };
  1295.  
  1296. typedef ErrRecord* ErrRecordPointer;
  1297. typedef ErrRecordPointer* ErrRecordHandle;
  1298.  
  1299. //==============================================================================
  1300. // Function Prototype
  1301. //==============================================================================
  1302.  
  1303. void    CreateTempName(short seed, Str255 name, ODBoolean isFile);
  1304.     // $opt: CreateTempName is duplicated in ODPrcs.cpp
  1305.     
  1306. void    GetTempFolder(ODSShort* VRef,ODSLong* DirID);
  1307. void    CreateNewFile(PlatformFile* newFile, ODBoolean forceNewName); // newFile is in/out
  1308.  
  1309. pascal void DrawSmallIcon(DialogPtr theDialog, short theItem);
  1310. pascal short SaveCopyDlgHook(short item, DialogPtr theDialog, void *yourDataPtr);
  1311.  
  1312. static ODBoolean isOptionKeyDown();
  1313.  
  1314. #if ODDebug
  1315. static ODBoolean isHeapKeyDown();
  1316.  
  1317. static ODBoolean isFilterKeyDown();
  1318.  
  1319. static void HeapInfo();
  1320.  
  1321. #endif
  1322.  
  1323. ODStatic void InitKindsPopup ( ODTypeList* kindList,
  1324.                             ODType theKind,
  1325.                            ControlHandle    itemHandle,
  1326.                            ODSShort* currentKindItem,
  1327.                            MenuHandle kindMenu,
  1328.                            ODSShort* translateItem,
  1329.                            ODSession* session );
  1330.                            
  1331. ODStatic void FindShellPlugInsFolder(short *vol, long *dir );
  1332. ODStatic void FindStationeryFolder(short *vol, long *dir );
  1333.                              
  1334. ODStatic void    CreateNewUntitledFile(PlatformFile* newFile, 
  1335.                         char* fileNameSeed = kODNULL);
  1336. // Note: fileNameSeed is ignored if newFile->IsStationery()
  1337.  
  1338. static ODIText* CreateDefaultIText(StringPtr text);
  1339. static OSErr SendFinderODOCEvent( const FSSpec *fileToOpen );
  1340. ODStatic OSErr GetCfrgInfo( ODFileSpec* fileSpec, long* offset, long* length );
  1341. ODStatic void    CopyResources(PlatformFile* srcFile, PlatformFile* dstFile);
  1342.             
  1343.  
  1344. extern ODBoolean gODBentoFatalErrorHasOccurred; // SessHdr.cpp
  1345. extern ODBoolean gODDelayBentoFatalError; // SessHdr.cpp
  1346. extern ODBoolean gODSuppressBentoFatalError; // SessHdr.cpp
  1347. extern void ODBentoFatalError(); // SessHdr.cpp
  1348.                              
  1349. #if ODDebug
  1350. static void DumpHeapObjects( ODBoolean objectsOnly );
  1351. #endif
  1352.                              
  1353. //==============================================================================
  1354. // ShellMain Function
  1355. //==============================================================================
  1356.  
  1357. #pragma lib_export on            // only ShellMain needs to be exported
  1358.  
  1359. #ifdef __cplusplus
  1360. extern "C" {
  1361. #endif
  1362.  
  1363. int ShellMain()
  1364. {
  1365.     MaxApplZone();
  1366.     MoreMasters();
  1367.     MoreMasters();
  1368.     MoreMasters();
  1369.     MoreMasters();        // $Opt: May need more of these. Poke about at runtime to see.
  1370.  
  1371.     InitGraf(&qd.thePort);
  1372.  
  1373.     InitFonts();
  1374.     FlushEvents(everyEvent, 0);
  1375.     InitWindows();
  1376.     InitMenus();
  1377.     TEInit();
  1378.     InitDialogs(kODNULL);
  1379.     WatchCursor();
  1380.  
  1381. /* Note below that we continue even if the Edition Manager or TSM are not around. 
  1382.    There is no express reason that either one of these need to be around for OpenDoc
  1383.    in general to function.  Lack of Edition Manager just means you can't do linking.
  1384.  */
  1385.  
  1386.     if (InitEditionPack() != noErr)
  1387.         SHLDebugStr("\pInitEditionPack failed");
  1388.  
  1389.     long gestaltResponse;
  1390.     ODBoolean hasTSM = (Gestalt(gestaltTSMgrVersion, &gestaltResponse) == noErr) &&
  1391.          (gestaltResponse >= 1);
  1392.     if (hasTSM)
  1393.     {
  1394.         if (InitTSMAwareApplication() == noErr)
  1395.         {
  1396.             const TSMDocumentID    kAnyDoc = kODNULL;
  1397.         
  1398.             if (UseInputWindow(kAnyDoc, kODTrue) != noErr)
  1399.                 SHLDebugStr("\pUseInputWindow failed.");
  1400.         }
  1401.         else
  1402.         {
  1403.             SHLDebugStr("\pInitTSMAwareApplication failed.");
  1404.         }
  1405.     }
  1406.     else
  1407.     {
  1408.         SHLDebugStr("\pTSM unavailable.");
  1409.     }
  1410.     
  1411.     TRY
  1412.         ODInitExceptions();        // Sets up SOMError and SOMPrintf
  1413.     
  1414.     #if ODDebug
  1415.         MMBeginMemValidation();
  1416.         gMemValidation = kODTrue;
  1417.     #endif
  1418.     
  1419.     #if VALIDATE_EVERYTHING
  1420.         // MMBeginMemValidation(); Should be taken care of by above.
  1421.         MMBeginHeapChecking( );
  1422.     #endif
  1423.     
  1424.         if (isOptionKeyDown())
  1425.             SHLDebugStr("\pAbout to create and enter the Shell.  You may proceed.");
  1426.         
  1427.     #if ODDebug
  1428.         if (isHeapKeyDown())
  1429.         {
  1430.             SHLDebugStr("\pAbout to track heap block stack crawls. Type g to proceed.");
  1431.             gDumpBlocksOnClose = kODTrue;
  1432.             gTrackStackCrawls = kODTrue;
  1433.         }
  1434.     #endif
  1435.         
  1436.         RealShell*    le = new RealShell;
  1437.         le->go();
  1438.         delete le;
  1439.         
  1440.     #if VALIDATE_EVERYTHING
  1441.         MMEndHeapChecking( );
  1442.         MMEndMemValidation();
  1443.     #endif
  1444.     
  1445.         if (hasTSM)
  1446.             CloseTSMAwareApplication();
  1447.     CATCH_ALL
  1448.         /* Not much we can do here folks.
  1449.            Either ODInitExceptions failed, or creating a RealShell object failed.
  1450.            If the latter, then we don't have enough memory to put up a dialog.
  1451.            If the former, then something is really wrong the runtime.
  1452.          */
  1453.         SHLDebugStr("\pException reached ShellMain. Possibly ODInitExceptions failed");
  1454.     ENDTRY
  1455.  
  1456.     return 0;
  1457. }
  1458.  
  1459. #ifdef __cplusplus
  1460. }
  1461. #endif
  1462.  
  1463. #pragma lib_export off
  1464.  
  1465. //==============================================================================
  1466. // Static Functions
  1467. //==============================================================================
  1468.  
  1469. #if ODDebug
  1470. static ODBoolean isThisKeyDown(ODUShort theKey) // generic function
  1471. {
  1472.     unsigned char theKeys[16];
  1473.     GetKeys((UInt32*)&theKeys);
  1474.  
  1475.     return ((theKeys[theKey >> 3] >> (theKey & 7)) & 1);
  1476. }
  1477. static ODBoolean isHeapKeyDown() // use 'h' to mean "heap"
  1478. {
  1479.     const ODUShort heapKey = 4;    // the 'h' key
  1480.     return isThisKeyDown(heapKey);
  1481. }
  1482. static ODBoolean isFilterKeyDown() // use 'f' to mean "filter"
  1483. {
  1484.     const ODUShort filterKey = 3;    // the 'f' key
  1485.     return isThisKeyDown(filterKey);
  1486. }
  1487. #endif
  1488.  
  1489. static ODBoolean isOptionKeyDown()
  1490. {
  1491.     const ODUShort theKey = 0x3A;    // option key
  1492.     unsigned char theKeys[16];
  1493.     GetKeys((UInt32*)&theKeys);
  1494.  
  1495.     return ((theKeys[theKey >> 3] >> (theKey & 7)) & 1);
  1496. }
  1497.  
  1498. #if ODDebug
  1499.  
  1500. static void
  1501. ParamTextHeapInfo( )
  1502. {
  1503.     const char *name;
  1504.     size_t allocated, free,blocks,objects,contig;
  1505.     
  1506.     MMGetHeapInfo(kDefaultHeapID,
  1507.                   &name, &allocated, &free, &blocks, &objects);
  1508.     char nameStr[256], infoStr[256], appInfoStr[256];
  1509.     strcpy((char*)nameStr, name);
  1510.     sprintf(infoStr,"%lu\r%lu (%.1f%%)\r%lu (%lu objs)",
  1511.             allocated, free,
  1512.             100.0*free/(float)(allocated+free),
  1513.             blocks,objects);
  1514.  
  1515.     MMSystemFreeSpace(kMMAppMemory, &free,&contig);
  1516.     allocated = (ApplicationZone()->bkLim-(Ptr)&ApplicationZone()->heapData) - free;
  1517.     sprintf(appInfoStr,"%lu\r%lu (%.1f%%)\r%lu",
  1518.             allocated, free,
  1519.             100.0*free/(float)(allocated+free),
  1520.             contig);
  1521.  
  1522.     ParamText(CToPascalString(nameStr),CToPascalString(infoStr),
  1523.               "\pMacOS Application Heap",CToPascalString(appInfoStr));
  1524. }
  1525.  
  1526. static void HeapInfo()
  1527. {
  1528.     ParamTextHeapInfo();
  1529.     ODSLong        savedRefNum;
  1530.     BeginUsingLibraryResources(savedRefNum);
  1531.     NoteAlert(kODHeapInfoAlert, NULL);
  1532.     EndUsingLibraryResources(savedRefNum);
  1533. }
  1534.  
  1535. #endif
  1536.  
  1537.  
  1538. //==============================================================================
  1539. // RealShell
  1540. //==============================================================================
  1541.  
  1542.  
  1543. //-------------------------------------------------------------------------------------
  1544. // Initialization
  1545. //-------------------------------------------------------------------------------------
  1546.  
  1547. RealShell::RealShell()
  1548. {
  1549.     fEV         = kODNULL;
  1550.     fSession                 = kODNULL;
  1551.     fDispatcher             = kODNULL;
  1552.     fWindowState            = kODNULL;
  1553.     fSIHelper                = kODNULL;
  1554.  
  1555.     fAlreadyInCoercion        = kODFalse;
  1556.     fErrorFromOpenEvents    = noErr;
  1557.     fUniqueNameSeed            = 1;
  1558.     fShellHasMenuFocus        = kODFalse;
  1559.     fLastNewDocPSN.lowLongOfPSN = kNoProcess;
  1560.  
  1561.     fSaveCopyData            = kODNULL;
  1562.     fSaveDiffVolDialog        = kODNULL;
  1563.     
  1564.     fLowMemNotified            = kODFalse;
  1565.     
  1566.     fFailedPlugInName[0]    = 0;
  1567. }
  1568.  
  1569.  
  1570. RealShell::~RealShell()
  1571. {
  1572.     
  1573.     ODDeleteObject(fSIHelper);
  1574.     
  1575.     this->ExportClipboard(kODFalse);
  1576. #ifdef SHLHeapDebug
  1577.     SHLDebugStr("\pPostCloseDoc/PreSessionDelete HeapInfo…");
  1578.     HeapInfo();
  1579. #endif
  1580.     delete fSession;
  1581. #ifdef SHLHeapDebug
  1582.     SHLDebugStr("\pPostSessionDelete HeapInfo…");
  1583.     HeapInfo();
  1584. #endif
  1585.  
  1586. #if ODDebug
  1587.     if( gDumpBlocksOnClose ) {
  1588.         somPrintf("SOM objects and tracked blocks in heap contents after closing the session:\n");
  1589.         DumpHeapObjects(/*objectsOnly*/ kODFalse);
  1590.     }
  1591. #endif
  1592.     WASSERT(fSaveDiffVolDialog==kODNULL);
  1593. }
  1594.  
  1595.  
  1596.  
  1597. void RealShell::Initialize()
  1598. {
  1599.     fEV = somGetGlobalEnvironment();
  1600.         
  1601.     fSession = new ODSession;
  1602.     THROW_IF_NULL(fSession); // som objects don't autothrow if unable to allocate.
  1603.     fSession->InitSession(fEV);
  1604.     // Note: we need fDispatcher & fWindowState BEFORE ShellPlugIns are installed.
  1605.     fDispatcher = fSession->GetDispatcher(fEV);
  1606.     fWindowState = fSession->GetWindowState(fEV);
  1607.         
  1608.     // Is the app curently the active process?
  1609.     ProcessSerialNumber me = {0,kCurrentProcess};
  1610.     ProcessSerialNumber cur;
  1611.     GetFrontProcess(&cur);
  1612.     SameProcess(&me,&cur,&fProcessIsActive);
  1613.  
  1614.     this->InstallMenuBar();
  1615.     this->InitAE();
  1616.     this->InitMemory();
  1617. }
  1618.  
  1619. void RealShell::InstallMenuBar()
  1620. {
  1621.     ODSLong        savedRefNum;
  1622.     BeginUsingLibraryResources(savedRefNum);
  1623.  
  1624.     ODPlatformMenuBar    menuBar;
  1625.     menuBar = GetNewMBar(kODAppleMenuID);
  1626.     
  1627.     if( !menuBar ) THROW(resNotFound);
  1628.     SetMenuBar(menuBar);
  1629.  
  1630.     MenuHandle appleMenu = GetMenuHandle(kODAppleMenuID);
  1631.     DetachResource((Handle)appleMenu);
  1632.     
  1633. #if ODDebugMenu
  1634.     // Add "ODDebug" menu item, with submenu, below "About..." command:
  1635.     InsertMenuItem(appleMenu,"\pODDebug",1);
  1636.     SetItemCmd(appleMenu,2,0x1B);
  1637.     SetItemMark(appleMenu,2, kDebugMenuID);
  1638.     
  1639.     MenuHandle dbMenu = NewMenu(kDebugMenuID,"\pODDebug");
  1640.     THROW_IF_NULL(dbMenu);
  1641.     AppendMenu(dbMenu,    "\pHeap Info;"
  1642.                         "Memory Validation;"
  1643.                         "Heap Checking;"
  1644.                         "Leak Checking;"
  1645.                         "Dump Blocks On Close;"
  1646.                         "Track Block Stack Crawls;"
  1647.                         "Eat Memory;"
  1648.                         "Purge;"
  1649.                         "(-;"
  1650.                         "Log To stdout File;"
  1651.                         "Log To DebugWindow;"
  1652.                         "Generate DebugStrs;"
  1653.                         "Dump ODObjects;"
  1654.                         "Dump Tracked Blocks;"
  1655.                         "(-;"
  1656.                         "Break On THROW;"
  1657.                         "SOM Trace" );
  1658.     InsertMenu(dbMenu,hierMenu);
  1659.  
  1660.     const int kNumDebugMenuItems = 17;
  1661.  
  1662.     static const ODCommandID kDBCommands[kNumDebugMenuItems] = {kODCommandDBHeapInfo,
  1663.                                                 kODCommandDBMemValidation,
  1664.                                                 kODCommandDBHeapChecking,
  1665.                                                 kODCommandDBLeakChecking,
  1666.                                                 kODCommandDBDumpBlocksOnClose,
  1667.                                                 kODCommandDBTrackStackCrawls,
  1668.                                                 kODCommandDBEatMemory,
  1669.                                                 kODCommandDBPurge,
  1670.     /* Used below... */                            0,
  1671.                                                 kODCommandDBLogStdout,
  1672.                                                 kODCommandDBLogDebugWindow,
  1673.                                                 kODCommandDBLogDebugStr,
  1674.                                                 kODCommandDBDumpObjects,
  1675.                                                 kODCommandDBDumpBlocks,
  1676.                                                 0,
  1677.                                                 kODCommandDBBreakOnThrow,
  1678.                                                 kODCommandDBSOMTrace};
  1679.  
  1680.     DisposeHandle((Handle)menuBar);                // Update menuBar variable with new menu
  1681.     menuBar = GetMenuBar();
  1682. #endif
  1683.     
  1684.     // create a new ODMenuBar object
  1685.     TempODMenuBar baseMenuBar = fWindowState->CreateMenuBar(fEV, menuBar);
  1686.     
  1687.     // add DA names to Apple menu
  1688.     AppendResMenu(appleMenu, kODDASMenuRsrc);
  1689.  
  1690.     MenuHandle documentMenu = GetMenu(kODDocumentMenuID);
  1691.  
  1692.     DetachResource((Handle)documentMenu);
  1693.     baseMenuBar->AddMenuLast(fEV, kODDocumentMenuID, documentMenu, kODNULL);
  1694.  
  1695.     MenuHandle editMenu = GetMenu(kODEditMenuID);
  1696.     DetachResource((Handle)editMenu);
  1697.     baseMenuBar->AddMenuLast(fEV, kODEditMenuID, editMenu, kODNULL);
  1698.  
  1699. //    Save off the default undo and redo menu items so that we can use them when
  1700. //    there's nothing on the undo or redo stack.
  1701.  
  1702.     this->SaveMenuItem(appleMenu, kSHLMenuAbout, &fDefaultAboutMenuItem);
  1703.     this->SaveMenuItem(editMenu, kSHLMenuUndo, &fDefaultUndoMenuItem);
  1704.     this->SaveMenuItem(editMenu, kSHLMenuRedo, &fDefaultRedoMenuItem);
  1705.     this->SaveMenuItem(editMenu, kSHLMenuPreferences, &fDefaultPrefsMenuItem);
  1706.  
  1707.      EndUsingLibraryResources(savedRefNum);
  1708.  
  1709.     baseMenuBar->RegisterCommand(fEV, kODCommandAppleMenu, kODAppleMenuID, 0);
  1710.     baseMenuBar->RegisterCommand(fEV, kODCommandAbout, kODAppleMenuID, kSHLMenuAbout);
  1711.     
  1712.     baseMenuBar->RegisterCommand(fEV, kODCommandDocumentMenu, kODDocumentMenuID, 0);
  1713.     baseMenuBar->RegisterCommand(fEV, kODCommandNew, kODDocumentMenuID, kSHLMenuNew);
  1714.     baseMenuBar->RegisterCommand(fEV, kODCommandOpen, kODDocumentMenuID, kSHLMenuOpen);
  1715.     baseMenuBar->RegisterCommand(fEV, kODCommandOpenDocument, kODDocumentMenuID, kSHLMenuOpenDocument);
  1716.     baseMenuBar->RegisterCommand(fEV, kODCommandInsert, kODDocumentMenuID, kSHLMenuInsert);
  1717.     baseMenuBar->RegisterCommand(fEV, kODCommandClose, kODDocumentMenuID, kSHLMenuClose);
  1718.     baseMenuBar->RegisterCommand(fEV, kODCommandDeleteDocument, kODDocumentMenuID, kSHLMenuDeleteDocument);
  1719.     
  1720.     baseMenuBar->RegisterCommand(fEV, kODCommandSave, kODDocumentMenuID, kSHLMenuSave);
  1721.     baseMenuBar->RegisterCommand(fEV, kODCommandSaveACopy, kODDocumentMenuID, kSHLMenuSaveACopy);
  1722.     baseMenuBar->RegisterCommand(fEV, kODCommandRevert, kODDocumentMenuID, kSHLMenuRevert);
  1723.     baseMenuBar->RegisterCommand(fEV, kODCommandDraft, kODDocumentMenuID, kSHLMenuDraft);
  1724.     baseMenuBar->RegisterCommand(fEV, kODCommandDocumentInfo, kODDocumentMenuID, kSHLMenuDocumentInfo);
  1725.     
  1726.     baseMenuBar->RegisterCommand(fEV, kODCommandPageSetup, kODDocumentMenuID,
  1727.             kSHLMenuPageSetup );
  1728.     baseMenuBar->RegisterCommand(fEV, kODCommandPrint, kODDocumentMenuID,
  1729.             kSHLMenuPrint );
  1730.     
  1731.     baseMenuBar->RegisterCommand(fEV, kODCommandEditMenu, kODEditMenuID, 0);
  1732.     baseMenuBar->RegisterCommand(fEV, kODCommandUndo, kODEditMenuID, kSHLMenuUndo);
  1733.     baseMenuBar->RegisterCommand(fEV, kODCommandRedo, kODEditMenuID, kSHLMenuRedo);
  1734.     baseMenuBar->RegisterCommand(fEV, kODCommandCut, kODEditMenuID, kSHLMenuCut);
  1735.     baseMenuBar->RegisterCommand(fEV, kODCommandCopy, kODEditMenuID, kSHLMenuCopy);
  1736.     baseMenuBar->RegisterCommand(fEV, kODCommandPaste, kODEditMenuID, kSHLMenuPaste);
  1737.     baseMenuBar->RegisterCommand(fEV, kODCommandPasteAs, kODEditMenuID, kSHLMenuPasteAs);
  1738.     baseMenuBar->RegisterCommand(fEV, kODCommandClear, kODEditMenuID, kSHLMenuClear);
  1739.     baseMenuBar->RegisterCommand(fEV, kODCommandSelectAll, kODEditMenuID, kSHLMenuSelectAll);
  1740.     baseMenuBar->RegisterCommand(fEV, kODCommandGetPartInfo, kODEditMenuID, kSHLMenuGetPartInfo);
  1741.     baseMenuBar->RegisterCommand(fEV, kODCommandPreferences, kODEditMenuID, kSHLMenuPreferences);
  1742.     baseMenuBar->RegisterCommand(fEV, kODCommandViewAsWin, kODEditMenuID, kSHLMenuViewAsWin);
  1743.     
  1744. #if ODDebugMenu
  1745.     for( short i=0; i<kNumDebugMenuItems; i++ )
  1746.         if( kDBCommands[i] )
  1747.             baseMenuBar->RegisterCommand(fEV, kDBCommands[i], kDebugMenuID, i+1);
  1748. #endif
  1749.  
  1750.     fWindowState->SetBaseMenuBar(fEV,baseMenuBar);
  1751.     baseMenuBar->Display(fEV);
  1752. }
  1753.  
  1754. //------------------------------------------------------------------------------
  1755. // RealShell::SaveMenuItem
  1756. //------------------------------------------------------------------------------
  1757.  
  1758. void RealShell::SaveMenuItem(MenuHandle menu, short itemNum, MenuItemInfo* info)
  1759. {
  1760.     GetMenuItemText(menu, itemNum, (*info).text);
  1761.     GetItemCmd(menu, itemNum, &(*info).cmdChar);
  1762.     GetItemIcon(menu, itemNum, &(*info).iconID);
  1763.     GetItemMark(menu, itemNum, &(*info).markChar);
  1764.     GetItemStyle(menu, itemNum, &(*info).textStyle);
  1765. }
  1766.  
  1767. //------------------------------------------------------------------------------
  1768. // RealShell::RestoreMenuItem
  1769. //------------------------------------------------------------------------------
  1770.  
  1771. void RealShell::RestoreMenuItem(MenuHandle menu, short itemNum, MenuItemInfo* info)
  1772. {
  1773.     SetMenuItemText(menu, itemNum, (*info).text);
  1774.     SetItemCmd(menu, itemNum, (*info).cmdChar);
  1775.     SetItemIcon(menu, itemNum, (*info).iconID);
  1776.     SetItemMark(menu, itemNum, (*info).markChar);
  1777.     SetItemStyle(menu, itemNum, (*info).textStyle);
  1778. }
  1779.  
  1780. //------------------------------------------------------------------------------
  1781. // RealShell::InstallShellPlugIns
  1782. //------------------------------------------------------------------------------
  1783.  
  1784. void RealShell::InstallShellPlugIns(ODDraft* draft)
  1785. {
  1786.     // get reference to OpenDoc Shell PlugIns directory
  1787.     ODSShort fldrVRefNum=0;
  1788.     ODSLong fldrDirID=0;
  1789.  
  1790.     TRY{
  1791.         FindShellPlugInsFolder(&fldrVRefNum, &fldrDirID);
  1792.         this->ScanShellPlugInsFldr(fldrVRefNum, fldrDirID, draft);
  1793.     }CATCH_ALL{
  1794.         if ( fFailedPlugInName[0] )
  1795.             RERAISE;
  1796.     }ENDTRY
  1797.  
  1798. }
  1799.  
  1800. //------------------------------------------------------------------------------
  1801. // GetCfrgInfo
  1802. // Given a file spec, find the record within the 'cfrg' resource in that
  1803. // file that corresponds to the platform we're on and the symbol we're
  1804. // looking for.  Having found it, return the offset and length from the
  1805. // record; failing, return an error.
  1806. //------------------------------------------------------------------------------
  1807.  
  1808. ODStatic OSErr GetCfrgInfo( ODFileSpec* fileSpec, long* offset, long* length )
  1809. {
  1810.     struct FragDesc {
  1811.         ResType codeType;
  1812.         long ignore[5];
  1813.         long offsetToFrag;
  1814.         long lengthOfFrag;
  1815.         long moreIgnore[2];
  1816.         short recordLength;
  1817.         Str63 name;
  1818.     };
  1819.     
  1820.     struct CFRGResource {
  1821.         long ignore[7];
  1822.         long numFrags;
  1823.         struct FragDesc firstDesc;
  1824.     };
  1825.  
  1826.     OSErr err = resNotFound;
  1827.  
  1828.     short refNum = HOpenResFile( fileSpec->vRefNum, fileSpec->parID,
  1829.             fileSpec->name, fsRdPerm );
  1830.     short saveRefNum = CurResFile();
  1831.     UseResFile( refNum );
  1832.  
  1833.     struct CFRGResource** cfrgHandle =
  1834.             (struct CFRGResource**)Get1Resource( 'cfrg', 0 );
  1835.     if ( cfrgHandle )
  1836.     {
  1837.         long entryCount = (*cfrgHandle)->numFrags;
  1838. #ifdef ODDebug
  1839.         if ( entryCount > 2 )
  1840.             WARN( "Plugin cfrg has more than 2 entries (ie isn't just fat)"
  1841.                     " and we aren't checking names" );
  1842. #endif
  1843.         struct FragDesc* oneEntryPtr = &(*cfrgHandle)->firstDesc;
  1844.         while ( entryCount-- )
  1845.         {
  1846.             if ( oneEntryPtr->codeType == kCurrentCFragArch )
  1847.             {
  1848.                 *offset = oneEntryPtr->offsetToFrag;
  1849.                 *length = oneEntryPtr->lengthOfFrag;
  1850.                 err = noErr;
  1851.                 break;
  1852.             }
  1853.             else
  1854.                 oneEntryPtr = (FragDesc*)(oneEntryPtr->recordLength
  1855.                         + (char*)oneEntryPtr);
  1856.         }
  1857.     }
  1858.     else
  1859.         err = ResError();
  1860.  
  1861.     CloseResFile( refNum );
  1862.     UseResFile( saveRefNum );
  1863.     return err;
  1864. }
  1865.  
  1866. //------------------------------------------------------------------------------
  1867. // RealShell::ScanShellPlugInsFldr
  1868. //------------------------------------------------------------------------------
  1869.  
  1870. void RealShell::ScanShellPlugInsFldr(ODSShort fldrVRefNum, ODSLong fldrDirID,
  1871.                                     ODDraft* draft)
  1872. {
  1873.         // iterate through files in that directory (code copied from Prefs.cpp:LoadNameSpaceTable)
  1874.         ODFileSpec        theFileSpec;
  1875.         CInfoPBRec        CinfoPB;
  1876.         Str255            fileName;
  1877.     
  1878.         memset (&CinfoPB,0,sizeof(CinfoPB));
  1879.         CinfoPB.hFileInfo.ioNamePtr = (StringPtr)fileName;
  1880.         CinfoPB.hFileInfo.ioFDirIndex = 1;
  1881.         CinfoPB.hFileInfo.ioVRefNum = fldrVRefNum;
  1882.         CinfoPB.hFileInfo.ioDirID = fldrDirID;
  1883.  
  1884.         TempPlatformFile file(new PlatformFile);
  1885.         
  1886.         for( ODSShort i = PBGetCatInfoSync( &CinfoPB ); 
  1887.                         i == noErr; 
  1888.                        i = PBGetCatInfoSync( &CinfoPB ) )
  1889.         {
  1890.                 // if this is not a folder and we successfully create an FSSpec
  1891.             if (( ! (CinfoPB.hFileInfo.ioFlAttrib & (1<<4)) ) 
  1892.                 && ( noErr == (FSMakeFSSpec( CinfoPB.hFileInfo.ioVRefNum, 
  1893.                                   CinfoPB.hFileInfo.ioFlParID, //ioDirID, 
  1894.                                   fileName, 
  1895.                                   &theFileSpec ) ) ))
  1896.             {
  1897.                 file->Specify(&theFileSpec);
  1898.                 if ( file->GetPlatformType() == kCFragLibraryFileType)
  1899.                 {
  1900.                     CFragConnectionID connID;
  1901.                     Ptr mainAddr;
  1902.                     Str255 errName;
  1903.  
  1904.                     long length;
  1905.                     long offset;
  1906.                     OSErr err = GetCfrgInfo( &theFileSpec, &offset, &length );
  1907.  
  1908.                     if ( !err )
  1909.                         err = GetDiskFragment( &theFileSpec, offset, length,
  1910.                                 NULL, kNewCFragCopy, &connID, &mainAddr,
  1911.                                 errName );
  1912.                     if ( !err )
  1913.                     {
  1914.                         ODShellPlugInInstallProc installMethod;
  1915.                         CFragSymbolClass symClass;
  1916.                         err = FindSymbol( connID, "\pODShellPlugInInstall",
  1917.                                 (Ptr*)&installMethod, &symClass );
  1918.                         ODShellPlugInActionCodes action
  1919.                                 = kODShellPlugInNoAction;
  1920.                         if ( !err )
  1921.                         {
  1922.                             WASSERT( symClass == kTVectorCFragSymbol );
  1923.                             TRY
  1924.                                 err = (*installMethod)( fEV, draft, &action );
  1925.                                 SetErrorCode(kODNoError);
  1926.                             CATCH_ALL
  1927.                                 SetErrorCode(kODNoError);
  1928.                             ENDTRY
  1929.                         }
  1930.                         // else is not a shell plugin; continue with next file
  1931.  
  1932.                         // test again; if the FindSymbol call failed we
  1933.                         // still want to close the connection
  1934.                         if ( (err != noErr) ||
  1935.                                 BITTEST(action, kODShellPlugInCloseConnection) )
  1936.                             err = CloseConnection( &connID );
  1937.                     }
  1938.                     if ( err )
  1939.                     {
  1940.                         ODBlockMove( theFileSpec.name, fFailedPlugInName,
  1941.                                 theFileSpec.name[0]+1 );
  1942.                         THROW( err );
  1943.                     }
  1944.                 }
  1945.             }
  1946.             CinfoPB.hFileInfo.ioFDirIndex++;
  1947.                     
  1948.         //need to do this each time since PBGetCatInfo call returns val here
  1949.             CinfoPB.hFileInfo.ioNamePtr = (StringPtr)fileName;
  1950.             CinfoPB.hFileInfo.ioVRefNum = fldrVRefNum;
  1951.             CinfoPB.hFileInfo.ioDirID = fldrDirID;  
  1952.         }
  1953. }
  1954.  
  1955. //------------------------------------------------------------------------------
  1956. // FindShellPlugInsFolder //ccg
  1957. //------------------------------------------------------------------------------
  1958.  
  1959. static void FindShellPlugInsFolder(short *vol, long *dir )
  1960. {
  1961.     Str255    folderName;
  1962.     
  1963.     CInfoPBRec        pb;
  1964.     memset (&pb,0,sizeof(pb));
  1965.  
  1966.         //First find System Folder
  1967.     THROW_IF_ERROR( FindFolder(kOnSystemDisk, kSystemFolderType, kDontCreateFolder, 
  1968.                                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID) );
  1969.  
  1970.         // find Shell Plug Ins Folder path name
  1971.     ODGetString(folderName, kODEditorsFldrStrID);
  1972.     pb.dirInfo.ioNamePtr = (StringPtr)&folderName;
  1973.     pb.dirInfo.ioFDirIndex = 0;
  1974.     THROW_IF_ERROR( PBGetCatInfoSync( &pb ) );
  1975.  
  1976.     ODGetString(folderName, kODOpenDocPartsFolderStrID);
  1977.     pb.dirInfo.ioNamePtr = (StringPtr)&folderName;
  1978.     pb.dirInfo.ioFDirIndex = 0;
  1979.     THROW_IF_ERROR( PBGetCatInfoSync( &pb ) );
  1980.  
  1981.     ODGetString(folderName, kODShellPlugInFolderStrID);
  1982.     pb.dirInfo.ioNamePtr = (StringPtr)&folderName;
  1983.     pb.dirInfo.ioFDirIndex = 0;
  1984.     THROW_IF_ERROR( PBGetCatInfoSync( &pb ) );
  1985.  
  1986.     *vol = pb.dirInfo.ioVRefNum;
  1987.     *dir = pb.dirInfo.ioDrDirID;
  1988. }
  1989. //------------------------------------------------------------------------------
  1990. // FindStationeryFolder
  1991. //------------------------------------------------------------------------------
  1992. static void FindStationeryFolder(short *vol, long *dir )
  1993. {
  1994.     Str255    folderName;
  1995.     ODSLong    unused;
  1996.     
  1997.     CInfoPBRec        pb;
  1998.     memset (&pb,0,sizeof(pb));
  1999.  
  2000.         //First find Desktop Folder
  2001.     THROW_IF_ERROR( FindFolder(kOnSystemDisk, kDesktopFolderType, kCreateFolder, 
  2002.                                 vol, &unused ));
  2003.  
  2004.         // find Stationery Folder path name
  2005.     ODGetString(folderName, kODStationeryFldrStrID);
  2006.     pb.dirInfo.ioNamePtr = (StringPtr)&folderName;
  2007.     pb.dirInfo.ioDrDirID = fsRtDirID; //2;
  2008.     pb.dirInfo.ioVRefNum = *vol;
  2009.     pb.dirInfo.ioFDirIndex = 0;
  2010.     if ( PBGetCatInfoSync( &pb ) )
  2011.     {
  2012.         THROW_IF_ERROR( 
  2013.             DirCreate(*vol, fsRtDirID, folderName, dir));
  2014.     } else {    
  2015.         *dir = pb.dirInfo.ioDrDirID;
  2016.     }
  2017. }
  2018.  
  2019. //-------------------------------------------------------------------------------------
  2020. // RealShell::go
  2021. //-------------------------------------------------------------------------------------
  2022.  
  2023. void RealShell::go()
  2024. {
  2025.     ODBoolean    initialized;
  2026.     ODVolatile(initialized);
  2027.     ODULong        errorLoops = 0; // Counts the number of times in a row we caught
  2028.                                 //    an out-of-memory error in the event loop.
  2029.     ODVolatile(errorLoops);
  2030.     
  2031.     #if ODDebug
  2032.     if ( gDumpBlocksOnClose )
  2033.     {
  2034.         SetOutputMode(kWriteToFile);
  2035.         // MMBeginLeakChecking();
  2036.         // gLeakChecking = kODTrue;
  2037.         MMTrackStackCrawls( kODTrue );
  2038.     }
  2039.     #endif
  2040.     
  2041.     {
  2042.         TRY
  2043.             this->Initialize();
  2044.             initialized = kODTrue;
  2045.         CATCH_ALL
  2046.             initialized = kODFalse;
  2047.             this->ExceptionAlert(ErrorCode(),ErrorMessage());
  2048.         ENDTRY
  2049.     }
  2050.     
  2051. #ifdef SHLTestErrorDialogUsage
  2052.     SHLDebugStr("\pPreErrorDialog HeapInfo…");
  2053.     HeapInfo();
  2054.     this->ExceptionAlert(1,kODNULL);
  2055. #endif
  2056.  
  2057. #ifdef SHLTestSessionOverhead
  2058.     SHLDebugStr("\pPreExtraSession HeapInfo…");
  2059.     HeapInfo();
  2060.  
  2061.     TRY
  2062.         TempODSession aSession = new ODSession;
  2063.         THROW_IF_NULL(aSession); // som objects don't autothrow if unable to allocate.
  2064.         aSession->InitSession(fEV);
  2065.     CATCH_ALL
  2066.     ENDTRY
  2067.  
  2068.     SHLDebugStr("\pPostExtraSession HeapInfo…");
  2069.     HeapInfo();
  2070. #endif
  2071.  
  2072.     EventRecord        eventRec;
  2073.     if (initialized)
  2074.     while (!fDispatcher->ShouldExit(fEV)) 
  2075.     {
  2076.         TRY
  2077.             if ( gODBentoFatalErrorHasOccurred )
  2078.                 ODBentoFatalError();
  2079.  
  2080.             if( this->CheckFileLocation() )            // Update if document renamed/moved
  2081.                 break;                                // we may need to quit if trashed
  2082.             
  2083.             ODSLong sleep = fDispatcher->GetSleepTime(fEV);
  2084.             if( sleep > kMaxTimeBetweenLocationChecks )
  2085.                 sleep = kMaxTimeBetweenLocationChecks;
  2086.             
  2087.             WaitNextEvent (everyEvent, &eventRec, sleep, fDispatcher->GetMouseRegion(fEV));
  2088.             if( eventRec.what == osEvt && (( eventRec.message >> 24 ) & 0x00FF)==0x01 )
  2089.                 fProcessIsActive= (eventRec.message & 0x01)!=0;
  2090.  
  2091.             this->DispatchEvent((ODEventData*)&eventRec);
  2092.  
  2093.             this->CheckMenuBar();
  2094.  
  2095.             if( fProcessIsActive )
  2096.                 this->CheckFreeMemory();            // Display low-mem alert
  2097.     
  2098.             errorLoops = 0; // Reset this. We got through the loop OK.
  2099.  
  2100.         CATCH_ALL
  2101.  
  2102.             // IF WE CATCH A LOW-MEMORY ERROR HERE MORE THAN 2 TIMES IN A ROW,
  2103.             //    WE OUTTIE.
  2104.             ODError thisError = ErrorCode();
  2105.             if (thisError == kODErrOutOfMemory || thisError == memFullErr)
  2106.             {
  2107.                 ++errorLoops;
  2108.                 if (errorLoops > 2)
  2109.                     ODShellLowMemoryGoodbye();
  2110.             }
  2111.  
  2112.             this->ExceptionAlert(ErrorCode(),ErrorMessage());
  2113.  
  2114.         ENDTRY
  2115.  
  2116.     }
  2117.     
  2118.     // Check to see if we failed in the odoc or oapp appleevent handlers.
  2119.     ODError    err = this->GetAEError();
  2120.     if (err)
  2121.     {
  2122.         this->ExceptionAlert(err,kODNULL);
  2123.     }
  2124. }
  2125.  
  2126.  
  2127. //-------------------------------------------------------------------------------------
  2128. // Notification Stuff
  2129. //-------------------------------------------------------------------------------------
  2130.  
  2131. struct NotEntry :public Link {
  2132.     RealShell::Notifier n;
  2133.     ODULong                refCon;
  2134.     NMRec                nm;
  2135.     
  2136.     virtual ~NotEntry( );
  2137. };
  2138.  
  2139. NotEntry::~NotEntry( )
  2140. {
  2141.     if( nm.nmIcon ) DisposeIconSuite(nm.nmIcon,kODTrue);
  2142. }
  2143.  
  2144. static ODIconFamily
  2145. GetRootPartIconFamily( Environment*    ev, ODSession* session )
  2146. {
  2147.     static ODIconFamily sIcon = kODNULL;
  2148.     if( !sIcon ) {
  2149.         TempODWindow odWindow = session->GetWindowState(ev)->AcquireFrontRootWindow(ev);
  2150.         ODFrame* rootFrame = odWindow ? odWindow->GetRootFrame(ev) : kODNULL;
  2151.         sIcon = ODGetIconFamily(ev, rootFrame);
  2152.     }
  2153.     return sIcon;
  2154. }
  2155.  
  2156.  
  2157. //-------------------------------------------------------------------------------------
  2158. // RealShell::Notify
  2159. //-------------------------------------------------------------------------------------
  2160.  
  2161. void
  2162. RealShell::Notify( RealShell::Notifier n, ODULong refCon )
  2163. {
  2164.     if( fProcessIsActive )
  2165.         (this->*n)( refCon );                        // We're active, so call notifier right now.
  2166.         
  2167.     else {
  2168.         NotEntry *e = new NotEntry;
  2169.         e->n = n;
  2170.         e->refCon = refCon;
  2171.         fNotifiers.AddLast(e);
  2172.         
  2173.         e->nm.qType = nmType;
  2174.         e->nm.nmMark = 1;                                    // Mark process menu
  2175.         e->nm.nmIcon = GetRootPartIconFamily(fEV, fSession);    // Show root part's icon
  2176.         e->nm.nmSound = (Handle)-1L;                        // Play system beep
  2177.         e->nm.nmStr = kODNULL;
  2178.         e->nm.nmResp = kODNULL;
  2179.         OSErr err= NMInstall(&e->nm);
  2180.         WASSERT(err==noErr);
  2181.     }
  2182. }
  2183.  
  2184.  
  2185. //-------------------------------------------------------------------------------------
  2186. // RealShell::CancelNotification
  2187. //-------------------------------------------------------------------------------------
  2188.  
  2189. void
  2190. RealShell::CancelNotification( RealShell::Notifier n )
  2191. {
  2192.     // Removes all notifications pointing to this notifier proc.
  2193.     NotEntry *next;
  2194.     for( NotEntry *e = (NotEntry*)fNotifiers.First(); e; e=next ) {
  2195.         next = (NotEntry*)fNotifiers.After(*e);
  2196.         if( e->n == n ) {
  2197.             NMRemove(&e->nm);
  2198.             fNotifiers.Remove(*e);
  2199.             delete e;
  2200.         }
  2201.     }
  2202. }
  2203.  
  2204.  
  2205. //-------------------------------------------------------------------------------------
  2206. // RealShell::ShowPendingNotification
  2207. //-------------------------------------------------------------------------------------
  2208.  
  2209. void
  2210. RealShell::ShowPendingNotifications( )
  2211. {
  2212.     if( fProcessIsActive ) {
  2213.         NotEntry *e;
  2214.         while( !fNotifiers.IsEmpty() ) {
  2215.             e = (NotEntry*) fNotifiers.RemoveFirst();
  2216.             NMRemove(&e->nm);
  2217.             (this->*(e->n))( e->refCon );                        // Call notifier method
  2218.             delete e;
  2219.         }
  2220.     }
  2221. }
  2222.  
  2223.  
  2224. //-------------------------------------------------------------------------------------
  2225. // RealShell::DispatchEvent
  2226. //-------------------------------------------------------------------------------------
  2227.  
  2228. void RealShell::DispatchEvent(ODEventData* event)
  2229. {
  2230.     switch (event->what)
  2231.     {
  2232.     case kODEvtMouseDown:    
  2233.         this->DispatchMouseDownEvent(event);                
  2234.         break;
  2235.                 
  2236.     case kODEvtKeyDown:
  2237.         this->DispatchKeyDownEvent(event);                
  2238.         break;
  2239.                                     
  2240.     case kODEvtOS:
  2241.         // FOR NOW, EAT ALL ERRORS OCCURING DURING A SUSPEND.
  2242.         //    SEE WHAT TYPE OF OS EVENT IT IS
  2243.         ODUByte        typeOSEvent = (ODUByte) (event->message >> 24) & 0x00FF;
  2244.         ODBoolean    isSuspendEvent;
  2245.  
  2246.         //    IF IT'S A SUSPEND MESSAGE
  2247.         isSuspendEvent = ((typeOSEvent & suspendResumeMessage)
  2248.                             && (!(event->message & resumeFlag)));
  2249.         TRY
  2250.             fDispatcher->Dispatch(fEV,event);
  2251.             this->HandleOSEvent(event);
  2252.         CATCH_ALL
  2253.             if (isSuspendEvent)
  2254.                 WARN("Eating an error that occurred during suspend time.");
  2255.             else
  2256.                 RERAISE;
  2257.         ENDTRY
  2258.         break;
  2259.  
  2260.     case kHighLevelEvent:    
  2261.         if (!fDispatcher->Dispatch(fEV,event))
  2262.             this->HandleHighLevelEvent(event);                
  2263.         break;
  2264.         
  2265.     default:            
  2266.         fDispatcher->Dispatch(fEV,event);
  2267.         break;
  2268.     }
  2269. }
  2270.  
  2271. //-------------------------------------------------------------------------------------
  2272. // RealShell::DispatchMouseDownEvent
  2273. //-------------------------------------------------------------------------------------
  2274.  
  2275. void RealShell::DispatchMouseDownEvent(ODEventData* event)
  2276. {
  2277.     WindowPtr     theWindow = kODNULL;
  2278.     ODSShort     partCode = FindWindow(event->where, &theWindow);
  2279.     if (partCode == kODMDInMenuBar)
  2280.         this->DispatchMenuEvent(event);
  2281.     else if (!(fDispatcher->Dispatch(fEV,event)) && theWindow)
  2282.         this->HandleMouseDownInWindow(theWindow, partCode, event);
  2283. }
  2284.  
  2285. //-------------------------------------------------------------------------------------
  2286. // RealShell::DispatchMenuEvent
  2287. //-------------------------------------------------------------------------------------
  2288.  
  2289. void RealShell::DispatchMenuEvent(ODEventData* event)
  2290. {
  2291.     this->UpdateMenus();
  2292.     if (!(fDispatcher->Dispatch(fEV,event)))
  2293.         this->HandleMenuCommand(event->message, event);
  2294. }
  2295.  
  2296. //-------------------------------------------------------------------------------------
  2297. // RealShell::DispatchKeyDownEvent
  2298. //-------------------------------------------------------------------------------------
  2299.  
  2300. void RealShell::DispatchKeyDownEvent(ODEventData* event)
  2301. {    
  2302.     ODBoolean cmdKeyDown = (event->modifiers & cmdKey) != 0;
  2303.     ODBoolean optionKeyDown = (event->modifiers & optionKey) != 0;
  2304.     if (cmdKeyDown) // || F1, f2, f3, f4 were pressed
  2305.         this->UpdateMenus();    
  2306.         // Fix #1221897
  2307.         // should also do update if function keys for Undo/Cut/Copy/Paste were pressed
  2308.  
  2309.     if ( !fDispatcher->Dispatch(fEV, event) )
  2310.     {
  2311.         if ( event->what == kODEvtMenu )
  2312.             this->HandleMenuCommand(event->message, event );
  2313.         else if ( cmdKeyDown && optionKeyDown )
  2314.         {
  2315.             // we have a command-key equivalent that didn't get recognized
  2316.             // because UI doesn't like the option key.  So we need to change
  2317.             // the character to what it would be without the option, then get
  2318.             // the equivalent menu and invoke its handler with the additional
  2319.             // information that the option key was down.
  2320.             
  2321.             // Adapted from Finder code furnished by Greg Anderson
  2322.             unsigned char key = event->message & charCodeMask;
  2323.             short mangledKeyCode = (short)((event->message & keyCodeMask) >> 8)
  2324.                     | (event->modifiers & keyCodeMask);  // raw key w/ all modifiers
  2325.             UInt32 state = 0;
  2326.             Ptr kchrCache = (Ptr)GetScriptManagerVariable(smKCHRCache);
  2327.             
  2328.             // Find out if the raw key code matches the character in event.message.
  2329.             unsigned char computedKey =        // only keep low byte
  2330.                     (unsigned char)KeyTranslate( kchrCache, mangledKeyCode,
  2331.                     &state );
  2332.                     
  2333.             if (computedKey == key)
  2334.             {
  2335.                 mangledKeyCode &= (0xFFFF - optionKey);    // mask out option bit
  2336.                 key = (unsigned char) KeyTranslate(kchrCache, mangledKeyCode, &state);
  2337.                 // only keep low byte; we'll use this new keycode w/o option.
  2338.  
  2339.                 // NOTE: I'm not changing the event, which HandleMenuCommand
  2340.                 // ignores anyway.
  2341. //                ODBoolean oldOptionValue = fOptionKeyDownOnMenuBarClick;
  2342.                 fOptionKeyDownOnMenuBarClick = kODTrue;            
  2343.                 this->HandleMenuCommand( MenuKey(key), event );
  2344. //                fOptionKeyDownOnMenuBarClick = oldOptionValue;
  2345.             }
  2346.         }
  2347.     }
  2348. }
  2349.  
  2350. //-------------------------------------------------------------------------------------
  2351. // RealShell::HandleOSEvent
  2352. //-------------------------------------------------------------------------------------
  2353.  
  2354. void RealShell::HandleOSEvent(ODEventData* event)
  2355. {
  2356.     // Is it a multifinder event?
  2357.     ODUByte typeOSEvent = (ODUByte) (event->message >> 24) & 0x00FF;
  2358.     
  2359.     // Switch on the type of OSEvent that occurred, high byte of message is event type
  2360.     switch (typeOSEvent) 
  2361.     {     
  2362.     case suspendResumeMessage:
  2363.         if( event->message & resumeFlag )
  2364.             this->ShowPendingNotifications();        // Display pending notifications
  2365.         else
  2366.             this->ExportClipboard(kODFalse);
  2367.         break;
  2368.     }
  2369. }
  2370.  
  2371. //-------------------------------------------------------------------------------------
  2372. // RealShell::ExportClipboard
  2373. //-------------------------------------------------------------------------------------
  2374.  
  2375. void RealShell::ExportClipboard(ODBoolean canAlert)
  2376. {
  2377.     ODClipboard* clipboard = fSession->GetClipboard(fEV);
  2378.  
  2379. //    TRY
  2380.         clipboard->ExportClipboard(fEV);
  2381. //    CATCH_ALL
  2382. //        if ( canAlert )
  2383. //            this->ExceptionAlert(ErrorCode(),ErrorMessage());
  2384. //    ENDTRY;
  2385. }
  2386.  
  2387. //-------------------------------------------------------------------------------------
  2388. // Debug Menu Support
  2389. //-------------------------------------------------------------------------------------
  2390.  
  2391.  
  2392. #if ODDebugMenu
  2393.  
  2394. #define OBJECTMASTERKLUDGE
  2395. #ifdef OBJECTMASTERKLUDGE
  2396. extern "C" {
  2397. #endif
  2398.  
  2399.     #define kDumpTmpBufSize 3000
  2400.     
  2401.     static char gFilterNewClass; 
  2402.     // gFilterNewClass is a global with a unique address passed to DumpObjProc as refCon
  2403.     
  2404.     static MMBoolean DumpObjProc(  const void *blk, size_t size, MMBoolean isObject,
  2405.                                     void *refCon )
  2406.     {
  2407.         if( isObject ) {
  2408.             MMValidateObject((ODObject*)blk);
  2409.             somPrintf("  %p %4lu  %s\r", blk,size, ((ODObject*)blk)->somGetClassName());
  2410.         }
  2411.         return true;        // Might check for cmd-period or something to abort...
  2412.     }
  2413.     
  2414.     static void DumpBlockStackCrawl(  const void *blk, size_t size, ODBoolean isObject,
  2415.                                     ODBoolean filter )
  2416.     {
  2417.         long flags = 0;
  2418.         StackCrawl*    sc = MMGetBlockStackCrawl( blk, &flags );
  2419.         if (sc)
  2420.         {
  2421.             if ( !isObject )
  2422.             {
  2423.                 somPrintf("%p %4lu:\r", blk, size);
  2424.             }
  2425.             static const char* kTooLongString = "... [too long]\n";
  2426.             char buffer[kDumpTmpBufSize + 32]; // add 32 for kTooLongString
  2427.             buffer[0] = 0;
  2428.             long    numFrames = sc->CountFrames();
  2429.             long    pos = 0;
  2430.             for (long i = 0; i < numFrames && pos < kDumpTmpBufSize; i++)
  2431.             {
  2432.                 size_t    offset;
  2433.                 char    tmpBuffer[256];
  2434.                 char    fnName[256];
  2435.                 if (sc->LookupSymbol(i, fnName, &offset))
  2436.                 {
  2437.                     sprintf(tmpBuffer, "%s+%d\n", fnName, offset);
  2438.                     long newPos = pos + strlen(tmpBuffer);
  2439.                     if ( newPos < kDumpTmpBufSize )
  2440.                         sprintf(&(buffer[pos]), "%s", tmpBuffer);
  2441.                     else
  2442.                         strcpy(&(buffer[pos]), kTooLongString);
  2443.                     
  2444.                     pos = newPos;
  2445.                 } 
  2446.             }
  2447.             if ( filter )
  2448.             {
  2449.                 if ( buffer[0] && !strstr(buffer, "NewClass") )
  2450.                     somPrintf("%s\r", buffer);
  2451.             }
  2452.             else
  2453.             {
  2454.                 if ( buffer[0] )
  2455.                     somPrintf("%s\r", buffer);
  2456.             }
  2457.         }
  2458.     }
  2459.  
  2460. #ifdef OBJECTMASTERKLUDGE
  2461. }
  2462. #endif
  2463.  
  2464.  
  2465. struct TrackedBlockLink {
  2466.     TrackedBlockLink* fNext;
  2467.     const void*          fFirstBlock;
  2468.     StackCrawl*       fStack;
  2469.     unsigned long      fCount;
  2470.     unsigned long      fTotalSize;
  2471. };
  2472.  
  2473. static TrackedBlockLink* sTrackedBlockLinks;
  2474.     
  2475. extern "C" {
  2476. static MMBoolean 
  2477. FindObjsProc(  const void *blk, size_t size, MMBoolean isObject, void *refCon )
  2478. {
  2479.     long flags;
  2480.     StackCrawl* s = MMGetBlockStackCrawl(blk, &flags);
  2481.     if( s ) {
  2482.         size_t blockSize = MMBlockSize(blk);
  2483.         
  2484.         // This is a new block, check its stack crawl:
  2485.         TrackedBlockLink *l;
  2486.         for( l = sTrackedBlockLinks; l; l = l->fNext )
  2487.             if( *(l->fStack) == *s ) {
  2488.                 l->fCount++;
  2489.                 l->fTotalSize += blockSize;
  2490.                 // delete s;
  2491.                 // MMSetBlockStackCrawl(blk,kODNULL,0);
  2492.                 return kODTrue;
  2493.             }
  2494.         l = new TrackedBlockLink;
  2495.         l->fNext = sTrackedBlockLinks;
  2496.         l->fFirstBlock = blk;
  2497.         l->fTotalSize = blockSize;
  2498.         l->fStack = s;
  2499.         l->fCount = 1;
  2500.         sTrackedBlockLinks = l;
  2501.     }
  2502.     return kODTrue;
  2503. }
  2504. }
  2505.  
  2506. static void 
  2507. DumpFoundObjs()
  2508. {
  2509.     unsigned long count = 0;
  2510.     unsigned long space = 0;
  2511.     TrackedBlockLink* next;
  2512.     ODBoolean filter = isFilterKeyDown();
  2513.     
  2514.     for( TrackedBlockLink * l = sTrackedBlockLinks; l; l = next ) {
  2515.         count += l->fCount;
  2516.         next = l->fNext;
  2517.         // if( l->fCount >= 3 ) {
  2518.             somPrintf("• Occurred %lu time%s, %lu total bytes:\r", 
  2519.                 l->fCount, (l->fCount == 1)? "": "s", l->fTotalSize);
  2520.             size_t size = MMBlockSize(l->fFirstBlock);
  2521.             ODBoolean isObject = MMIsObject(l->fFirstBlock);
  2522.             
  2523.             DumpObjProc(l->fFirstBlock, size, isObject, kODNULL);
  2524.             DumpBlockStackCrawl(l->fFirstBlock, size, isObject, filter);
  2525.             
  2526.             space += l->fTotalSize + (l->fCount * 8);    // Add 8 bytes for per-block overhead
  2527.         // }
  2528.         delete l;
  2529.     }
  2530.     sTrackedBlockLinks = kODNULL;
  2531.     if( space > 0 )
  2532.         somPrintf("••• Estimated space in %lu tracked blocks: %lu bytes\r", count, space);
  2533.     else
  2534.         somPrintf("••• No tracked blocks found!\r");
  2535. }    
  2536.  
  2537. static void
  2538. DumpHeapObjects( ODBoolean objectsOnly )
  2539. {
  2540.     const char *name;
  2541.     size_t allocated, free,blocks,objects;
  2542.     MMGetHeapInfo(kDefaultHeapID,
  2543.                     &name, &allocated, &free, &blocks, &objects);
  2544.     somPrintf("••• Dump of %s •••\r%lu bytes allocated, %lu free (%.1f%% free).\r",
  2545.                     name, (ODULong)allocated, (ODULong)free, 100.0*free/(float)(allocated+free) );
  2546.     somPrintf("There are %lu blocks, of which %lu are objects:\r", (ODULong)blocks, (ODULong)objects);
  2547.  
  2548.     if ( !objectsOnly && gTrackStackCrawls )
  2549.     {
  2550.         sTrackedBlockLinks = kODNULL;
  2551.  
  2552.         MMTrackStackCrawls(kODFalse); // disable stack crawls in FindObjsProc()
  2553.         MMWalkHeap(kDefaultHeapID, &FindObjsProc, kODNULL);
  2554.         DumpFoundObjs();
  2555.         MMTrackStackCrawls(kODTrue); // re-enable stack crawls
  2556.  
  2557.         sTrackedBlockLinks = kODNULL;
  2558.     }
  2559.     else
  2560.     {
  2561.         somPrintf("  ADDRESS  SIZE  CLASS\r");
  2562.         MMWalkHeap(kDefaultHeapID, &DumpObjProc, kODNULL);
  2563.     }
  2564. }
  2565.  
  2566.  
  2567. #endif
  2568.  
  2569. //-------------------------------------------------------------------------------------
  2570. // RealShell::HandleMenuCommand
  2571. //-------------------------------------------------------------------------------------
  2572.  
  2573.  
  2574. void RealShell::HandleMenuCommand(ODSLong menuResult, ODEventData* event)
  2575. {
  2576.     ODUnused(event);
  2577.  
  2578.     ODSShort menu = HiWord(menuResult);
  2579.     ODSShort item = LoWord(menuResult);
  2580.     TempODMenuBar menuBar = fWindowState->AcquireCurrentMenuBar(fEV);
  2581.     ODCommandID command = menuBar->GetCommand(fEV,menu, item);
  2582.  
  2583.     if (menuBar->IsCommandSynthetic(fEV,command))
  2584.     {
  2585.         switch (menu)
  2586.         {
  2587.             case kODAppleMenuID: // Apple
  2588.             {
  2589.                 Str255        daName;
  2590.                 ODSShort    daRefNum;
  2591.                 
  2592.                 GetMenuItemText(GetMenuHandle(kODAppleMenuID), item, daName);
  2593.                 daRefNum = OpenDeskAcc(daName);
  2594.                 HiliteMenu(0);
  2595.                 break;
  2596.             }
  2597.  
  2598.             default:
  2599.                 break;
  2600.         }
  2601.     }
  2602.     else 
  2603.     {
  2604.         ODDraft*        activeDraft  = ODGetActiveDraft(fEV, fSession);
  2605.         ODDocument*        activeDocument;
  2606.         if (activeDraft)
  2607.             activeDocument = activeDraft->GetDocument(fEV);
  2608.         else
  2609.             activeDocument = kODNULL;
  2610.         
  2611.         switch(command)
  2612.         {
  2613.             case kODCommandAbout: {
  2614.                 CUsingLibraryResources r;
  2615.                 ODSShort itemHit;
  2616.                 GrafPtr savePort;
  2617.                 GetPort(&savePort);
  2618.                 
  2619.                 fWindowState->DeactivateFrontWindows(fEV);
  2620.                 TRY
  2621.                     DialogPtr aboutDlg = ShowAboutScreen();
  2622.                 
  2623.                     ModalDialog(kODNULL /*modalFilter*/, &itemHit);
  2624.                     if (aboutDlg)
  2625.                         DisposeDialog(aboutDlg);
  2626.                 CATCH_ALL
  2627.                     fWindowState->ActivateFrontWindows(fEV);
  2628.                     RERAISE;
  2629.                 ENDTRY
  2630.                 fWindowState->ActivateFrontWindows(fEV);
  2631.  
  2632.                 SetPort(savePort);
  2633.                 break;
  2634.             }
  2635.             
  2636. // POSSIBLE FIX NEEDED: needs to use activeDocument?
  2637.             case kODCommandNew:            delete (this->New());    break;
  2638.                     
  2639.             case kODCommandOpenDocument:    this->OpenStdFile();    break;
  2640.                 
  2641.             case kODCommandClose:
  2642.                 if (fOptionKeyDownOnMenuBarClick)
  2643.                 {
  2644.                     this->CloseDocument(activeDocument, kAEAsk);
  2645.                 } 
  2646.                 else
  2647.                 {
  2648.                     WindowPtr platformWindow = kODNULL;
  2649.                     {
  2650.                     TempODWindow window = ODAcquireActiveWindow(fEV, fSession);
  2651.                     if (window)
  2652.                         platformWindow = window->GetPlatformWindow(fEV);
  2653.                     }
  2654.                     this->CloseWindow(platformWindow, kAEAsk);
  2655.                 }
  2656.                 break;
  2657.  
  2658.             case kODCommandDeleteDocument:    this->DeleteDocument(activeDocument);    break;
  2659.             
  2660.             case kODCommandSave:            this->Save(activeDocument);                break;
  2661.                 
  2662.             case kODCommandSaveACopy:        this->SaveACopy(activeDraft);            break;
  2663.                 
  2664.             case kODCommandRevert:            this->Revert(activeDocument);            break;
  2665.                 
  2666.             case kODCommandDraft:            this->Drafts(activeDocument);            break;
  2667.                     
  2668.             case kODCommandDocumentInfo:    this->DocumentInfo(activeDocument);        break;
  2669.                     
  2670.             case kODCommandUndo:    fSession->GetUndo(fEV)->Undo(fEV);        break;
  2671.  
  2672.             case kODCommandRedo:    fSession->GetUndo(fEV)->Redo(fEV);        break;
  2673.  
  2674.             // case kODCommandGetPartInfo:        this->PartInfo();        break;
  2675.  
  2676. #if ODDebugMenu
  2677.             case kODCommandDBHeapInfo: {
  2678.                 HeapInfo();
  2679.                 break;
  2680.             }
  2681.             case kODCommandDBDumpObjects:
  2682.                 DumpHeapObjects( /*objectsOnly*/ kODTrue );
  2683.                 break;
  2684.             case kODCommandDBDumpBlocks:
  2685.                 DumpHeapObjects( /*objectsOnly*/ kODFalse );
  2686.                 break;
  2687.             case kODCommandDBMemValidation:
  2688.                 if( gMemValidation ) {
  2689.                     if( gHeapChecking ) {            // When turning off validation,
  2690.                         MMEndHeapChecking();        // turn heap checking off too
  2691.                         gHeapChecking = kODFalse;
  2692.                     }
  2693.                     MMEndMemValidation();
  2694.                     gMemValidation = kODFalse;
  2695.                 } else {
  2696.                     MMBeginMemValidation();
  2697.                     gMemValidation = kODTrue;
  2698.                 }
  2699.                 break;
  2700.             case kODCommandDBHeapChecking:
  2701.                 if( gHeapChecking ) {
  2702.                     MMEndHeapChecking();
  2703.                     gHeapChecking = kODFalse;
  2704.                 } else {
  2705.                     MMBeginMemValidation();            // When turning on heap checking,
  2706.                     gMemValidation = kODTrue;        // turn validation on too
  2707.                     MMBeginHeapChecking();
  2708.                     gHeapChecking = kODTrue;
  2709.                 }
  2710.                 break;
  2711.             case kODCommandDBLeakChecking:
  2712.                 if( gLeakChecking )
  2713.                     MMEndLeakChecking();
  2714.                 else
  2715.                     MMBeginLeakChecking();
  2716.                 gLeakChecking = !gLeakChecking;
  2717.                 gTrackStackCrawls = gLeakChecking;
  2718.                 break;
  2719.             case kODCommandDBDumpBlocksOnClose:
  2720.                 gDumpBlocksOnClose = !gDumpBlocksOnClose;
  2721.                 break;
  2722.             case kODCommandDBTrackStackCrawls:
  2723.                 if( gTrackStackCrawls )
  2724.                     MMTrackStackCrawls( kODFalse );
  2725.                 else
  2726.                     MMTrackStackCrawls( kODTrue );
  2727.                 gTrackStackCrawls = !gTrackStackCrawls;
  2728.                 break;
  2729.             case kODCommandDBEatMemory:
  2730.                 (void) NewHandle(32*1024);            // For testing low-mem survival!
  2731.                 if( MemError() ) {
  2732.                     SysBeep(3);
  2733.                     WARN("Error %d eating memory!;ht",MemError());
  2734.                 }
  2735.                 break;
  2736.             case kODCommandDBPurge:
  2737.                 this->Purge(10*1024*1024);
  2738.                 break;
  2739.             case kODCommandDBLogStdout:
  2740.                 if( GetOutputMode() != kWriteToFile )
  2741.                     SetOutputMode(kWriteToFile);
  2742.                 else
  2743.                     SetOutputMode(kNoOutput);
  2744.                 break;
  2745.             case kODCommandDBLogDebugWindow:
  2746.                 if( GetOutputMode() != kWriteToDebugWindow )
  2747.                     SetOutputMode(kWriteToDebugWindow);
  2748.                 else
  2749.                     SetOutputMode(kNoOutput);
  2750.                 break;
  2751.             case kODCommandDBLogDebugStr:
  2752.                 if( GetOutputMode() != kGenerateDebugStrs )
  2753.                     SetOutputMode(kGenerateDebugStrs);
  2754.                 else
  2755.                     SetOutputMode(kNoOutput);
  2756.                 break;
  2757.             case kODCommandDBBreakOnThrow:
  2758.                 BreakOnThrow( ! BreakOnThrow(kODFalse) );
  2759.                 // This looks weird, but we have to call it once to get the
  2760.                 // old value, then again to set it to the opposite of that.
  2761.                 break;
  2762.             case kODCommandDBSOMTrace:
  2763.                 SOM_TraceLevel = !SOM_TraceLevel;
  2764.                 break;
  2765. #endif
  2766.  
  2767.             default:
  2768.                 // some part enabled a menu command but did not handle it
  2769.                 break;
  2770.         }
  2771.         HiliteMenu(0);
  2772.     } 
  2773. }
  2774.  
  2775. //-------------------------------------------------------------------------------------
  2776. // RealShell::HandleMouseDownInWindow
  2777. //-------------------------------------------------------------------------------------
  2778.  
  2779. void RealShell::HandleMouseDownInWindow(WindowPtr pwindow, ODSShort partCode, ODEventData* event)
  2780. {
  2781.     switch (partCode)
  2782.     {
  2783.     case kODMDInGoAway:    
  2784.         this->HandleMouseDownInCloseBox(pwindow, event);            
  2785.         break;
  2786.  
  2787.     case kODMDInDrag:        
  2788.         this->HandleMouseDownInDragRegion(pwindow, event);            
  2789.         break;
  2790.         
  2791.     case kODMDInGrow:        
  2792.         this->HandleMouseDownInGrowBox(pwindow, event);            
  2793.         break;
  2794.                         
  2795.     case kODMDInZoomIn:
  2796.     case kODMDInZoomOut:    
  2797.         this->HandleMouseDownInZoomBox(pwindow, partCode,event);    
  2798.         break;
  2799.         
  2800.     case kODMDInContent:
  2801.         {
  2802.         TempODWindow window = fWindowState->AcquireODWindow(fEV,pwindow);
  2803.         if (window != kODNULL)
  2804.             window->Select(fEV);
  2805.         else
  2806.             SelectWindow(pwindow);
  2807.         break; 
  2808.         }                
  2809.     default:                
  2810.         break;
  2811.     }
  2812. }
  2813.  
  2814. //-------------------------------------------------------------------------------------
  2815. // RealShell::HandleMouseDownInCloseBox
  2816. //-------------------------------------------------------------------------------------
  2817.  
  2818. void RealShell::HandleMouseDownInCloseBox(WindowPtr pwindow, ODEventData* event)
  2819. {
  2820.     if (TrackGoAway (pwindow, event->where))
  2821.     {
  2822.         if (isOptionKeyDown())
  2823.         {    
  2824.             ODDocument* document = kODNULL;
  2825.             {
  2826.             TempODWindow     window = fWindowState->AcquireODWindow(fEV, pwindow);
  2827.             WASSERT(window != kODNULL);
  2828.             document = ODGetDraftOfWindow(fEV, window)->GetDocument(fEV);
  2829.             }
  2830.             this->CloseDocument(document, kAEAsk);
  2831.         }
  2832.         else
  2833.             this->CloseWindow(pwindow, kAEAsk);
  2834.     }
  2835. }
  2836.  
  2837. //-------------------------------------------------------------------------------------
  2838. // RealShell::HandleMouseDownInDragRegion
  2839. //-------------------------------------------------------------------------------------
  2840.  
  2841. void RealShell::HandleMouseDownInDragRegion(WindowPtr platformWindow, ODEventData* event)
  2842. {
  2843.     TempODWindow     window = fWindowState->AcquireODWindow(fEV,platformWindow);
  2844.     if (window != kODNULL) 
  2845.     {
  2846.         window->Drag(fEV, &event->where, (Rect*)&ODQDGlobals.screenBits.bounds);
  2847.     }
  2848.     else 
  2849.     {
  2850.         WARN("Dragging non-ODWindow.");
  2851.         DragWindow(platformWindow, event->where, &(ODQDGlobals.screenBits.bounds));
  2852.     }
  2853. }
  2854.  
  2855. //-------------------------------------------------------------------------------------
  2856. // RealShell::HandleMouseDownInGrowBox
  2857. //-------------------------------------------------------------------------------------
  2858.  
  2859. void RealShell::HandleMouseDownInGrowBox(WindowPtr pwindow, ODEventData* event)
  2860. {
  2861.     if (!fWindowState->IsODWindow(fEV,pwindow))
  2862.         return;
  2863.     
  2864.     TempODWindow window = fWindowState->AcquireODWindow(fEV,pwindow);
  2865.  
  2866.     if (window == kODNULL)
  2867.         return;
  2868.         
  2869.     if (window->IsResizable(fEV))
  2870.     {
  2871.         Rect growLimits; //  = ODQDGlobals.screenBits.bounds);
  2872.         
  2873.         ODRgnHandle contRgn = 
  2874.             ((WindowRecord*)(window->GetPlatformWindow(fEV)))->contRgn;
  2875.         Rect currentBounds = (**contRgn).rgnBBox;
  2876.  
  2877.         window->GetWindowBounds(fEV, ¤tBounds);
  2878.         
  2879.         growLimits.left = currentBounds.right-currentBounds.left;
  2880.         if (growLimits.left > kMinWindowWidth)
  2881.             growLimits.left = kMinWindowWidth;
  2882.         growLimits.top = currentBounds.bottom-currentBounds.top;
  2883.         if (growLimits.top > kMinWindowHeight)
  2884.             growLimits.top = kMinWindowHeight;
  2885.             
  2886.         growLimits.right = kMaxWindowWidth;
  2887.         growLimits.bottom = kMaxWindowHeight;
  2888.         
  2889.         ODSLong newWindowSize = GrowWindow(pwindow, event->where, &growLimits);
  2890.         SizeWindow(pwindow, LoWord(newWindowSize), HiWord(newWindowSize), true);
  2891.     
  2892.         window->AdjustWindowShape(fEV);
  2893.     
  2894.         Rect r = pwindow->portRect;
  2895.         r.left = r.right  - 15;
  2896.         r.top  = r.bottom - 15;
  2897.         RgnHandle    oldClip = nil;
  2898.         GetClip(oldClip = ODNewRgn());
  2899.         ClipRect(&r);
  2900.         DrawGrowIcon(pwindow);
  2901.         SetClip(oldClip);
  2902.         ODDisposeHandle((Handle)oldClip);
  2903.     }
  2904. }
  2905.  
  2906. //-------------------------------------------------------------------------------------
  2907. // RealShell::HandleMouseDownInZoomBox
  2908. //-------------------------------------------------------------------------------------
  2909.  
  2910. void RealShell::HandleMouseDownInZoomBox(WindowPtr pwindow, ODSShort partcode, ODEventData* event)
  2911. {
  2912.     if (TrackBox(pwindow, event->where, partcode))
  2913.     {
  2914.         TempODWindow  window = kODNULL;
  2915.         
  2916.         if (fWindowState->IsODWindow(fEV,pwindow))
  2917.             window = fWindowState->AcquireODWindow(fEV,pwindow);
  2918.         
  2919.         GrafPtr port;
  2920.         GetPort(&port);
  2921.         SetPort(pwindow);
  2922.         
  2923.         ZoomWindow(pwindow, partcode, kODFalse);
  2924.         
  2925.         SetPort(port);
  2926.         
  2927.         if (window)
  2928.             window->AdjustWindowShape(fEV);
  2929.     }
  2930. }
  2931.  
  2932. //-------------------------------------------------------------------------------------
  2933. // RealShell::UpdateMenus
  2934. //-------------------------------------------------------------------------------------
  2935.  
  2936. void RealShell::UpdateMenus()
  2937. {
  2938.     ODIText*        menuItem;
  2939.     TempODMenuBar    menuBar = fWindowState->AcquireCurrentMenuBar(fEV);
  2940.     MenuHandle        appleMenu = menuBar->GetMenu(fEV, kODAppleMenuID);
  2941.     MenuHandle        editMenu = menuBar->GetMenu(fEV, kODEditMenuID);
  2942.     ODDocument*        activeDocument = ODGetActiveDocument(fEV, fSession);
  2943.  
  2944.     fOptionKeyDownOnMenuBarClick = isOptionKeyDown();
  2945.     
  2946. // Menu items which require resources:
  2947.     { CUsingLibraryResources r;
  2948.     
  2949.     // About Menu item
  2950.         this->RestoreMenuItem(appleMenu, kSHLMenuAbout, &fDefaultAboutMenuItem);
  2951.  
  2952.     //== Document-wide menu items
  2953.         Str255 targetName;
  2954.         if (activeDocument)
  2955.         {
  2956.             TempPlatformFile    file = 
  2957.                 GetPlatformFileFromContainer(fEV, activeDocument->GetContainer(fEV));                            
  2958.     
  2959.             file->GetAsciiName( (char*)targetName, sizeof(targetName) );
  2960.             CToPascalString((char*)targetName);
  2961.         }
  2962.         else
  2963.         {
  2964.             targetName[0] = 0;
  2965.         }
  2966.         Str255 destString;
  2967.         
  2968.     // Delete Menu item
  2969.         ReplaceIntoString( kSHLDeleteItemTemplateStrID, targetName, kODNULL,
  2970.                 destString );
  2971.         menuItem = CreateDefaultIText(destString);
  2972.         menuBar->SetItemString(fEV, kODCommandDeleteDocument, menuItem);
  2973.         DisposeIText(menuItem);
  2974.  
  2975.     // Save Menu item
  2976.         ReplaceIntoString( kSHLSaveItemTemplateStrID, targetName, kODNULL,
  2977.                 destString );
  2978.         menuItem = CreateDefaultIText(destString);
  2979.         menuBar->SetItemString(fEV, kODCommandSave, menuItem);
  2980.         DisposeIText(menuItem);
  2981.  
  2982.     // Close Menu item
  2983.         if ( !isOptionKeyDown() )        // close the whole document
  2984.         {
  2985.             TempODWindow window = ODAcquireActiveWindow(fEV, fSession);
  2986.             ODPlatformWindow pwin = window ?
  2987.                     window->GetPlatformWindow(fEV) : kODNULL;
  2988.             if ( pwin )
  2989.                 GetWTitle( pwin, targetName );
  2990.             else
  2991.                 targetName[0] = '\0';
  2992.         }
  2993.  
  2994.         ReplaceIntoString( kSHLCloseItemTemplateStrID, targetName, kODNULL,
  2995.                 destString );
  2996.         menuItem = CreateDefaultIText(destString);
  2997.         menuBar->SetItemString(fEV, kODCommandClose, menuItem);
  2998.         DisposeIText(menuItem);
  2999.  
  3000.     // Part Info menu item
  3001.         menuItem = GetODITextInd(kSHLStrsID, kSHLStrIndMPartInfo);
  3002.         menuBar->SetItemString(fEV, kODCommandGetPartInfo, menuItem);
  3003.         DisposeIText(menuItem);
  3004.         }
  3005.     menuBar->EnableCommand(fEV, kODCommandAbout, kODTrue);
  3006.     menuBar->EnableCommand(fEV, kODCommandClose, kODTrue);
  3007.     menuBar->EnableCommand(fEV, kODCommandGetPartInfo, kODFalse);
  3008.     
  3009. // Document Menu
  3010.  
  3011.     menuBar->EnableCommand(fEV, kODCommandNew, kODTrue);
  3012.     menuBar->EnableCommand(fEV, kODCommandOpen, kODFalse);
  3013.     menuBar->EnableCommand(fEV, kODCommandOpenDocument, kODTrue);
  3014.     menuBar->EnableCommand(fEV, kODCommandInsert, kODFalse);            
  3015.     menuBar->EnableCommand(fEV, kODCommandDeleteDocument, 
  3016.             ODDocumentHasWriteAccess(fEV, fSession, activeDocument));            
  3017.  
  3018.     ODBoolean unsavedChanges = ODDocumentHasChanges(fEV, fSession, activeDocument);
  3019.     menuBar->EnableCommand(fEV, kODCommandSave, unsavedChanges);
  3020.     menuBar->EnableCommand(fEV, kODCommandSaveACopy, kODTrue);
  3021.     menuBar->EnableCommand(fEV, kODCommandRevert, unsavedChanges);
  3022.  
  3023.     menuBar->EnableCommand(fEV, kODCommandDraft,  kODTrue);
  3024.     menuBar->EnableCommand(fEV, kODCommandDocumentInfo, kODTrue);
  3025.     menuBar->EnableCommand(fEV, kODCommandPageSetup, kODFalse);
  3026.     menuBar->EnableCommand(fEV, kODCommandPrint, kODFalse);
  3027.  
  3028. // Edit Menu
  3029.  
  3030.     this->UpdateUndoMenus();
  3031.  
  3032.     menuBar->EnableCommand(fEV, kODCommandCut, kODFalse);
  3033.     menuBar->EnableCommand(fEV, kODCommandCopy, kODFalse);
  3034.     menuBar->EnableCommand(fEV, kODCommandPaste, kODFalse);
  3035.     menuBar->EnableCommand(fEV, kODCommandPasteAs, kODFalse);
  3036.     menuBar->EnableCommand(fEV, kODCommandClear, kODFalse);
  3037.     menuBar->EnableCommand(fEV, kODCommandSelectAll, kODFalse);
  3038.  
  3039.     menuBar->EnableCommand(fEV, kODCommandPreferences , kODFalse);
  3040.     menuBar->EnableCommand(fEV, kODCommandViewAsWin, kODFalse);
  3041.  
  3042.     if ( editMenu )
  3043.         this->RestoreMenuItem(editMenu, kSHLMenuPreferences, &fDefaultPrefsMenuItem);
  3044.  
  3045. #if ODDebugMenu
  3046.     DebugOutputMode outMode = GetOutputMode();
  3047.     ODBoolean breakingOnThrow = BreakOnThrow(kODFalse);
  3048.     BreakOnThrow(breakingOnThrow);    // Have to reset original value...
  3049.     menuBar->EnableCommand(fEV, kODCommandDBDumpObjects,    outMode!=kNoOutput);
  3050.     menuBar->EnableCommand(fEV, kODCommandDBDumpBlocks,    gTrackStackCrawls>0 && outMode!=kNoOutput);
  3051.     menuBar->CheckCommand(fEV, kODCommandDBMemValidation,    gMemValidation>0);
  3052.     menuBar->CheckCommand(fEV, kODCommandDBHeapChecking,    gHeapChecking>0);
  3053.     menuBar->EnableCommand(fEV, kODCommandDBLeakChecking,    outMode!=kNoOutput);
  3054.     menuBar->CheckCommand(fEV, kODCommandDBLeakChecking,    gLeakChecking>0);
  3055.     menuBar->EnableCommand(fEV, kODCommandDBDumpBlocksOnClose,    outMode!=kNoOutput);
  3056.     menuBar->CheckCommand(fEV, kODCommandDBDumpBlocksOnClose,    gDumpBlocksOnClose>0);
  3057.     menuBar->EnableCommand(fEV, kODCommandDBTrackStackCrawls,    kODTrue);
  3058.     menuBar->CheckCommand(fEV, kODCommandDBTrackStackCrawls,    gTrackStackCrawls>0);
  3059.     menuBar->CheckCommand(fEV, kODCommandDBLogStdout,        outMode==kWriteToFile);
  3060.     menuBar->CheckCommand(fEV, kODCommandDBLogDebugWindow,    outMode==kWriteToDebugWindow);
  3061.     menuBar->CheckCommand(fEV, kODCommandDBLogDebugStr,    outMode==kGenerateDebugStrs);
  3062.     menuBar->CheckCommand(fEV, kODCommandDBBreakOnThrow,    breakingOnThrow);
  3063.     menuBar->CheckCommand(fEV, kODCommandDBSOMTrace,        SOM_TraceLevel!=0);
  3064. #endif
  3065.  
  3066.     // Let the parts have the last crack at the menus.
  3067.     fWindowState->AdjustPartMenus(fEV);
  3068. }
  3069.  
  3070. //------------------------------------------------------------------------------
  3071. // RealShell::CheckMenuBar
  3072. //------------------------------------------------------------------------------
  3073.  
  3074. void RealShell::CheckMenuBar()
  3075. {
  3076.     ODBoolean shellHadMenuFocus = fShellHasMenuFocus;
  3077.     ODTypeToken menuFocus = fSession->Tokenize(fEV, kODMenuFocus);
  3078.     TempODFrame focusFrame = fSession->GetArbitrator(fEV)->AcquireFocusOwner(fEV, menuFocus);
  3079.     fShellHasMenuFocus = (focusFrame == kODNULL);
  3080.  
  3081.     if (fShellHasMenuFocus && !shellHadMenuFocus)
  3082.     {
  3083.         TempODMenuBar baseMenuBar = fWindowState->AcquireBaseMenuBar(fEV);
  3084.         if (baseMenuBar)
  3085.             baseMenuBar->Display(fEV);
  3086.     }
  3087. }
  3088.     
  3089. //------------------------------------------------------------------------------
  3090. // RealShell::UpdateUndoMenus
  3091. //------------------------------------------------------------------------------
  3092.  
  3093. void RealShell::UpdateUndoMenus()
  3094. {
  3095.     ODUndo*            undo = fSession->GetUndo(fEV);
  3096.     ODPart*            part;
  3097.     ODActionData    actionData;
  3098.     ODActionType    actionType;
  3099.     ODName            actionLabel;
  3100.  
  3101.     ODVolatile(actionLabel);
  3102.     ODVolatile(actionData);
  3103.  
  3104.     actionLabel.text._buffer = kODNULL;
  3105.     actionData._buffer = kODNULL;
  3106.  
  3107.     TRY
  3108.         TempODMenuBar    menuBar = fWindowState->AcquireCurrentMenuBar(fEV);
  3109.         MenuHandle        editMenu = menuBar->GetMenu(fEV, kODEditMenuID);
  3110.  
  3111.         // these IsCommandRegistered calls are to prevent ResetUndoText from
  3112.         // being called with a null menu, which is what you get at least
  3113.         // in the EditorSetup case.  Other cases might not be detected
  3114.  
  3115.         if (undo->PeekUndoHistory(fEV, &part, &actionData, &actionType,
  3116.                                     &actionLabel))
  3117.         {
  3118.             menuBar->EnableCommand(fEV, kODCommandUndo, kODTrue);
  3119.             menuBar->SetItemString(fEV, kODCommandUndo, &actionLabel);
  3120.         }
  3121.         else
  3122.         {
  3123.             menuBar->EnableCommand(fEV, kODCommandUndo, kODFalse);
  3124.             this->ResetUndoText(editMenu);
  3125.         }
  3126.     
  3127.         DisposeITextStruct(actionLabel);
  3128.         DisposeByteArrayStruct(actionData);
  3129.         actionLabel.text._buffer = kODNULL;
  3130.         actionData._buffer = kODNULL;
  3131.  
  3132.         if (undo->PeekRedoHistory(fEV, &part, &actionData, &actionType,
  3133.                                     &actionLabel))
  3134.         {
  3135.             menuBar->EnableCommand(fEV, kODCommandRedo, kODTrue);
  3136.             menuBar->SetItemString(fEV, kODCommandRedo, &actionLabel);
  3137.         }
  3138.         else
  3139.         {
  3140.             menuBar->EnableCommand(fEV, kODCommandRedo, kODFalse);
  3141.             this->ResetRedoText(editMenu);
  3142.         }
  3143.     CATCH_ALL
  3144.         if (actionLabel.text._buffer)
  3145.             DisposeITextStruct(actionLabel);
  3146.         if (actionData._buffer)
  3147.             DisposeByteArrayStruct(actionData);
  3148.         RERAISE;
  3149.     ENDTRY
  3150.  
  3151.     DisposeITextStruct(actionLabel);
  3152.     DisposeByteArrayStruct(actionData);
  3153. }
  3154.  
  3155.  
  3156. //-------------------------------------------------------------------------------------
  3157. // RealShell::ResetUndoText
  3158. //-------------------------------------------------------------------------------------
  3159.  
  3160. void RealShell::ResetUndoText(MenuHandle editMenu)
  3161. {
  3162.     if ( editMenu )
  3163.         this->RestoreMenuItem(editMenu, kSHLMenuUndo, &fDefaultUndoMenuItem);
  3164. }
  3165.  
  3166. //-------------------------------------------------------------------------------------
  3167. // RealShell::ResetRedoText
  3168. //-------------------------------------------------------------------------------------
  3169.  
  3170. void RealShell::ResetRedoText(MenuHandle editMenu)
  3171. {
  3172.     if ( editMenu )
  3173.         this->RestoreMenuItem(editMenu, kSHLMenuRedo, &fDefaultRedoMenuItem);
  3174. }
  3175.  
  3176. //-------------------------------------------------------------------------------------
  3177. // New
  3178. //-------------------------------------------------------------------------------------
  3179.  
  3180. PlatformFile*    RealShell::New()
  3181. {
  3182.     // create another container, create a root part of the same kind and editor
  3183.     // as the root part of the active window
  3184.  
  3185.     TempODType         rootPartType    = kODNULL;
  3186.     TempODEditor    editor            = kODNULL;
  3187.     TempODName        category        = kODNULL;
  3188.     ODStorageUnit*    psu                = kODNULL;
  3189.     PlatformFile*     newFile            = new PlatformFile();
  3190.  
  3191.     TempODWindow    window = ODAcquireActiveWindow(fEV, fSession);
  3192.     if (window)
  3193.     {
  3194.         TempODPart part = window->GetRootFrame(fEV)->AcquirePart(fEV);
  3195.         ASSERT((ODPart*)part != kODNULL, kODErrNoDraftProperties);  
  3196.             // !!!!! Should probably have its own errorcode, even though the user
  3197.             // error message will be the same.
  3198.         category = ODGetCategory(fEV, part, fSession->GetNameSpaceManager(fEV));    
  3199.         psu = part->GetStorageUnit(fEV);
  3200.     }
  3201.     
  3202.     if (psu &&
  3203.         psu->Exists(fEV, kODPropContents, (ODValueType)kODNULL, (ODValueIndex)kODNULL)) 
  3204.     {
  3205.         psu->Focus(fEV, kODPropContents, kODPosSame, (ODValueType)kODNULL,1, kODPosFirstSib);
  3206.         rootPartType = psu->GetType(fEV);
  3207.         editor = (ODEditor)ODGetISOStrProp(fEV, psu, kODPropPreferredEditor, kODEditor, kODNULL, kODNULL);
  3208.  
  3209.         TempPlatformFile    file = GetPlatformFileFromContainer(fEV,
  3210.                                     psu->GetDraft(fEV)->GetDocument(fEV)->GetContainer(fEV));
  3211.         newFile->SpecifyFromFile(file);
  3212.     }
  3213.  
  3214.     {
  3215.     ODContainer*    container;
  3216.     CreateUntitledContainer(kODNULL, &container, newFile, category);
  3217.     TempODContainer newContainer = container;
  3218.     ODNewDocument(fEV, newContainer, rootPartType, editor);    
  3219.     }
  3220.     
  3221.     this->OpenAnotherFile(newFile, kODNULL, kODTrue, kODTrue);        // Both are true because this is a new unsaved doc
  3222.     return newFile;
  3223. }
  3224.  
  3225. //-------------------------------------------------------------------------------------
  3226. // New File(Name/Spec)
  3227. //-------------------------------------------------------------------------------------
  3228.  
  3229. ODStatic void    CreateNewUntitledFile(PlatformFile* newFile, 
  3230.                         char* fileNameSeed)
  3231. {
  3232.     Str255        fileName; // !!!! MUST BE AN ARRAY IN ORDER TO WORK (sizeof used below)
  3233.         
  3234.     if (newFile->IsStationery())
  3235.     {
  3236.         newFile->GetAsciiName((char*)fileName, sizeof(fileName)-1);
  3237.     }
  3238.     else if (fileNameSeed != kODNULL)
  3239.     {
  3240.         strncpy((char*)fileName, fileNameSeed, sizeof(fileName)-1);
  3241.     }
  3242.     else
  3243.     {
  3244.         strcpy((char*)fileName, "");
  3245.     }
  3246.     
  3247.     CToPascalString((char*)fileName);
  3248.     if ( fileName[0] > kODMaxFileNameSize )
  3249.         (void)ClipStringToBytes( fileName, kODMaxFileNameSize, smSystemScript );
  3250.     PascalToCString(fileName);
  3251.     
  3252.     newFile->SetAsciiName((char*)fileName);
  3253.     
  3254.     CreateNewFile(newFile, kODForceNewName);
  3255. }
  3256.  
  3257. void    CreateNewFile(PlatformFile* newFile, ODBoolean forceNewName)
  3258. {
  3259.     ODSLong        seed = 0;
  3260.     ODULong        err = noErr;
  3261.  
  3262.     ODSByte         prefixName[kODMaxFileNameSize+1];
  3263.     newFile->GetAsciiName(prefixName, kODMaxFileNameSize);
  3264.     prefixName[kODMaxFileNameSize] = 0;
  3265.     ODUShort    prefixLen = strlen(prefixName);
  3266.  
  3267.     ODSByte         newName[kODMaxFileNameSize+1];
  3268.     strcpy(newName,prefixName);
  3269.     
  3270.     ODFileSpec fs = newFile->GetFileSpec();
  3271.  
  3272.     while (GetVolumeWritableSpace(&fs, kODNULL) < kSpaceNeededForNewDocument)
  3273.     {
  3274.         
  3275.         THROW_IF_ERROR(FindFolder(kOnSystemDisk, kDesktopFolderType, kCreateFolder,
  3276.                                 &(fs.vRefNum), &(fs.parID)));
  3277.         
  3278.         if (GetVolumeWritableSpace(&fs, &err) >= kSpaceNeededForNewDocument)
  3279.               break;
  3280.  
  3281.         THROW_IF_ERROR(err);
  3282.         THROW(kODErrSystemVolumeIsFull);
  3283.  
  3284.     // It would be nice to try other volumes as well, like:
  3285.     //   iterate through local non-removable volumes
  3286.     //     if enough space on one of those, then use it & break; break;
  3287.     //   iterate through local removable volumes
  3288.     //     if enough space on one of those, then use it & break; break;
  3289.     //   iterate through remote volumes
  3290.     //     if enough space on one of those, then use it & break; break;
  3291.     
  3292.     //  THROW(kODErrAllWritableVolumesAreFull);
  3293.  
  3294.     }
  3295.     newFile->Specify(&fs);
  3296.     newFile->UniquifyName( kODNoResourceID /*kConcatDefaultNameNoNumStrID*/, kODNULL,
  3297.             kSHLNewFilenameTemplateStrID, kODNULL, 1, kSpecifyNewNameOnly, forceNewName );
  3298.     
  3299. }    // CreateNewFile
  3300.  
  3301. void    RealShell::CreateUntitledContainer(ODDocument** documentPtr,
  3302.             ODContainer** containerPtr, PlatformFile* newFile, ODName* fileNameSeed)
  3303. {
  3304.     char* cfnSeed = kODNULL;
  3305.     if (fileNameSeed != kODNULL)
  3306.         cfnSeed = GetITextCString(fileNameSeed, kODNULL);
  3307.         
  3308.     CreateNewUntitledFile(newFile, cfnSeed);
  3309.  
  3310.     ODDeleteObject(cfnSeed);
  3311.     
  3312.     newFile->Create(kODShellSignature, kODShellSignature, 0);
  3313.  
  3314.     ODULong refNumCount;
  3315.     ODSShort* refNums;
  3316.     if (documentPtr)
  3317.     {
  3318.         GetLocalPaths(&(newFile->GetFileSpec()), kDataFork,
  3319.                           &refNumCount, &refNums);
  3320.     }
  3321.  
  3322.     (*containerPtr) = CreateFileContainer(fEV, fSession, &(newFile->GetFileSpec()));
  3323.  
  3324.     if (documentPtr)
  3325.     {
  3326.         *documentPtr = (*containerPtr)->AcquireDocument(fEV, kODDefaultDocument);    // -- TÇ: documentPtr acquires a document
  3327.     }
  3328. }
  3329.  
  3330. void    RealShell::CreateTitledContainer(ODDocument** documentPtr,
  3331.             ODContainer** containerPtr, PlatformFile* newFile, char* newName)
  3332. {
  3333.     newFile->SetAsciiName(newName);
  3334.     
  3335.     CreateNewFile(newFile, kODTryCurrentName);
  3336.     
  3337.     newFile->Create(kODShellSignature, kODShellSignature, 0);
  3338.  
  3339.     ODULong refNumCount;
  3340.     ODSShort* refNums;
  3341.     if (documentPtr)
  3342.     {
  3343.         GetLocalPaths(&(newFile->GetFileSpec()), kDataFork,
  3344.                           &refNumCount, &refNums);
  3345.     }
  3346.     
  3347.     (*containerPtr) = CreateFileContainer(fEV, fSession, &(newFile->GetFileSpec()));
  3348.         
  3349.     if (documentPtr)
  3350.     {
  3351.         *documentPtr = (*containerPtr)->AcquireDocument(fEV, kODDefaultDocument);    // -- TÇ: documentPtr acquires a document
  3352.     }
  3353. }
  3354.  
  3355. //------------------------------------------------------------------------------
  3356. // Temporary File(Name/Spec)
  3357. //------------------------------------------------------------------------------
  3358.  
  3359. void    CreateTempName(short seed, Str255 name, ODBoolean isFile)
  3360. {
  3361.     // Don't modify this one!
  3362.     char* nmSeed = isFile? "ODShellTempFile" : "ODShellTempFolder";
  3363.     strcpy((char*)name, nmSeed);
  3364.  
  3365.     char theNum[10];
  3366.     NumToString(seed, (StringPtr)theNum); 
  3367.     WASSERT(theNum[0] <= 5);
  3368.     p2cstr((StringPtr)theNum);
  3369.  
  3370.     strcat((char*)name, theNum);
  3371.     c2pstr((char *)name);
  3372. }
  3373.  
  3374.  
  3375. void RealShell::CreateUniqueTmpFolderForFile(ODFileSpec* result,
  3376.         Str63 fileName)
  3377. {
  3378.     Str255        myName;
  3379.     ODSLong    myDirID;
  3380.     ODSShort    myVRef;
  3381.     GetTempFolder(&myVRef, &myDirID);
  3382.  
  3383.     OSErr err;
  3384.     short limit = kMaxUniqueNameTries;
  3385.     while ( --limit )
  3386.     {
  3387.         CreateTempName( fUniqueNameSeed++, myName, kODFalse );
  3388.         long createdDirID;
  3389.         err = DirCreate( myVRef, myDirID, myName,
  3390.                 &createdDirID );
  3391.         if ( err == noErr )
  3392.         {
  3393.             FSMakeFSSpec(myVRef, createdDirID, fileName, result);
  3394.             return;
  3395.         }
  3396.     }
  3397.     THROW( err );
  3398. }
  3399.  
  3400. void    GetTempFolder(ODSShort* VRef,ODSLong* DirID)
  3401. {
  3402.     FindFolder(0, kTemporaryFolderType, kCreateFolder,VRef,DirID);
  3403. }
  3404.  
  3405. //-------------------------------------------------------------------------------------
  3406. // CopyResources -- copy the document resources from one file to another
  3407. //-------------------------------------------------------------------------------------
  3408.  
  3409. ODStatic void    CopyResources(PlatformFile* srcFile, PlatformFile* dstFile)
  3410. {
  3411.     CUsingLibraryResources r;
  3412.     VerifyDocumentStub(&(dstFile->GetFileSpec()), kODNULL);
  3413.     // Makes sure to copy resources into the new document.
  3414.     
  3415.     ODULong sizeOfResource;
  3416.     for(ODUShort i=0; i<= 1; i++) {
  3417.         ODPtr sizeRes = srcFile->ReadResourcePtr(kSIZERsrcType, i, &sizeOfResource);
  3418.         if (sizeRes != kODNULL) {
  3419.             dstFile->WriteResourcePtr(kSIZERsrcType, i, sizeRes, sizeOfResource);
  3420.             ODDisposePtr(sizeRes);
  3421.         }
  3422.     }    
  3423. }
  3424.  
  3425. //-------------------------------------------------------------------------------------
  3426. // Open
  3427. //-------------------------------------------------------------------------------------
  3428.  
  3429. void    RealShell::OpenFile(PlatformFile* file)
  3430. {
  3431. // if the file is a stationery seed, 
  3432. //    produce mature stationery in the Stationery folder and quit
  3433. // else create a new container if the given file is stationery
  3434. // else open the container and document and current draft and install ShellPlugIns
  3435. // note: file is not consumed and is presumed to be disposed of by the caller
  3436.     
  3437.     WatchCursor();
  3438.     ODPlatformType fileType = file->GetPlatformType();
  3439.  
  3440.     ODFileSpec fs = file->GetFileSpec();
  3441.     
  3442.     // ASSERT(the document is at the end of the resource chain)
  3443.  
  3444.     ODSShort numSeeds = Count1Resources(kDocSeedResType);
  3445.     if (numSeeds > 0)
  3446.     {
  3447.         FindStationeryFolder(&(fs.vRefNum), &(fs.parID));
  3448.         file->Specify(&fs);
  3449.         
  3450.         for (;numSeeds;--numSeeds)
  3451.         {
  3452.             Handle            seedEditor;
  3453.             ODContainer*    container;
  3454.             short            unusedID; 
  3455.             ResType            unusedType;
  3456.             Str255            editorName;
  3457.             
  3458.             seedEditor = Get1IndResource(kDocSeedResType, numSeeds);
  3459.             TempODType editor = (ODType)ODNewPtr(GetHandleSize(seedEditor),0);//•minor leak [FIXED]
  3460.             HLock(seedEditor);        //• unnecessary; CFM libs have no segments
  3461.             strcpy((char*)editor, (char*)*seedEditor);
  3462.             HUnlock(seedEditor);
  3463.             GetResInfo(seedEditor, &unusedID, &unusedType, editorName);
  3464.             if (editorName[0] > 31)
  3465.                 ClipStringToBytes( editorName, 31, smCurrentScript );
  3466.             PascalToCString(editorName);
  3467.             CreateTitledContainer(kODNULL, &container, file, (char*)editorName);//•minor leak on exception [FIXED]
  3468.             TempODContainer tempContainer = container; // ensures it's released
  3469.             
  3470.             ODNewDocument(fEV, container, kODNULL, editor);    
  3471.             file->SetStationery(kODTrue);
  3472.                         
  3473.             RemoveResource(seedEditor);
  3474.         }
  3475.  
  3476.         UpdateResFile(CurResFile());        
  3477.         fDispatcher->Exit(fEV);
  3478.     }
  3479.     else
  3480.     {
  3481.         PlatformFile*    newFile = kODNULL;
  3482.         ODVolatile(newFile);
  3483.         if (file->GetPlatformCreator() == kODShellSignature)
  3484.         {                              
  3485.             if (file->IsStationery()) 
  3486.             {
  3487.             TRY
  3488.                 ODContainer*    container = kODNULL;
  3489.                 ODDocument*        document = kODNULL;
  3490.                 ODDraft*        draft = kODNULL;
  3491.                 ODAcquireCtrDocTopDraft(fEV, fSession, file, &container, &document, &draft);
  3492.                 TempODContainer    sContainer = container;
  3493.                 TempODDocument    sDocument = document;
  3494.                 TempODDraft        sDraft = draft;
  3495.     
  3496.                 newFile = new PlatformFile;
  3497.                 newFile->SpecifyFromFile(file);
  3498.                 
  3499.                 container = kODNULL; document = kODNULL;
  3500.                 CreateUntitledContainer(&document, &container, newFile);
  3501.                 TempODContainer    newContainer = container;
  3502.                 TempODDocument    newDocument = document;
  3503.                 
  3504.                 CopyResources(file, newFile);
  3505.                 newDocument->SetBaseDraftFromForeignDraft(fEV, sDraft);    
  3506.                 TempODDraft newDraft = newDocument->AcquireBaseDraft(fEV, kODDPExclusiveWrite);
  3507.                 {
  3508.                 TempODStorageUnit su = newDraft->AcquireDraftProperties(fEV);
  3509.                 ODResetDateModByInfo(fEV, su);
  3510.                 }
  3511.                 {
  3512.                 TempODStorageUnit su = ODAcquireRootPartSUOfDraft(fEV, newDraft);
  3513.                 ODResetDateModByInfo(fEV, su);    
  3514.                 }
  3515.                 ODSetIsUnsavedNewDocument(fEV, newDraft);
  3516.                 newDraft->Externalize(fEV);
  3517.  
  3518.                 newFile->SetPlatformType(file->GetPlatformType());
  3519.                     
  3520.                 { TempODDocumentName name(newFile->GetName());
  3521.                   newDocument->SetName(fEV, name);
  3522.                 }
  3523.                             
  3524.                 file = newFile;
  3525.             CATCH_ALL
  3526.                 if (newFile)
  3527.                 {
  3528.                 TRY
  3529.                     newFile->MoveToTrash();
  3530.                 CATCH_ALL
  3531.                 ENDTRY
  3532.                 }
  3533.                 RERAISE;
  3534.             ENDTRY
  3535.             }
  3536.                         
  3537.         }
  3538.         else
  3539.         {            
  3540.             // translate fileType into an OpenDoc kind
  3541.             TempODType theKind = fSession->GetTranslation(fEV)->
  3542.                 GetISOTypeFromPlatformType(fEV, fileType, kODPlatformFileType);
  3543.             
  3544.             // Check to see if fileType is supported by an OpenDoc Editor
  3545.             ODEditor theEditor = fSession->GetBinding(fEV)->ChooseEditorForPart( fEV, kODNULL, theKind );
  3546.             if (!theEditor)
  3547.             {
  3548.                 fDispatcher->Exit(fEV);  
  3549.                 THROW( kODErrCouldNotBindForeignDocument );
  3550.             }
  3551.             
  3552.             // create new File
  3553.             newFile    = new PlatformFile();        //• leak on exception
  3554.             newFile->SpecifyFromFile(file);
  3555.             Str255    fileName;
  3556.             Str255    newName;
  3557.             newFile->GetAsciiName( (char*)fileName, kODMaxFileNameSize );
  3558.             CToPascalString((char*)fileName);
  3559.             { CUsingLibraryResources r;
  3560.                 ReplaceIntoString(kSHLPreODDocNameStrID, fileName,
  3561.                                     kODEmptyPString, newName);
  3562.             }
  3563.             PascalToCString(newName);
  3564.             
  3565.             // Need actual object pointers because of CreateTitledContainer calling conventions
  3566.             ODDocument* document = kODNULL;
  3567.             ODContainer* container = kODNULL;
  3568.             
  3569.             CreateTitledContainer(&document, &container, newFile, (char*)newName);
  3570.             // Now immediately assign to tempobj's to be exception safe.
  3571.             TempODContainer newContainer = container;
  3572.             TempODDocument newDocument = document;
  3573.  
  3574.             HFSFlavor hfsFlavor;
  3575.             hfsFlavor.fileType = fileType;
  3576.             hfsFlavor.fileCreator = file->GetPlatformCreator();
  3577.             hfsFlavor.fdFlags = file->GetFInfoFlags();
  3578.             hfsFlavor.fileSpec = file->GetFileSpec();
  3579.  
  3580.             ((ODUByte*)(&fileType))[0] = kODPlatformKindFileChar1;
  3581.             newFile->SetPlatformType(fileType); 
  3582.             
  3583.             TempODDraft newDraft = newDocument->AcquireBaseDraft(fEV, kODDPExclusiveWrite);
  3584.             TempODStorageUnit su = newDraft->AcquireDraftProperties(fEV);
  3585.             ODResetDateModByInfo(fEV, su);
  3586.  
  3587.             TempODStorageUnit rootPartSU = newDraft->CreateStorageUnit(fEV);
  3588.             ODSetRootPartSUOfDraft(fEV, newDraft, rootPartSU);
  3589.             
  3590.                 // create contents prop/ value for kODApplehfs
  3591.             ODSUAddPropValue(fEV, rootPartSU, kODPropContents, kODApplehfs);
  3592.             StorageUnitSetValue(rootPartSU, fEV, sizeof( hfsFlavor ), &hfsFlavor);
  3593.             rootPartSU->AddValue(fEV, theKind);
  3594.  
  3595.             ODSetISOStrProp(fEV, rootPartSU, kODPropPreferredEditor, kODEditor, theEditor);
  3596.  
  3597.             ODSetIsUnsavedNewDocument(fEV, newDraft);
  3598.             newDraft->Externalize(fEV);
  3599.             file = newFile;
  3600.         }
  3601.         
  3602.         ODDraft* topdraft = kODNULL;
  3603.         ODVolatile(topdraft);
  3604.         
  3605.         TRY
  3606.             // Open the document
  3607.             topdraft = ODOpenFileDocument(fEV, fSession, file, kODDPExclusiveWrite);
  3608.             this->InstallShellPlugIns(topdraft);
  3609.     
  3610.             ODOpenDraft(fEV, fSession, topdraft);
  3611.             ODReleaseObject(fEV, topdraft);
  3612.  
  3613.             fDispatcher = fSession->GetDispatcher(fEV);
  3614.             fWindowState = fSession->GetWindowState(fEV);
  3615.         
  3616.             ODFileSpec fileFSSpec = file->GetFileSpec();
  3617.     
  3618.             LMSetSFSaveDisk(-(fileFSSpec.vRefNum));
  3619.             LMSetCurDirStore(fileFSSpec.parID);
  3620.             ODDeleteObject(newFile);
  3621.         CATCH_ALL
  3622.             this->CheckFreeMemory();
  3623.             if (topdraft)
  3624.             {
  3625.                 ODDocument* document = topdraft->GetDocument(fEV);
  3626.                 ODSafeReleaseObject(topdraft);
  3627.                 if (ODCloseDocument(fEV, fSession, document))
  3628.                     fDispatcher->Exit(fEV);
  3629.             }    
  3630.             this->SetAEError(ErrorCode());
  3631.         ENDTRY
  3632.         ArrowCursor();
  3633.     }
  3634. }    // RealShell::OpenFile
  3635.  
  3636. //------------------------------------------------------------------------------
  3637. // RealShell::OpenAnotherFile
  3638. //------------------------------------------------------------------------------
  3639.  
  3640. void    RealShell::OpenAnotherFile(PlatformFile* file,
  3641.                                     AEDescList* replyInfo, 
  3642.                                     ODBoolean deleteOnFailure,
  3643.                                     ODBoolean unsavedDoc)
  3644. {
  3645.     // launch another document stub to open the passed in PlatformFile
  3646.     OSErr err = noErr;
  3647.     ODFileSpec theDocument = file->GetFileSpec();
  3648.     if (WasLaunchedThenActivate(&theDocument,  kAEOpenDocuments, err))
  3649.         return;
  3650.             
  3651.     ODSLong    savedRefNum;
  3652.     BeginUsingLibraryResources(savedRefNum);
  3653.     AEDesc docDesc;
  3654.     ProcessSerialNumber psn;
  3655.     err = AECreateDesc( typeFSS, &theDocument, sizeof(theDocument),
  3656.             &docDesc );
  3657.     if ( !err )
  3658.     {
  3659.         err = VerifyAndLaunchDocumentStub(&docDesc, replyInfo, &psn,
  3660.                 kAEOpenDocuments, kODNULL, unsavedDoc);
  3661.         AEDisposeDesc( &docDesc );
  3662.     }
  3663.     EndUsingLibraryResources(savedRefNum);
  3664.     if ( err ) {
  3665.         if( deleteOnFailure )
  3666.             file->Delete();
  3667.         THROW( err );
  3668.     } else if( deleteOnFailure ) {
  3669.         // Remember PSN and spec in case launch fails; CFM will send us an error and
  3670.         // we can then delete the new file. See HandleLaunchFailedEvent...
  3671.         fLastNewDocPSN = psn;
  3672.         fLastNewDocSpec= file->GetFileSpec();
  3673.     }
  3674. }
  3675.  
  3676. //------------------------------------------------------------------------------
  3677. // OpenFileFilter
  3678. //
  3679. //    Return true (don't show this item) for invisible files and folders
  3680. //
  3681. //    Addendum: There appears to be no way to filter out invisible folders, since
  3682. //    thie function is only passed files. Oh well. Leaving code in anyway in case
  3683. //    this changes.
  3684. //------------------------------------------------------------------------------
  3685.  
  3686. static pascal Boolean OpenFileFilter(CInfoPBPtr fileInfo)
  3687. {
  3688.     if (fileInfo->hFileInfo.ioFlAttrib & ioDirMask) // FOLDER
  3689.     {
  3690.         if (fileInfo->dirInfo.ioDrUsrWds.frFlags & fInvisible)
  3691.             return true;
  3692.     }
  3693.     else // FILE
  3694.     {
  3695.         if (fileInfo->hFileInfo.ioFlFndrInfo.fdFlags & fInvisible)
  3696.             return true;
  3697.     }
  3698.  
  3699.     return false;
  3700. }
  3701.  
  3702. //------------------------------------------------------------------------------
  3703. // RealShell::OpenStdFile
  3704. //------------------------------------------------------------------------------
  3705.  
  3706. void    RealShell::OpenStdFile()
  3707. {
  3708.     // call display StdFile (with all documents) and open document in a new shell
  3709.     ArrowCursor();
  3710.     StandardFileReply sfReply;
  3711.     SFTypeList sfTypes;
  3712.     
  3713.     fWindowState->DeactivateFrontWindows(fEV);
  3714.  
  3715.     FileFilterUPP openFileFilterUPP = NewFileFilterProc(OpenFileFilter);
  3716.     StandardGetFile((FileFilterUPP)openFileFilterUPP, -1, sfTypes, &sfReply);
  3717.     DisposeRoutineDescriptor(openFileFilterUPP);
  3718.  
  3719.     fWindowState->ActivateFrontWindows(fEV);
  3720.  
  3721.     if (sfReply.sfGood) 
  3722.     {
  3723.         PlatformFile* file = new PlatformFile();
  3724.         file->Specify(&(sfReply.sfFile));
  3725.         if (file->GetPlatformCreator() == kODShellSignature &&
  3726.             file->GetPlatformType() != 'APPL')        // not the launcher
  3727.         {
  3728.             this->OpenAnotherFile(file);
  3729.         }
  3730.         else
  3731.         {
  3732.             THROW_IF_ERROR( SendFinderODOCEvent( &sfReply.sfFile ) );
  3733.  
  3734.             // Fix #1221901:
  3735.             // else (if creator≠ kODShellSignature)
  3736.             // 'appl' = launch application
  3737.             // else 'snd ' = play sound
  3738.             // else 'cdev' = open control panel
  3739.             // else use MEO,desktop database to find appropriate application to use,
  3740.             //    then launch application with document
  3741.         }
  3742.         delete file;
  3743.     }
  3744. }
  3745.  
  3746. //-------------------------------------------------------------------------------------
  3747. // DoesUserCancelClose
  3748. //
  3749. //    To do: Fix flow of control
  3750. //-------------------------------------------------------------------------------------
  3751.  
  3752. ODBoolean    RealShell::DoesUserCancelClose(ODDocument* document, DescType saveOptions)
  3753. {
  3754. // asks user "Save changes before closing? Discard Changes, Cancel , Save"
  3755.     ODBoolean stillSave;
  3756.     switch(saveOptions)
  3757.     {
  3758.         case kAEAsk:
  3759.         {
  3760.             if (AEInteractWithUser(kNoTimeOut, NULL, NULL) != noErr)
  3761.                 return kODTrue;
  3762.             ArrowCursor();
  3763.             char    fileName[256];
  3764.             ODGetDocumentFileName(fEV, document, &(fileName[0]));
  3765.             CToPascalString(fileName);
  3766.  
  3767.  
  3768.             ODSShort btnClicked;
  3769.             if (ODIsTempDocument(fEV, fSession, document))
  3770.             {
  3771.                 if (ODIsUnsavedNewDocument(fEV, fSession, document))
  3772.                     btnClicked = kSHLscNo;
  3773.                 else
  3774.                     btnClicked = kSHLscOK;
  3775.             }
  3776.             else
  3777.             {
  3778.                 ODSLong        savedRefNum;
  3779.                 BeginUsingLibraryResources(savedRefNum);
  3780.                 ParamText((unsigned char const *)fileName, kODEmptyPString, 
  3781.                             kODEmptyPString, kODEmptyPString);
  3782.                 fWindowState->DeactivateFrontWindows(fEV);
  3783.                 TRY
  3784.                 {
  3785.                     DialogPtr askSaveDlg = kODNULL;
  3786.                     askSaveDlg = ODGetNewDialog( fEV, kSHLsvChanges, fSession, kODTrue );
  3787.                     THROW_IF_NULL( askSaveDlg );
  3788.                     ODUseCommandKeyStringsResource( kSHLsvChangesCmdKeyStrs );
  3789.                     ::ShowWindow( askSaveDlg );
  3790. //                    FIX_THIS_PLACE
  3791.                     ::ModalDialog( GetODButtonKeyFilterProc(), &btnClicked );
  3792.                     ::DisposeDialog( askSaveDlg );
  3793.                 }
  3794.                 CATCH_ALL
  3795.                 {
  3796.                     btnClicked = kSHLscCancel;        // Cancel the close
  3797.                 }
  3798.                 ENDTRY
  3799.      
  3800.                 fWindowState->ActivateFrontWindows(fEV);
  3801.     
  3802.                 EndUsingLibraryResources(savedRefNum);
  3803.             }
  3804.             if (btnClicked == kSHLscCancel)
  3805.                 return kODTrue;
  3806.             else if (btnClicked == kSHLscNo &&
  3807.                      ODIsUnsavedNewDocument(fEV, fSession, document))
  3808.             {
  3809.                 TempPlatformFile file = 
  3810.                     GetPlatformFileFromContainer(fEV, document->GetContainer(fEV));
  3811.                 file->MoveToTrash();
  3812.             }
  3813.                 
  3814.             stillSave = (btnClicked == kSHLscOK);
  3815.         }
  3816.             break;
  3817.         case kAEYes:
  3818.             stillSave = kODTrue;
  3819.             break;
  3820.         case kAENo:
  3821.             stillSave = kODFalse;
  3822.             break;
  3823.         default:
  3824.             THROW(errAETypeError);
  3825.     }
  3826.  
  3827.     if (stillSave) 
  3828.     {
  3829.         if (this->Save(document, kODTrue))
  3830.             ;
  3831.         else // The user canceled the Save As dialog, which cancels the close
  3832.             return kODTrue;
  3833.     }
  3834.     return kODFalse;
  3835. }
  3836.  
  3837.  
  3838. void    RealShell::CloseWindow(ODPlatformWindow pwindow, DescType saveOptions)
  3839. {
  3840.     if (pwindow==kODNULL)
  3841.     {
  3842.         fDispatcher->Exit(fEV);
  3843.         return;
  3844.     }
  3845.     
  3846.     if (!fWindowState->IsODWindow(fEV,pwindow))
  3847.     {
  3848.         ASSERT(fWindowState->IsODWindow(fEV,pwindow), kODErrClosingNonODWindow);
  3849.         return;
  3850.     }
  3851.     
  3852.     ODWindow*  window = fWindowState->AcquireODWindow(fEV,pwindow);
  3853.     if (!window)
  3854.         return;    
  3855.  
  3856.     ODDraft* draft = window->GetDraft(fEV);
  3857.     ODDocument* document = draft->GetDocument(fEV);
  3858.     ODBoolean isOnlyTopDraftWindow =
  3859.         window->IsRootWindow(fEV) && (fWindowState->GetRootWindowCount(fEV,draft) == 1) && 
  3860.         (!(document->Exists(fEV, kODNULLID, draft, kODPosFirstAbove)));
  3861.  
  3862.     if (isOnlyTopDraftWindow &&
  3863.         ODDraftHasWriteAccess(fEV, draft) &&
  3864.         (draft->ChangedFromPrev(fEV) || ODIsUnsavedNewDocument(fEV, fSession, document)))
  3865.     {
  3866.         if (saveOptions == kAEYes)
  3867.         {
  3868.             ODSaveDocument(fEV, fSession, document);
  3869.         }
  3870.         else 
  3871.         {
  3872.             ODReleaseObject(fEV, window);    // balances AcquireODWindow above
  3873.  
  3874.             if (this->DoesUserCancelClose(document, saveOptions))
  3875.                 return;
  3876.                 
  3877.             window = fWindowState->AcquireODWindow(fEV,pwindow); // reacquire because user did not cancel close
  3878.             // NOTE: If the user SAVED the document inside the DoesUserCancelClose 
  3879.             // call above for the first time, (thereby using StdFile), and to a 
  3880.             // different volume, then DoesUserCancelClose did NOT reopen the document,
  3881.             // and pwindow is no longer a valid WindowPtr.  Therefore, the windowstate 
  3882.             // does not find it, and return kODNULL which causes the same code 
  3883.             // execution as if the return statement above was executed.
  3884.         }
  3885.     }
  3886.     
  3887.     if (window)
  3888.         if (ODReleaseCloseWindow(fEV, fSession, window)) // balances AcquireODWindow above
  3889.             fDispatcher->Exit(fEV);
  3890. }
  3891.  
  3892. //------------------------------------------------------------------------------
  3893. // RealShell::CloseDocument
  3894. //
  3895. //    Result of true means that document was closed (or close was attempted).
  3896. //    Result of false means that the process was cancelled. 
  3897. //------------------------------------------------------------------------------
  3898.  
  3899. ODBoolean RealShell::CloseDocument(ODDocument* document, DescType saveOptions)
  3900. {
  3901.     ODDraft*    draft = ODGetTempDraftFromOpenDocument(fEV, fSession, document);
  3902.     ODBoolean    result = kODTrue;
  3903.     
  3904.     if (draft != kODNULL &&
  3905.         ODDraftHasWriteAccess(fEV, draft) &&
  3906.         (draft->ChangedFromPrev(fEV) || ODIsUnsavedNewDocument(fEV, fSession,
  3907.                                                                 document)))
  3908.     {
  3909.         if (this->DoesUserCancelClose(document, saveOptions))
  3910.             result = kODFalse;
  3911.     }
  3912.     if (result == kODTrue)
  3913.     {
  3914.         if (ODCloseDocument(fEV, fSession, document))
  3915.             fDispatcher->Exit(fEV);
  3916.     }
  3917.  
  3918.     return result;
  3919. }
  3920.  
  3921. //------------------------------------------------------------------------------
  3922. // RealShell::DeleteDocument
  3923. //------------------------------------------------------------------------------
  3924.  
  3925. void RealShell::DeleteDocument(ODDocument* document)
  3926. {
  3927.     // First, ask the user if they are sure they want to delete!
  3928.     if (!isOptionKeyDown())
  3929.     {
  3930.         ArrowCursor();
  3931.     
  3932.         char    fileName[256];
  3933.         ODGetDocumentFileName(fEV, document, &(fileName[0]));
  3934.         CToPascalString(fileName);
  3935.     
  3936.         ODSLong        savedRefNum;
  3937.         BeginUsingLibraryResources(savedRefNum);
  3938.     
  3939.         ParamText(kODEmptyPString, (unsigned char const *)fileName, 
  3940.                     kODEmptyPString, kODEmptyPString);
  3941.     
  3942.         fWindowState->DeactivateFrontWindows(fEV);
  3943.         
  3944.         ODSShort btnClicked;
  3945.         TRY
  3946.         {
  3947.             DialogPtr askRevertDlg = kODNULL;
  3948.             askRevertDlg = ODGetNewDialog( fEV, kSHLDeleteDLOG, fSession, kODTrue );
  3949.             THROW_IF_NULL( askRevertDlg );
  3950.             ODUseCommandKeyStringsResource( kSHLDeleteDLOGCmdKeyStrs );
  3951.             ::ShowWindow( askRevertDlg );
  3952.             ::ModalDialog( GetODButtonKeyFilterProc(), &btnClicked );
  3953.             ::DisposeDialog( askRevertDlg );
  3954.         }
  3955.         CATCH_ALL
  3956.         {
  3957.             btnClicked = kSHLscCancel;        // Cancel the delete
  3958.         }
  3959.         ENDTRY;
  3960.     
  3961.         fWindowState->ActivateFrontWindows(fEV);
  3962.     
  3963.         EndUsingLibraryResources(savedRefNum);
  3964.         if (!(kSHLscOK == btnClicked))
  3965.             return;
  3966.     }
  3967.     
  3968.     TempPlatformFile    
  3969.         currentFile = GetPlatformFileFromContainer(fEV, document->GetContainer(fEV));                            
  3970.  
  3971.     ODSaveDocument(fEV, fSession, document);
  3972.     if (ODCloseDocument(fEV, fSession, document))
  3973.         fDispatcher->Exit(fEV);
  3974.         
  3975.     currentFile->MoveToTrash();
  3976. }
  3977.  
  3978. //-------------------------------------------------------------------------------------
  3979. // Save
  3980. //-------------------------------------------------------------------------------------
  3981.  
  3982. ODBoolean    RealShell::Save(ODDocument* document, ODBoolean isClosing)
  3983. {    
  3984.     if (ODIsUnsavedNewDocument(fEV, fSession, document))
  3985.     {
  3986.         StandardFileReply reply;
  3987.         Str255 fileName;
  3988.         ODGetDocumentFileName(fEV, document, (char*)&(fileName[0]));
  3989.         CToPascalString((char*)fileName);
  3990.         
  3991.         Str255 msg;                
  3992.         { CUsingLibraryResources r;
  3993.             GetIndString(msg, kSHLStrsID, kSHLStrIndDSaveAs);
  3994.         }
  3995.         
  3996.         TempPlatformFile
  3997.             currentFile = GetPlatformFileFromContainer(fEV, document->GetContainer(fEV));
  3998.         
  3999.         // Need to rename file on disk briefly to avoid erroneous "Replace?" dialog
  4000.         
  4001.         // $$$$$ DOES NOT ACCOUNT FOR THE CASE WHERE THE filename+" " already exists !!!!!!
  4002.         
  4003.         FSSpec currentFSSpec = currentFile->GetFileSpec();
  4004.         if (currentFSSpec.name[0] < kODMaxFileNameSize)
  4005.             currentFSSpec.name[++currentFSSpec.name[0]] = 0x20;
  4006.         else
  4007.             --currentFSSpec.name[0];
  4008.         
  4009.         TRY
  4010.             currentFile->Rename(currentFSSpec.name);
  4011.         CATCH_ALL
  4012.             WARN("Unable to rename to avoid replace dialog. One replace dialog coming up!");
  4013.         ENDTRY
  4014.         
  4015.         // This would be cleaner, but not optimal
  4016.         // currentFile->UniquifyName(,,,,kRenameInPlace);
  4017.         
  4018.         ODDraft* draft = ODGetTempDraftFromOpenDocument(fEV, fSession, document);
  4019.         ODBoolean isStationery = 
  4020.             this->AskUserWhereToPutIt(draft, fileName, msg, &reply );
  4021.  
  4022.         if (!reply.sfGood) 
  4023.         {
  4024.             TRY
  4025.                 currentFile->Rename(fileName);
  4026.             CATCH_ALL
  4027.             ENDTRY
  4028.             return kODFalse;
  4029.         }
  4030.         
  4031.         {
  4032.             // This assumes that the front window is the one being saved.
  4033.             // This might not be true for scripting, although it is right now
  4034.             // since we can only script the front window.
  4035.             TempODWindow window = fWindowState->AcquireFrontRootWindow(fEV);
  4036.             ODSetIsStationery(fEV, window->GetRootFacet(fEV)->GetFrame(fEV), isStationery);
  4037.         }
  4038.         
  4039.         TempPlatformFile file = new PlatformFile();
  4040.         file->Specify(&reply.sfFile);
  4041.         
  4042.         if (file->IsEqualTo(currentFile))
  4043.             ; // do nothing, we'll save down below right ontop of the current document.
  4044.         else 
  4045.         {
  4046.             if (reply.sfReplacing)
  4047.             {
  4048.                 TRY
  4049.                     file->Delete();
  4050.                 CATCH_ALL
  4051.                     THROW(kODErrCannotSaveAsOntoBusyDoc);
  4052.                 ENDTRY;
  4053.             }
  4054.             
  4055.             if (reply.sfFile.vRefNum == currentFile->GetFileSpec().vRefNum)
  4056.             {
  4057.                 currentFile->MoveRename(&(reply.sfFile), kODFalse);
  4058.             }
  4059.             else
  4060.             {
  4061.                 if (!isClosing)
  4062.                     this->ShowSaveDiffVolDialog();
  4063.                 
  4064.                 ODSaveDocument(fEV, fSession, document);
  4065.                 ODBoolean wasLastDocument = ODCloseDocument(fEV, fSession, document);
  4066.                 file->CopyFrom(currentFile);
  4067.                 currentFile->Delete();
  4068.                 if (!isClosing) 
  4069.                 {
  4070.                     ODDraft* topdraft = ODOpenFileDocument(fEV, fSession, file, kODDPExclusiveWrite);
  4071.                     document = topdraft->GetDocument(fEV);
  4072.                     this->InstallShellPlugIns(topdraft);
  4073.             
  4074.                     ODOpenDraft(fEV, fSession, topdraft);
  4075.                     this->CloseSaveDiffVolDialog();
  4076.                     
  4077.                     ODReleaseObject(fEV, topdraft);
  4078.         
  4079.                     fDispatcher = fSession->GetDispatcher(fEV);
  4080.                     fWindowState = fSession->GetWindowState(fEV);
  4081.                 }
  4082.                 else
  4083.                 {
  4084.                  if (wasLastDocument)
  4085.                     fDispatcher->Exit(fEV);
  4086.                 }
  4087.                 
  4088.                 LMSetSFSaveDisk(-(reply.sfFile.vRefNum));
  4089.                 LMSetCurDirStore(reply.sfFile.parID);
  4090.             }
  4091.         }
  4092.     }
  4093.  
  4094.     ODSetIsTempDocument(fEV, ODGetTempDraftFromOpenDocument(fEV, fSession, document), kODFalse);
  4095.     ODSaveDocument(fEV, fSession, document);
  4096.     return kODTrue;
  4097. }    // RealShell::Save
  4098.  
  4099. void RealShell::ShowSaveDiffVolDialog( )
  4100. {
  4101.     if( !fSaveDiffVolDialog ) {
  4102.         CUsingLibraryResources r;
  4103.         fSaveDiffVolDialog = ::GetNewDialog(kSHLSaveDiffVolDialogID,kODNULL,(WindowPtr)-1L);
  4104.         ::ShowWindow(fSaveDiffVolDialog);
  4105.         ::DrawDialog(fSaveDiffVolDialog);
  4106.     }
  4107. }
  4108.  
  4109. void RealShell::CloseSaveDiffVolDialog( )
  4110. {
  4111.     if( fSaveDiffVolDialog ) {
  4112.         CUsingLibraryResources r;
  4113.         ::DisposeDialog(fSaveDiffVolDialog);
  4114.         fSaveDiffVolDialog = kODNULL;
  4115.     }
  4116. }
  4117.  
  4118. //-------------------------------------------------------------------------------------
  4119. // Save A Copy
  4120. //-------------------------------------------------------------------------------------
  4121.  
  4122. pascal void DrawSmallIcon(DialogPtr theDialog, short theItem)
  4123. {
  4124.     short  itemHit;
  4125.     Handle scratchHandle;
  4126.     Rect   scratchRect;
  4127.     
  4128.     GetDialogItem(theDialog, theItem, &itemHit, &scratchHandle, &scratchRect);
  4129.  
  4130.     (void) PlotIconID (&scratchRect, atNone, ttNone,
  4131.                        theItem == kSHLSaCDocumentIconItem ? kSHLSaCDocumentIconID : kSHLSaCStationeryIconID);
  4132. }
  4133.  
  4134. pascal short SaveCopyDlgHook(short item, DialogPtr theDialog, void *saveDataPtr)
  4135. {
  4136.     short  itemHit;
  4137.     Handle scratchHandle;
  4138.     Rect   scratchRect;
  4139.     ODSShort     translateItem = 0;
  4140.     ODSShort     currentKindItem = 0;
  4141.     
  4142.     UserItemUPP drawSmallIconUPP = ((SaveCopyStruct*)saveDataPtr)->iconUPP;
  4143.     
  4144.     if ( ((WindowPeek)theDialog)->refCon == sfMainDialogRefCon )
  4145.         switch (item) {
  4146.         case sfHookFirstCall:
  4147.             GetDialogItem(theDialog, kSHLSaCDocumentIconItem, &itemHit, &scratchHandle, &scratchRect);
  4148.             SetDialogItem(theDialog, kSHLSaCDocumentIconItem, itemHit, (Handle) drawSmallIconUPP, &scratchRect);
  4149.     
  4150.             GetDialogItem(theDialog, kSHLSaCStationeryIconItem, &itemHit, &scratchHandle, &scratchRect);
  4151.             SetDialogItem(theDialog, kSHLSaCStationeryIconItem, itemHit, (Handle) drawSmallIconUPP, &scratchRect);
  4152.             
  4153.             GetDialogItem(theDialog, kSHLSaCDocumentRadioBtn, &itemHit, &scratchHandle, &scratchRect);
  4154.             SetControlValue( (ControlHandle) scratchHandle, !((SaveCopyStruct*)saveDataPtr)->makeStationery);
  4155.     
  4156.             GetDialogItem(theDialog, kSHLSaCStationeryRadioBtn, &itemHit, &scratchHandle, &scratchRect);
  4157.             SetControlValue( (ControlHandle) scratchHandle, ((SaveCopyStruct*)saveDataPtr)->makeStationery);
  4158.             
  4159.             GetDialogItem(theDialog, kSHLSaCKindPopupItem, &itemHit, &scratchHandle, &scratchRect);
  4160.             MenuHandle kindMenu = GetMenu(kSHLSaCKindPopupMenu);
  4161.             THROW_IF_NULL(kindMenu);
  4162.  
  4163.             InitKindsPopup(((SaveCopyStruct*)saveDataPtr)->kindList, 
  4164.                             ((SaveCopyStruct*)saveDataPtr)->partKind, 
  4165.                             (ControlHandle)scratchHandle, 
  4166.                             ¤tKindItem, kindMenu, &translateItem,
  4167.                             ((SaveCopyStruct*)saveDataPtr)->session);
  4168.             break;
  4169.     
  4170.         case kSHLSaCDocumentRadioBtn :
  4171.             GetDialogItem(theDialog, kSHLSaCDocumentRadioBtn, &itemHit, &scratchHandle, &scratchRect);
  4172.             SetControlValue( (ControlHandle) scratchHandle, 1);
  4173.             GetDialogItem(theDialog, kSHLSaCStationeryRadioBtn, &itemHit, &scratchHandle, &scratchRect);
  4174.             SetControlValue( (ControlHandle) scratchHandle, 0);
  4175.             
  4176.             break;
  4177.             
  4178.         case kSHLSaCStationeryRadioBtn :
  4179.             GetDialogItem(theDialog, kSHLSaCDocumentRadioBtn, &itemHit, &scratchHandle, &scratchRect);
  4180.             SetControlValue( (ControlHandle) scratchHandle, 0);
  4181.             GetDialogItem(theDialog, kSHLSaCStationeryRadioBtn, &itemHit, &scratchHandle, &scratchRect);
  4182.             SetControlValue( (ControlHandle) scratchHandle, 1);
  4183.     
  4184.             break;
  4185.             
  4186.         case sfHookLastCall :
  4187.             /* check value of radio buttons and save accordingly */
  4188.             GetDialogItem(theDialog, kSHLSaCStationeryRadioBtn, &itemHit, &scratchHandle, &scratchRect);
  4189.             ((SaveCopyStruct*)saveDataPtr)->makeStationery = GetControlValue( (ControlHandle) scratchHandle);
  4190.             ((SaveCopyStruct*)saveDataPtr)->changeKind = kODNULL;
  4191.             GetDialogItem(theDialog, kSHLSaCKindPopupItem, &itemHit, &scratchHandle, &scratchRect);
  4192.             ODSShort kindItem = (ODSShort) GetControlValue((ControlHandle)scratchHandle);
  4193.             if (kindItem != currentKindItem)
  4194.             {
  4195.                 ODType newKind = GetThisKindFromList(kindItem,
  4196.                                     ((SaveCopyStruct*)saveDataPtr)->kindList);
  4197.                 ((SaveCopyStruct*)saveDataPtr)->changeKind = newKind;
  4198.             }
  4199.         
  4200.             break;
  4201.         }
  4202.                                                                                                                                 
  4203.     return (item);
  4204. }
  4205.  
  4206. ODBoolean RealShell::AskUserWhereToPutIt( ODDraft* whichDraft, Str255 defaultName,
  4207.         Str255 msg, StandardFileReply* reply )
  4208. {
  4209.     Point              pt;
  4210.     SetPt(&pt, 0, 0);
  4211.  
  4212.     ODBoolean    makeStationery;
  4213.  
  4214.     ODSLong        savedRefNum;
  4215.         // Setup fSaveCopyData fields for custom put file
  4216.     fSaveCopyData = new SaveCopyStruct;
  4217.  
  4218.     fSaveCopyData->session = this->GetSession();
  4219.     TempODPart rootPart = ODAcquireRootPartOfDraft(fEV, whichDraft);
  4220.     
  4221.     // This should probably use a frame, otherwise we're ignoring the disk file
  4222.     fSaveCopyData->makeStationery = kODFalse; // always default to saving a document
  4223.     
  4224.     fSaveCopyData->partKind = ODGetKind(fEV, rootPart );
  4225.     fSaveCopyData->kindList = 
  4226.         fSession->GetStorageSystem(fEV)->CreateTypeList(fEV, kODNULL);
  4227.  
  4228.         // get StorageUnit kinds
  4229.     ContentValueTypes(rootPart->GetStorageUnit(fEV), fSaveCopyData->kindList);
  4230.  
  4231.         // get all kinds supported by this editor
  4232.     ODNameSpaceManager* nsm = fSaveCopyData->session->GetNameSpaceManager(fEV);
  4233.     ODEditor editorID = GetCurrentEditorForPart(rootPart);
  4234.     GetAllKindsForEditor(nsm, fSaveCopyData->kindList, editorID);
  4235.     ODDisposePtr(editorID);
  4236.     
  4237.     BeginUsingLibraryResources(savedRefNum);
  4238.     fSaveCopyData->iconUPP = NewUserItemProc(DrawSmallIcon);
  4239.     DlgHookYDUPP saveACopyUPP = NewDlgHookYDProc(SaveCopyDlgHook);
  4240.  
  4241.     fWindowState->DeactivateFrontWindows(fEV);
  4242.     
  4243.     {
  4244.     TempODMenuBar currentMenuBar = fWindowState->AcquireCurrentMenuBar(fEV);
  4245.     ODDialogBegin(fEV, fSession, currentMenuBar, kODNULL);
  4246.     CustomPutFile(msg, defaultName, reply,
  4247.                   kSHLSaveCopyDlgID, pt, saveACopyUPP, kODNULL, kODNULL , kODNULL, fSaveCopyData);
  4248.     ODDialogEnd();
  4249.     }
  4250.  
  4251.     fWindowState->ActivateFrontWindows(fEV);
  4252.  
  4253.     DisposeRoutineDescriptor(saveACopyUPP);    
  4254.     DisposeRoutineDescriptor(fSaveCopyData->iconUPP);
  4255.      EndUsingLibraryResources(savedRefNum);
  4256.  
  4257.     makeStationery = fSaveCopyData->makeStationery;
  4258.     
  4259.     ODDisposePtr( fSaveCopyData->partKind );
  4260.     ODDeleteObject( fSaveCopyData->kindList );
  4261.     ODDeleteObject( fSaveCopyData );
  4262.     
  4263.      return makeStationery;
  4264. }
  4265.  
  4266. void RealShell::SaveACopy(ODDraft* draft)        
  4267. {
  4268. // save a copy of the topmost draft into a new container
  4269.     StandardFileReply reply;
  4270.     
  4271.     Str255 msg;
  4272.     
  4273.     ODDocument* document = draft->GetDocument(fEV);
  4274.     
  4275.     Str255 fileName;
  4276.     ODGetDocumentFileName(fEV, document, (char*)&(fileName[0]));
  4277.     CToPascalString((char*)fileName);
  4278.     
  4279.     Str255 defaultName;
  4280.     
  4281.     // HI$ #1247070: should we append " Draft <n>" if the user happens to be saving
  4282.     // a copy of a draft?
  4283.     
  4284.     { CUsingLibraryResources r;
  4285.         GetIndString(msg, kSHLStrsID, kSHLStrIndDSaveACopy);
  4286.         ReplaceIntoString(kSHLCopyDefaultStrID, fileName, kODEmptyPString, defaultName);
  4287.     }
  4288.     if (defaultName[0] > kODMaxFileNameSize)
  4289.         ClipStringToBytes( defaultName, kODMaxFileNameSize, smCurrentScript );
  4290.     
  4291.     ODBoolean isStationery = 
  4292.         this->AskUserWhereToPutIt(draft, defaultName, msg, &reply );
  4293.     if (!reply.sfGood) 
  4294.         return;
  4295.     
  4296.     TempPlatformFile file = new PlatformFile();
  4297.     file->Specify(&reply.sfFile);
  4298.     
  4299.     TempPlatformFile
  4300.         currentFile = GetPlatformFileFromContainer(fEV, document->GetContainer(fEV));
  4301.  
  4302.     if (reply.sfReplacing)
  4303.     {
  4304.         ODBoolean isEqual = file->IsEqualTo(currentFile);
  4305.         
  4306.         if (isEqual != kODFalse)
  4307.         {
  4308.             THROW(kODErrCannotSaveACopyOntoCurrentDoc);
  4309.         }
  4310.         
  4311.         TRY
  4312.             file->Delete();
  4313.         CATCH_ALL
  4314.             THROW(kODErrCannotSaveACopyOntoBusyDoc);
  4315.         ENDTRY;
  4316.     }
  4317.     
  4318.     ODSaveACopyOfDraft(fEV, fSession, draft, file);
  4319.     file->SetStationery(isStationery);
  4320.     CopyResources(currentFile, file); // copy the resource over to the new copy
  4321. }
  4322.  
  4323.  
  4324. //------------------------------------------------------------------------------
  4325. // InitKindsPopup $$$$$ copied from Info.cpp, can this be factored? $Opt
  4326. //------------------------------------------------------------------------------
  4327.  
  4328. ODStatic void InitKindsPopup ( ODTypeList* kindList,
  4329.                             ODType theKind,
  4330.                            ControlHandle    itemHandle,
  4331.                            ODSShort* currentKindItem,
  4332.                            MenuHandle kindMenu,
  4333.                            ODSShort* translateItem,
  4334.                            ODSession* session )
  4335. {
  4336.     ODSShort        item = 1;
  4337.  
  4338.     Environment* ev = somGetGlobalEnvironment();
  4339.  
  4340.     ODUShort i;
  4341.  
  4342.     for (i = CountMItems(kindMenu) - 1;  i > 0;  --i)
  4343.     {
  4344.         DeleteMenuItem(kindMenu, i);
  4345.     }
  4346.  
  4347.     AddTypesToMenu(kindList, kindMenu, session);
  4348.  
  4349.     {
  4350.         for( TempODTypeListIterator kindIter(ev ,kindList); kindIter.Current(); kindIter.Next(), item++ )
  4351.         {
  4352.             ODBoolean isEqual = ODISOStrEqual(kindIter.Current(), theKind);
  4353.             if ( isEqual )
  4354.                 break;
  4355.         }
  4356.     }
  4357.  
  4358.     EnableItem(kindMenu, *translateItem);
  4359.     *translateItem = kindList->Count(ev)+1;
  4360.  
  4361.     SetControlMinimum(itemHandle, 1);
  4362.     SetControlMaximum(itemHandle, *translateItem);
  4363.     SetControlValue(itemHandle, item);
  4364.     *currentKindItem = item;
  4365.     
  4366.  
  4367.         // Determine if translation is an option
  4368.     ODTypeList*    translateToList = 
  4369.         session->GetStorageSystem(ev)->CreateTypeList(ev, kODNULL);
  4370.     
  4371.     TRY
  4372.         GetDestinationKindsList(kindList, translateToList, kODNULL, session);
  4373.         if ( translateToList->Count(ev) == 0 )
  4374.             DisableItem(kindMenu, *translateItem);
  4375.     CATCH_ALL
  4376.         DisableItem(kindMenu, *translateItem);
  4377.     ENDTRY
  4378.     
  4379.     delete translateToList;
  4380. }
  4381.  
  4382. //-------------------------------------------------------------------------------------
  4383. // Revert
  4384. //-------------------------------------------------------------------------------------
  4385.  
  4386.  
  4387. void    RealShell::Revert(ODDocument* document)
  4388. {
  4389.     if (this->DoesUserOKRevert(document)) 
  4390.     {
  4391.         ODRevertDocument(fEV, fSession, document);
  4392.     }
  4393. }
  4394.  
  4395. ODBoolean    RealShell::DoesUserOKRevert(ODDocument* document)
  4396. {
  4397. // asks user "Revert to the last saved version?"
  4398.  
  4399.     ArrowCursor();
  4400.  
  4401.     char    fileName[256];
  4402.     ODGetDocumentFileName(fEV, document, &(fileName[0]));
  4403.     CToPascalString(fileName);
  4404.  
  4405.     ODSLong        savedRefNum;
  4406.     BeginUsingLibraryResources(savedRefNum);
  4407.  
  4408.     ParamText(kODEmptyPString, (unsigned char const *)fileName, 
  4409.                 kODEmptyPString, kODEmptyPString);
  4410.  
  4411.     fWindowState->DeactivateFrontWindows(fEV);
  4412.     
  4413.     ODSShort btnClicked;
  4414.     TRY
  4415.     {
  4416.         DialogPtr askRevertDlg = kODNULL;
  4417.         askRevertDlg = ODGetNewDialog( fEV, kSHLsvRevert, fSession, kODTrue );
  4418.         THROW_IF_NULL( askRevertDlg );
  4419.         ODUseCommandKeyStringsResource( kSHLsvRevertCmdKeyStrs );
  4420.         ::ShowWindow( askRevertDlg );
  4421.         ::ModalDialog( GetODButtonKeyFilterProc(), &btnClicked );
  4422.         ::DisposeDialog( askRevertDlg );
  4423.     }
  4424.     CATCH_ALL
  4425.     {
  4426.         btnClicked = kSHLscCancel;        // Cancel the revert
  4427.     }
  4428.     ENDTRY;
  4429.  
  4430.     fWindowState->ActivateFrontWindows(fEV);
  4431.  
  4432.     EndUsingLibraryResources(savedRefNum);;
  4433.     return kSHLscOK == btnClicked;
  4434. }
  4435.  
  4436.  
  4437. //-------------------------------------------------------------------------------------
  4438. // Drafts
  4439. //-------------------------------------------------------------------------------------
  4440.  
  4441. void    RealShell::Drafts(ODDocument* document)
  4442. {
  4443.     ODDraft* topDraft = ODGetTempDraftFromOpenDocument(fEV, fSession, document);
  4444.     if (topDraft)
  4445.         topDraft->Acquire(fEV);
  4446.     else
  4447.         topDraft = document->AcquireDraft(fEV,kODDPReadOnly,0,kODNULL,kODPosTop,kODFalse);
  4448.     
  4449.     DraftWindow* d = new DraftWindow;
  4450.     DraftWinAction     dWinAction = kDraftWinNone;
  4451.     ODDraft*    curDraft = kODNULL;
  4452.     d->InitDraftWindow(fEV, topDraft);
  4453.  
  4454.     fWindowState->DeactivateFrontWindows(fEV);
  4455.     ArrowCursor();
  4456.     do {
  4457.         dWinAction = d->Drafts(fEV, curDraft, dWinAction, ODDraftHasWriteAccess(fEV, topDraft));
  4458.         switch (dWinAction) {
  4459.             case kDraftWinCreate:
  4460.                 WASSERT(ODDraftHasWriteAccess(fEV, topDraft));
  4461.                 fWindowState->ActivateFrontWindows(fEV);
  4462.                 d->DraftSaved(fEV, topDraft);
  4463.                 ODSaveDocument(fEV, fSession, document);
  4464.                 ODCloseDraft(fEV, fSession, topDraft);
  4465. #ifdef ODDebug
  4466.                 ODULong topDraftRefCount = topDraft->GetRefCount(fEV);
  4467.                 WASSERT(topDraftRefCount == 2);
  4468. #endif
  4469.                 topDraft->Release(fEV); // to balance the CreateDraft when the document was opened
  4470.                 topDraft = document->CreateDraft(fEV, topDraft, kODTrue);
  4471.                     // This CreateDraft call is doing two things with refcounts.
  4472.                     // First, it is releasing topDraft which balances the Acquire at the top of
  4473.                     // this function.
  4474.                     // Second, it is creating a new temp draft, which puts us in the same
  4475.                     // state as we were before the above topDraft->Release, except
  4476.                     // for the need to Reacquire the topDraft as was done at the top of this 
  4477.                     // function which we do in the next statement.
  4478.                 topDraft->Acquire(fEV);
  4479.                 
  4480.                 ODTempDraftCreated(fEV, fSession, document, topDraft);
  4481.                 curDraft = topDraft;
  4482.  
  4483.                 {
  4484.                 TempODStorageUnit su = topDraft->AcquireDraftProperties(fEV);
  4485.                 ODResetDateModByInfo(fEV, su);    
  4486.                 }
  4487.                 
  4488.                 d->InitDraftWindow(fEV, topDraft);
  4489.                 ODOpenDraft(fEV, fSession, topDraft);
  4490.                 ODSaveDocument(fEV, fSession, document);
  4491.                 fWindowState->DeactivateFrontWindows(fEV);
  4492.                 
  4493.                 break;
  4494.             case kDraftWinDelete:
  4495.                 ODDraft* selDraft = d->GetSelectedDraft();
  4496.  
  4497.                 ODCloseDraft(fEV, fSession, selDraft);
  4498.                 ODReleaseObject( fEV, selDraft );    // -- TÇ: was acquired in draftswindow
  4499.  
  4500.                 d->DeleteSelectedDraft(fEV, fSession); 
  4501.                 break;
  4502.         }
  4503.     } while (dWinAction == kDraftWinDelete);
  4504.  
  4505.     fWindowState->ActivateFrontWindows(fEV);
  4506.     
  4507.     if (dWinAction == kDraftWinOpen)
  4508.     {
  4509.         // open selected Drafts as additional root windows within this process
  4510.         // if a particular draft already has a window, bring it to front, don't create a new one
  4511.         ODDraft* selDraft = d->GetSelectedDraft();
  4512.         WASSERT(selDraft);
  4513.         
  4514.         ODOpenDraft(fEV, fSession, selDraft);
  4515.     }
  4516.     ODDeleteObject(d);
  4517.     ODReleaseObject( fEV, topDraft );    // balances Acquire & AcquireDraft at beginning.
  4518.  
  4519.     if ( dWinAction == kDraftWinLowMemAbort )
  4520.         THROW( kODErrOutOfMemory );
  4521. }
  4522.  
  4523. //-------------------------------------------------------------------------------------
  4524. // Info
  4525. //-------------------------------------------------------------------------------------
  4526.  
  4527.  
  4528. void    RealShell::DocumentInfo(ODDocument* document)
  4529. {
  4530.     ODUnused(document);
  4531.     
  4532.     ODDocumentInfo(fEV, fSession);
  4533. }
  4534.  
  4535. /*
  4536. // Default implementation for active parts which do nothing.  Keep this code -TÇ.
  4537. void    RealShell::PartInfo()
  4538. {
  4539.     ArrowCursor();
  4540.     ODTypeToken selectionFocus = fSession->Tokenize(fEV, kODSelectionFocus);
  4541.     TempODFrame activeFrame = fSession->GetArbitrator(fEV)->AcquireFocusOwner(fEV, selectionFocus);
  4542.     ODFrameFacetIterator* facets = activeFrame->CreateFacetIterator(fEV);
  4543.     fSession->GetInfo(fEV)->ShowPartFrameInfo(fEV, facets->First(fEV),
  4544.         this->HasWriteAccess());
  4545.     ODDeleteObject(facets);
  4546. }
  4547. */
  4548.  
  4549. //-------------------------------------------------------------------------------------
  4550. // Error Handling
  4551. //-------------------------------------------------------------------------------------
  4552.  
  4553. void    RealShell::ExceptionAlert(ODError exceptionCode, const char message[])
  4554. {
  4555.     Str255 errStr;
  4556.  
  4557.     if ( gODBentoFatalErrorHasOccurred )
  4558.         ODBentoFatalError();
  4559.  
  4560.     // Errors not to display:
  4561.     if( exceptionCode == kODNoError || exceptionCode == kODErrAlreadyNotified
  4562.                                     || exceptionCode == userCanceledErr )
  4563.         return;
  4564.  
  4565.     // If interaction is allowed, notify user until process is activated:
  4566.     if( AEInteractWithUser(kNoTimeOut,kODNULL,kODNULL) != noErr )
  4567.         return;
  4568.     
  4569.     TRY{
  4570.     
  4571.         CUsingLibraryResources r;
  4572.  
  4573.         ODBoolean lowMem = ! this->CheckFreeMemory();
  4574.     
  4575.         TRY{
  4576.             if (fWindowState)
  4577.                 fWindowState->DeactivateFrontWindows(fEV);
  4578.         }CATCH_ALL{
  4579.             WARN("Error %d deactivating front windows",ErrorCode());
  4580.             // don't reraise
  4581.         }ENDTRY
  4582.         
  4583.         LookupErrString(exceptionCode, kODErrUserID, errStr);
  4584.         if ( fFailedPlugInName[0] != 0 )
  4585.         {
  4586.             ReplaceIntoString( kSHLPlugInErrorStrID, fFailedPlugInName, errStr, errStr);
  4587.             fFailedPlugInName[0] = 0;
  4588.         }
  4589.     
  4590.     #if ODDebug
  4591.         ParamText(errStr, "\pOption-click OK for more…", kODEmptyPString, kODEmptyPString);
  4592.             // NOTE: This hard coded string is ok because it is for debugging only. -TC
  4593.     #else
  4594.         ParamText(errStr, kODEmptyPString, kODEmptyPString, kODEmptyPString);
  4595.     #endif
  4596.     
  4597.         // Do not use a filter-proc if low on memory since it calls back to OpenDoc!
  4598.         ModalFilterUPP filter = lowMem ?kODNULL :GetODButtonKeyFilterProc();
  4599.     
  4600.     
  4601.         // Shazam! Show the alert:
  4602.         ShowAlert(fEV, kSHLphGenError, filter, fSession);
  4603.     
  4604.         TRY{
  4605.             if (isOptionKeyDown()) 
  4606.             {
  4607.                 Str255    debugStrString;
  4608.                 debugStrString[0] = 0;
  4609.                 
  4610.                 GetIndString(debugStrString, kSHLStrsID, kSHLStrIndDException);
  4611.                 
  4612.                 Str255    tempString;
  4613.         
  4614.                 NumToString(exceptionCode, tempString);
  4615.                 if (debugStrString[0] + tempString[0] <= 255)
  4616.                     ConcatPascalStrings(debugStrString, tempString);
  4617.         
  4618.                 LookupErrString(exceptionCode, kODErrSupportID, errStr);
  4619.                 
  4620.                 char msg[256];
  4621.                 if( message ) {
  4622.                     strncpy(msg,message,255);
  4623.                     msg[255] = 0;
  4624.                     c2pstr(msg);
  4625.                 } else
  4626.                     msg[0] = 0;
  4627.                 
  4628.                 ParamText(errStr, debugStrString, (StringPtr)msg, kODEmptyPString);
  4629.                 ShowAlert(fEV, kSHLphGenError, filter, fSession);
  4630.             }
  4631.         }CATCH_ALL{
  4632.             WARN("Error %d handling opt key down",ErrorCode());
  4633.             // don't reraise
  4634.         }ENDTRY
  4635.         
  4636.     #ifdef SHLTestErrorDialogUsage
  4637.         SHLDebugStr("\pPostErrorDialog HeapInfo…");
  4638.         HeapInfo();
  4639.     #endif
  4640.             
  4641.         TRY{
  4642.             if (fWindowState)
  4643.                 fWindowState->ActivateFrontWindows(fEV);
  4644.         }CATCH_ALL{
  4645.             WARN("Error %d re-activating front windows",ErrorCode());
  4646.             // don't reraise
  4647.         }ENDTRY
  4648.     
  4649.         ResetAlertStage();
  4650.         
  4651.     }CATCH_ALL{
  4652.         SysBeep(3);
  4653.         WARN("Error %d thrown by exception alert",ErrorCode());
  4654.         // Eat exception, don't reraise
  4655.     }ENDTRY
  4656.  
  4657.     if( exceptionCode == kODErrFatalContainerError )
  4658.         fSession->GetDispatcher(fEV)->Exit(fEV);        // Fatal error means we must quit!
  4659. }
  4660.  
  4661. //----------------------------------------------------------------------------------------
  4662. // SearchErrTable: Private function
  4663. //----------------------------------------------------------------------------------------
  4664.  
  4665. ODBoolean RealShell::SearchErrTable(ODError value,
  4666.                               ODResNumber resourceID,
  4667.                               Str255 str)
  4668. {
  4669.     ErrRecordHandle table;
  4670.  
  4671.     str[0] = 0;
  4672.     ODSLong        savedRefNum;
  4673.     BeginUsingLibraryResources(savedRefNum);
  4674.     table = (ErrRecordHandle)GetResource('errs', resourceID);
  4675.     DetachResource((Handle)table);
  4676.     EndUsingLibraryResources(savedRefNum);
  4677.     
  4678.     if (table)
  4679.     {
  4680.         short lenTab;
  4681.         ODResNumber strID = 0;
  4682.         SignedByte savedState = HGetState((Handle)table);
  4683.         HLock((Handle)table);
  4684.         
  4685.         ErrRecordPointer pEntry = *table;
  4686.  
  4687.         lenTab = (short)(GetHandleSize((Handle)table) / sizeof(ErrRecord));
  4688.         for (short i = 1; i <= lenTab; ++i, ++pEntry)
  4689.         {
  4690.             if (pEntry->lowErr == 0)
  4691.                 strID = (ODResNumber)(pEntry->index);    // WARNING: assigning an ODULong to a short
  4692.             else if ((pEntry->lowErr <= value) && (value <= pEntry->highErr))
  4693.             {
  4694.                 if (pEntry->index > 0)
  4695.                 {
  4696.                     ODSLong        savedRefNum;
  4697.                     BeginUsingLibraryResources(savedRefNum);
  4698.                     GetIndString(str, strID, (ODResNumber)(pEntry->index)); // WARNING: passing in an ODULong as a short
  4699.                     EndUsingLibraryResources(savedRefNum);;
  4700.                 }
  4701.                 return kODTrue;
  4702.             }
  4703.         }
  4704.         HSetState((Handle)table, savedState);
  4705.     }
  4706.     return kODFalse;
  4707. } // SearchErrTable 
  4708.  
  4709.  
  4710. //----------------------------------------------------------------------------------------
  4711. // LookupErrString: 
  4712. //----------------------------------------------------------------------------------------
  4713. ODBoolean RealShell::LookupErrString(ODError value,
  4714.                                ODResNumber resourceID,
  4715.                                Str255 str)
  4716. {
  4717.     if (SearchErrTable(value, 0/*errAppTable*/ + resourceID, str))
  4718.         return kODTrue;
  4719.     else
  4720.         return SearchErrTable(value, resourceID, str);
  4721. } // LookupErrString 
  4722.  
  4723. //----------------------------------------------------------------------------------------
  4724. // CreateDefaultIText: 
  4725. //----------------------------------------------------------------------------------------
  4726. // <eeh> this might be more useful in IText.cpp or whatever it's called.
  4727. static ODIText* CreateDefaultIText(StringPtr text)
  4728. {
  4729.     ODScriptCode script = FontToScript( GetSysFont() );;
  4730.     ODLangCode lang = GetScriptVariable(script, smScriptLang);
  4731.     return CreateITextPString( script, lang, text);
  4732. }
  4733.  
  4734. /*********************************************************************************
  4735. SendFinderODOCEvent
  4736. Temporary function that should be merged with Jens's CreateFinderRevealEvent in
  4737. WinPopM.cpp (UI subsystem).  Or perhaps we needn't bother, since this is just
  4738. a workaround anyway.
  4739. *********************************************************************************/
  4740.  
  4741. static OSErr SendFinderODOCEvent( const FSSpec *fileToOpen )
  4742. {
  4743. const DescType kFinderSignature    = 'MACS';
  4744. const DescType kFinderEventClass    = 'FNDR';
  4745.  
  4746.     OSErr err;
  4747.     OSType finderSignature = kFinderSignature;
  4748.     AliasHandle alias = NULL;
  4749.     AEDesc target = NULL_DESCRIPTOR_DEFINITION;
  4750.     AEDescList list = NULL_DESCRIPTOR_DEFINITION;
  4751.  
  4752.     AppleEvent openEvent = NULL_DESCRIPTOR_DEFINITION;
  4753.     
  4754.     err= AECreateDesc(typeApplSignature,&finderSignature,sizeof(OSType), &target);
  4755.     if( err ) goto exit;
  4756.     err= AECreateAppleEvent( kCoreEventClass, kAEOpenDocuments, &target,
  4757.             kAutoGenerateReturnID, kAnyTransactionID, &openEvent );
  4758.     if( err ) goto exit;
  4759. //    AEDisposeDesc(&target);
  4760.     err= NewAliasMinimal( fileToOpen, &alias );
  4761.     if( err ) goto exit;
  4762.  
  4763.     err= AECreateList(NULL,0,false, &list);
  4764.     if( err ) goto exit;
  4765.     err= AEPutPtr(&list,1,typeAlias,*alias,GetHandleSize((Handle)alias));
  4766.     if( err ) goto exit;
  4767.     
  4768.     err= AEPutParamDesc(&openEvent, keyDirectObject, &list);
  4769.     if( err ) goto exit;
  4770.  
  4771.     err = AESend( &openEvent, kODNULL,
  4772.             kAENoReply|kAEAlwaysInteract|kAECanSwitchLayer,
  4773.             kAENormalPriority, kNoTimeOut, kODNULL, kODNULL );
  4774.  
  4775. exit:
  4776.     AEDisposeDesc(&target);
  4777.     AEDisposeDesc(&list);
  4778.     if( alias ) DisposeHandle((Handle)alias);
  4779. //    if( err )
  4780.         AEDisposeDesc(&openEvent);
  4781.     
  4782.     return err;
  4783. }
  4784.