home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / opendc12.zip / od124os2.exe / od12osr1.exe / src / DocMgr.cpp < prev    next >
C/C++ Source or Header  |  1997-03-21  |  90KB  |  2,678 lines

  1. /* @(#)Z 1.102 com/src/docshell/DocMgr.cpp, odshell, od96os2, odos29712d 97/03/21 17:37:31 (97/03/05 14:33:48) */
  2.  
  3. //
  4. //
  5. //   COMPONENT_NAME: odshell
  6. //
  7. //   CLASSES: none
  8. //
  9. //   ORIGINS: 82,27
  10. //
  11. //
  12. //   (C) COPYRIGHT International Business Machines Corp. 1995,1996
  13. //   All Rights Reserved
  14. //   Licensed Materials - Property of IBM
  15. //   US Government Users Restricted Rights - Use, duplication or
  16. //   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  17. //       
  18. //   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  19. //   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20. //   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  21. //   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  22. //   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  23. //   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  24. //   OR PERFORMANCE OF THIS SOFTWARE.
  25. //
  26. //====END_GENERATED_PROLOG========================================
  27. //
  28.  
  29.  
  30. //------------------------------------------------------------------------------
  31. // DocMgr.cpp
  32. //
  33. //    This file provides the implementation of the DocumentManager class.
  34. //    An instance of this class is created for each document which is opened
  35. //    or created.
  36. //
  37. //------------------------------------------------------------------------------
  38.  
  39. #ifndef SOM_Module_docmgr_Source
  40. #define SOM_Module_docmgr_Source
  41. #endif
  42. #define DocumentManager_Class_Source
  43.  
  44. #include <time.h>
  45. #include <ODTypes.h>
  46. #include <ODUtils.h>
  47. #include <StorUtil.h>
  48. #include <DocUtils.h>
  49. #include <StdProps.xh>
  50. #include <StdTypes.xh>
  51. #include <StdTypIO.h>
  52. #include <ODSessn.xh>
  53. #include <ODStor.xh>
  54. #include <ODCtr.xh>
  55. #include <Document.xh>
  56. #include <Part.xh>
  57. #include <StorageU.xh>
  58. #include <Undo.xh>
  59. #include <WinIter.xh>
  60. #include <LinkMgr.xh>
  61. #ifdef _PLATFORM_OS2_
  62. #include <IODDefs.xh>
  63. #include <ILnkSrvc.xh>
  64. #endif
  65. #include <Except.h>
  66. #include <Clipbd.xh>
  67. #include <DragDrp.xh>
  68. #include <Disptch.xh>
  69. #include <ODPrtRei.xh>
  70. #include "DraftRec.h"
  71. #include <TempObj.h>
  72. #include <EditrSet.h>
  73. #include <ISOStr.h>
  74. #include <BndNSUtl.h>
  75. #include <BArray.h>
  76. #include "ShPInLst.h"
  77. #include "DocShell.h"
  78. #include "ShellUtl.h"
  79.  
  80. #ifdef _PLATFORM_WIN32_
  81. #include <olewrap.h>
  82. #include <olemgrw.h>
  83. #endif
  84.  
  85. #define VARIABLE_MACROS
  86. #include "DocMgr.xih"
  87.  
  88. #ifdef _PLATFORM_WIN32_
  89. #include <objidl.h>
  90. #endif
  91.  
  92. #undef LOGGING
  93. #define LOGGING 1
  94.  
  95. #define UNTITLED_FILENAME "NewDoc.od"
  96. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_)
  97. #define PATH_SEPARATOR "\\"
  98. #else
  99. #define PATH_SEPARATOR "/"
  100. #endif
  101.  
  102. #define FILE_LENGTH 256
  103.  
  104. SOMEXTERN ODBoolean SOMLINK ReadOnlyDlg(Environment *ev);
  105.  
  106. //------------------------------------------------------------------------------
  107. // Initialize
  108. //
  109. //    Initialize a newly created DocumentManager
  110. //------------------------------------------------------------------------------
  111. SOM_Scope void  SOMLINK DocumentManagerInitialize(DocumentManager *somSelf, 
  112.                                         Environment *ev, ODSession* session)
  113. {
  114.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  115.     DocumentManagerMethodDebug("DocumentManager", "DocumentManagerInitialize");
  116.  
  117.     try
  118.     {
  119.     // Cache references to the session and window state
  120.         _fSession = session;
  121.         if (_fSession)
  122.             _fWindowState = session->GetWindowState(ev);
  123.  
  124.     // Set the draft permissions to the default
  125.         _fDraftPermissions = kODDPExclusiveWrite;
  126.  
  127.         // Initialize file name and root kind name
  128.         _fFileName[0] = kODNULL;
  129.         _fPartKindName[0] = kODNULL;
  130.  
  131.         // Initialize to existing document
  132.         _fUnsavedDocument = kODFalse;
  133.  
  134.     }
  135.     catch (ODException _exception)
  136.     {
  137.         LOG("SOM exception occured in DocumentManager::Initialize\n");
  138.     ODSetSOMException(ev, _exception);
  139.     }
  140. }
  141.  
  142. //------------------------------------------------------------------------------
  143. // OpenDocumentFromFile
  144. //
  145. //    Opens a document that exists on disk
  146. //------------------------------------------------------------------------------
  147. SOM_Scope char*  SOMLINK DocumentManagerOpenDocumentFromFile(
  148.                     DocumentManager *somSelf, 
  149.                                         Environment *ev, char *fileName,
  150.                     ODUShort actionFlag)
  151. {
  152.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  153.     DocumentManagerMethodDebug("DocumentManager",
  154.                     "DocumentManagerOpenDocumentFromFile");
  155.  
  156.     char* rootPartKind = kODNULL;
  157.     PlatformFile* file = new PlatformFile;
  158.  
  159.     try
  160.     {
  161.  
  162.         // Set the file name  -  need error handling for file existence  - RLC
  163.         file->Specify((ODFileSpec *)fileName);
  164.  
  165. #ifdef _PLATFORM_WIN32_
  166.     // Setup linking by registering this filename
  167.     somSelf->GetOleWrapper(ev)->RegisterFilename(fileName, FALSE);
  168. #endif
  169.  
  170.         // Check if it is a read-only document. If so, display a
  171.         // read-only alert dialog to ask user whether to continue
  172.         // or not. If continue, then proceed to open the document.
  173.         if (somSelf->IsReadOnlyDocument(ev, file))
  174.         {
  175.  
  176.            // Get the document from the file
  177.            somSelf->OpenFile(ev, file, actionFlag);
  178.  
  179.            // Install Shell Plug-in
  180.            InstallShellPlugIn(ev, _fDraft);
  181.  
  182. #if defined(_PLATFORM_OS2_)
  183.            _fSession->GetLinkService(ev)->
  184.                            DraftOpened(ev, _fDraft, kODFalse, fileName);
  185. #endif
  186.  
  187.            // Open the root part of the document
  188.            rootPartKind = somSelf->OpenRootPart(ev);
  189.  
  190.            // Display window title
  191.            _fWindowState->SetDefaultWindowTitles(ev, _fDraft);
  192.         }
  193.  
  194.     }
  195.     catch (ODException _exception)
  196.     {
  197.         LOG("SOM exception occured in DocumentManager::OpenDocumentFromFile\n");
  198.     ODSetSOMException(ev, _exception);
  199.     }
  200.  
  201.     // Cache the kindname and filename
  202.     // Note: _fFileName is already set if create a new document off stationery
  203.     if (fileName && (_fFileName[0] == kODNULL))
  204.        strcpy(_fFileName, fileName);
  205.     if (rootPartKind)
  206.        strcpy(_fPartKindName, rootPartKind);
  207.     delete file;
  208.  
  209.     return rootPartKind;
  210.  
  211. }
  212.  
  213. //------------------------------------------------------------------------------
  214. // OpenDocumentFromMemory
  215. //
  216. //    Opens a document that exists in memory
  217. //------------------------------------------------------------------------------
  218. SOM_Scope char*  SOMLINK DocumentManagerOpenDocumentFromMemory(
  219.                     DocumentManager *somSelf, 
  220.                                         Environment *ev,
  221.                     ODHandle handle)
  222. {
  223.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  224.     DocumentManagerMethodDebug("DocumentManager",
  225.                 "DocumentManagerOpenDocumentFromMemory");
  226.  
  227.     char* rootPartKind = kODNULL,
  228.           *rootPartNameStr = kODNULL;
  229.     ODIText *rootPartName = kODNULL;
  230.  
  231.     try
  232.     {
  233.         // Get the container from the given memory location
  234.         _fContainer = GetMemoryContainer(ev, _fSession, handle, 
  235.                     kODDefaultMemoryContainer);
  236.  
  237.         // Get the newly created document from the memory container
  238.         somSelf->OpenContainer(ev, _fContainer);
  239.  
  240.         // Install Shell Plug-in
  241.         InstallShellPlugIn(ev, _fDraft);
  242.  
  243.         // Open the root part of the document
  244.         rootPartKind = somSelf->OpenRootPart(ev);
  245.  
  246.         // Display root part kind as the window title
  247.         // Note: If kODPropName is not set by the part, then use the
  248.         //       rootPartKind returned from OpenRootPart as the text
  249.         //       in window title. 
  250.         TempODStorageUnit rootSU = ODAcquireRootPartSUOfDraft(ev, _fDraft);
  251.         rootPartName = ODGetITextProp(ev, rootSU, kODPropName, 
  252.                                                kODPlatformIText, kODNULL);
  253.         if (rootPartName)
  254.         {
  255.            ODULong strLength = GetITextStringLength(rootPartName);
  256.            rootPartNameStr = new char[strLength+1];
  257.            GetITextString(rootPartName, rootPartNameStr);
  258.         }
  259.         else
  260.         {
  261.            rootPartNameStr = new char[strlen(rootPartKind)+1];
  262.            strcpy(rootPartNameStr, rootPartKind);
  263.         }
  264.         
  265.         if (rootPartNameStr) 
  266.         {
  267.            _fWindowState->SetLongName(ev, rootPartNameStr);
  268.            _fWindowState->SetDefaultWindowTitles(ev, _fDraft);
  269.         }
  270.  
  271.     }
  272.     catch (ODException _exception)
  273.     {
  274.         LOG("SOM exception occured in DocumentManager::OpenDocumentFromMemory\n");
  275.         ODError error = ErrorCode();
  276.         if (_fContainer)
  277.            SaveAndRestoreEv1(_fContainer);
  278.         ODSetSOMException(ev, error);
  279.     }
  280.      
  281.     // Cache the kindname
  282.     if (rootPartKind)
  283.        strcpy(_fPartKindName, rootPartKind);
  284.  
  285.     if (rootPartNameStr)
  286.        delete[] rootPartNameStr;
  287.  
  288.     if (rootPartName)
  289.        DisposeIText(rootPartName);
  290.  
  291.     return rootPartKind;
  292. }
  293.  
  294. //------------------------------------------------------------------------------
  295. // CreateDocumentInFile
  296. //
  297. //    Create a document in a new file container
  298. //------------------------------------------------------------------------------
  299. SOM_Scope void  SOMLINK DocumentManagerCreateDocumentInFile(
  300.                     DocumentManager *somSelf, 
  301.                                         Environment *ev, ODType kindName,
  302.                     char *filename)
  303. {
  304.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  305.     DocumentManagerMethodDebug("DocumentManager",
  306.                 "DocumentManagerCreateDocumentInFile");
  307.  
  308.     PlatformFile *file = kODNULL;
  309.  
  310.     // Cache the kindname and filename
  311.     strcpy(_fFileName, filename);
  312.     strcpy(_fPartKindName, kindName);
  313.  
  314.     try
  315.     {
  316.         // Create a new container in a file - filename may be "uniquified"
  317.         file = somSelf->NewFileContainer(ev, &_fContainer, _fFileName);
  318.         file->GetAsciiName(_fFileName, FILE_LENGTH - 1);
  319.  
  320.         // Create a new document in the new container and externalize it
  321.         somSelf->CreateDocument(ev, _fContainer, kindName);
  322.  
  323.         // Release the new container
  324.         // Note: Need to release the container which is acquired in
  325.         //      CreateFileContainer.
  326.         //      The call to GetFileContainer in OpenFile will acquire
  327.         //      the created container so the refcount for the container
  328.         //      remains 1.
  329.         ODReleaseObject(ev, _fContainer);
  330.  
  331. #ifdef _PLATFORM_WIN32_
  332.     // Setup linking by registering this filename
  333.     // char fileName[_MAX_PATH];
  334.     // file->GetAsciiName(fileName, _MAX_PATH);
  335.     somSelf->GetOleWrapper(ev)->RegisterFilename(_fFileName, FALSE);
  336. #endif
  337.  
  338.         // Get the newly created document from the file
  339.         somSelf->OpenFile(ev, file, kODNULL);
  340.  
  341.         // Install Shell Plug-in
  342.         InstallShellPlugIn(ev, _fDraft);
  343.  
  344.         // Open the root part of the document
  345.         somSelf->OpenRootPart(ev);
  346.  
  347.         // Sync up window titles with file name
  348.         _fWindowState->SetDefaultWindowTitles(ev, _fDraft);
  349.  
  350.         // Mark document as unsaved document
  351.         // Note: Should mark this as unsaved document only if working
  352.         // with file container, not for memory container.
  353.         _fUnsavedDocument = kODTrue;
  354.     }
  355.     catch (ODException _exception)
  356.     {
  357.         LOG("SOM exception occured in DocumentManager::CreateDocumentInFile\n");
  358.         ODError error = ErrorCode();
  359.         if (_fContainer)
  360.            SaveAndRestoreEv1(_fContainer);
  361.         ODSetSOMException(ev, error);
  362.     }
  363.  
  364.     if (file)
  365.        delete file;
  366.  
  367. }
  368.  
  369. //------------------------------------------------------------------------------
  370. // CreateDocumentInMemory
  371. //
  372. //    Create a document in a new memory container
  373. //------------------------------------------------------------------------------
  374. SOM_Scope void  SOMLINK DocumentManagerCreateDocumentInMemory(
  375.                     DocumentManager *somSelf, 
  376.                                         Environment *ev, ODType kindName)
  377. {
  378.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  379.     DocumentManagerMethodDebug("DocumentManager",
  380.                 "DocumentManagerCreateDocumentInMemory");
  381.  
  382.     char *rootPartNameStr = kODNULL;
  383.     ODIText *rootPartName = kODNULL;
  384.  
  385.     // Cache the kindname
  386.     strcpy(_fPartKindName, kindName);
  387.  
  388.     try
  389.     {
  390.         // Create a new memory container
  391.         somSelf->NewMemoryContainer(ev, &_fContainer);
  392.  
  393.         // Create a new document in the new container and externalize it
  394.         somSelf->CreateDocument(ev, _fContainer, kindName);
  395.  
  396.         // Get the newly created document from the memory container.
  397.         //
  398.         // Note: For memory container, the container is not acquired
  399.         //      again in OpenMemoryContainer. So the container created
  400.         //      in CreatedMemoryContainer is not released.
  401.         somSelf->OpenContainer(ev, _fContainer);
  402.  
  403.         // Install Shell Plug-in
  404.         InstallShellPlugIn(ev, _fDraft);
  405.  
  406.         // Open the root part of the document
  407.         char *rootPartKind = somSelf->OpenRootPart(ev);
  408.  
  409.         // Display root part kind as the window title
  410.         // Note: If kODPropName is not set by the part, then use the
  411.         //       rootPartKind returned from OpenRootPart as the text
  412.         //       in window title. 
  413.         TempODStorageUnit rootSU = ODAcquireRootPartSUOfDraft(ev, _fDraft);
  414.         rootPartName = ODGetITextProp(ev, rootSU, kODPropName, 
  415.                                                kODPlatformIText, kODNULL);
  416.         if (rootPartName)
  417.         {
  418.            ODULong strLength = GetITextStringLength(rootPartName);
  419.            rootPartNameStr = new char[strLength+1];
  420.            GetITextString(rootPartName, rootPartNameStr);
  421.         }
  422.         else
  423.            // Note: Use rootPartKind returned from OpenRootPart not 
  424.            //       kindName passed in because OpenRootPart may fail
  425.            //       and open NoPart instead.
  426.            rootPartNameStr = rootPartKind;
  427.         
  428.         if (rootPartNameStr) 
  429.         {
  430.             _fWindowState->SetLongName(ev, rootPartNameStr);
  431.             _fWindowState->SetDefaultWindowTitles(ev, _fDraft);
  432.         }
  433.     }
  434.     catch (ODException _exception)
  435.     {
  436.         LOG("SOM exception occured in DocumentManager::CreateDocumentInMemory\n");
  437.         ODError error = ErrorCode();
  438.         if (_fContainer)
  439.            SaveAndRestoreEv1(_fContainer);
  440.         ODSetSOMException(ev, error);
  441.     }
  442.  
  443.     if (rootPartNameStr)
  444.        delete[] rootPartNameStr;
  445.  
  446.     if (rootPartName)
  447.        DisposeIText(rootPartName);
  448. }
  449.  
  450. //------------------------------------------------------------------------------
  451. // CreateDocumentAsStationery
  452. //
  453. //    Create a document in a new file container and mark the document as
  454. //      stationery
  455. //------------------------------------------------------------------------------
  456. SOM_Scope void  SOMLINK DocumentManagerCreateDocumentAsStationery(
  457.                     DocumentManager *somSelf, 
  458.                                         Environment *ev, ODType kindName,
  459.                     char *filename)
  460. {
  461.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  462.     DocumentManagerMethodDebug("DocumentManager",
  463.                 "DocumentManagerCreateDocumentAsStationery");
  464.  
  465.     PlatformFile *file = kODNULL;
  466.  
  467.     // Cache the kindname and filename
  468.     strcpy(_fFileName, filename);
  469.     strcpy(_fPartKindName, kindName);
  470.  
  471.     try
  472.     {
  473.         // Create a new container in a file - filename may be "uniquified"
  474.         file = somSelf->NewFileContainer(ev, &_fContainer, _fFileName);
  475.         file->GetAsciiName(_fFileName, FILE_LENGTH - 1);
  476.  
  477.         // Create a new document in the new container and externalize it
  478.         somSelf->CreateDocument(ev, _fContainer, kindName);
  479.  
  480.         // Acquire new document and draft. CreateDocument method releases
  481.         // the document and draft it acquired before returned to caller.
  482.         _fDocument = _fContainer->AcquireDocument(ev, kODDefaultDocument);
  483.         _fDraft = _fDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  484.  
  485.         // Mark the document as stationery
  486.         somSelf->SetStationery(ev, _fDraft);
  487.  
  488.         // Write out draft
  489.         _fDraft->Externalize(ev);
  490.  
  491.         ODReleaseObject(ev, _fDraft);
  492.         ODReleaseObject(ev, _fDocument);
  493.         ODReleaseObject(ev, _fContainer);
  494.     }
  495.     catch (ODException _exception)
  496.     {
  497.         LOG("SOM exception occured in DocumentManager::CreateDocumentAsStationery\n");
  498.         ODError error = ErrorCode();
  499.         if (file)
  500.            delete file;
  501.         if (_fDraft || _fDocument || _fContainer)
  502.            SaveAndRestoreEv3(_fDraft, _fDocument, _fContainer);
  503.         ODSetSOMException(ev, error);
  504.     }
  505.  
  506. }
  507.  
  508. //------------------------------------------------------------------------------
  509. // NewFileContainer
  510. //
  511. //    Create a new file container with a unique name
  512. //------------------------------------------------------------------------------
  513. SOM_Scope PlatformFile*  SOMLINK DocumentManagerNewFileContainer(
  514.                     DocumentManager *somSelf, 
  515.                                         Environment *ev, 
  516.                     ODContainer **container,
  517.                     char *filename)
  518. {
  519.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  520.     DocumentManagerMethodDebug("DocumentManager",
  521.                     "DocumentManagerNewFileContainer");
  522.  
  523.     PlatformFile *file = kODNULL;
  524.  
  525.     try
  526.     {
  527.         // Create a uniquely named file
  528.         file = somSelf->CreateUntitledFile(ev, filename);
  529.  
  530.     // If problem creating untitled file in current directory, create
  531.     // untitled file in directory set in ODTMP.
  532.     if (!file)
  533.         file = somSelf->CreateUntitledFile(ev, _fFileName);
  534.  
  535.         // Create a new file container
  536.         if (file)
  537.         (*container) = CreateFileContainer(ev, _fSession, 
  538.                         &(file->GetFileSpec()));
  539.  
  540.     }
  541.     catch (ODException _exception)
  542.     {
  543.         LOG("SOM exception occured in DocumentManager::NewFileContainer\n");
  544.         if (file)
  545.            delete file;
  546.         file = kODNULL;
  547.     ODSetSOMException(ev, _exception);
  548.     }
  549.  
  550.     return file;
  551. }
  552.  
  553. //------------------------------------------------------------------------------
  554. // NewMemoryContainer
  555. //
  556. //    Create a new memory container
  557. //------------------------------------------------------------------------------
  558. SOM_Scope void  SOMLINK DocumentManagerNewMemoryContainer(
  559.                         DocumentManager *somSelf,
  560.                         Environment *ev,
  561.                         ODContainer** container)
  562. {
  563.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  564.     DocumentManagerMethodDebug("DocumentManager",
  565.                     "DocumentManagerNewMemoryContainer");
  566.     ODHandle containerHandle;
  567.  
  568.     try
  569.     {
  570.         containerHandle = ODNewHandle(0);
  571.         ASSERTMSG((containerHandle != 0), kODErrOpeningMemContainer,
  572.          "Error allocating document memory container",AMSG_500);
  573.  
  574.         *container = CreateMemoryContainer(ev, _fSession, containerHandle,
  575.                 kODDefaultMemoryContainer);
  576.  
  577.     }
  578.     catch (ODException _exception)
  579.     {
  580.         LOG("SOM exception occured in DocumentManager::NewMemoryContainer\n");
  581.         if (containerHandle)
  582.             ODDisposeHandle(containerHandle);
  583.         *container = kODNULL;
  584.     ODSetSOMException(ev, _exception);
  585.     }
  586.  
  587. }
  588.  
  589. //------------------------------------------------------------------------------
  590. // CreateDocument
  591. //
  592. //    Initialize a document in a new container
  593. //------------------------------------------------------------------------------
  594. SOM_Scope void  SOMLINK DocumentManagerCreateDocument(DocumentManager *somSelf, 
  595.                                                  Environment *ev, 
  596.                                                  ODContainer* newContainer,
  597.                          ODType partKind)
  598. {
  599.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  600.     DocumentManagerMethodDebug("DocumentManager",
  601.                     "DocumentManagerCreateDocument");
  602.  
  603.     try
  604.     {
  605.         // Get the document from the container and base draft from the document
  606.         TempODDocument newDocument = newContainer->AcquireDocument(ev, 
  607.                         kODDefaultDocument);
  608.  
  609.     // Set the current document so that when GetDocumentManagerOfDraft
  610.     // is called the current document is set.
  611.     _fDocument = newDocument;
  612.  
  613.         TempODDraft newDraft = newDocument->AcquireBaseDraft(ev, 
  614.                                                          kODDPExclusiveWrite);
  615.  
  616.         // Modify timestamp and user properties for draft
  617.         TempODStorageUnit draftSU = newDraft->AcquireDraftProperties(ev);
  618.         somSelf->ResetDateModByInfo(ev, draftSU);
  619.  
  620.         // Create the root part
  621.         TempODPart rootPart = newDraft->CreatePart(ev, partKind, kODNULL);
  622.         TempODStorageUnit su = rootPart->GetStorageUnit(ev);
  623.     if (su)
  624.     {
  625.         // Need to acquire the storage unit. The storage unit
  626.         // returned by GetStorageUnit does not increment the
  627.         // refcount.
  628.         su->Acquire(ev);
  629.             ODSetRootPartSUOfDraft(ev, newDraft, su);
  630.     }
  631.  
  632.         // Modify timestamp and user properties for root part
  633.         somSelf->ResetDateModByInfo(ev, su);
  634.  
  635.         // Close the document (can't FinalRelease the part since it may have a
  636.         // refcount > 1 upon creation, e.g. some might register for idle time, 
  637.         // etc.
  638.         newDraft->Externalize(ev);
  639.  
  640.     // Reset the current document to null
  641.     _fDocument = kODNULL;
  642.  
  643.     }
  644.     catch (ODException _exception)
  645.     {
  646.         LOG("SOM exception occured in DocumentManager::CreateDocument\n");
  647.     ODSetSOMException(ev, _exception);
  648.     }
  649.  
  650. }
  651.  
  652. //------------------------------------------------------------------------------
  653. // OpenFile
  654. //
  655. //    Get the container, document and top draft from the platform file.
  656. //    If we've got stationery then open a copy of the file instead.
  657. //------------------------------------------------------------------------------
  658. SOM_Scope void  SOMLINK DocumentManagerOpenFile(DocumentManager *somSelf, 
  659.                                                  Environment *ev, 
  660.                                                  PlatformFile* file,
  661.                          ODUShort actionFlag)
  662. {
  663.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  664.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerOpenFile");
  665.  
  666.     PlatformFile *newFile = kODNULL;
  667.  
  668.     try
  669.     {
  670.         ODFileAttrFlags fileAttrs;
  671.  
  672.         // If file is readonly, set file draft permission to read only.
  673.         file->GetFileAttributes(&fileAttrs);
  674.         if (fileAttrs & kODFileAttrReadOnly)
  675.            _fDraftPermissions = kODDPReadOnly;
  676.  
  677.         // Get the container, document, and top draft
  678.         _fContainer = GetFileContainer(ev, _fSession, &(file->GetFileSpec()));
  679.         _fDocument = _fContainer->AcquireDocument(ev, kODDefaultDocument);
  680.  
  681.     // Setting draft permission to read so that a new version won't be
  682.     // created. 
  683.         _fDraft = _fDocument->AcquireDraft(ev,  kODDPReadOnly, 0, 
  684.                     kODNULL, kODPosTop, kODFalse);
  685.     }
  686.     catch (ODException _exception)
  687.     {
  688.            char  fileName[FILE_LENGTH];
  689.            file->GetAsciiName(fileName, FILE_LENGTH - 1); 
  690.         
  691.         ODError error = ErrorCode();
  692.  
  693.         if (error == kODErrDraftDoesNotExist)
  694.        WARNMSG(WARN_INDEX(AMSG_901), 
  695.         "CPPOD0404 - Docshell: File %s is not a valid OpenDoc file.", fileName);
  696.         else
  697.        WARNMSG(WARN_INDEX(AMSG_862), 
  698.         "CPPOD0347 - Docshell: Error opening file %s.", fileName);
  699.  
  700.         if (_fDraft || _fDocument || _fContainer)
  701.            SaveAndRestoreEv3(_fDraft, _fDocument, _fContainer);
  702.         ODSetSOMException(ev, error);
  703.     return;
  704.     }
  705.  
  706.     try
  707.     {
  708.         // If file is a stationery and not a request to open the stationery, 
  709.         // then save a copy of the stationery to a new file.
  710.         if ((somSelf->IsStationery(ev, _fDraft)) && 
  711.             (actionFlag != kODEditStationery))
  712.         {
  713.            newFile = somSelf->CopyStationery(ev);
  714.            somSelf->OpenFile(ev, newFile, kODNULL);
  715.  
  716.               char  fileName[FILE_LENGTH];
  717.            // Cache the new file name
  718.            newFile->GetAsciiName(fileName, FILE_LENGTH - 1); 
  719.            strcpy(_fFileName, fileName);
  720.  
  721.            delete newFile;
  722.            newFile = kODNULL;
  723.         }
  724.         else
  725.            // Create working draft
  726.            somSelf->CreateWorkingDraft(ev);
  727.     }
  728.     catch (ODException _exception)
  729.     {
  730.         LOG("SOM exception occured in DocumentManager::OpenFile\n");
  731.         ODError error = ErrorCode();
  732.         if (newFile)
  733.            delete newFile;
  734.         if (_fDraft || _fDocument || _fContainer)
  735.            SaveAndRestoreEv3(_fDraft, _fDocument, _fContainer);
  736.         ODSetSOMException(ev, error);
  737.     }
  738. }
  739.  
  740.  
  741. //------------------------------------------------------------------------------
  742. // CopyStationery
  743. //
  744. //    Create a new document file and save the top most draft of the 
  745. //      stationery to the new document.
  746. //------------------------------------------------------------------------------
  747. SOM_Scope PlatformFile* SOMLINK DocumentManagerCopyStationery(
  748.                                                  DocumentManager *somSelf, 
  749.                                                  Environment *ev) 
  750. {
  751.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  752.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerCopyStationery");
  753.  
  754.     PlatformFile *newFile = kODNULL;
  755.  
  756.     try
  757.     {
  758.        ODContainer *tmpContainer;
  759.        TempODContainer stationeryContainer = _fContainer;
  760.        TempODDocument  stationeryDocument = _fDocument;
  761.        TempODDraft     stationeryDraft = _fDraft;
  762.  
  763.        _fContainer = kODNULL;
  764.        _fDocument  = kODNULL;
  765.        _fDraft     = kODNULL;
  766.  
  767.        // Reset draft permission to the default value
  768.        _fDraftPermissions = kODDPExclusiveWrite;
  769.  
  770.        // Create a new file container
  771.        newFile = somSelf->NewFileContainer(ev, 
  772.                 &tmpContainer, UNTITLED_FILENAME);
  773.        TempODContainer newContainer = tmpContainer;
  774.  
  775.        // Create a new document in the newly created file container
  776.        TempODDocument newDoc = newContainer->AcquireDocument(ev, 
  777.                                               kODDefaultDocument);
  778.  
  779.        // Copy the topmost draft of the stationery to the base draft
  780.        // of the new document
  781.        newDoc->SetBaseDraftFromForeignDraft(ev, stationeryDraft);
  782.  
  783.        // Get a reference of the base draft with write permission
  784.        TempODDraft newDraft = newDoc->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  785.     
  786.        // Remove stationery property
  787.        somSelf->UnsetStationery(ev, newDraft);
  788.  
  789.        // Modify timestamp and user properties
  790.        {
  791.            TempODStorageUnit rootsu = ODAcquireRootPartSUOfDraft(ev, 
  792.                                 newDraft);
  793.            // Note: Need to get the root part kind before calling
  794.            // ResetDateModByInfo
  795.            char *partKindName = ODGetKindFromPartSU(ev,rootsu);
  796.            if (partKindName)
  797.               strcpy(_fPartKindName, partKindName);
  798.            somSelf->ResetDateModByInfo(ev, rootsu); 
  799.  
  800.            TempODStorageUnit su = newDraft->AcquireDraftProperties(ev);
  801.            somSelf->ResetDateModByInfo(ev, su); 
  802.        }
  803.  
  804.        // Save the base draft 
  805.        newDraft->Externalize(ev);
  806.  
  807.    }
  808.    catch (ODException _exception)
  809.    {
  810.       WARNMSG(WARN_INDEX(AMSG_863), 
  811.         "CPPOD0348 - Docshell: Error creating file from stationery.");
  812.       if (newFile)
  813.          delete newFile;
  814.       newFile = kODNULL;
  815.       ODSetSOMException(ev, _exception);
  816.    }
  817.  
  818.    return newFile;
  819. }
  820.  
  821. //------------------------------------------------------------------------------
  822. // OpenContainer
  823. //------------------------------------------------------------------------------
  824. SOM_Scope void  SOMLINK DocumentManagerOpenContainer(
  825.                                                 DocumentManager *somSelf,
  826.                                                  Environment *ev,
  827.                                                  ODContainer* container)
  828. {
  829.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  830.     DocumentManagerMethodDebug("DocumentManager",
  831.                                         "DocumentManagerOpenContainer");
  832.  
  833.     try
  834.     {
  835.         // Get the document and top draft from the memory container
  836.         _fContainer = container;
  837.         _fDocument = _fContainer->AcquireDocument(ev, kODDefaultDocument);
  838.         _fDraft = _fDocument->AcquireDraft(ev, _fDraftPermissions, 0, kODNULL,
  839.                                         kODPosTop, kODFalse);
  840.  
  841.         // Create working draft
  842.         somSelf->CreateWorkingDraft(ev);
  843.  
  844.     }
  845.     catch (ODException _exception)
  846.     {
  847.         LOG("SOM exception occured in DocumentManager::OpenContainer\n");
  848.         ODError error = ErrorCode();
  849.         if (_fDraft || _fDocument || _fContainer)
  850.            SaveAndRestoreEv3(_fDraft, _fDocument, _fContainer);
  851.         ODSetSOMException(ev, error);
  852.     }
  853.  
  854. }
  855.  
  856.  
  857. //------------------------------------------------------------------------------
  858. // CreateWorkingDraft
  859. //
  860. //    Create a working draft on top of current draft
  861. //------------------------------------------------------------------------------
  862. SOM_Scope void  SOMLINK DocumentManagerCreateWorkingDraft(
  863.                                            DocumentManager *somSelf,
  864.                                            Environment *ev)
  865. {
  866.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  867.     DocumentManagerMethodDebug("DocumentManager",
  868.                                  "DocumentManagerCreateWorkingDraft");
  869.  
  870.     try
  871.     {
  872.         // Create working draft on top of current most draft so that  
  873.         // saving a modified draft which has a draft created on it
  874.         // before the changes won't corrupt the draft.
  875.         if (somSelf->HasWriteAccess(ev))
  876.         {
  877.            _fDraft = _fDocument->CreateDraft(ev, _fDraft, kODTrue);
  878.  
  879.        if (_fDraft->GetPermissions(ev) != _fDraftPermissions)
  880.               // Release the current draft and get a reference of the
  881.               // draft again with the specified draft permission
  882.               //
  883.               // Note: The new working draft is set to have kODDPExclusiveWrite
  884.           //    permission by default.
  885.               _fDraft = _fDocument->AcquireDraft(ev, _fDraftPermissions, 
  886.                 kODNULLID, _fDraft, kODPosSame, kODTrue);
  887.  
  888.        // Notify link manager that this draft is opened
  889. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_UNIX_)
  890.        _fSession->GetLinkManager(ev)->DraftOpened(ev, _fDraft);
  891. #elif defined(_PLATFORM_OS2_)
  892.            _fSession->GetLinkService(ev)->
  893.                            DraftOpened(ev, _fDraft, kODFalse, _fFileName);
  894. #endif 
  895.         }
  896.  
  897.    }
  898.    catch (ODException _exception)
  899.    {
  900.         LOG("SOM exception occured in DocumentManager::CreateWorkingDraft\n");
  901.     ODSetSOMException(ev, _exception);
  902.    }
  903.  
  904. }
  905.  
  906.  
  907. //------------------------------------------------------------------------------
  908. // OpenRootPart
  909. //
  910. //    Acquire the root part of the document and invoke its Open method
  911. //------------------------------------------------------------------------------
  912. SOM_Scope char*  SOMLINK DocumentManagerOpenRootPart(DocumentManager *somSelf,
  913.                                              Environment *ev)
  914. {
  915.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  916.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerOpenRootPart");
  917.  
  918.     char *rootPartKind = kODNULL;
  919.  
  920.     try
  921.     {
  922.         // Open the root part
  923.         _fWindowState->Internalize(ev, _fDraft);
  924.         _fWindowState->OpenWindows(ev, _fDraft);
  925.         if (_fWindowState->GetRootWindowCount(ev, _fDraft) == 0)
  926.         {
  927.             TempODPart rootPart = ODAcquireRootPartOfDraft(ev, _fDraft);
  928.             rootPart->Open(ev, kODNULL);
  929.         }
  930.  
  931.         // Get the root part kind to return
  932.     {
  933.         TempODStorageUnit su = ODAcquireRootPartSUOfDraft(ev, _fDraft);
  934.             rootPartKind = ODGetKindFromPartSU(ev,su);
  935.     }
  936.  
  937. #ifdef DEBUG
  938.     ODULong refcount = _fDraft->GetRefCount(ev);
  939. #endif
  940.  
  941.     }
  942.     catch (ODException _exception)
  943.     {
  944.         LOG("SOM exception occured in DocumentManager::OpenRootPart\n");
  945.     ODSetSOMException(ev, _exception);
  946.     }
  947.  
  948.     return rootPartKind;
  949.  
  950. }
  951.  
  952.  
  953. //------------------------------------------------------------------------------
  954. // CreateUntitledFile
  955. //
  956. //    Create a new platform file with a unique name
  957. //------------------------------------------------------------------------------
  958. SOM_Scope PlatformFile*  SOMLINK DocumentManagerCreateUntitledFile(
  959.                         DocumentManager *somSelf,
  960.                         Environment *ev,
  961.                         char *filename)
  962. {
  963.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  964.     DocumentManagerMethodDebug("DocumentManager",
  965.                     "DocumentManagerCreateUntitledFile");
  966.  
  967.     static retry = kODTrue;
  968.     PlatformFile*    file = kODNULL;
  969.  
  970.     try
  971.     {
  972.         // Default file name...
  973.     if (filename == kODNULL)
  974.         filename = UNTITLED_FILENAME;
  975.  
  976.         // Create a new PlatformFile
  977.         file = new PlatformFile;
  978.  
  979.         // Set the PlatformFile's name to the default
  980.         file->Specify((ODFileSpec *)filename);
  981.  
  982.         // Create a uniquely named file
  983.         file->UniquifyAndCreate(
  984.             kODShellSignature,    // creator
  985.             kODShellSignature,    // fileType
  986.             0,            // scriptCode
  987.             1,            // copyCount
  988.             kODTryCurrentName);    // forceNewName
  989.     }
  990.     catch (ODException _exception)
  991.     {
  992.     delete file;
  993.     file = kODNULL;
  994.     if (!retry)
  995.     {
  996.         // If attempted to create file in ODTMP is tried, print out
  997.         // a warning.
  998.             WARNMSG(WARN_INDEX(AMSG_858),"CPPOD0343 - Docshell: Problem creating file %s. Directory may be full or write-protected.", filename);
  999.         ODSetSOMException(ev, _exception);
  1000.     }
  1001.     else
  1002.     {
  1003.         // Setup untitled file to directory set in ODTMP
  1004.         retry = kODFalse;
  1005.         char *tmppath = getenv("ODTMP");
  1006.         if (tmppath != NULL)
  1007.                {
  1008.             strcpy(_fFileName, tmppath);
  1009.             if (strncmp(tmppath+strlen(tmppath)-1, PATH_SEPARATOR,
  1010.                      1) != 0)
  1011.                 strcat(_fFileName, PATH_SEPARATOR);
  1012.             strcat(_fFileName, UNTITLED_FILENAME);
  1013.  
  1014.             // Clear the error 
  1015.                    SetErrorCodeEv(ev, kODNoError);
  1016.         }
  1017.         else
  1018.         {
  1019.             // If ODTMP is not set, print out a warning.
  1020.                 WARNMSG(WARN_INDEX(AMSG_858),"CPPOD0343 - Docshell: Problem creating file %s. Directory may be full or write-protected.", filename);
  1021.             ODSetSOMException(ev, _exception);
  1022.         }
  1023.     }
  1024.  
  1025.     }
  1026.  
  1027.     return file;
  1028.  
  1029. }
  1030.  
  1031.  
  1032. //------------------------------------------------------------------------------
  1033. // SaveDocument
  1034. //
  1035. //    Save the document, taking care of Undo/Redo.
  1036. //------------------------------------------------------------------------------
  1037. SOM_Scope void  SOMLINK DocumentManagerSaveDocument(DocumentManager *somSelf, 
  1038.                                                      Environment *ev)
  1039. {
  1040.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1041.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerSaveDocument");
  1042.  
  1043.     try
  1044.     {
  1045.     if (_fSession)
  1046.     {
  1047.         ODUndo *Undo = _fSession->GetUndo(ev);
  1048.  
  1049.         // Clear the undo and redo stacks
  1050.         if (Undo)
  1051.         Undo->ClearActionHistory(ev, kODDontRespectMarks);
  1052.     }
  1053.  
  1054.     // Save the draft
  1055.     somSelf->SaveDraft(ev);
  1056.     if (_fDraft)
  1057.         // Note: After calling SaveToAPrevious, the draft is marked clean.
  1058.         _fDraft->SaveToAPrevious(ev, kODNULL);
  1059.  
  1060.         // Mark it as a saved document
  1061.         _fUnsavedDocument = kODFalse;
  1062.     }
  1063.     catch (ODException _exception)
  1064.     {
  1065.         LOG("SOM exception occured in DocumentManager::SaveDocument\n");
  1066.     ODSetSOMException(ev, _exception);
  1067.     }
  1068. }
  1069.  
  1070.  
  1071. //------------------------------------------------------------------------------
  1072. // CloseDocument
  1073. //
  1074. //    Save document, close all draft windows belonging to this document,
  1075. //    remove working draft, and release objects.
  1076. //------------------------------------------------------------------------------
  1077. SOM_Scope void  SOMLINK DocumentManagerCloseDocument(DocumentManager *somSelf, 
  1078.                                                       Environment *ev,
  1079.                               ODULong saveOption)
  1080. {
  1081.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1082.     DocumentManagerMethodDebug("DocumentManager",
  1083.                     "DocumentManagerCloseDocument");
  1084.  
  1085.     ODWindowIterator *iter = kODNULL;
  1086.     ODWindow         *curWindow, *nextWindow;
  1087.     PlatformFile     *file; 
  1088.  
  1089.     try
  1090.     {
  1091.  
  1092.     // Saves the document if user chooses to save the changes to
  1093.     // the document before exit
  1094.     if (saveOption == kODCommandSaveChanges)
  1095.         somSelf->SaveDocument(ev);
  1096.  
  1097.     // Close windows of all drafts belonging to this document
  1098.         //
  1099.         // Note: If the current window returned by the window iterator
  1100.         //    is closed, the window iterator will be out of sync. To
  1101.         //     take care of this, start the iterator from the beginning.
  1102.         //    This is a performance hit if we've lots of windows at the
  1103.         //    beginning of the iterator that don't belong to this document. 
  1104.         iter = _fWindowState->CreateWindowIterator(ev);
  1105.     curWindow = iter->First(ev);
  1106.         while (iter->IsNotComplete(ev))
  1107.         {
  1108.             if (somSelf->CloseWindow(ev, curWindow->GetPlatformWindow(ev),
  1109.                                         kODFalse))
  1110.            curWindow = iter->First(ev);
  1111.         else
  1112.                curWindow = iter->Next(ev);
  1113.         }
  1114.     ODDeleteObject(iter);
  1115.  
  1116.     // Remove the working draft from document
  1117.     // Note: Changes made to the working draft should already be
  1118.     //    saved if user chooses to save changes before exit. In
  1119.     //     this case, the working draft is empty. Otherwise, the
  1120.     //    changes in the working draft is discarded and the working
  1121.     //    draft is removed from the document.
  1122.     somSelf->RemoveChanges(ev, _fDraft);
  1123.  
  1124.         // Get name of document file to be deleted 
  1125.         if (_fUnsavedDocument)
  1126.            file = GetPlatformFileFromContainer(ev, _fContainer);
  1127.  
  1128.     // Release the document and container objects
  1129.     ODFinalReleaseObject(ev, _fDocument);
  1130. #if DEBUG
  1131.         ODULong refcount = _fContainer->GetRefCount(ev);
  1132. #endif
  1133.     ODFinalReleaseObject(ev, _fContainer);
  1134.  
  1135.         // Delete the unsaved document file
  1136.         if (_fUnsavedDocument)
  1137.            file->Delete();
  1138.  
  1139. #ifdef _PLATFORM_WIN32_
  1140.     // if there's a wrapper associated with the document manager,
  1141.     // tell it we're going away.  Do this last or other methods
  1142.     // above will cause another wrapper to be created through
  1143.     // the GetOleWrapper interface.
  1144.         //
  1145.         // SetOleWrapper now does an AddRef (when set) and Release 
  1146.         // when NULL'ed, so that the wrapper remains in existance until 
  1147.         // OpenDoc has closed this document. This will avoid additional
  1148.         // wrappers being instantiated just for closing this document.
  1149.  
  1150.     if (_fOleWrapper) {
  1151.         _fOleWrapper->SetDocumentManager(NULL);
  1152.             somSelf->SetOleWrapper(ev, NULL);
  1153.     }
  1154. #endif
  1155.  
  1156.     }
  1157.     catch (ODException _exception)
  1158.     {
  1159.         LOG("SOM exception occured in DocumentManager::CloseDocument\n");
  1160.         if (iter)
  1161.            ODDeleteObject(iter);
  1162.     ODSetSOMException(ev, _exception);
  1163.     }
  1164.  
  1165. }
  1166.  
  1167.  
  1168. //------------------------------------------------------------------------------
  1169. // CloseWindow
  1170. //
  1171. //    Close window belong to the current active document manager. For
  1172. //    non-root window, close the window. For root window containing
  1173. //    intermediate draft with readonly permission only, close the
  1174. //    draft and release the draft object. For root window containing
  1175. //    the working draft, if caller requests to confirm
  1176. //    the removal of the window, returns to caller. Otherwise
  1177. //    close the draft and release the draft object.
  1178. //------------------------------------------------------------------------------
  1179.  
  1180. SOM_Scope ODBoolean  SOMLINK DocumentManagerCloseWindow(
  1181.                         DocumentManager *somSelf, 
  1182.                                                 Environment *ev,
  1183.                         ODPlatformWindow platWindow,
  1184.                         ODBoolean confirm)
  1185. {
  1186. //  if confirm is set to kODTrue, the actual closing of the draft
  1187. //  and window is not performed if the window containing the current
  1188. //  draft (stored in _fDraft) is closed. Instead this function returns 
  1189. //  kODTrue to the caller to inform caller that this is such case. The 
  1190. //  caller can then call CloseDocument to close windows belonging to this
  1191. //  document and release its draft objects.
  1192. //
  1193. //  if confirm is set to kODFalse, this function returns kODTrue if
  1194. //  closing of window(s) takes place. Otherwise this function returns
  1195. //  kODFalse.
  1196.  
  1197.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1198.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerCloseWindow");
  1199.  
  1200.     ODDraft        *winDraft;
  1201.     ODBoolean        result = kODFalse;
  1202.  
  1203.     try
  1204.     {
  1205.  
  1206.     // Get the ODWindow for the platform window that will be closed
  1207.     if (platWindow && _fWindowState 
  1208.                 && (_fWindowState->IsODWindow(ev, platWindow)))
  1209.         {
  1210.         TempODWindow window = _fWindowState->AcquireODWindow(ev,platWindow);
  1211.           ASSERTMSG(window != kODNULL, kODErrClosingNonODWindow, 
  1212.               "Docshell: Window to be closed does not belong to OpenDoc.", 
  1213.               AMSG_460);
  1214.  
  1215.         // Get the draft for the ODWindow 
  1216.         winDraft = window->GetDraft(ev);
  1217.             ASSERTMSG(winDraft != kODNULL, kODErrNoDraftInWindow, 
  1218.           "Docshell: Window to be closed has no draft in it.", AMSG_470);
  1219.  
  1220.             // Get the document for the draft and determines
  1221.             // if the document belongs to the current 
  1222.             // active document manager.
  1223.             //
  1224.             // Note: The active document manager is set by the
  1225.             // activate event.
  1226.         if (winDraft && (winDraft->GetDocument(ev) == _fDocument))
  1227.         {
  1228.             // Determine if it is the root draft that is being 
  1229.               // closed or some other window
  1230.             ODBoolean isRootWindow = window->IsRootWindow(ev);
  1231.             ODBoolean isDraftRootWindow = isRootWindow &&
  1232.             (_fWindowState->GetRootWindowCount(ev, winDraft) == 1);
  1233.             if (isDraftRootWindow)
  1234.             {
  1235.                 // if current draft (_fDraft) is closed and 
  1236.                     // caller requests to confirm the close, 
  1237.                     // return to caller.
  1238.                     // Note: Caller should check the return code 
  1239.                     //       returned by CloseWindow. If return
  1240.                     //       code is kODTrue, then call CloseDocument
  1241.                     //       to close all draft and window objects
  1242.                     //       belonging to the current document and
  1243.                     //       close down the current active manager.
  1244.                 if (winDraft == _fDraft)
  1245.                 {
  1246.                if (confirm)
  1247.                   result = kODTrue;
  1248.                 }
  1249.  
  1250.                     if (result == kODFalse)
  1251.                     {
  1252.                       // Close the draft and release object
  1253.             // Note: the draft acquired by window is released
  1254.             //    when the window is closed.
  1255.                     somSelf->CloseDraft(ev, winDraft);
  1256. #ifdef DEBUG
  1257.                     ODULong refcnt = _fDraft->GetRefCount(ev);
  1258. #endif
  1259.             if (!confirm)
  1260.                result = kODTrue;
  1261.                 }
  1262.     
  1263.                  }
  1264.              else
  1265.              {
  1266.                 // Other ODWindows, simply close and remove the 
  1267.                     // window object.
  1268.             //
  1269.             // Note: Need to actually acquire the window and not
  1270.             //    releasing it because CloseAndRemove releases it.
  1271.             window->Acquire(ev);
  1272.                 window->CloseAndRemove(ev);
  1273.             if (!confirm)
  1274.             result = kODTrue;
  1275.              }    
  1276.              }
  1277.         }
  1278.  
  1279.     }
  1280.     catch (ODException _exception)
  1281.     {
  1282.         LOG("SOM exception occured in DocumentManager::CloseWindow\n");
  1283.     result = kODFalse;
  1284.     ODSetSOMException(ev, _exception);
  1285.     }
  1286.  
  1287.     return result;
  1288. }
  1289.             
  1290.  
  1291. //------------------------------------------------------------------------------
  1292. // CreateDraft
  1293. //
  1294. //    Save the current working draft and create a new working draft
  1295. //------------------------------------------------------------------------------
  1296. SOM_Scope void  SOMLINK DocumentManagerCreateDraft(DocumentManager *somSelf, 
  1297.                                                 Environment *ev,
  1298.                         ODULong draftNum,
  1299.                         ODIText *modUser,
  1300.                         ODIText *comment)
  1301. {
  1302.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1303.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerCreateDraft");
  1304.  
  1305.     try
  1306.     {
  1307.  
  1308.         if (somSelf->HasWriteAccess(ev))
  1309.         {
  1310.             {
  1311.                 ODTime savedDate;
  1312.  
  1313.                 // Set the draft properties
  1314.                 TempODStorageUnit su = _fDraft->AcquireDraftProperties(ev);
  1315.  
  1316.                 if (modUser)
  1317.                     ODSetITextProp(ev, su, kODPropModUser, 
  1318.                         kODPlatformIText, modUser);
  1319.                 if (comment)
  1320.                     ODSetITextProp(ev, su, kODPropDraftComment, 
  1321.                         kODPlatformIText, comment);
  1322.  
  1323.                 time((time_t *)(&savedDate));
  1324.                 ODSetTime_TProp(ev, su, kODPropDraftSavedDate, 
  1325.                         kODTime_T, savedDate);
  1326.                 ODSetULongProp(ev, su, kODPropDraftNumber, 
  1327.                                     kODULong, draftNum); 
  1328.             }
  1329.  
  1330.             // Save the document and close the current draft
  1331.             somSelf->SaveDocument(ev);
  1332.  
  1333. #ifdef DEBUG
  1334.         ODULong refcnt = _fDraft->GetRefCount(ev);
  1335. #endif
  1336.         // Note: Before calling CloseDraft, the refcount of 
  1337.         //  current working draft is 2 (the first reference is
  1338.             //  is obtained in CreateWorkingDraft and the second reference
  1339.             //  is obtained after calling rootPart->Open in OpenRootPart).
  1340.         //  After calling CloseWindows in CloseDraft, the refcount
  1341.         //  of current working draft is down to 1 (the draft reference
  1342.         //  acquired by window is released when window is closed).
  1343.         //  With the release done in CreateDraft below, the refcount
  1344.         //  for this draft will reduce to 0.
  1345.             somSelf->CloseDraft(ev, _fDraft);
  1346.  
  1347. #ifdef DEBUG
  1348.         refcnt = _fDraft->GetRefCount(ev);
  1349. #endif
  1350.  
  1351.         // Create a new working draft.
  1352.         // Note: This create releases the refcount for the current
  1353.         //    draft before creating a new draft. 
  1354.         _fDraft = _fDocument->CreateDraft(ev, _fDraft, kODTrue);
  1355.         
  1356.         if (_fDraft)
  1357.             {
  1358.                 {
  1359.                     TempODStorageUnit su = _fDraft->AcquireDraftProperties(ev);
  1360.  
  1361.                 // Reset timestamp and user properties
  1362.                     somSelf->ResetDateModByInfo(ev, su); 
  1363.             // Reset drop number to 0
  1364.                        ODSetULongProp(ev, su, kODPropDraftNumber, 
  1365.                                     kODULong, 0L); 
  1366.                 }
  1367.         
  1368. #ifdef DEBUG
  1369.             refcnt = _fDraft->GetRefCount(ev);
  1370. #endif
  1371.             // Open the draft
  1372.                    // Note: The refcount for this draft will be 2
  1373.                 //    after calling OpenDraft
  1374.             somSelf->OpenDraft(ev, _fDraft, kODFalse);
  1375.  
  1376.             somSelf->SaveDocument(ev);
  1377.  
  1378. #ifdef DEBUG
  1379.             refcnt = _fDraft->GetRefCount(ev);
  1380. #endif
  1381.         }
  1382.  
  1383.     }
  1384.  
  1385.     }
  1386.     catch (ODException _exception)
  1387.     {
  1388.         LOG("SOM exception occured in DocumentManager::CreateDraft\n");
  1389.     ODSetSOMException(ev, _exception);
  1390.     }
  1391.  
  1392.     return;
  1393. }
  1394.  
  1395.  
  1396. //------------------------------------------------------------------------------
  1397. // OpenDraft
  1398. //
  1399. //    Read in draft's window and frame information and open its windows.
  1400. //    If request by caller, the reference to draft is released.
  1401. //
  1402. //    Note: Caller needs to acquire a reference to the draft before
  1403. //        calling this method
  1404. //------------------------------------------------------------------------------
  1405. SOM_Scope ODBoolean  SOMLINK DocumentManagerOpenDraft(
  1406.                           DocumentManager *somSelf, 
  1407.                                                   Environment *ev,
  1408.                           ODDraft     *draft,
  1409.                           ODBoolean   toBeRelease)
  1410. {
  1411.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1412.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerOpenDraft");
  1413.  
  1414.     ODBoolean result = kODTrue;
  1415.  
  1416.     try
  1417.     {
  1418.  
  1419.     ODBoolean       windowsOpen = kODFalse;
  1420.  
  1421.     // Notify link manager that this draft is opened
  1422. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_UNIX_)
  1423.     _fSession->GetLinkManager(ev)->DraftOpened(ev, draft);
  1424. #elif defined(_PLATFORM_OS2_)
  1425.     _fSession->GetLinkService(ev)->
  1426.                         DraftOpened(ev, draft, kODFalse, _fFileName);
  1427. #endif
  1428.  
  1429.     // Read in all root frames for this draft
  1430.     _fWindowState->Internalize(ev, draft);
  1431.  
  1432.     // Open all windows belonging to this draft
  1433.     _fWindowState->OpenWindows(ev, draft);
  1434.  
  1435.     windowsOpen = (_fWindowState->GetRootWindowCount(ev, draft)>0);
  1436.  
  1437.     if (!windowsOpen)
  1438.     {
  1439.         TempODPart    rootPart = ODAcquireRootPartOfDraft(ev, draft);
  1440.         rootPart->Open(ev, kODNULL);
  1441.  
  1442.         // For now, title is the same for all drafts 
  1443.         _fWindowState->SetDefaultWindowTitles(ev, draft);
  1444.     }
  1445.     
  1446.     // Release the reference to draft if request by caller
  1447.     if (toBeRelease)
  1448.         ODReleaseObject(ev, draft);
  1449.  
  1450.     }
  1451.     catch (ODException _exception)
  1452.     {
  1453.         LOG("SOM exception occured in DocumentManager::OpenDraft\n");
  1454.         result = kODFalse;
  1455.     ODSetSOMException(ev, _exception);
  1456.     }
  1457.  
  1458.     return result;
  1459.  
  1460. }
  1461.  
  1462.  
  1463. //------------------------------------------------------------------------------
  1464. // CloseDraft
  1465. //
  1466. //    Close the draft, clear the undo/redo stack, and close all
  1467. //    windows belonging to the draft.
  1468. //------------------------------------------------------------------------------
  1469. SOM_Scope void  SOMLINK DocumentManagerCloseDraft(DocumentManager *somSelf, 
  1470.                                                    Environment *ev,
  1471.                            ODDraft *draft)
  1472. {
  1473.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1474.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerCloseDraft");
  1475.  
  1476.     try
  1477.     {
  1478.  
  1479.     
  1480.     // Notify the link manager. If unsaved cross-document
  1481.     // links exist, the link manager breaks those links at
  1482.     // the source.
  1483. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_UNIX_)
  1484.     ODLinkManager *LinkMgr = _fSession->GetLinkManager(ev);
  1485.     if (LinkMgr)
  1486.         LinkMgr->DraftClosing(ev, draft);
  1487. #elif defined(_PLATFORM_OS2_)
  1488.     IODLinkService *LinkService = _fSession->GetLinkService(ev);
  1489.     if (LinkService)
  1490.         LinkService->DraftClosing(ev, draft);
  1491. #endif
  1492.  
  1493.     if (draft == _fDraft)
  1494.     {
  1495.         ODUndo *Undo = _fSession->GetUndo(ev);
  1496.  
  1497.         // Clear the undo and redo stacks
  1498.         if (Undo)
  1499.         Undo->ClearActionHistory(ev, kODDontRespectMarks);
  1500.     }
  1501.     
  1502.  
  1503.     // Notify Clipboard that this draft is to be closed
  1504.     ODClipboard *ClipBoard = _fSession->GetClipboard(ev);
  1505.     if (ClipBoard)
  1506.         ClipBoard->DraftClosing(ev, draft);
  1507.  
  1508.  
  1509.     // Notify DragAndDrop object that this draft is to be closed
  1510.     ODDragAndDrop *DragDrop = _fSession->GetDragAndDrop(ev);
  1511.     if (DragDrop)
  1512.         DragDrop->DraftClosing(ev, draft);
  1513.  
  1514.     // Close all windows belonging to this draft
  1515.     // Note: CloseWindows releases the draft acquired by the window
  1516.     if (_fWindowState)
  1517.         _fWindowState->CloseWindows(ev, draft);
  1518.  
  1519.     }
  1520.     catch (ODException _exception)
  1521.     {
  1522.         LOG("SOM exception occured in DocumentManager::CloseDraft\n");
  1523.     ODSetSOMException(ev, _exception);
  1524.     }
  1525.  
  1526.     return;
  1527. }
  1528.  
  1529.  
  1530. //------------------------------------------------------------------------------
  1531. // SaveDraft
  1532. //
  1533. //    Save the current draft, writing out its window and frame state
  1534. //    and persistent objects.
  1535. //------------------------------------------------------------------------------
  1536. SOM_Scope void  SOMLINK DocumentManagerSaveDraft(DocumentManager *somSelf, 
  1537.                                                   Environment *ev)
  1538. {
  1539.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1540.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerSaveDraft");
  1541.  
  1542.     try
  1543.     {
  1544.     // Save the window properties and frame of this draft
  1545.     if (_fWindowState)
  1546.         _fWindowState->Externalize(ev, _fDraft);
  1547.  
  1548.     // Save all persistent objects and storage units belonging
  1549.     // to this draft
  1550.     if (_fDraft)
  1551.         _fDraft->Externalize(ev);
  1552.  
  1553.     if (_fSession)
  1554.     {
  1555.         // Notify link manager to update cross-document links
  1556.         ODLinkManager *LinkMgr = _fSession-> GetLinkManager(ev);
  1557.         if (LinkMgr)
  1558.         LinkMgr->DraftSaved(ev, _fDraft);
  1559.  
  1560.         // Notify Clipboard that the draft has been saved
  1561.         ODClipboard *ClipBoard = _fSession->GetClipboard(ev);
  1562.         if (ClipBoard)
  1563.         ClipBoard->DraftSaved(ev, _fDraft);
  1564.     }
  1565.  
  1566.     }
  1567.     catch (ODException _exception)
  1568.     {
  1569.         LOG("SOM exception occured in DocumentManager::SaveDraft\n");
  1570.     ODSetSOMException(ev, _exception);
  1571.     }
  1572.  
  1573.     return;
  1574. }
  1575.  
  1576. //------------------------------------------------------------------------------
  1577. // DeleteDraft
  1578. //
  1579. //    Remove draft from document
  1580. //
  1581. //    Note: Caller needs to acquire a reference to the draft before
  1582. //        calling this method
  1583. //------------------------------------------------------------------------------
  1584. SOM_Scope ODBoolean  SOMLINK DocumentManagerDeleteDraft(
  1585.                             DocumentManager *somSelf, 
  1586.                                                     Environment *ev,
  1587.                             DraftInfoRec *draftInfoRec)
  1588. {
  1589.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1590.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerDeleteDraft");
  1591.  
  1592.     ODBoolean result = kODTrue;
  1593.     ODDraft   *fromDraft = kODNULL;
  1594.  
  1595.     if (!draftInfoRec)
  1596.        return kODFalse;
  1597.  
  1598.     // Get draft associated with the draft info record
  1599.     ODDraft *draft = draftInfoRec->GetDraft();
  1600.  
  1601.     if (!draft)
  1602.       return kODFalse;
  1603.  
  1604.     try
  1605.     {
  1606.  
  1607.     // Release the object which was acquired before calling 
  1608.     // DeleteDraft
  1609.     if (draft->GetRefCount(ev) > 1) ODRelease(ev, draft);
  1610.  
  1611.         if (draft->GetRefCount(ev) != 1)
  1612.         {
  1613.           // Check whether trying to delete open draft
  1614.       WARNMSG(WARN_INDEX(AMSG_480), 
  1615.                                    "Docshell: trying to delete open draft.");
  1616.  
  1617.           result = kODFalse;
  1618.         }
  1619.         else
  1620.         {
  1621.       if (!draft || draft == _fDraft)
  1622.         ; // can't delete current draft, this shouldn't happen!
  1623.       else
  1624.       {
  1625.         // Close the draft
  1626.         somSelf->CloseDraft(ev, draft);
  1627.  
  1628.         // Get draft above it
  1629.         ODDraft *fromDraft = _fDocument->AcquireDraft(ev,
  1630.                             kODDPReadOnly,
  1631.                             kODNULL,
  1632.                             draft,
  1633.                             kODPosFirstAbove,
  1634.                             kODFalse);
  1635.  
  1636.         // If draft above is open, close and open it again.
  1637.         // Otherwise, the window is pointing to the wrong draft.
  1638.         ODBoolean openDraftAbove = _fWindowState->GetRootWindowCount(ev,
  1639.                         fromDraft);
  1640.         if (openDraftAbove == kODTrue)
  1641.             somSelf->CloseDraft(ev, fromDraft);
  1642.  
  1643. #ifdef DEBUG
  1644.         ODULong refcount =  draft->GetRefCount(ev);
  1645. #endif
  1646.             // Check if draft above is in the draft history list. If not,
  1647.             // keep the reference, else release it.
  1648.             if (draftInfoRec->GetPrev())
  1649.                ODRelease(ev, fromDraft);
  1650.  
  1651. #ifdef DEBUG
  1652.         refcount =  draft->GetRefCount(ev);
  1653. #endif
  1654.     
  1655.         // Get the previous and next DraftInfoRec info
  1656.         // to update the draft list
  1657.         DraftInfoRec *prevDIR = draftInfoRec->GetPrev();
  1658.         DraftInfoRec *nextDIR = draftInfoRec->GetNext();
  1659.  
  1660.         // Get a reference to the draft. Otherwise, deleting the
  1661.         // draft's draftInfoRec deletes its last reference.
  1662.         draft = _fDocument->AcquireDraft(ev, kODDPReadOnly, kODNULL,
  1663.                     draft, kODPosSame, kODFalse);
  1664.         delete draftInfoRec; 
  1665. #ifdef DEBUG
  1666.         refcount =  draft->GetRefCount(ev);
  1667. #endif
  1668.  
  1669.         _fDocument->SaveToAPrevDraft(ev, fromDraft, draft);
  1670.         _fDocument->CollapseDrafts(ev, fromDraft, draft);
  1671.  
  1672.             // Note: fromDraft is no longer valid
  1673.             fromDraft = kODNULL;
  1674.         
  1675.         if (openDraftAbove == kODTrue)
  1676.         {
  1677. #ifdef DEBUG
  1678.         ODULong refcount = draft->GetRefCount(ev);
  1679. #endif
  1680.         somSelf->OpenDraft(ev, draft, kODFalse);
  1681.             
  1682. #ifdef DEBUG
  1683.         refcount = draft->GetRefCount(ev);
  1684. #endif
  1685.         }
  1686.  
  1687.         // Readjust the draft list
  1688.         if (prevDIR == kODNULL && nextDIR == kODNULL)
  1689.             {
  1690.         // Nothing in the draft list
  1691.         _fDraftList = kODNULL;
  1692.  
  1693.                 // Release the draft
  1694.                 draft->Release(ev);
  1695.             }
  1696.         else if (prevDIR == kODNULL)
  1697.         {
  1698.         // The deleted draft is head of the draft list,
  1699.         // reset head of the draft list.
  1700.         nextDIR->SetPrev(kODNULL);
  1701.         _fDraftList = nextDIR;
  1702.  
  1703.                 // Release the draft
  1704.                 draft->Release(ev);
  1705.         }
  1706.         else if (nextDIR == kODNULL)
  1707.         {
  1708.         // The deleted draft is tail of the draft list
  1709.         prevDIR->SetNext(kODNULL);
  1710.  
  1711.         // Reset the draft object for the draft above the
  1712.         // deleted draft
  1713.         prevDIR->SetDraft(draft);
  1714.         }
  1715.         else
  1716.         {
  1717.         // The deleted draft is in the middle of the draft
  1718.         // list
  1719.         prevDIR->SetNext(nextDIR);
  1720.         nextDIR->SetPrev(prevDIR);
  1721.  
  1722.         // Reset the draft object for the draft above the
  1723.         // deleted draft
  1724.         prevDIR->SetDraft(draft);
  1725.         }
  1726.       }
  1727.         }
  1728.     }
  1729.     catch (ODException _exception)
  1730.     {
  1731.         LOG("SOM exception occured in DocumentManager::DeleteDraft\n");
  1732.         ODError error = ErrorCode();
  1733.         if (fromDraft)
  1734.            SaveAndRestoreEv1(fromDraft);
  1735.         result = kODFalse;
  1736.         ODSetSOMException(ev, error);
  1737.     }
  1738.  
  1739.     return result;
  1740.  
  1741. }
  1742.  
  1743.  
  1744. //------------------------------------------------------------------------------
  1745. // RemoveChanges
  1746. //
  1747. //    Remove changes in the working draft if draft is dirty and remove
  1748. //    working draft from the document
  1749. //------------------------------------------------------------------------------
  1750. SOM_Scope void  SOMLINK DocumentManagerRemoveChanges(DocumentManager *somSelf, 
  1751.                                                     Environment *ev,
  1752.                             ODDraft *draft)
  1753. {
  1754.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1755.     DocumentManagerMethodDebug("DocumentManager",
  1756.             "DocumentManagerRemoveChanges");
  1757.  
  1758.     try
  1759.     {
  1760.  
  1761.     if (_fDraft == draft)
  1762.     {
  1763.         // For current draft, if draft's permissions provides 
  1764.         // write access, 
  1765.         // - remove changes made to this draft if draft is 
  1766.         //   marked dirty
  1767.         // - remove this draft from document
  1768.         //   Note: The call to RemoveFromDocument releases 
  1769.         //         the draft object too.
  1770.         if (somSelf->HasWriteAccess(ev))
  1771.         {
  1772.         if (_fDraft->ChangedFromPrev(ev))
  1773.             _fDraft->RemoveChanges(ev);
  1774.         _fDraft->RemoveFromDocument(ev);
  1775.         _fDraft = kODNULL;
  1776.         }
  1777.         else
  1778.         // if draft's permission does not allow write
  1779.         // access, release the current draft
  1780.         ODFinalReleaseObject(ev, _fDraft);
  1781.     }
  1782.  
  1783.  
  1784.     }
  1785.     catch (ODException _exception)
  1786.     {
  1787.         LOG("SOM exception occured in DocumentManager::RemoveChanges\n");
  1788.     ODSetSOMException(ev, _exception);
  1789.     }
  1790.  
  1791. }
  1792.  
  1793.  
  1794. //------------------------------------------------------------------------------
  1795. // Revert
  1796. //
  1797. //    Revert to the last saved version of the document
  1798. //------------------------------------------------------------------------------
  1799. SOM_Scope void  SOMLINK DocumentManagerRevert(DocumentManager *somSelf, 
  1800.                                                Environment *ev)
  1801. {
  1802.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1803.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerRevert");
  1804.  
  1805.     try
  1806.     {
  1807.     // Close the working draft
  1808.     somSelf->CloseDraft(ev, _fDraft);
  1809.  
  1810.     // Remove changes belonging to the working draft
  1811.     _fDraft->RemoveChanges(ev);
  1812.  
  1813.     // Open the last saved draft
  1814.     somSelf->OpenDraft(ev, _fDraft, kODFalse);
  1815.  
  1816.     }
  1817.     catch (ODException _exception)
  1818.     {
  1819.         LOG("SOM exception occured in DocumentManager::Revert\n");
  1820.     ODSetSOMException(ev, _exception);
  1821.     }
  1822.  
  1823.     return;
  1824. }
  1825.  
  1826. //------------------------------------------------------------------------------
  1827. // SetSession
  1828. //------------------------------------------------------------------------------
  1829. SOM_Scope void  SOMLINK DocumentManagerSetSession(DocumentManager *somSelf, 
  1830.                                                 Environment *ev,
  1831.                         ODSession *session)
  1832. {
  1833.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1834.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerSetSession");
  1835.  
  1836.     _fSession = session;
  1837. }
  1838.  
  1839.  
  1840. //------------------------------------------------------------------------------
  1841. // SetWindowState
  1842. //------------------------------------------------------------------------------
  1843. SOM_Scope void  SOMLINK DocumentManagerSetWindowState(DocumentManager *somSelf, 
  1844.                                                 Environment *ev,
  1845.                         ODWindowState *windowState)
  1846. {
  1847.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1848.     DocumentManagerMethodDebug("DocumentManager",
  1849.                 "DocumentManagerSetWindowState");
  1850.  
  1851.     _fWindowState = windowState;
  1852. }
  1853.  
  1854.  
  1855. //------------------------------------------------------------------------------
  1856. // SetDraftList
  1857. //------------------------------------------------------------------------------
  1858. SOM_Scope void  SOMLINK DocumentManagerSetDraftList(DocumentManager *somSelf, 
  1859.                                                 Environment *ev,
  1860.                         DraftInfoRec *draftList)
  1861. {
  1862.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1863.     DocumentManagerMethodDebug("DocumentManager","DocumentManagerSetDraftList");
  1864.  
  1865.     _fDraftList = draftList;
  1866. }
  1867.  
  1868.  
  1869. //------------------------------------------------------------------------------
  1870. // HasWriteAccess
  1871. //------------------------------------------------------------------------------
  1872. SOM_Scope ODBoolean  SOMLINK DocumentManagerHasWriteAccess(
  1873.                         DocumentManager *somSelf, 
  1874.                                                 Environment *ev)
  1875. {
  1876.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1877.     DocumentManagerMethodDebug("DocumentManager",
  1878.                 "DocumentManagerHasWriteAccess");
  1879.  
  1880.     // Returns true if draft's current permission includes 
  1881.     // kODDPSharedWrite or kODDPExclusiveWrite.
  1882.     // Note: ODDraftPermissions is a enum with write permission
  1883.     //       values set at the end.
  1884.     return _fDraftPermissions >= kODDPSharedWrite;
  1885. }
  1886.  
  1887.  
  1888. //------------------------------------------------------------------------------
  1889. // GetDraft
  1890. //------------------------------------------------------------------------------
  1891. SOM_Scope ODDraft*  SOMLINK DocumentManagerGetDraft(
  1892.                         DocumentManager *somSelf, 
  1893.                                                 Environment *ev)
  1894. {
  1895.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1896.     DocumentManagerMethodDebug("DocumentManager",
  1897.                 "DocumentManagerGetDraft");
  1898.  
  1899.     return _fDraft;
  1900. }
  1901.  
  1902.  
  1903. //------------------------------------------------------------------------------
  1904. // GetDocument
  1905. //------------------------------------------------------------------------------
  1906. SOM_Scope ODDocument*  SOMLINK DocumentManagerGetDocument(
  1907.                         DocumentManager *somSelf, 
  1908.                                                 Environment *ev)
  1909. {
  1910.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1911.     DocumentManagerMethodDebug("DocumentManager",
  1912.                 "DocumentManagerGetDocument");
  1913.  
  1914.     return _fDocument;
  1915. }
  1916.  
  1917.  
  1918. //------------------------------------------------------------------------------
  1919. // GetContainer
  1920. //------------------------------------------------------------------------------
  1921. SOM_Scope ODContainer*  SOMLINK DocumentManagerGetContainer(
  1922.                                                 DocumentManager *somSelf,
  1923.                                                 Environment *ev)
  1924. {
  1925.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1926.     DocumentManagerMethodDebug("DocumentManager",
  1927.                                     "DocumentManagerGetContainer");
  1928.  
  1929.     return _fContainer;
  1930. }
  1931.  
  1932.  
  1933. //------------------------------------------------------------------------------
  1934. // GetDraftList
  1935. //------------------------------------------------------------------------------
  1936. SOM_Scope DraftInfoRec*  SOMLINK DocumentManagerGetDraftList(
  1937.                         DocumentManager *somSelf, 
  1938.                                                 Environment *ev)
  1939. {
  1940.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1941.     DocumentManagerMethodDebug("DocumentManager",
  1942.                 "DocumentManagerGetDraftList");
  1943.  
  1944.     return _fDraftList;
  1945. }
  1946.  
  1947.  
  1948. //------------------------------------------------------------------------------
  1949. // InternalizeHistory
  1950. //
  1951. //    Build the list of draft to be displayed in the draft history 
  1952. //    window 
  1953. //------------------------------------------------------------------------------
  1954. SOM_Scope void  SOMLINK DocumentManagerInternalizeHistory(
  1955.                         DocumentManager *somSelf, 
  1956.                                                 Environment *ev)
  1957. {
  1958.     // The list stored in _fDraftList will have the most recent
  1959.     // draft in the front followed by the least recent drafts.
  1960.  
  1961.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  1962.     DocumentManagerMethodDebug("DocumentManager",
  1963.                 "DocumentManagerInternalizeHistory");
  1964.  
  1965.     DraftInfoRec  *firstInfoRec = kODNULL;
  1966.     try
  1967.     {
  1968.  
  1969.     TempODDraft    prevDraft = kODNULL;
  1970.         TempODDraft    bottomDraft = _fDocument->AcquireBaseDraft(ev,
  1971.                             kODDPReadOnly);
  1972.     DraftInfoRec    *aDraftInfoRec, *newDIR;
  1973.  
  1974.         // Get the most recent created draft in the document
  1975.         prevDraft = somSelf->GetLatestCreatedDraft(ev);
  1976.  
  1977.     // If there are drafts created in the document, traverse through
  1978.     // the draft list to retrieve the draft info.
  1979.     //
  1980.     // Note: The most recent draft created by using the Create Draft
  1981.     //     dialog will be the second draft below the working
  1982.     //    draft. See Create Draft for more info.
  1983.     if (prevDraft)
  1984.     {
  1985.         for ( ; ; )
  1986.         {
  1987.         newDIR = new DraftInfoRec;
  1988.  
  1989.         // Retrieve the draft info
  1990.         newDIR->InitDraftInfoRec(ev, prevDraft);
  1991.                 
  1992.         // Connect the draft list
  1993.         if (firstInfoRec)
  1994.         {
  1995.             aDraftInfoRec->SetNext(newDIR);
  1996.             newDIR->SetPrev(aDraftInfoRec);
  1997.             aDraftInfoRec = newDIR;
  1998.         }
  1999.         else
  2000.         {
  2001.             aDraftInfoRec = newDIR;
  2002.             firstInfoRec = aDraftInfoRec;
  2003.         }
  2004.         if ( prevDraft == bottomDraft )
  2005.             break;
  2006.  
  2007.         prevDraft = _fDocument->AcquireDraft(ev, kODDPReadOnly,
  2008.                             kODNULL,
  2009.                             prevDraft,
  2010.                             kODPosFirstBelow,
  2011.                             kODTrue);
  2012.             }
  2013.     }
  2014.  
  2015.     // Set DraftList
  2016.     _fDraftList = firstInfoRec;
  2017.  
  2018.     }
  2019.     catch (ODException _exception)
  2020.     {
  2021.        LOG("SOM exception occured in DocumentManager::InternalizeHistory\n");
  2022.        if (firstInfoRec)
  2023.        {
  2024.           ODError error = ErrorCode();
  2025.           SaveEv();
  2026.           DraftInfoRec  *curDIR, *nextDIR;
  2027.  
  2028.           // Iterate through the list of draft to delete each newly
  2029.           // created draft record
  2030.           for (curDIR = nextDIR = firstInfoRec; 
  2031.                curDIR != kODNULL; 
  2032.                curDIR = nextDIR)
  2033.           {
  2034.               nextDIR = curDIR->GetNext();
  2035.               try
  2036.               {
  2037.                  delete curDIR;
  2038.               }
  2039.               catch (ODException _exception)
  2040.               {
  2041.                  // Clear the error
  2042.                  SetErrorCodeEv(ev, kODNoError);
  2043.               }
  2044.           }
  2045.           RestoreEv();
  2046.           ODSetSOMException(ev, error);
  2047.        }
  2048.     }
  2049.  
  2050. }
  2051.  
  2052.  
  2053. //------------------------------------------------------------------------------
  2054. // IsStationery
  2055. //
  2056. //    Determine whether document is a stationery document or not
  2057. //------------------------------------------------------------------------------
  2058. SOM_Scope ODBoolean  SOMLINK DocumentManagerIsStationery(
  2059.                         DocumentManager *somSelf, 
  2060.                                                 Environment *ev,
  2061.                                                 ODDraft *draft)
  2062. {
  2063.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2064.     DocumentManagerMethodDebug("DocumentManager", 
  2065.                 "DocumentManagerIsStationery");
  2066.  
  2067.     ODBoolean stationeryExist = kODFalse;
  2068.  
  2069.     try
  2070.     {
  2071.  
  2072.     TempODStorageUnit su = ODAcquireRootPartSUOfDraft(ev, draft);
  2073.  
  2074.     if (su)
  2075.     {
  2076.         // kODPropIsStationery is a property to tell whether
  2077.         // this is a stationery or not.
  2078.         // Check whether this property exists or not. If this
  2079.         // property exists, get the value.
  2080.         stationeryExist = (ODSUExistsThenFocus(ev, su, 
  2081.                         kODPropIsStationery, 
  2082.                         kODBoolean));
  2083.  
  2084.         if (stationeryExist)
  2085.         StorageUnitGetValue(su, ev, sizeof(ODBoolean),
  2086.                         (ODValue)&stationeryExist);
  2087.  
  2088.     }
  2089.         
  2090.  
  2091.     }
  2092.     catch (ODException _exception)
  2093.     {
  2094.         LOG("SOM exception occured in DocumentManager::IsStationery\n");
  2095.     ODSetSOMException(ev, _exception);
  2096.     }
  2097.  
  2098.     return stationeryExist;
  2099. }
  2100.  
  2101.  
  2102.  
  2103. //------------------------------------------------------------------------------
  2104. // SetStationery
  2105. //
  2106. //    Set document as stationery document 
  2107. //------------------------------------------------------------------------------
  2108. SOM_Scope void SOMLINK DocumentManagerSetStationery(
  2109.                         DocumentManager *somSelf, 
  2110.                                                 Environment *ev,
  2111.                         ODDraft *draft)
  2112. {
  2113.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2114.     DocumentManagerMethodDebug("DocumentManager", 
  2115.                 "DocumentManagerSetStationery");
  2116.  
  2117.     try
  2118.     {
  2119.  
  2120.     TempODStorageUnit su = ODAcquireRootPartSUOfDraft(ev, draft);
  2121.  
  2122.     // Set kODPropIsStationery property to signal that this document
  2123.     // is a stationery
  2124.     if (su)
  2125.         ODSetBooleanProp(ev, su, kODPropIsStationery, kODBoolean, kODTrue);
  2126.  
  2127.     }
  2128.     catch (ODException _exception)
  2129.     {
  2130.         LOG("SOM exception occured in DocumentManager::SetStationery\n");
  2131.     ODSetSOMException(ev, _exception);
  2132.     }
  2133. }
  2134.  
  2135.  
  2136. //------------------------------------------------------------------------------
  2137. // UnsetStationery
  2138. //
  2139. //    Remove stationery from root part
  2140. //------------------------------------------------------------------------------
  2141. SOM_Scope void SOMLINK DocumentManagerUnsetStationery(
  2142.                         DocumentManager *somSelf, 
  2143.                                                 Environment *ev,
  2144.                         ODDraft *draft)
  2145. {
  2146.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2147.     DocumentManagerMethodDebug("DocumentManager", 
  2148.                 "DocumentManagerUnsetStationery");
  2149.  
  2150.     try
  2151.     {
  2152.  
  2153.     TempODStorageUnit su = ODAcquireRootPartSUOfDraft(ev, draft);
  2154.  
  2155.     // Remove stationery property from document
  2156.     if (su)
  2157.         ODSURemoveProperty(ev, su, kODPropIsStationery);
  2158.  
  2159.     }
  2160.     catch (ODException _exception)
  2161.     {
  2162.         LOG("SOM exception occured in DocumentManager::UnsetStationery\n");
  2163.     ODSetSOMException(ev, _exception);
  2164.     }
  2165. }
  2166.  
  2167.  
  2168.  
  2169. //------------------------------------------------------------------------------
  2170. // GetLatestCreatedDraft
  2171. //
  2172. //    Get the most recent created draft in the document
  2173. //
  2174. //     Note: Caller is responsible to release the draft returned by
  2175. //         this method.
  2176. //------------------------------------------------------------------------------
  2177. SOM_Scope ODDraft* SOMLINK DocumentManagerGetLatestCreatedDraft(
  2178.                         DocumentManager *somSelf, 
  2179.                                                 Environment *ev)
  2180. {
  2181.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2182.     DocumentManagerMethodDebug("DocumentManager", 
  2183.                 "DocumentManagerGetLatestCreatedDraft");
  2184.  
  2185.     ODDraft    *prevDraft = kODNULL;
  2186.  
  2187.     try
  2188.     {
  2189.  
  2190.     // If working draft provides write access, get 
  2191.     // a copy of the draft below the working draft. Otherwise,
  2192.     // get the working draft.
  2193.     if (somSelf->HasWriteAccess(ev))
  2194.     {
  2195.         prevDraft = _fDocument->AcquireDraft(ev, kODDPReadOnly,
  2196.                 kODNULL, _fDraft, kODPosFirstBelow, kODFalse);
  2197.     }
  2198.     else
  2199.     {
  2200.         prevDraft = _fDraft;
  2201.         prevDraft->Acquire(ev);
  2202.     }
  2203.  
  2204.     // Get the latest created draft from the document if there is one.
  2205.     // Otherwise, release the draft and set the latest created draft
  2206.     // to null.
  2207.     if (_fDocument->Exists(ev, kODNULLID, prevDraft, kODPosFirstBelow))
  2208.         prevDraft = _fDocument->AcquireDraft(ev, kODDPReadOnly,
  2209.                 kODNULL, prevDraft, kODPosFirstBelow, kODTrue);
  2210.     else
  2211.         // Note: ODReleaseObject will set prevDraft to NULL
  2212.         ODReleaseObject(ev, prevDraft);
  2213.  
  2214.     }
  2215.     catch (ODException _exception)
  2216.     {
  2217.        LOG("SOM exception occured in DocumentManager::GetLatestCreatedDraft\n");
  2218.        ODError error = ErrorCode();
  2219.        if (prevDraft)
  2220.           SaveAndRestoreEv1(prevDraft);
  2221.        ODSetSOMException(ev, error);
  2222.     }
  2223.  
  2224.     return (prevDraft);
  2225.     
  2226. }
  2227.  
  2228.  
  2229. //------------------------------------------------------------------------------
  2230. // SaveACopyAs
  2231. //
  2232. //    Save a copy of the top draft to a named file
  2233. //------------------------------------------------------------------------------
  2234. SOM_Scope void  SOMLINK DocumentManagerSaveACopyAs(
  2235.                                                 DocumentManager *somSelf,
  2236.                                                 Environment *ev,
  2237.                         ODDraft *draft,
  2238.                         PlatformFile *file)
  2239. {
  2240.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2241.     DocumentManagerMethodDebug("DocumentManager",
  2242.                                     "DocumentManagerSaveACopyAs");
  2243.  
  2244.     try
  2245.     {
  2246.        ODBoolean fileError = kODFalse;
  2247.  
  2248.        // if there is a problem creating the new file, delete existing file
  2249.        // and then create the new file again.
  2250.        try 
  2251.        {
  2252.           // Create a new file
  2253.           file->Create(kODShellSignature, kODShellSignature, 0);
  2254.        } 
  2255.        catch (ODException _exception)
  2256.        {
  2257.           // Clear the exception
  2258.           SetErrorCodeEv(ev, kODNoError);
  2259.           fileError = kODTrue;
  2260.        }
  2261.  
  2262.        if (fileError)
  2263.        {
  2264.           char  fileName[FILE_LENGTH];
  2265.           
  2266.           file->GetAsciiName(fileName, FILE_LENGTH - 1); 
  2267.           TempPlatformFile currentFile = GetPlatformFileFromContainer(ev, 
  2268.                         _fDocument->GetContainer(ev));
  2269.  
  2270.           ODBoolean exists = kODFalse;
  2271.           try
  2272.           {
  2273.              exists = file->Exists();
  2274.           }
  2275.           catch (ODException _exception)
  2276.           {
  2277.              // Clear the exception. 
  2278.              SetErrorCodeEv(ev, kODNoError);
  2279.           }
  2280.  
  2281.           // If error creating the file and file does not exist, then
  2282.           // it must be an invalid path or file name. Issue a warning
  2283.           // and then return to the caller.
  2284.           if (!exists)
  2285.              WARNMSG(WARN_INDEX(AMSG_850),"CPPOD0335 - Docshell: Problem creating file %s.  File or pathname could be invalid.", fileName);
  2286.           else
  2287.           {
  2288.              // If file to where a copy is saved is the same file name as
  2289.              // the one used by the current document, issue a warning and
  2290.              // then return to the caller.
  2291.              if (file->IsEqualTo(currentFile))
  2292.                 WARNMSG(WARN_INDEX(AMSG_859),"CPPOD0344 - DocMgr: Cannot save a copy of file onto current document.");
  2293.              else 
  2294.              {
  2295.                 // If file exists, delete the file and then create the
  2296.                 // file again.
  2297.                 fileError = kODFalse;
  2298.                 try
  2299.                 {
  2300.                    file->Delete();
  2301.                 }
  2302.                 catch (ODException _exception)
  2303.                 {
  2304.                    // If error deleting the file, issue a warning and then
  2305.                    // return to the caller.
  2306.                    WARNMSG(WARN_INDEX(AMSG_860),"CPPOD0345 - DocMgr: File %s is already in use. Select a new name or close the file in use by another application.", fileName);
  2307.                    // Clear the exception
  2308.                    SetErrorCodeEv(ev, kODNoError);
  2309.                    fileError = kODTrue;
  2310.                 }
  2311.  
  2312.                 if (!fileError)
  2313.                 {
  2314.                    try
  2315.                    {
  2316.                       file->Create(kODShellSignature, kODShellSignature, 0);
  2317.                    } 
  2318.                    catch (ODException _exception)
  2319.                    {
  2320.                       WARNMSG(WARN_INDEX(AMSG_858),"CPPOD0343 - Docshell: Problem creating file %s. Directory may be full or write-protected.", fileName);
  2321.                       // Clear the exception
  2322.                       SetErrorCodeEv(ev, kODNoError);
  2323.                       fileError = kODTrue;
  2324.                    }
  2325.                 }
  2326.              }
  2327.           }
  2328.        }
  2329.  
  2330.        if (!fileError)
  2331.        {
  2332.           TempODContainer newContainer = CreateFileContainer(ev, _fSession, 
  2333.                         &(file->GetFileSpec()));
  2334.  
  2335.           // Save the top draft to the container
  2336.           somSelf->ContainerSaveACopyAs(ev, draft, newContainer); 
  2337.        }
  2338.     }
  2339.  
  2340.     catch (ODException _exception)
  2341.     {
  2342.         WARNMSG(WARN_INDEX(AMSG_907), "CPPOD0454 - Docshell: Error saving a copy of draft into a new document.");
  2343.  
  2344.         // Clear the error
  2345.     SetErrorCodeEv(ev, kODNoError);
  2346.     }
  2347.  
  2348.     return;
  2349. }
  2350.  
  2351.  
  2352. //------------------------------------------------------------------------------
  2353. // ContainerSaveACopyAs
  2354. //
  2355. //    Save a copy of the top draft to a named container
  2356. //------------------------------------------------------------------------------
  2357. SOM_Scope void  SOMLINK DocumentManagerContainerSaveACopyAs(
  2358.                                                 DocumentManager *somSelf,
  2359.                                                 Environment *ev,
  2360.                         ODDraft *draft,
  2361.                         ODContainer *newContainer)
  2362. {
  2363.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2364.     DocumentManagerMethodDebug("DocumentManager",
  2365.                                     "DocumentManagerContainerSaveACopyAs");
  2366.  
  2367.     try
  2368.     {
  2369.  
  2370.     // if draft's permission allows write and draft is dirty,
  2371.     // save the window state and persistent object of draft. 
  2372.         if (draft && draft->GetPermissions(ev) >= kODDPSharedWrite &&
  2373.         draft->ChangedFromPrev(ev))
  2374.     {
  2375.         _fWindowState->Externalize(ev, draft);
  2376.         draft->Externalize(ev);
  2377.     }
  2378.  
  2379.     if (draft)
  2380.     {
  2381.         // Create a new document in the newly created container
  2382.         TempODDocument  newDocument = newContainer->AcquireDocument(ev,
  2383.                             kODDefaultDocument);
  2384.  
  2385.         // Copy the draft as the base draft of the new document
  2386.         newDocument->SetBaseDraftFromForeignDraft(ev, draft);
  2387.  
  2388.         // Get a reference of the newly created base draft
  2389.         TempODDraft newDraft = newDocument->AcquireBaseDraft(ev,
  2390.                             kODDPExclusiveWrite);
  2391.  
  2392.         // Modify timestamp and user properties
  2393.             TempODStorageUnit su = newDraft->AcquireDraftProperties(ev);
  2394.             somSelf->ResetDateModByInfo(ev, su);
  2395.  
  2396.         // Reset drop number to 0
  2397.             ODSetULongProp(ev, su, kODPropDraftNumber, kODULong, 0L); 
  2398.  
  2399.             TempODStorageUnit rootsu = ODAcquireRootPartSUOfDraft(ev, newDraft);
  2400.             somSelf->ResetDateModByInfo(ev, rootsu);
  2401.  
  2402.         // Save the base draft
  2403.         newDraft->Externalize(ev);
  2404.     }
  2405.  
  2406.     }
  2407.     catch (ODException _exception)
  2408.     {
  2409.         LOG("SOM exception occured in DocumentManager::ContainerSaveACopyAs\n");
  2410.     ODSetSOMException(ev, _exception);
  2411.     }
  2412. }
  2413.  
  2414.  
  2415. //------------------------------------------------------------------------------
  2416. // ResetDateModByInfo
  2417. //
  2418. //    Modify timestamp and user properties stored in the passed-in 
  2419. //    storage unit
  2420. //------------------------------------------------------------------------------
  2421. SOM_Scope void  SOMLINK DocumentManagerResetDateModByInfo(
  2422.                                                 DocumentManager *somSelf,
  2423.                                                 Environment *ev,
  2424.                         ODStorageUnit *su)
  2425. {
  2426.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2427.     DocumentManagerMethodDebug("DocumentManager",
  2428.                                     "DocumentManagerResetDateModByInfo");
  2429.  
  2430.     ODIText *modBy = kODNULL;
  2431.     ODTime  modDate;
  2432.  
  2433.     try
  2434.     {
  2435.  
  2436.        // Reset creation and modification date 
  2437.        time((time_t *)(&modDate));
  2438.        ODSetTime_TProp(ev, su, kODPropCreateDate, kODTime_T, modDate);
  2439.        ODSetTime_TProp(ev, su, kODPropModDate, kODTime_T, modDate);
  2440.        _fSession->GetUserName(ev, &modBy);
  2441.        ODSetITextProp(ev, su, kODPropModUser, kODPlatformIText, modBy);
  2442.        DisposeITextStruct(*modBy);
  2443.        modBy = kODNULL;
  2444.     }
  2445.     catch (ODException _exception)
  2446.     {
  2447.         LOG("SOM exception occured in DocumentManager::ResetDateModByInfo\n");
  2448.         if (modBy)
  2449.            DisposeITextStruct(*modBy);
  2450.     ODSetSOMException(ev, _exception);
  2451.     }
  2452. }    
  2453.  
  2454. //------------------------------------------------------------------------------
  2455. // DeleteDraftList
  2456. //
  2457. //      Delete the list of draft built for draft history
  2458. //------------------------------------------------------------------------------
  2459. SOM_Scope void  SOMLINK DocumentManagerDeleteDraftList(
  2460.                                                 DocumentManager *somSelf,
  2461.                                                 Environment *ev)
  2462. {
  2463.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2464.     DocumentManagerMethodDebug("DocumentManager",
  2465.                                         "DocumentManagerDeleteDraftList");
  2466.  
  2467.     DraftInfoRec *curDIR, *nextDIR;
  2468.  
  2469.     try
  2470.     {
  2471.        // Iterate through the list of draft to delete each draft record
  2472.        for (curDIR = nextDIR = _fDraftList; curDIR != kODNULL; curDIR = nextDIR)
  2473.        {
  2474.            nextDIR = curDIR->GetNext();
  2475.            delete curDIR;
  2476.        }
  2477.     }
  2478.     catch (ODException _exception)
  2479.     {
  2480.        LOG("SOM exception occured in DocMgr::DeleteDraftList\n");
  2481.        ODSetSOMException(ev, _exception);
  2482.     }
  2483.     _fDraftList = kODNULL;
  2484. }
  2485.  
  2486. //------------------------------------------------------------------------------
  2487. // GetFileName
  2488. //
  2489. //      Accessor method for _fFileName
  2490. //------------------------------------------------------------------------------
  2491. SOM_Scope char*  SOMLINK DocumentManagerGetFileName(
  2492.                                                 DocumentManager *somSelf,
  2493.                                                 Environment *ev)
  2494. {
  2495.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2496.     DocumentManagerMethodDebug("DocumentManager",
  2497.                                         "DocumentManagerGetFileName");
  2498.  
  2499.     return(_fFileName);
  2500. }
  2501.  
  2502. //------------------------------------------------------------------------------
  2503. // SetFileName
  2504. //
  2505. //      Accessor method for _fFileName
  2506. //------------------------------------------------------------------------------
  2507. SOM_Scope void  SOMLINK DocumentManagerSetFileName(
  2508.                                                 DocumentManager *somSelf,
  2509.                                                 Environment *ev,
  2510.                                                 char *fileName)
  2511. {
  2512.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2513.     DocumentManagerMethodDebug("DocumentManager",
  2514.                                         "DocumentManagerGetFileName");
  2515.  
  2516.     if (fileName)
  2517.         strcpy(_fFileName, fileName);
  2518. }
  2519.  
  2520. //------------------------------------------------------------------------------
  2521. // GetPartKindName
  2522. //
  2523. //      Accessor method for _fPartKindName
  2524. //------------------------------------------------------------------------------
  2525. SOM_Scope char*  SOMLINK DocumentManagerGetPartKindName(
  2526.                                                 DocumentManager *somSelf,
  2527.                                                 Environment *ev)
  2528. {
  2529.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2530.     DocumentManagerMethodDebug("DocumentManager",
  2531.                                         "DocumentManagerGetPartKindName");
  2532.  
  2533.     return(_fPartKindName);
  2534. }
  2535.  
  2536. //------------------------------------------------------------------------------
  2537. // SetPartKindName
  2538. //
  2539. //      Accessor method for _fPartKindName
  2540. //------------------------------------------------------------------------------
  2541. SOM_Scope void  SOMLINK DocumentManagerSetPartKindName(
  2542.                                                 DocumentManager *somSelf,
  2543.                                                 Environment *ev,
  2544.                                                 char *kindName)
  2545. {
  2546.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2547.     DocumentManagerMethodDebug("DocumentManager",
  2548.                                         "DocumentManagerGetPartKindName");
  2549.  
  2550.     if (kindName)
  2551.         strcpy(_fPartKindName, kindName);
  2552. }
  2553.  
  2554.  
  2555. //==============================================================================
  2556. //==============================================================================
  2557. //==============================================================================
  2558.  
  2559. //------------------------------------------------------------------------------
  2560. // The remaining methods in this class are required for OLE interoperability
  2561. // and so are only applicable on the Win32 platform
  2562. //------------------------------------------------------------------------------
  2563.  
  2564. #ifdef _PLATFORM_WIN32_
  2565.  
  2566. //------------------------------------------------------------------------------
  2567. // SetOleWrapper
  2568. //------------------------------------------------------------------------------
  2569. SOM_Scope void  SOMLINK DocumentManagerSetOleWrapper(
  2570.                                                 DocumentManager *somSelf,
  2571.                                                 Environment *ev,
  2572.                         OleWrapper *oleWrapper)
  2573. {
  2574.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2575.     DocumentManagerMethodDebug("DocumentManager",
  2576.                                     "DocumentManagerSetOleWrapper");
  2577.  
  2578.     try
  2579.     {
  2580.        if ( oleWrapper )
  2581.            oleWrapper->AddRef();
  2582.        else   /* NULL */
  2583.            _fOleWrapper->Release();
  2584.     }
  2585.     catch (ODException _exception)
  2586.     {
  2587.         LOG("SOM exception occured in DocumentManager::SetOleWrapper\n");
  2588.     ODSetSOMException(ev, _exception);
  2589.     }
  2590.  
  2591.     _fOleWrapper = oleWrapper;
  2592. }
  2593.  
  2594. //------------------------------------------------------------------------------
  2595. // GetOleWrapper
  2596. //------------------------------------------------------------------------------
  2597. SOM_Scope OleWrapper*  SOMLINK DocumentManagerGetOleWrapper(
  2598.                                                 DocumentManager *somSelf,
  2599.                                                 Environment *ev)
  2600. {
  2601.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2602.     DocumentManagerMethodDebug("DocumentManager",
  2603.                                     "DocumentManagerGetOleWrapper");
  2604.  
  2605.     try
  2606.     {
  2607.        // ensure there is always an ole wrapper to return
  2608.        if (!_fOleWrapper) {
  2609.          OleWrapper* wrapper;
  2610.       ODOLEManager* oleManager;
  2611.  
  2612.       // this hairy path is how we get a handle on the wrapper factory
  2613.       // (creating it if necessary).  we then use the factory to create
  2614.       // a wrapper. 
  2615.       oleManager = _fSession->GetOleManager(ev);
  2616.  
  2617.       // first make sure we have a factory appropriately registered
  2618.       if (!oleManager->GetProcessData()->gFactory &&
  2619.           !oleManager->RegisterOleFactory(FALSE))
  2620.         return NULL;
  2621.  
  2622.       // Now create a wrapper and save it away.  Tell the wrapper
  2623.       // about the association as well
  2624.       ((WrapIClassFactory*)oleManager->GetProcessData()->gFactory)->CreateInstance(NULL, IID_IUnknown, (void**)&wrapper);
  2625.       somSelf->SetOleWrapper(ev, wrapper);
  2626.       wrapper->SetDocumentManager(somSelf);
  2627.  
  2628.       // may need to set the magic WFLG_LOADEDFROMFILE bit here
  2629.       // wrapper->fWFlg |= WFLG_LOADEDFROMFILE;
  2630.        }
  2631.     }
  2632.     catch (ODException _exception)
  2633.     {
  2634.         LOG("SOM exception occured in DocumentManager::GetOleWrapper\n");
  2635.     ODSetSOMException(ev, _exception);
  2636.     }
  2637.     return _fOleWrapper;
  2638. }
  2639. #endif
  2640.  
  2641.  
  2642. //------------------------------------------------------------------------------
  2643. // IsReadOnlyDocument
  2644. //
  2645. //      Display an alert dialog to prompt user whether to continue to 
  2646. //    open the document or not if the document is read-only.
  2647. //------------------------------------------------------------------------------
  2648. SOM_Scope ODBoolean  SOMLINK DocumentManagerIsReadOnlyDocument(
  2649.                                                 DocumentManager *somSelf,
  2650.                                                 Environment *ev,
  2651.                                                 PlatformFile *file)
  2652. {
  2653.     DocumentManagerData *somThis = DocumentManagerGetData(somSelf);
  2654.     DocumentManagerMethodDebug("DocumentManager",
  2655.                                     "DocumentManagerIsReadOnlyDocument");
  2656.  
  2657.     ODBoolean rc = kODTrue;
  2658.  
  2659.     try
  2660.     {
  2661.         ODFileAttrFlags fileAttrs;
  2662.  
  2663.         // Check if file is readonly. If so, display an alert dialog
  2664.         // and ask whether user wants to continue or not?
  2665.         file->GetFileAttributes(&fileAttrs);
  2666.         if (fileAttrs & kODFileAttrReadOnly)
  2667.            rc = ReadOnlyDlg(ev);
  2668.     } 
  2669.     catch (ODException _exception)
  2670.     {
  2671.         LOG("SOM exception occured in DocumentManager::IsReadOnlyDocument\n");
  2672.     ODSetSOMException(ev, _exception);
  2673.     }
  2674.  
  2675.     return rc;
  2676. }
  2677.  
  2678.