home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / Framewrk / FWPart / FWPart.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  47.1 KB  |  1,569 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWPart.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFrameW.hpp"
  11.  
  12. #ifndef FWPART_H
  13. #include "FWPart.h"
  14. #endif
  15.  
  16. #ifndef FWPRESEN_H
  17. #include "FWPresen.h"
  18. #endif
  19.  
  20. #ifndef FWMNUBAR_H
  21. #include "FWMnuBar.h"
  22. #endif
  23.  
  24. #ifndef FWEVENTD_H
  25. #include "FWEventD.h"
  26. #endif
  27.  
  28. #ifndef FWSEMINT_H
  29. #include "FWSemInt.h"
  30. #endif
  31.  
  32. #ifndef FWLNKMGR_H
  33. #include "FWLnkMgr.h"
  34. #endif
  35.  
  36. #ifndef FWCONTNT_H
  37. #include "FWContnt.h"
  38. #endif
  39.  
  40. #ifndef FWINTER_H
  41. #include "FWInter.h"
  42. #endif
  43.  
  44. #ifndef FWKIND_H
  45. #include "FWKind.h"
  46. #endif
  47.  
  48. #ifndef FWCFMRES_H
  49. #include "FWCFMRes.h"
  50. #endif
  51.  
  52. #ifndef FWALERT_H
  53. #include "FWAlert.h"
  54. #endif
  55.  
  56. #ifndef FWPART_K
  57. #include "FWPart.k"
  58. #endif
  59.  
  60. #ifndef FWRESSIN_H
  61. #include "FWResSin.h"
  62. #endif
  63.  
  64. #ifndef FWSESION_H
  65. #include "FWSesion.h"
  66. #endif
  67.  
  68. #ifndef FWFRAME_H
  69. #include "FWFrame.h"
  70. #endif
  71.  
  72. #ifndef FWMEMHLP_H
  73. #include "FWMemHlp.h"
  74. #endif
  75.  
  76. #ifndef FWACQUIR_H
  77. #include "FWAcquir.h"
  78. #endif
  79.  
  80. #ifndef FWCLNINF_H
  81. #include "FWClnInf.h"
  82. #endif
  83.  
  84. #ifndef FWPRTITE_H
  85. #include "FWPrtIte.h"
  86. #endif
  87.  
  88. #ifndef FWUTIL_H
  89. #include "FWUtil.h"
  90. #endif
  91.  
  92. #ifndef SLODFSTR_K
  93. #include "SLODFStr.k"
  94. #endif
  95.  
  96. #ifndef SLODFSTR_H
  97. #include "SLODFStr.h"
  98. #endif
  99.  
  100. #ifndef FWSELECT_H
  101. #include "FWSelect.h"
  102. #endif
  103.  
  104. #ifndef FWIDLE_H
  105. #include "FWIdle.h"
  106. #endif
  107.  
  108. #ifndef FWITERS_H
  109. #include "FWIters.h"
  110. #endif
  111.  
  112. #ifndef SLMIXOS_H
  113. #include "SLMixOS.h"
  114. #endif
  115.  
  116. // ----- OD Utils -----
  117.  
  118. #ifndef _STDTYPIO_
  119. #include "StdTypIO.h"
  120. #endif
  121.  
  122. #ifndef _ITEXT_
  123. #include "IText.h"
  124. #endif
  125.  
  126. // ----- OpenDoc -----
  127.  
  128. #ifndef SOM_Module_OpenDoc_Foci_defined
  129. #include <Foci.xh>
  130. #endif
  131.  
  132. #ifndef SOM_ODTypeList_xh
  133. #include <TypeList.xh>
  134. #endif
  135.  
  136. #ifndef SOM_ODStorageUnit_xh
  137. #include <StorageU.xh>
  138. #endif
  139.  
  140. #ifndef SOM_Module_OpenDoc_StdProps_defined
  141. #include <StdProps.xh>
  142. #endif
  143.  
  144. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  145. #include <StdTypes.xh>
  146. #endif
  147.  
  148. #ifndef SOM_ODTranslation_xh
  149. #include <Translt.xh>
  150. #endif
  151.  
  152. //========================================================================================
  153. // Globals
  154. //========================================================================================
  155.  
  156. unsigned short FW_CPart::fgSessionGlobalsCount = 0;
  157.  
  158. ODTypeToken FW_CPart::fgSelectionFocusToken = 0;
  159. ODTypeToken FW_CPart::fgMenuFocusToken = 0;
  160. ODTypeToken FW_CPart::fgKeyFocusToken = 0;
  161. ODTypeToken FW_CPart::fgModalFocusToken = 0;
  162. ODTypeToken FW_CPart::fgClipboardFocusToken = 0;
  163. ODTypeToken FW_CPart::fgScrollingFocusToken = 0;
  164. ODTypeToken FW_CPart::fgMouseFocusToken = 0;
  165. ODTypeToken FW_CPart::fgViewAsFrameToken = 0;
  166. ODTypeToken FW_CPart::fgViewAsSmallIconToken = 0;
  167. ODTypeToken FW_CPart::fgViewAsLargeIconToken = 0;
  168. ODTypeToken FW_CPart::fgViewAsThumbnailToken = 0;
  169.  
  170. //========================================================================================
  171. // RunTime Info
  172. //========================================================================================
  173.  
  174. #ifdef FW_BUILD_MAC
  175. #pragma segment fwpart2
  176. #endif
  177.  
  178. FW_DEFINE_CLASS_M1(FW_CPart, FW_MEventHandler)
  179. FW_DEFINE_AUTO(FW_CPart)
  180.  
  181. //========================================================================================
  182. //    class FW_CPart
  183. //========================================================================================
  184.  
  185. //----------------------------------------------------------------------------------------
  186. //    FW_CPart::FW_CPart    
  187. //----------------------------------------------------------------------------------------
  188.  
  189. FW_CPart::FW_CPart(ODPart* odPart,
  190.                     FW_Instance partInstance,
  191.                     FW_ResourceID partInfoID) :
  192.     FW_MEventHandler(),
  193.     fODPart(odPart),
  194.     fMenuBar(NULL),
  195.     fEventDispatcher(NULL),
  196.     fLastActiveFrame(NULL),
  197.     fPresentations(NULL),
  198.     fDefaultPresentation(NULL),
  199.     fIdleCount(0),
  200.     fModalDialogCount(0),
  201.     fExtensionManager(NULL),
  202.     fSemanticInterface(NULL),
  203.     fPartInstance(partInstance),
  204.     fViewAsIconID(0),
  205.     fDocumentWindowID(0),
  206.     fLinkManager(NULL),
  207.     fPrintInfo(NULL),
  208.     fIdler(NULL),
  209.     fContent(NULL),
  210.     fDataInterchange(NULL),
  211.     fPartInfoID(partInfoID),
  212.     fNeedPrepping(TRUE),
  213.     fPartKind(NULL),
  214.     fPreferredKind(NULL),
  215.     fPartWindowFrame(NULL)
  216. {
  217.     FW_END_CONSTRUCTOR
  218. }
  219.  
  220. //----------------------------------------------------------------------------------------
  221. //    FW_CPart::~FW_CPart    
  222. //----------------------------------------------------------------------------------------
  223.  
  224. FW_CPart::~FW_CPart()
  225. {    
  226.     FW_START_DESTRUCTOR
  227.     FW_ASSERT(fIdleCount == 0);
  228.     FW_ASSERT(fModalDialogCount == 0);
  229.     
  230.     FW_ASSERT(fIdler == NULL);    // Should be NULL by now
  231.     
  232.     // ----- Delete all the presentations
  233.     if (fPresentations)
  234.     {
  235.         FW_CPresentation* presentation;
  236.         while ((presentation = fPresentations->First()) != NULL)
  237.         {
  238.             PrivRemovePresentation(presentation);
  239.             delete presentation;
  240.         }        
  241.     }
  242.  
  243.     delete fPresentations;
  244.     fPresentations = NULL;
  245.  
  246.     // ----- Delete MenuBar
  247.     delete fMenuBar;
  248.     fMenuBar = NULL;
  249.     
  250.     // ----- Delete Event Dispatcher
  251.     delete fEventDispatcher;
  252.     fEventDispatcher = NULL;
  253.     
  254.     // ----- Delete Semantic Interface
  255.     delete fSemanticInterface;
  256.     fSemanticInterface = NULL;
  257.     
  258.     // ----- Delete Link Manager
  259.     delete fLinkManager;
  260.     fLinkManager = NULL;
  261.     
  262.     // ----- Delete Content
  263.     delete fContent;
  264.     fContent = NULL;
  265.     
  266.     // ----- Delete Data Interchange
  267.     delete fDataInterchange;
  268.     fDataInterchange = NULL;
  269.     
  270.     // ----- Release All the globals
  271.     PrivReleaseGlobals();
  272.     
  273.     // ----- Delete all the kinds
  274.     if (fKinds)
  275.     {
  276.         FW_CKind* kind;
  277.         while ((kind = fKinds->First()) != NULL)
  278.         {
  279.             fKinds->Remove(kind);
  280.             delete kind;
  281.         }        
  282.  
  283.         delete fKinds;
  284.         fKinds = NULL;
  285.     }
  286. }
  287.  
  288. //---------------------------------------------------------------------------------------
  289. //    FW_CPart::Initialize
  290. //---------------------------------------------------------------------------------------
  291. // Call inherited first when overriding
  292.  
  293. void FW_CPart::Initialize(Environment *ev, ODStorageUnit* storageUnit, FW_Boolean fromStorage)
  294. {
  295. FW_UNUSED(fromStorage);
  296.  
  297.     PrivInitGlobals(ev, storageUnit);
  298.     
  299.     // ----- Menu bar -----
  300.     fMenuBar = FW_NEW(FW_CMenuBar, (ev, fODPart, fPartInstance));
  301.     
  302.     // ----- Create Event Dispatcher -----
  303.     fEventDispatcher = this->NewEventDispatcher(ev);
  304.     
  305.     // ----- Presentation collection -----
  306.     fPresentations = FW_NEW(FW_TOrderedCollection<FW_CPresentation>, ());
  307.  
  308.     // ----- Data Interchage object -----
  309.     fDataInterchange = this->NewDataInterchange(ev);
  310.  
  311.     // ----- Part Content object -----
  312.     fContent = this->NewPartContent(ev);
  313.  
  314.     // ----- Linking Support -----
  315.     fLinkManager = this->NewLinkManager(ev);
  316.     
  317.     // ----- Kinds -----
  318.     fKinds = FW_NEW(FW_TOrderedCollection<FW_CKind>, ());
  319.     
  320.     // ----- Load Part Info Resource -----
  321.     FW_PSharedLibraryResourceFile resFile(ev, fPartInstance);
  322. #ifdef FW_DEBUG
  323.     if (!resFile->HasResource(ev, fPartInfoID, FW_kPartInfoResourceType))
  324.         FW_DEBUG_MESSAGE("The part info resource is missing");
  325. #endif    
  326.     FW_PResource resource(ev, resFile, fPartInfoID, FW_kPartInfoResourceType);
  327.     FW_PResourceSink sink(ev, resource);
  328.     FW_CReadableStream stream(sink);
  329.  
  330.     stream >> fViewAsIconID;
  331.  
  332.     FW_ResourceID menuBarID;
  333.     stream >> menuBarID;
  334.  
  335.     stream >> fDocumentWindowID;
  336.  
  337.     stream >> fPartUserName;    
  338.  
  339.     FW_CAcquireODISOStr partKind = FW_ReadODValueTypeFromStream(ev, stream);
  340.     fPartKind = RegisterKind(ev, partKind, FW_kAllStorage, FW_kImportExportEnabled);
  341.     fPartKind->PrivSetAsPartKind(ev);
  342.     fPartKind->PrivSetAsPreferredKind(ev, TRUE);
  343.     fPreferredKind = fPartKind;
  344.     
  345.     // ----- If was called from InitPart, write out the preferred kind (in this case the part kind)
  346.     if (!fromStorage)
  347.         ODSetISOStrProp(ev, storageUnit, kODPropPreferredKind, kODISOStr, fPreferredKind->GetType(ev));
  348.     
  349.     // ----- Initialize MenuBar if menuBarID != 0 -----
  350.     if (menuBarID != 0)
  351.     {
  352.         fMenuBar->InitializeFromResource(ev, menuBarID);
  353.         fAboutString = fMenuBar->GetAboutString(ev);    // About string read in from menuBar resource
  354.     }
  355.     if (fAboutString.IsEmpty())        // user didn't supply an About string, so get the default one
  356.         ::FW_PrivLoadODFString(ev, FW_kAboutString, fAboutString);
  357. }
  358.  
  359. //---------------------------------------------------------------------------------------
  360. //    FW_CPart::InstallScripingCallbacks
  361. //---------------------------------------------------------------------------------------
  362.  
  363. void FW_CPart::InstallScriptingCallbacks(Environment* ev)
  364. {
  365. FW_UNUSED(ev);
  366.     // Scriptable parts that require custom AEDesc coercion functions or custom
  367.     // AEDesc comparison functions should override this method and call the following
  368.     // static functions to install custom handlers:
  369.     //         FW_CDescCoercionCallbacks::RegisterHandler
  370.     //        FW_CDescComparisonCallbacks::RegisterHandler
  371. }
  372.  
  373. //---------------------------------------------------------------------------------------
  374. //    FW_CPart::PrivInitGlobals
  375. //---------------------------------------------------------------------------------------
  376.  
  377. void FW_CPart::PrivInitGlobals(Environment *ev, ODStorageUnit* storageUnit)
  378. {
  379.     if (FW_CSession::fgSession == NULL)
  380.         FW_CSession::fgSession = storageUnit->GetSession(ev);
  381.         
  382.     if (fgSessionGlobalsCount == 0)
  383.     {
  384.         FW_ASSERT(fgSelectionFocusToken == 0);
  385.         fgSelectionFocusToken = FW_CSession::Tokenize(ev, kODSelectionFocus);
  386.         
  387.         FW_ASSERT(fgMenuFocusToken == 0);
  388.         fgMenuFocusToken = FW_CSession::Tokenize(ev, kODMenuFocus);
  389.         
  390.         FW_ASSERT(fgKeyFocusToken == 0);
  391.         fgKeyFocusToken = FW_CSession::Tokenize(ev, kODKeyFocus);
  392.         
  393.         FW_ASSERT(fgClipboardFocusToken == 0);
  394.         fgClipboardFocusToken = FW_CSession::Tokenize(ev, kODClipboardFocus);
  395.         
  396.         FW_ASSERT(fgModalFocusToken == 0);
  397.         fgModalFocusToken = FW_CSession::Tokenize(ev, kODModalFocus);
  398.         
  399.         FW_ASSERT(fgScrollingFocusToken == 0);
  400.         fgScrollingFocusToken = FW_CSession::Tokenize(ev, kODScrollingFocus);
  401.         
  402.         FW_ASSERT(fgMouseFocusToken == 0);
  403.         fgMouseFocusToken = FW_CSession::Tokenize(ev, kODMouseFocus);
  404.  
  405.         FW_ASSERT(fgViewAsFrameToken == 0);
  406.         fgViewAsFrameToken = FW_CSession::Tokenize(ev, kODViewAsFrame);
  407.         
  408.         FW_ASSERT(fgViewAsSmallIconToken == 0);
  409.         fgViewAsSmallIconToken = FW_CSession::Tokenize(ev, kODViewAsSmallIcon);
  410.         
  411.         FW_ASSERT(fgViewAsLargeIconToken == 0);
  412.         fgViewAsLargeIconToken = FW_CSession::Tokenize(ev, kODViewAsLargeIcon);
  413.         
  414.         FW_ASSERT(fgViewAsThumbnailToken == 0);
  415.         fgViewAsThumbnailToken = FW_CSession::Tokenize(ev, kODViewAsThumbnail);
  416.         
  417.         InstallScriptingCallbacks(ev);
  418.     }
  419.     
  420.     fgSessionGlobalsCount++;
  421. }    
  422.  
  423. //---------------------------------------------------------------------------------------
  424. //    FW_CPart::PrivReleaseGlobals
  425. //---------------------------------------------------------------------------------------
  426.  
  427. void FW_CPart::PrivReleaseGlobals()
  428. {
  429.     fgSessionGlobalsCount--;
  430.     FW_ASSERT(fgSessionGlobalsCount >= 0);
  431.     
  432.     if (fgSessionGlobalsCount == 0)
  433.     {
  434.         // I am resetting those globals to their default value
  435.         //    because if the DLL is not unloaded they wont be reinitialized
  436.         fgSelectionFocusToken =    
  437.         fgMenuFocusToken =        
  438.         fgKeyFocusToken =    
  439.         fgClipboardFocusToken =        
  440.         fgModalFocusToken =    
  441.         fgScrollingFocusToken =    
  442.         fgMouseFocusToken =    
  443.         fgViewAsFrameToken =    
  444.         fgViewAsSmallIconToken =    
  445.         fgViewAsLargeIconToken =    
  446.         fgViewAsThumbnailToken = 0;
  447.     }
  448. }
  449.  
  450. //---------------------------------------------------------------------------------------
  451. //    FW_CPart::AddAnnotationProperties
  452. //---------------------------------------------------------------------------------------
  453. //    Attention - AddAnnotationProperties can be called multiple times
  454.  
  455. void FW_CPart::AddAnnotationProperties(Environment* ev, ODStorageUnit* storageUnit, FW_StorageKinds storageKind)
  456. {        
  457. FW_UNUSED(ev);
  458. FW_UNUSED(storageUnit);
  459. FW_UNUSED(storageKind);
  460. }
  461.  
  462. //---------------------------------------------------------------------------------------
  463. //    FW_CPart::ChangeKind
  464. //---------------------------------------------------------------------------------------
  465. //    1) convert kind to a FW_CKind
  466. //    2) Change my preferred kind
  467. //    3) if there is a change (ChangePreferredKind sets the fNeedPrep to true)
  468. //        4) change the kODPreferredKind property
  469. //        5) Externalize my content
  470. void FW_CPart::ChangeKind(Environment* ev, ODType kind)
  471. {
  472.     FW_CKind* newPreferredKind = GetKind(ev, kind);
  473.     if (newPreferredKind == NULL)
  474.     {
  475.         FW_DEBUG_MESSAGE("This kind is not supported. Did you forget to call RegisterKind?");
  476.         return;
  477.     }
  478.     if (!newPreferredKind->ExportSupported(ev, FW_kPartStorage))
  479.     {
  480.         FW_DEBUG_MESSAGE("This part cannot export this kind.");
  481.         return;
  482.     }
  483.     
  484.     // ----- Change the preferred kind -----
  485.     if (ChangePreferredKind(ev, newPreferredKind))
  486.     {
  487.         ODStorageUnit* su = GetStorageUnit(ev);
  488.     
  489.         // ----- Write the new preferred kind in the preferred kind property -----
  490.         ODSetISOStrProp(ev, su, kODPropPreferredKind, kODISOStr, newPreferredKind->GetType(ev));
  491.  
  492.         // ----- Externalize with the new preferred kind -----
  493.         ExternalizeContent(ev, su, NULL);
  494.     }
  495. }
  496.  
  497. //------------------------------------------------------------------------------
  498. // FW_RemoveUnsupportedValues
  499. //------------------------------------------------------------------------------
  500. //    Common method for PrepContentProperty and ExternalizeKinds
  501.  
  502. static void FW_RemoveUnsupportedValues(Environment* ev, unsigned long numValues, ODStorageUnit* storageUnit, FW_Boolean* toKeep)
  503. {
  504.     for (unsigned long index = numValues; index >= 1; index--)
  505.     {
  506.         if (!toKeep[index-1])
  507.         {
  508.             storageUnit->Focus(ev, kODPropContents, kODPosUndefined, NULL, index, kODPosUndefined);
  509.             storageUnit->Remove(ev);
  510.         }
  511.     }
  512. }
  513.  
  514. //------------------------------------------------------------------------------
  515. // FW_CPart::PrepContentProperty
  516. //------------------------------------------------------------------------------
  517.  
  518. void FW_CPart::PrepContentProperty(Environment* ev, ODStorageUnit* storageUnit, FW_StorageKinds storageKind, FW_Boolean allSupportedKinds)
  519. {
  520.     storageUnit->Focus(ev, kODPropContents, kODPosUndefined, NULL, 0, kODPosAll);
  521.     
  522.     // ----- First look at all the values I have to remove ------
  523.     // There is no API to insert a value 
  524.     FW_CKind* currentKind = fKinds->First();
  525.  
  526.     unsigned long numValues = storageUnit->CountValues(ev);
  527.     
  528.     if (numValues != 0)
  529.     {
  530. #if 0 // [MH]
  531.     // This code is to preserve any supported values. Problem is that any values that contain su-refs
  532.     // must be removed and replaced. Since we have no idea about which ones those might be, we will
  533.     // just remove all values, then add all the supported ones back.
  534.     
  535.         FW_CAcquireTemporaryMemory tempMemory(numValues * sizeof(FW_Boolean));
  536.         FW_Boolean* toKeep = (FW_Boolean*)tempMemory.GetPointer();
  537.         
  538.         for (unsigned long index = 0; index < numValues ; index++)
  539.         {
  540.             toKeep[index] = FALSE;
  541.             
  542.             storageUnit->Focus(ev, kODPropContents, kODPosUndefined, NULL, index+1, kODPosUndefined);
  543.  
  544.             if (currentKind != NULL)
  545.             {
  546.                 FW_CAcquireODISOStr valueType = storageUnit->GetType(ev);
  547.                 if (currentKind->IsEqual(ev, valueType)) {
  548.                     // ----- When saving the document to the part storage I need to always save it in the
  549.                     // ----- preferred part kind
  550.                     FW_Boolean supported;
  551.                     if (allSupportedKinds)
  552.                         supported = currentKind->ExportSupported(ev, storageKind);
  553.                     else
  554.                         supported = currentKind->ToBeExported(ev, storageKind);
  555.                         
  556.                     toKeep[index] = supported || (currentKind->IsPreferredKind(ev) && storageKind == FW_kPartStorage);
  557.                     currentKind = fKinds->After(currentKind);
  558.                 }
  559.             }
  560.         }
  561.         
  562.         // ----- Now we can really remove them going backward -----
  563.         FW_RemoveUnsupportedValues(ev, numValues, storageUnit, toKeep);
  564. #endif
  565.  
  566.         // just remove all the values
  567.         for (unsigned long index = numValues; index >= 1; index--)
  568.         {
  569.             storageUnit->Focus(ev, kODPropContents, kODPosUndefined, NULL, index, kODPosUndefined);
  570.             storageUnit->Remove(ev);
  571.         }
  572.     }
  573.     
  574.     // ----- Add all the other kinds ----- [MH] Now always adds all kinds!
  575.     while (currentKind)
  576.     {
  577.         FW_Boolean supported;
  578.         if (allSupportedKinds)
  579.             supported = currentKind->ExportSupported(ev, storageKind);
  580.         else
  581.             supported = currentKind->ToBeExported(ev, storageKind);
  582.         
  583.         if (supported)
  584.         {
  585.             FW_ASSERT(!storageUnit->Exists(ev, kODPropContents, currentKind->GetType(ev), 0)); // It should not exist
  586.             storageUnit->AddValue(ev, currentKind->GetType(ev));
  587.             currentKind->PrivSetDirty(ev, TRUE, storageKind); // If it doesn't exist it will have to be externalize
  588.         }
  589.         
  590.         currentKind = fKinds->After(currentKind);
  591.     }
  592.     
  593.     AddAnnotationProperties(ev, storageUnit, storageKind);
  594. }
  595.  
  596. //---------------------------------------------------------------------------------------
  597. // FW_CPart::ExternalizeKinds
  598. //---------------------------------------------------------------------------------------
  599. //    A content object is necessary to support this API
  600.  
  601. void FW_CPart::ExternalizeKinds(Environment *ev, ODTypeList* kindset)
  602. {
  603.     if (fContent == NULL)
  604.         return;
  605.     
  606.     ODStorageUnit* storageUnit = GetStorageUnit(ev);
  607.     
  608.     storageUnit->Focus(ev, kODPropContents, kODPosUndefined, NULL, 0, kODPosAll);
  609.     
  610.     // ----- First look at all the value I have to remove ------
  611.     // There is no API to insert a value 
  612.     FW_CKind* currentKind = fKinds->First();
  613.  
  614.     unsigned long numValues = storageUnit->CountValues(ev);
  615.     
  616.     if (numValues != 0)
  617.     {
  618.         FW_CAcquireTemporaryMemory tempMemory(numValues * sizeof(FW_Boolean));
  619.         FW_Boolean* toKeep = (FW_Boolean*)tempMemory.GetPointer();
  620.         
  621.         for (unsigned long index = 0; index < numValues ; index++)
  622.         {
  623.             toKeep[index] = FALSE;
  624.             
  625.             storageUnit->Focus(ev, kODPropContents, kODPosUndefined, NULL, index+1, kODPosUndefined);
  626.  
  627.             if (currentKind != NULL)
  628.             {
  629.                 FW_CAcquireODISOStr valueType = storageUnit->GetType(ev);
  630.                 if (currentKind->IsEqual(ev, valueType)) {
  631.                     // ----- I Don't keep it if it is not in the kinset but I still keep it if it is the preferred kind
  632.                     // I use ExportSupported and not ToBeExported
  633.                     if (currentKind->ExportSupported(ev, FW_kPartStorage))
  634.                         toKeep[index] = kindset->Contains(ev, valueType) || currentKind->IsPreferredKind(ev);
  635.                     
  636.                     currentKind = fKinds->After(currentKind);
  637.                 }
  638.             }
  639.         }
  640.         
  641.         // ----- Now we can really remove them going backward -----
  642.         FW_RemoveUnsupportedValues(ev, numValues, storageUnit, toKeep);
  643.     }
  644.     
  645.     // ----- Add all the other kinds -----
  646.     while (currentKind)
  647.     {
  648.         // I use ExportSupported and not ToBeExported
  649.         if (currentKind->ExportSupported(ev, FW_kPartStorage) && (kindset->Contains(ev, currentKind->GetType(ev)) || currentKind->IsPreferredKind(ev)))
  650.         {
  651.             FW_ASSERT(!storageUnit->Exists(ev, kODPropContents, currentKind->GetType(ev), 0)); // It should not exist
  652.             storageUnit->AddValue(ev, currentKind->GetType(ev));
  653.             currentKind->PrivSetDirty(ev, TRUE, FW_kPartStorage); // If it doesn't exist it will have to be externalize
  654.         }
  655.         
  656.         currentKind = fKinds->After(currentKind);
  657.     }
  658.     
  659.     // ----- Now I can call FW_CContent::ExternalizeKind on each existing value
  660.     fContent->PrivExternalizeAllValues(ev, storageUnit, FW_kPartStorage, NULL, NULL);
  661. }
  662.  
  663. //---------------------------------------------------------------------------------------
  664. //    FW_CPart::CloneInto
  665. //---------------------------------------------------------------------------------------
  666.  
  667. void FW_CPart::CloneInto(Environment* ev,
  668.                             ODDraftKey key,
  669.                             ODStorageUnit* toSU,
  670.                             ODFrame* scope)
  671. {        
  672.     ODStorageUnit* su = GetStorageUnit(ev);
  673.     ODDraft* fromDraft = su->GetDraft(ev);
  674.     ODDraft* toDraft = toSU->GetDraft(ev);
  675.     
  676.     FW_ASSERT((scope == NULL) || (scope != NULL && IsValidDisplayFrame(ev, scope->GetID(ev))));
  677.  
  678.     FW_CFrame *frame = scope == NULL ? NULL : FW_CFrame::ODtoFWFrame(ev, scope);
  679.     FW_ASSERT((scope == NULL) || (scope != NULL && frame != NULL));
  680.     
  681.     FW_CCloneInfo cloneInfo(ev, key, fromDraft, frame, 0);        // fromDraft->GetCloneKind(ev)
  682.     
  683.     FW_ASSERT(toDraft->GetPermissions(ev) >= kODDPSharedWrite);
  684.  
  685.     // [MH] As far as I know this has never been attempted before! We need to know what we are cloning to
  686.     // in order to determine the correct behavior, and also to allow the use of promises in cloneInto
  687.     
  688.     FW_StorageKinds storageKind = 0;
  689.     
  690.     // We  should never be asked to CloneInto  the part's storage unit
  691.     FW_ASSERT(!toSU->IsEqualTo(ev, su));
  692.     
  693.     if (toDraft->IsEqualTo(ev, fromDraft))  // if not the part, only a link uses the part draft.
  694.     {
  695.         storageKind = FW_kLinkStorage;
  696.     }
  697.     else if (toDraft->IsEqualTo(ev, FW_CSession::GetClipboard(ev)->GetContentStorageUnit(ev)->GetDraft(ev)))
  698.     {
  699.         storageKind = FW_kClipboardStorage;
  700.     }
  701.     
  702.     //  Craig Carper suspects that simply asking the d&d for its su may create a new draft, so 
  703.     // just assume that if it's none of the above, it must be d&d.
  704.     
  705.     else // if (toDraft->IsEqualTo->(ev, FW_CSession::GetDragAndDrop(ev)->GetContentStorageUnit(ev)->GetDraft(ev)))
  706.     {
  707.         storageKind = FW_kDragAndDropStorage;
  708.     }
  709.     
  710.     
  711.     FW_ASSERT(storageKind != 0);
  712.     
  713.     PrepContentProperty(ev, toSU, storageKind, TRUE);
  714.     if (fContent)
  715.         fContent->Externalize(ev, toSU, storageKind, &cloneInfo);
  716. }
  717.  
  718. //---------------------------------------------------------------------------------------
  719. //    FW_CPart::InternalizeContent
  720. //---------------------------------------------------------------------------------------
  721.  
  722. FW_Boolean FW_CPart::InternalizeContent(Environment* ev, ODStorageUnit* storageUnit, FW_CCloneInfo* cloneInfo)
  723. {
  724.     FW_Boolean result = TRUE;
  725.     
  726.     // ----- Simply forward to the content object if there is one -----
  727.     if (fContent)
  728.         result = fContent->Internalize(ev, storageUnit, FW_kPartStorage, cloneInfo);
  729.     
  730.     PrivSetDirty(ev, !result);
  731.     
  732.     return result;
  733. }
  734.  
  735. //---------------------------------------------------------------------------------------
  736. //    FW_CPart::PrivDeterminePreferredKind
  737. //---------------------------------------------------------------------------------------
  738.  
  739. void FW_CPart::PrivDeterminePreferredKind(Environment* ev, ODStorageUnit* storageUnit)
  740. {
  741.     // ----- Read in the preferred Kind -----
  742.     ODULong size;
  743.     FW_CAcquireODISOStr preferredKindISOStr = ODGetISOStrProp(ev, storageUnit, kODPropPreferredKind, kODISOStr, NULL, &size);
  744.  
  745.     // ----- Set the preferred kind -----
  746.     FW_CKind* preferredKind = NULL;
  747.     if ((const void*)preferredKindISOStr != NULL)
  748.         preferredKind = GetKind(ev, preferredKindISOStr);
  749.         
  750.     // ----- If I don't support the preferred kind or there is no preferred kind property use the first kind I support
  751.     // ----- as the preferred kind
  752.     if (preferredKind == NULL)
  753.     {
  754.         storageUnit->Focus(ev, kODPropContents, kODPosUndefined, NULL, 0, kODPosAll);
  755.         unsigned long numValues = storageUnit->CountValues(ev);
  756.         for (unsigned long index = 1; index <= numValues ; index++)
  757.         {
  758.             storageUnit->Focus(ev, kODPropContents, kODPosUndefined, NULL, index, kODPosUndefined);
  759.             FW_CAcquireODISOStr valueType = storageUnit->GetType(ev);
  760.             preferredKind = GetKind(ev, valueType);
  761.             if (preferredKind != NULL)
  762.                 break;
  763.         }
  764.     }
  765.     
  766.     FW_ASSERT(preferredKind != NULL);    // Otherwise why was I bound to this part?
  767.     ChangePreferredKind(ev, preferredKind);
  768. }
  769.  
  770. //---------------------------------------------------------------------------------------
  771. //    FW_CPart::ExternalizeContent
  772. //---------------------------------------------------------------------------------------
  773.  
  774. void FW_CPart::ExternalizeContent(Environment* ev, 
  775.                                 ODStorageUnit* storageUnit, 
  776.                                 FW_CCloneInfo* cloneInfo)
  777. {
  778.     if (storageUnit->GetDraft(ev)->GetPermissions(ev) >= kODDPSharedWrite)
  779.     {    
  780.         // [MH] we always need prepping because unless existing values are removed and replaced
  781.         // we can run into trouble with su ref's.  
  782.         
  783.         //if (fNeedPrepping) 
  784.         {
  785.             PrepContentProperty(ev, storageUnit, FW_kPartStorage, FALSE);
  786.             fNeedPrepping = FALSE;
  787.         }
  788.         
  789.         // ----- Externalize part specific data -----        
  790.         // Simply forward to the content object
  791.         if (fContent)
  792.             fContent->Externalize(ev, storageUnit, FW_kPartStorage, cloneInfo);
  793.     }
  794. }
  795.  
  796. //---------------------------------------------------------------------------------------
  797. //    FW_CPart::NewEventDispatcher
  798. //---------------------------------------------------------------------------------------
  799.  
  800. FW_CEventDispatcher* FW_CPart::NewEventDispatcher(Environment *ev)
  801. {
  802. FW_UNUSED(ev);
  803.  
  804.     return new FW_CEventDispatcher(this, fMenuBar);
  805. }
  806.  
  807. //----------------------------------------------------------------------------------------
  808. //    FW_CPart::NewPresentation    
  809. //----------------------------------------------------------------------------------------
  810.  
  811. FW_CPresentation* FW_CPart::NewPresentation(Environment *ev, 
  812.                                             FW_CSelection* selection,
  813.                                             ODTypeToken presentationType,
  814.                                             FW_ResourceID viewResourceID,
  815.                                             FW_ResourceID rootViewResourceID)
  816. {
  817.     return new FW_CPresentation(ev, this, selection, presentationType, viewResourceID, rootViewResourceID);
  818. }
  819.  
  820. //----------------------------------------------------------------------------------------
  821. //    FW_CPart::RegisterPresentation    
  822. //----------------------------------------------------------------------------------------
  823. //    the selection object will be owned by the presentation
  824.  
  825. FW_CPresentation* FW_CPart::RegisterPresentation(Environment *ev, 
  826.                                                 ODType presentationType,
  827.                                                 FW_Boolean defaultPresentation,
  828.                                                 FW_ResourceID viewResourceID,
  829.                                                 FW_ResourceID rootViewResourceID,
  830.                                                 FW_CSelection* selection)
  831. {
  832.     FW_CPresentation* presentation = NULL;
  833.     FW_VOLATILE(presentation);
  834.     
  835.     FW_TRY
  836.     {
  837.         ODTypeToken token = FW_CSession::Tokenize(ev, presentationType);
  838.     
  839.         // ----- Test that we don't register a presentation twice -----
  840.         FW_ASSERT(FindPresentation(ev, token) == NULL);
  841.     
  842.         presentation = NewPresentation(ev, selection, token, viewResourceID, rootViewResourceID);
  843.         
  844.         if (selection)
  845.             selection->PrivSetPresentation(presentation);
  846.         
  847.         PrivAddPresentation(presentation); 
  848.             
  849.         // ----- if flagged as default or first one -----
  850.         if (defaultPresentation || (fDefaultPresentation == NULL))
  851.             fDefaultPresentation = presentation;        
  852.     }
  853.     FW_CATCH_BEGIN
  854.     FW_CATCH_EVERYTHING()
  855.     {
  856.         if (presentation == NULL)
  857.             delete selection;        // Otherwise will be deleted by next line
  858.                 
  859.         delete presentation;
  860.         
  861.         FW_THROW_SAME();
  862.     }
  863.     FW_CATCH_END
  864.  
  865.     return presentation;
  866. }
  867.  
  868. //----------------------------------------------------------------------------------------
  869. //    FW_CPart::FindPresentation    
  870. //----------------------------------------------------------------------------------------
  871.  
  872. FW_CPresentation* FW_CPart::FindPresentation(Environment *ev, ODTypeToken presentationType) const
  873. {
  874.     FW_CPartPresentationIterator ite(this);
  875.     for (FW_CPresentation* presentation = ite.First(); ite.IsNotComplete(); presentation = ite.Next())
  876.     {
  877.         if (presentation->GetPresentationType(ev) == presentationType)
  878.             return presentation;
  879.     }
  880.     
  881.     return NULL;
  882. }
  883.  
  884. //----------------------------------------------------------------------------------------
  885. //    FW_CPart::CountDisplayFrame
  886. //----------------------------------------------------------------------------------------
  887.  
  888. unsigned long FW_CPart::CountDisplayFrame(Environment *ev) const
  889. {
  890.     unsigned long count = 0;
  891.     
  892.     FW_CPartPresentationIterator ite(this);
  893.     for (FW_CPresentation* presentation = ite.First(); ite.IsNotComplete(); presentation = ite.Next())
  894.     {
  895.         count += presentation->CountFrame(ev);
  896.     }
  897.     
  898.     return count;
  899. }
  900.  
  901. //---------------------------------------------------------------------------------------
  902. //    FW_CPart::NewLinkManager
  903. //---------------------------------------------------------------------------------------
  904.  
  905. FW_CLinkManager* FW_CPart::NewLinkManager(Environment *ev)
  906. {
  907. FW_UNUSED(ev);
  908.     // Must be overridden if part creates Links
  909.     return NULL;
  910. }
  911.  
  912. //---------------------------------------------------------------------------------------
  913. //    FW_CPart::GetPartName
  914. //---------------------------------------------------------------------------------------
  915.  
  916. FW_Boolean FW_CPart::GetPartName(Environment *ev, FW_CString& partName) const
  917. {
  918.     ODName*     windowName = NULL;
  919.     FW_Boolean     nameIsProperty = FALSE;
  920.  
  921.     windowName = ODGetITextProp(ev, fODPart->GetStorageUnit(ev), kODPropName, kODMacIText, windowName);
  922. //    windowName = ODGetPOName(ev, fODPart, NULL);
  923.  
  924.     if (windowName != NULL && GetITextStringLength(windowName) != 0)
  925.     {
  926.         partName = GetCStringFromIText(windowName);
  927.         nameIsProperty = TRUE;
  928.     }
  929.     else
  930.         partName = fPartUserName;
  931.         
  932.     if (windowName)
  933.         DisposeIText(windowName);
  934.         
  935.     return nameIsProperty;
  936. }
  937.  
  938. //---------------------------------------------------------------------------------------
  939. //    FW_CPart::PrivEnableMenuBar
  940. //---------------------------------------------------------------------------------------
  941. // This is called when opening/closing a modal dialog.
  942. // We keep a count of nested modal dialogs so that we don't re-enable the menu-bar 
  943. // if a modal dialog is still up
  944.  
  945. void FW_CPart::PrivEnableMenuBar(Environment *ev, FW_Boolean enable, FW_Boolean appleMenu)
  946. {
  947.     if (enable == false)
  948.         fModalDialogCount += 1;
  949.     else
  950.     {    
  951.         fModalDialogCount -= 1;
  952.         if (fModalDialogCount > 0) return;
  953.     }
  954.     
  955. #ifdef FW_BUILD_MAC
  956.     GetMenuBar(ev)->MacEnableMenuBar(ev, enable);
  957.     // We keep the Apple menu enabled for moveable dialog boxes
  958.     if (enable == false && appleMenu == true)
  959.         GetMenuBar(ev)->EnableCommand(ev, kODCommandAppleMenu, true);
  960. #endif
  961.  
  962. #ifdef FW_BUILD_WIN
  963.     // Windows does this automatically?
  964. #endif
  965. }
  966.  
  967. //---------------------------------------------------------------------------------------
  968. //    FW_CPart::InstallMenus
  969. //---------------------------------------------------------------------------------------
  970.  
  971. void FW_CPart::InstallMenus(Environment *ev, FW_CMenuBar* menuBar)
  972. {
  973.     if (menuBar)
  974.         menuBar->PrivDisplay(ev);
  975. }
  976.  
  977. //---------------------------------------------------------------------------------------
  978. //    FW_CPart::DoAbout
  979. //---------------------------------------------------------------------------------------
  980.  
  981. FW_Handled FW_CPart::DoAbout(Environment *ev)
  982. {
  983. FW_UNUSED(ev);
  984.  
  985.     return FW_kNotHandled;
  986. }
  987.  
  988. //----------------------------------------------------------------------------------------
  989. // FW_CPart::HandleMenu
  990. //----------------------------------------------------------------------------------------
  991.  
  992. FW_Handled FW_CPart::HandleMenu(Environment* ev, const FW_CMenuEvent& theMenuEvent)
  993. {
  994.     if (theMenuEvent.GetCommandID(ev) == kODCommandAbout)
  995.         return DoAbout(ev);
  996.     else
  997.         return FW_MEventHandler::HandleMenu(ev, theMenuEvent);
  998. }
  999.  
  1000. //---------------------------------------------------------------------------------------
  1001. //    FW_CPart::Changed
  1002. //---------------------------------------------------------------------------------------
  1003. //    ODF API
  1004.  
  1005. void FW_CPart::Changed(Environment *ev)
  1006. {
  1007.     GetDraft(ev)->SetChangedFromPrev(ev);
  1008.     
  1009.     PrivSetDirty(ev, TRUE);    
  1010. }
  1011.  
  1012. //---------------------------------------------------------------------------------------
  1013. //    FW_CPart::PrivSetDirty
  1014. //---------------------------------------------------------------------------------------
  1015.  
  1016. void FW_CPart::PrivSetDirty(Environment *ev, FW_Boolean state)
  1017. {
  1018.     // ----- Flag all kind as dirty -----
  1019.     FW_CPartKindIterator ite(this);
  1020.     for (FW_CKind* kind = ite.First(); ite.IsNotComplete();  kind = ite.Next())
  1021.         if (kind->ToBeExported(ev, FW_kPartStorage))
  1022.             kind->PrivSetDirty(ev, state, FW_kPartStorage);
  1023. }
  1024.  
  1025. //---------------------------------------------------------------------------------------
  1026. //    FW_CPart::PrivGetPresentation
  1027. //---------------------------------------------------------------------------------------
  1028.  
  1029. FW_CPresentation* FW_CPart::PrivGetPresentation(Environment *ev, ODFrame* odFrame) const
  1030. {
  1031.     ODTypeToken    presDefault = FW_CSession::Tokenize(ev, kODPresDefault);
  1032.     ODTypeToken token = presDefault;
  1033.     
  1034.     FW_CPresentation* presentation = NULL;
  1035.  
  1036.     if (odFrame != NULL)
  1037.         token = odFrame->GetPresentation(ev);
  1038.     
  1039.     if (token == presDefault)
  1040.         presentation = fDefaultPresentation;
  1041.     else
  1042.     {
  1043.         presentation = FindPresentation(ev, token);
  1044.         
  1045.         if (presentation == NULL)
  1046.             presentation = fDefaultPresentation;
  1047.     }
  1048.     
  1049.     return ValidatePresentation(ev, odFrame, presentation);
  1050. }
  1051.  
  1052. //---------------------------------------------------------------------------------------
  1053. //    FW_CPart::ValidatePresentation
  1054. //---------------------------------------------------------------------------------------
  1055.  
  1056. FW_CPresentation* FW_CPart::ValidatePresentation(Environment *ev, ODFrame* odFrame, FW_CPresentation *proposedPresentation) const
  1057. {
  1058. FW_UNUSED(ev);
  1059. FW_UNUSED(odFrame);
  1060.  
  1061.     return proposedPresentation;
  1062. }
  1063.  
  1064. //----------------------------------------------------------------------------------------
  1065. //    FW_CPart::HasSelectionFocus
  1066. //----------------------------------------------------------------------------------------
  1067.  
  1068. FW_Boolean FW_CPart::HasSelectionFocus(Environment *ev) const
  1069. {
  1070.     if (fLastActiveFrame)
  1071.     {
  1072.         return fLastActiveFrame->HasSelectionFocus(ev);
  1073.     }
  1074.     else
  1075.         return FALSE;
  1076. }
  1077.  
  1078. //----------------------------------------------------------------------------------------
  1079. //    FW_CPart::GetActiveFacet
  1080. //----------------------------------------------------------------------------------------
  1081.  
  1082. ODFacet* FW_CPart::GetActiveFacet(Environment *ev) const
  1083. {
  1084.     return (fLastActiveFrame != NULL) ? fLastActiveFrame->GetActiveFacet(ev) : NULL;
  1085. }
  1086.  
  1087. //----------------------------------------------------------------------------------------
  1088. //    FW_CPart::Release
  1089. //----------------------------------------------------------------------------------------
  1090. //    Call inherited first when overridden
  1091.  
  1092. void FW_CPart::Release(Environment *ev)
  1093. {
  1094.     unsigned long refcount = fODPart->GetRefCount(ev);
  1095.  
  1096.     // ------ The last refcount is caused by the register idle -----
  1097.     if (refcount == 1 && fIdler != NULL)
  1098.     {
  1099.         FW_ASSERT(fIdleCount == 1);    // We should only have the part register by now
  1100.         fIdler->UnregisterIdle(ev);
  1101.     }
  1102.     
  1103.     if (refcount == 0)
  1104.     {
  1105.         GetDraft(ev)->ReleasePart(ev, fODPart);
  1106.     }
  1107. }
  1108.  
  1109. //----------------------------------------------------------------------------------------
  1110. //    FW_CPart::ReleaseAll
  1111. //----------------------------------------------------------------------------------------
  1112. //    Call inherited first when overridden
  1113.  
  1114. void FW_CPart::ReleaseAll(Environment *ev)
  1115. {
  1116.     //     Will resolve or just delete my promises
  1117.     if (fDataInterchange)
  1118.         fDataInterchange->ResolveAllPromises(ev);
  1119.     
  1120.     // ----- Release part content
  1121.     if (fContent)
  1122.         fContent->ReleaseAll(ev);
  1123.  
  1124.     // ----- Delete any and all links
  1125.     if (fLinkManager)
  1126.         fLinkManager->RemoveAllLinks(ev);
  1127.     
  1128.     // ----- Release all display Frames
  1129.     FW_CPartPresentationIterator ite(this);
  1130.     for (FW_CPresentation* presentation = ite.First(); ite.IsNotComplete(); presentation = ite.Next())
  1131.     {
  1132.         presentation->ReleaseAll(ev);
  1133.     }
  1134.  
  1135. }
  1136.  
  1137. //----------------------------------------------------------------------------------------
  1138. //    FW_CPart::IsReadOnly
  1139. //----------------------------------------------------------------------------------------
  1140.  
  1141. FW_Boolean FW_CPart::IsReadOnly(Environment *ev) const
  1142. {
  1143.     return GetDraft(ev)->GetPermissions(ev) < kODDPSharedWrite;
  1144. }
  1145.  
  1146. //----------------------------------------------------------------------------------------
  1147. //    FW_CPart::GetDraft
  1148. //----------------------------------------------------------------------------------------
  1149.  
  1150. ODDraft* FW_CPart::GetDraft(Environment *ev) const
  1151. {
  1152.     return fODPart->GetStorageUnit(ev)->GetDraft(ev);
  1153. }
  1154.  
  1155. //----------------------------------------------------------------------------------------
  1156. //    FW_CPart::HandleAdjustMenus
  1157. //----------------------------------------------------------------------------------------
  1158. //    The part should have the last word in case it is readonly
  1159.  
  1160. FW_Handled FW_CPart::HandleAdjustMenus(Environment *ev, FW_CMenuBar* menuBar, FW_Boolean hasMenuFocus, FW_Boolean isRoot)
  1161. {    
  1162.     FW_Handled result = FW_MEventHandler::HandleAdjustMenus(ev, menuBar, hasMenuFocus, isRoot);
  1163.  
  1164.     // ------ Disable items we know have to be disabled ----- 
  1165.     if (hasMenuFocus)
  1166.     {
  1167.         if (IsReadOnly(ev))
  1168.         {
  1169.             menuBar->EnableCommand(ev, kODCommandPaste, FALSE);
  1170.             menuBar->EnableCommand(ev, kODCommandCut, FALSE);
  1171.             menuBar->EnableCommand(ev, kODCommandClear, FALSE);
  1172.             menuBar->EnableCommand(ev, kODCommandPasteAs, FALSE);
  1173.         }
  1174.  
  1175.         // Set the name in the About item 
  1176.         menuBar->SetItemString(ev, kODCommandAbout, fAboutString);
  1177.     }
  1178.     
  1179.     return result;
  1180. }
  1181.  
  1182. //----------------------------------------------------------------------------------------
  1183. //    FW_CPart::NewDocumentWindow
  1184. //----------------------------------------------------------------------------------------
  1185.  
  1186. FW_CWindow* FW_CPart::NewDocumentWindow(Environment* ev)
  1187. {
  1188.     FW_CPoint windSize(FW_kZeroPoint), windPos(FW_kZeroPoint);
  1189.     FW_CPresentation* presentation;
  1190.     FW_WindowStyle style;
  1191.         
  1192.     if (fDocumentWindowID != 0)
  1193.     {
  1194.         FW_PSharedLibraryResourceFile resFile(ev, fPartInstance);
  1195.         FW_PResource resource(ev, resFile, fDocumentWindowID, FW_kDocumentWindowResourceType);
  1196.         FW_PResourceSink sink(ev, resource);
  1197.         FW_CReadableStream stream(sink);
  1198.         
  1199.         stream >> windSize;
  1200.         stream >> windPos;
  1201.         stream >> style;
  1202.         
  1203.         ODTypeToken presentationToken = FW_ReadODTypeTokenFromStream(ev, stream);
  1204.         presentation = FindPresentation(ev, presentationToken);
  1205.     }
  1206.     else
  1207.     {
  1208.         presentation = PrivGetPresentation(ev, NULL);    // NULL means default presentation
  1209.         style = FW_kDocumentWindow;
  1210.     }
  1211.  
  1212.     FW_ASSERT(presentation);
  1213.     
  1214.     FW_CRect windRect;
  1215.     ::FW_GetMainScreenBounds(windRect);        
  1216.     
  1217.     if (windSize == FW_kZeroPoint)
  1218.         windSize = windRect.Size();    // I know it is too big but FW_CWindow::__ct will adjust it
  1219.     
  1220.     if (windPos == FW_kZeroPoint)
  1221.         windPos = windRect.TopLeft();
  1222.     
  1223.     return new FW_CWindow(ev,
  1224.                         this,
  1225.                          FW_CPart::fgViewAsFrameToken,
  1226.                         presentation,
  1227.                         windSize,
  1228.                         windPos,
  1229.                         style);
  1230. }
  1231.  
  1232. //----------------------------------------------------------------------------------------
  1233. //    FW_CPart::PrivCountIdleRegistering
  1234. //----------------------------------------------------------------------------------------
  1235.  
  1236. void FW_CPart::PrivCountIdleRegistering(FW_Boolean registering)
  1237. {
  1238.     if (registering)
  1239.         fIdleCount++;
  1240.     else
  1241.     {
  1242.         FW_ASSERT(fIdleCount >= 1);
  1243.         fIdleCount--;
  1244.     }
  1245. }
  1246.  
  1247. //---------------------------------------------------------------------------------------
  1248. //    FW_CPart::IsValidDisplayFrame
  1249. //---------------------------------------------------------------------------------------
  1250.  
  1251. FW_Boolean FW_CPart::IsValidDisplayFrame(Environment* ev, ODStorageUnitID displayFrameID) const
  1252. {
  1253.     FW_CPartFrameIterator ite(ev, this);
  1254.     for (FW_CFrame* frame = ite.First(ev); ite.IsNotComplete(ev); frame = ite.Next(ev))
  1255.     {
  1256.         if (frame->GetID(ev) == displayFrameID)
  1257.             return TRUE;
  1258.     }
  1259.     
  1260.     return FALSE;
  1261. }
  1262.  
  1263. //---------------------------------------------------------------------------------------
  1264. //    FW_CPart::NewDataInterchange
  1265. //---------------------------------------------------------------------------------------
  1266.  
  1267. FW_CDataInterchange* FW_CPart::NewDataInterchange(Environment* ev)
  1268. {
  1269.     return new FW_CDataInterchange(ev, this);
  1270. }
  1271.  
  1272. //---------------------------------------------------------------------------------------
  1273. //    FW_CPart::LinkStatusChanged
  1274. //---------------------------------------------------------------------------------------
  1275.  
  1276. void FW_CPart::LinkStatusChanged(Environment *ev, ODFrame* odFrame)
  1277. {
  1278. FW_UNUSED(ev);
  1279. FW_UNUSED(odFrame);
  1280.     // Nothing to do. See FW_CEmbeddingPart::LinkStatusChanged
  1281. }
  1282.  
  1283. //---------------------------------------------------------------------------------------
  1284. //    FW_CPart::Purge
  1285. //---------------------------------------------------------------------------------------
  1286.  
  1287. ODSize FW_CPart::Purge(Environment *ev, ODSize size)
  1288. {
  1289. FW_UNUSED(ev);
  1290. FW_UNUSED(size);
  1291.     return 0;
  1292. }
  1293.  
  1294. //---------------------------------------------------------------------------------------
  1295. // FW_CPart::SetPrintInfo
  1296. //---------------------------------------------------------------------------------------
  1297.  
  1298. void FW_CPart::SetPrintInfo(FW_CPrintInfo* printInfo)
  1299. {
  1300.     fPrintInfo = printInfo;
  1301. }
  1302.  
  1303. //---------------------------------------------------------------------------------------
  1304. // FW_CPart::GetPrintInfo
  1305. //---------------------------------------------------------------------------------------
  1306.  
  1307. FW_CPrintInfo* FW_CPart::GetPrintInfo() const
  1308. {
  1309.     return fPrintInfo;
  1310. }
  1311.  
  1312. //---------------------------------------------------------------------------------------
  1313. // FW_CPart::PrintInfoChanged
  1314. //---------------------------------------------------------------------------------------
  1315.  
  1316. void FW_CPart::PrintInfoChanged(Environment *ev, FW_CPrintInfo* printInfo)
  1317. {
  1318. FW_UNUSED(ev);
  1319. FW_UNUSED(printInfo);
  1320.     // Nothing to do.
  1321. }
  1322.  
  1323. //---------------------------------------------------------------------------------------
  1324. // FW_CPart::RegisterKind
  1325. //---------------------------------------------------------------------------------------
  1326.  
  1327. FW_CKind* FW_CPart::RegisterKind(Environment *ev,
  1328.                                 ODValueType kind,
  1329.                                 FW_StorageKinds storageKind,
  1330.                                 FW_ImportExport importExport)
  1331. {
  1332.     FW_CKind* theKind = new FW_CKind(ev, this, kind, storageKind, importExport);
  1333.     fKinds->AddLast(theKind);
  1334.     return theKind;
  1335. }
  1336.  
  1337. //---------------------------------------------------------------------------------------
  1338. // FW_CPart::RegisterKind
  1339. //---------------------------------------------------------------------------------------
  1340.  
  1341. FW_CKind* FW_CPart::RegisterKind(Environment *ev,
  1342.                                 ODPlatformType platformType,
  1343.                                 ODPlatformTypeSpace typeSpace,
  1344.                                 FW_StorageKinds storageKind,
  1345.                                 FW_ImportExport importExport)
  1346. {
  1347.     // [HLX] I need to do some checking on the typeSpace/storageKind
  1348.     ODTranslation *translate = FW_CSession::GetTranslation(ev);
  1349.     FW_CAcquireODISOStr type = translate->GetISOTypeFromPlatformType(ev, platformType, typeSpace);
  1350.     return RegisterKind(ev, type, storageKind, importExport);
  1351. }
  1352.  
  1353. //----------------------------------------------------------------------------------------
  1354. //    FW_CPart::GetSupportedKind
  1355. //----------------------------------------------------------------------------------------
  1356. //    Tests and returns that a storage unit has a supported kind for import
  1357.  
  1358. FW_CKind* FW_CPart::GetSupportedKind(Environment *ev, 
  1359.                                      ODStorageUnit *su, 
  1360.                                      FW_StorageKinds storageKind) const
  1361. {
  1362.     FW_CPartKindIterator ite(this);
  1363.     for (FW_CKind* kind = ite.First(); ite.IsNotComplete(); kind = ite.Next())
  1364.     {
  1365.         if (kind->ImportSupported(ev, storageKind))
  1366.             if (su->Exists(ev, kODPropContents, kind->GetType(ev), 0))
  1367.                 return kind;
  1368.     }
  1369.     
  1370.     return NULL;
  1371. }
  1372.  
  1373. //---------------------------------------------------------------------------------------
  1374. //    FW_CPart::ChangePreferredKind
  1375. //---------------------------------------------------------------------------------------
  1376. //    Returns true if the preferred kind has really been changed
  1377.  
  1378. FW_Boolean FW_CPart::ChangePreferredKind(Environment *ev, FW_CKind* newPreferredKind)
  1379. {
  1380.     if (fPreferredKind != newPreferredKind)
  1381.     {
  1382.         fPreferredKind->PrivSetAsPreferredKind(ev, FALSE);
  1383.         newPreferredKind->PrivSetAsPreferredKind(ev, TRUE);
  1384.         fPreferredKind = newPreferredKind;
  1385.         fNeedPrepping = TRUE;    // I changed the preferred kind. I need to reprep the storage unit
  1386.         return TRUE;
  1387.     }
  1388.     
  1389.     return FALSE;    // nothing has changed
  1390. }
  1391.  
  1392. //------------------------------------------------------------------------------
  1393. // FW_CPart::GetKind
  1394. //------------------------------------------------------------------------------
  1395.  
  1396. FW_CKind* FW_CPart::GetKind(Environment* ev, ODType type) const
  1397. {
  1398.     FW_CPartKindIterator ite(this);
  1399.     for (FW_CKind* kind = ite.First(); ite.IsNotComplete();  kind = ite.Next())
  1400.     {
  1401.         if (kind->IsEqual(ev, type))
  1402.             return kind;
  1403.     }
  1404.     
  1405.     return NULL;
  1406. }
  1407.  
  1408. //---------------------------------------------------------------------------------------
  1409. // FW_CPart::PrivAddPresentation
  1410. //---------------------------------------------------------------------------------------
  1411.  
  1412. void FW_CPart::PrivAddPresentation(FW_CPresentation* presentation)
  1413. {
  1414.     fPresentations->AddLast(presentation);
  1415. }
  1416.  
  1417. //---------------------------------------------------------------------------------------
  1418. // FW_CPart::PrivRemovePresentation
  1419. //---------------------------------------------------------------------------------------
  1420.  
  1421. void FW_CPart::PrivRemovePresentation(FW_CPresentation* presentation)
  1422. {
  1423.     fPresentations->Remove(presentation);
  1424. }
  1425.  
  1426. //---------------------------------------------------------------------------------------
  1427. // FW_CPart::PrivShowErrorAlert
  1428. //---------------------------------------------------------------------------------------
  1429. void FW_CPart::PrivShowErrorAlert(Environment* ev, short stringResID, short messageID)
  1430. {
  1431.     FW_CFrame* frame = this->GetLastActiveFrame(ev);
  1432.     FW_ASSERT(frame);
  1433.     
  1434.     FW_CWindow* window = frame->GetWindow(ev);
  1435.     FW_ASSERT(window);
  1436.     
  1437.     
  1438.     // ----- Activate the frame's window -----
  1439.     if (!window->IsActive(ev))
  1440.         window->Select(ev);    
  1441.         
  1442.     FW_ASSERT(window->IsActive(ev));
  1443.     
  1444.     if (window->IsActive(ev))
  1445.     {
  1446.         FW_CString partName;
  1447.         this->GetPartName(ev, partName);
  1448.         
  1449.         FW_CString message;
  1450.         ::FW_PrivLoadMessageString(ev, stringResID, messageID, message);
  1451.     
  1452.         ::FW_ErrorAlert(partName, message);
  1453.     }
  1454. }
  1455.  
  1456. //----------------------------------------------------------------------------------------
  1457. //    FW_CPart::SetAboutString
  1458. //----------------------------------------------------------------------------------------
  1459.  
  1460. void FW_CPart::SetAboutString(const FW_CString& string)
  1461. {
  1462.     fAboutString = string;
  1463. }
  1464.  
  1465. //----------------------------------------------------------------------------------------
  1466. // FW_CPart::GetPartWindow
  1467. //----------------------------------------------------------------------------------------
  1468.  
  1469. FW_CWindow* FW_CPart::GetPartWindow(Environment* ev) const
  1470. {
  1471.     return fPartWindowFrame ? fPartWindowFrame->GetWindow(ev) : NULL;
  1472. }
  1473.  
  1474. //----------------------------------------------------------------------------------------
  1475. //    FW_CPart::OpenPartWindow
  1476. //----------------------------------------------------------------------------------------
  1477.  
  1478. ODID FW_CPart::OpenPartWindow(Environment* ev, FW_CFrame* sourceFrame, ODFacet* sourceFacet)
  1479. {    
  1480.     FW_ASSERT(sourceFrame);    
  1481.         
  1482.     FW_CWindow* window = NULL;
  1483.     
  1484.     if (fPartWindowFrame != NULL)
  1485.     {
  1486.         window = fPartWindowFrame->GetWindow(ev);
  1487.     }
  1488.     else
  1489.     {
  1490.         if (sourceFacet == NULL)
  1491.         {
  1492.             FW_CFrameFacetIterator ite(ev, sourceFrame);
  1493.             sourceFacet = ite.First(ev);
  1494.         }
  1495.         FW_ASSERT(sourceFacet != NULL);
  1496.         
  1497.         // ----- Invalid all my frames if iconized -----
  1498.         PrivInvalidateIconizedFrames(ev);
  1499.         
  1500.         // ----- Calculate suggested WindowRect and WindowTitle -----
  1501.         FW_CRect frameBounds = sourceFrame->GetBounds(ev);
  1502.         FW_FrameToWindow(ev, sourceFacet, frameBounds);
  1503.  
  1504.         sourceFrame->GetWindow(ev)->WindowToScreen(ev, frameBounds);
  1505. #ifdef FW_BUILD_MAC
  1506.         FW_PlatformRect sourceRect = frameBounds.AsPlatformRect();
  1507. #endif
  1508.         frameBounds.Offset(FW_IntToFixed(20), FW_IntToFixed(20));
  1509. #ifdef FW_BUILD_MAC
  1510.         FW_PlatformRect toRect = frameBounds.AsPlatformRect();
  1511. #endif
  1512.         
  1513.         FW_CString255 partName;
  1514.         sourceFrame->GetPart(ev)->GetPartName(ev, partName);
  1515.     
  1516.         window = sourceFrame->NewPartWindow(ev, frameBounds, partName);        
  1517.  
  1518. #ifdef FW_BUILD_MAC
  1519.         ::ZoomRects(&sourceRect, &toRect, 12, zoomAccelerate);
  1520. #endif
  1521.     
  1522.         window->Show(ev);    // ATTENTION: Show should be before Select
  1523.         
  1524.         FW_CAcquiredODWindow odWindow = window->AcquireODWindow(ev);
  1525.         
  1526.         fPartWindowFrame = FW_CFrame::ODtoFWFrame(ev, odWindow->GetRootFacet(ev)->GetFrame(ev));
  1527.         FW_ASSERT(fPartWindowFrame != NULL);
  1528.     }
  1529.         
  1530.     window->Select(ev);
  1531.     
  1532.     return window->GetID(ev);
  1533. }
  1534.  
  1535. //----------------------------------------------------------------------------------------
  1536. // FW_CPart::PrivDisplayFrameRemoved
  1537. //----------------------------------------------------------------------------------------
  1538.  
  1539. void FW_CPart::PrivDisplayFrameRemoved(Environment *ev, ODFrame* frame, FW_Boolean toStorage)
  1540. {
  1541.     FW_CFrame* fwFrame = FW_CFrame::ODtoFWFrame(ev, frame);
  1542.     FW_ASSERT(fwFrame != NULL);
  1543.     
  1544.     // ----- if this frame was the "Open in Window" frame then ....
  1545.     if (fwFrame == fPartWindowFrame)
  1546.     {
  1547.         fPartWindowFrame = NULL;
  1548.         PrivInvalidateIconizedFrames(ev);
  1549.     }
  1550.     
  1551.     // ----- Notify the presentation that a frame is going away
  1552.     fwFrame->GetPresentation(ev)->PrivFrameRemoved(ev, fwFrame, toStorage);
  1553. }
  1554.  
  1555. //----------------------------------------------------------------------------------------
  1556. //    FW_CPart::PrivInvalidateIconizedFrames
  1557. //----------------------------------------------------------------------------------------
  1558.  
  1559. void FW_CPart::PrivInvalidateIconizedFrames(Environment *ev)
  1560. {
  1561.     FW_CPartFrameIterator ite(ev, this);
  1562.     for (FW_CFrame* aFrame = ite.First(ev); ite.IsNotComplete(ev); aFrame = ite.Next(ev))
  1563.     {
  1564.         ODTypeToken viewType = aFrame->GetViewType(ev);
  1565.         if (viewType == FW_CPart::fgViewAsLargeIconToken || viewType == FW_CPart::fgViewAsSmallIconToken)
  1566.             aFrame->GetODFrame(ev)->Invalidate(ev, NULL, NULL);
  1567.     }    
  1568. }
  1569.