home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / OpenDoc / ProcessMap / $Sources / CPProcessMap.InEx.cpp < prev    next >
Encoding:
Text File  |  1995-04-28  |  14.3 KB  |  418 lines  |  [TEXT/MPCC]

  1. //----------------------------------------------------------------------------------------
  2. // UI Events protocol
  3. //----------------------------------------------------------------------------------------
  4.  
  5. #ifndef _PROCESSMAP_
  6. #include "CPProcessMap.h"
  7. #endif
  8.  
  9. //----------------------------------------------------------------------------------------
  10.  
  11. void CPProcessMap::InitPart(Environment* ev, ODStorageUnit* storageUnit, ODPart* self)
  12. {
  13.     // CodeWarrior: Cmd-Click or Search:Find Definition • Explain_InitPart
  14.     EnteringMethod("\pCPProcessMap::InitPart");
  15.  
  16.     this->PrivInitProcessMap(ev, storageUnit, self);
  17.  
  18.     // remove after c18
  19.     storageUnit->AddProperty(ev, kODPropContents)->AddValue(ev, kProcessMapKind);
  20.     
  21.     {
  22.         CUsingLibraryResources fil;
  23.         ::GetIndString(fTextData, kContentStringResID, kContentStringID);
  24.     }        // Use CUsingLibraryResources to use your part's resource fork.
  25.             // Make it go out of scope when you are done.
  26.  
  27.     // Initialize your other fields here.
  28.     fDirty = kODTrue;
  29.         // Make sure our content is written out at least once.
  30. }
  31.  
  32. //----------------------------------------------------------------------------------------
  33.  
  34. void CPProcessMap::InitPartFromStorage(Environment* ev, ODStorageUnit* storageUnit, ODPart* self)
  35. {
  36.     // CodeWarrior: Cmd-Click or Search:Find Definition • Explain_InitPartFromStorage
  37.     EnteringMethod("\pCPProcessMap::InitPartFromStorage");
  38.  
  39.     TRY
  40.         // To allow editor swapping (translation) at runtime, OpenDoc requires
  41.         // that we pass in a "reference" to ourselves when interacting with the
  42.         // API (ie. WindowState::RegisterWindow(), Dispatcher::RegisterIdle, etc).
  43.         // The "partWrapper" passed to us here and in InitPart is the
  44.         // "reference" OpenDoc is asking us to use.
  45.         fSelf = self;
  46.             
  47.         // Are we being opened from a read-only draft? If so, we cannot
  48.         // write anything back out to our storage unit.
  49.         fReadOnlyStorage = ( storageUnit->GetDraft(ev)->
  50.                                         GetPermissions(ev) == kDPReadOnly );
  51.             
  52.         // Call the common initialization code to get set up.
  53.         this->PrivInitProcessMap(ev, storageUnit, self);
  54.     
  55.         // Read in the state the part was in when it was last Externalized.
  56.         // This allows the part to present the same "environment" the user
  57.         // had the part set up in the last time it was edited.
  58.         this->PrivInternalizeStateInfo(ev, storageUnit);
  59.     
  60.         // Read in the contents for your part editor.
  61.         this->PrivInternalizeContent(ev, storageUnit);
  62.  
  63.     CATCH_ALL
  64.         ODSetSOMException(ev, ErrorCode());
  65.  
  66.         // Clean up will occur in the destructor which will be called
  67.         // shortly after we THROW the error.
  68.     ENDTRY
  69. }
  70.  
  71. //----------------------------------------------------------------------------------------
  72.  
  73. void CPProcessMap::PrivInitProcessMap(Environment* ev, ODStorageUnit* storageUnit, ODPart* self)
  74. {
  75.     EnteringMethod("\pCPProcessMap::PrivInitProcessMap");
  76.  
  77.     // Save off some references.
  78.     fSelf = self;
  79.     fStorageUnit = storageUnit;
  80.  
  81.     fSession = fStorageUnit->GetSession(ev);
  82.         // As your part grows, add your initialization that is common
  83.         // between InitPart and InitPartFromStorage here.
  84.         // Note that GetStorageUnit can be used, since just prior to
  85.         // calling this method, InitPart calledInitPersistentObject or
  86.         // InitPartFromStorage called InitPersistentObjectFromStorage.
  87.  
  88.     fSelectionFocus = fSession->Tokenize(ev, kODSelectionFocus);
  89.     fMenuFocus      = fSession->Tokenize(ev, kODMenuFocus);
  90.     fKeyFocus       = fSession->Tokenize(ev, kODKeyFocus);
  91.     fModalFocus     = fSession->Tokenize(ev, kODModalFocus);
  92.  
  93.     fFocusSet = fSession->GetArbitrator(ev)->CreateFocusSet(ev);
  94.     fFocusSet->Add(ev, fKeyFocus);
  95.     fFocusSet->Add(ev, fMenuFocus);
  96.     fFocusSet->Add(ev, fSelectionFocus);
  97.  
  98.     fMenuBar = fSession->GetWindowState(ev)->CopyBaseMenuBar(ev);
  99.  
  100.     {
  101.         CUsingLibraryResources fil;
  102.         fMenu = ::GetMenu(kMenuID);
  103.         if (fMenu)
  104.             ::DetachResource((Handle)fMenu);        // Must detach it!
  105.     }
  106.  
  107.     if (!fMenu)
  108.         DebugStr("\pCPProcessMap::PrivInitProcessMap -- couldn't create menu.");
  109.             // We are using debug messages
  110.             // for these types of errors.  When SOM is available, this issue
  111.             // will be addressed correctly.
  112.  
  113.     fMenuBar->AddMenuLast(ev, kMenuID, fMenu, fSelf);
  114.  
  115.     for(int i=1;i<=MAX_PROCESS;i++)
  116.     {
  117.         fMenuBar->RegisterCommand(ev, kMenuID+i,kMenuID,i);
  118.     }
  119.     lLastTick = ::TickCount();
  120.     sNumOfProcess = 0;
  121.     PrevName[0] = 0;
  122.     fHorizontal = true;
  123.     ::TextFont(systemFont);
  124.     FontInfo fi;
  125.     ::GetFontInfo(&fi);
  126.     sSysFontHeight = fi.ascent + fi.descent;
  127.     sSysFontLeading= fi.leading;
  128.  
  129.     ::Gestalt(gestaltLogicalRAMSize , &lLogicalSize );
  130.     ::Gestalt(gestaltPhysicalRAMSize, &lPhysicalSize);
  131.  
  132.     THz theZone = ::SystemZone();
  133.     lSystemHeap = (long)theZone->bkLim;
  134.  
  135.     lAboveBufPtr= (long)::LMGetBufPtr();
  136.  
  137.     aProcesses = new CMyProcess[MAX_PROCESS];
  138.  
  139.     fSession->GetDispatcher(ev)->RegisterIdle(ev, fSelf, NULL, 1);
  140. }
  141.  
  142. //----------------------------------------------------------------------------------------
  143.  
  144. void CPProcessMap::PrivInternalizeStateInfo(Environment* ev, ODStorageUnit* storageUnit)
  145. {
  146.     // Description:    This method could be used to read in settings
  147.     //                information for the part. This would be information
  148.     //                related to the workings of the part editor, not the
  149.     //                content.
  150.     
  151.     EnteringMethod("\pPrivInternalizeStateInfo");
  152.  
  153.     ODStorageUnitRef    weakRef;
  154.     ODULong                size;
  155.  
  156.     // Internalize the part's display frame list.
  157.  
  158.     if ( storageUnit->Exists(ev, kODPropDisplayFrames, kODWeakStorageUnitRefs, 0) )
  159.     {
  160.         storageUnit->Focus(ev, kODPropDisplayFrames, kODPosUndefined,
  161.                                     kODWeakStorageUnitRefs, 0, kODPosUndefined);
  162.                                     
  163.         size = storageUnit->GetSize(ev);
  164.         storageUnit->SetOffset(ev, 0);    
  165.     
  166.         for (ODULong offset = 0; offset < size; offset += 4)
  167.         {    
  168.             TRY    
  169.                 StorageUnitGetValue(storageUnit, ev, sizeof(ODStorageUnitRef), (ODPtr)&weakRef);
  170.                 
  171.                 if ( storageUnit->IsValidStorageUnitRef(ev, weakRef) )
  172.                 {        
  173.                     ODFrame *frame = storageUnit->GetDraft(ev)->
  174.                         GetFrame(ev, storageUnit->GetIDFromStorageUnitRef(ev, weakRef));
  175.                     fDisplayFrames.Add(frame);
  176.                 }
  177.             SOM_ENDTRY
  178.         }
  179.     }
  180. }
  181.  
  182. //----------------------------------------------------------------------------------------
  183.  
  184. void CPProcessMap::PrivInternalizeContent(Environment* ev, ODStorageUnit* storageUnit)
  185. {
  186.     // Description:    This method is called during interalization of the
  187.     //                part. The content of the part should be read in.
  188.     EnteringMethod("\pInternalizeContent");
  189.     
  190.     storageUnit->Focus(ev, kODPropContents, kODPosSame,
  191.                        kProcessMapKind, 0, kODPosSame);
  192.     fTextData[0] = (unsigned char)storageUnit->GetSize(ev);
  193.     StorageUnitGetValue(storageUnit, ev, fTextData[0], &fTextData[1]);
  194. }
  195.  
  196. //----------------------------------------------------------------------------------------
  197.  
  198. void CPProcessMap::Externalize(Environment* ev)
  199. {
  200.     // CodeWarrior: Cmd-Click or Search:Find Definition • Explain_Externalize
  201.     EnteringMethod("\pCPProcessMap::Externalize");
  202.  
  203.     if (fDirty && !fReadOnlyStorage)
  204.     {
  205.         // Get our storage unit.
  206.         ODStorageUnit* storageUnit = fSelf->GetStorageUnit(ev);
  207.  
  208.         // Verify that the storage unit has the appropriate properties
  209.         // and values to allow us to run. If not, add them.
  210.         this->PrivCheckAndAddProperties(ev, storageUnit);
  211.     
  212.         // Verify that there are no "bogus" values in the Content
  213.         // property.
  214.         this->PrivCleanContentProperty(ev, storageUnit);
  215.     
  216.         // Write out the part's state information.
  217.         this->PrivExternalizeStateInfo(ev, storageUnit, 0, kODNULL);
  218.             
  219.         // Write out the part's content.
  220.         this->PrivExternalizeContent(ev, storageUnit);
  221.  
  222.         // Update the "last modified" date and other part annotations.
  223.         UpdateModificationInfo(ev, storageUnit);
  224.  
  225.         // Flag our part as no longer being dirty.
  226.         fDirty = kODFalse;
  227.     }
  228. }
  229.  
  230. //----------------------------------------------------------------------------------------
  231.  
  232. static ODBoolean PrivGetUserCatFromCat(ODNameSpaceManager* theNmSpcMgr, 
  233.                                     ODType category, ODIText** name)
  234. {
  235.     ODBoolean result = kODFalse ;
  236.  
  237.     Environment* ev = somGetGlobalEnvironment();
  238.  
  239.         // look it up in the spaceName namespace
  240.     ODObjectNameSpace* userStringNameSpace = 
  241.         (ODObjectNameSpace*)theNmSpcMgr->HasNameSpace( ev, kODCategoryUserString );
  242.  
  243.     if (userStringNameSpace)
  244.         result = userStringNameSpace->GetEntry( ev, category, (ODObject**)name );
  245.     return result ;
  246. }
  247.  
  248. void CPProcessMap::PrivCheckAndAddProperties(Environment* ev, ODStorageUnit* storageUnit)
  249. {
  250.     // Description:    This method is called during the creation of
  251.     //                stationery, to prepare a storage unit, and during
  252.     //                externalization, to verify that all the properties we
  253.     //                need are present.
  254.     //
  255.     //                The part adds the default content property, a
  256.     //                preferred editor property (to aid in part binding), 
  257.     //                and a default name for the part.
  258.  
  259.     EnteringMethod("\pPrivCheckAndAddProperties");
  260.  
  261.     // Create our content property and preferred content property kind.
  262.  
  263.     if ( !storageUnit->Exists(ev, kODPropContents, kODNULL, 0) )
  264.         storageUnit->AddProperty(ev, kODPropContents);
  265.     if ( !storageUnit->Exists(ev, kODPropContents, kProcessMapKind, 0) )
  266.         storageUnit->AddValue(ev, kProcessMapKind);
  267.  
  268.     if ( !storageUnit->Exists(ev, kODPropPreferredKind, kODNULL, 0) )
  269.         storageUnit->AddProperty(ev, kODPropPreferredKind);
  270.     if ( !storageUnit->Exists(ev, kODPropPreferredKind, kODISOStr, 0) )
  271.     {
  272.         storageUnit->AddValue(ev, kODISOStr);
  273.         
  274.         // Since we are setting up the preferred kind property, we just write
  275.         // out our default "kind" for the editor. We can write out the user
  276.         // chosen kind in the PrivExternalizeStateInfo method.
  277.  
  278.         StorageUnitSetValue(storageUnit, ev, ODISOStrLength(kProcessMapKind), kProcessMapKind);
  279.     }
  280.     
  281.     // Add our display frame list.
  282.     if ( !storageUnit->Exists(ev, kODPropDisplayFrames, kODNULL, 0) )
  283.         storageUnit->AddProperty(ev, kODPropDisplayFrames);
  284.     if ( !storageUnit->Exists(ev, kODPropDisplayFrames, kODWeakStorageUnitRefs, 0) )
  285.         storageUnit->AddValue(ev, kODWeakStorageUnitRefs);
  286.  
  287.     // Parts by default have no name, though one is visible from 
  288.     // the part info dialog and is required during Drag&Drop to the
  289.     // Finder. We check for existence of the name property. If there
  290.     // is none, we add it; if there is, we focus to it.
  291.  
  292.     if ( !storageUnit->Exists(ev, kODPropName, kODMacIText, 0) )
  293.     {
  294.         storageUnit->AddProperty(ev, kODPropName)->AddValue(ev, kODMacIText);
  295.     
  296.         // Generate a default name for the part using the category user string.
  297.         ODNameSpaceManager* nsMgr = fSelf->GetStorageUnit(ev)->
  298.                     GetSession(ev)->GetNameSpaceManager(ev);
  299.                     
  300.         // Get the category string from the category name space.
  301.         ODIText* defaultName;
  302.         if ( PrivGetUserCatFromCat(nsMgr, kODCategorySampledSound, &defaultName) )
  303.         {
  304.             if ( storageUnit->Exists(ev, kODPropName, kODMacIText, 0) )
  305.             {
  306.                 ODSetITextProp(ev, storageUnit, kODPropName, kODMacIText, defaultName);
  307.             }
  308.         }
  309.                 
  310.         // Do not dispose defaultName!!!
  311.     }
  312. }
  313.  
  314. //----------------------------------------------------------------------------------------
  315.  
  316. void CPProcessMap::PrivCleanContentProperty(Environment* ev, ODStorageUnit* storageUnit)
  317. {
  318.     // Description:    This method is called during exteralization of the
  319.     //                part. The part should remove any value in the content property
  320.     //                that it cannot "accurately" write to.
  321.     EnteringMethod("\pPrivCleanContentProperty");
  322.  
  323.     storageUnit->Focus(ev, kODPropContents, kODPosUndefined, kODNULL, 0, kODPosAll);
  324.     
  325.     ODULong numValues = storageUnit->CountValues(ev);
  326.     
  327.     for (ODULong index = numValues; index > 1; index--)
  328.     {
  329.         // Index from 1 to n through the values.
  330.         storageUnit->Focus(ev, kODPropContents, kODPosUndefined, 
  331.                                 kODNULL, index, kODPosUndefined);
  332.         ODValueType value = storageUnit->GetType(ev);
  333.         
  334.         // If the value type is not one we support, remove it.
  335.         if ( ODISOStrCompare(value, kProcessMapKind) != 0 )
  336.             storageUnit->Remove(ev);
  337.     }
  338. }
  339.  
  340. //----------------------------------------------------------------------------------------
  341.  
  342. void CPProcessMap::PrivExternalizeStateInfo(Environment*        ev,
  343.                                        ODStorageUnit*    storageUnit,
  344.                                        ODDraftKey        key,
  345.                                        ODFrame*            scopeFrame)
  346. {
  347.     // Description:    This method is called during externalization of the
  348.     //                part. The current "state" of the editor should be
  349.     //                written out. This "state" information may be lost
  350.     //                during Data Interchange operations, so the part needs
  351.     //                to recover gracefully if information is missing or
  352.     //                incomplete.
  353.     
  354.     EnteringMethod("\pPrivExternalizeStateInfo");
  355.  
  356.     ODStorageUnitRef    weakRef;
  357.     ODFrame*            frame;
  358.     ODID                frameID;
  359.     ODID                scopeFrameID = ( scopeFrame ? scopeFrame->GetID(ev) : 0 );
  360.     ODDraft*            fromDraft = fSelf->GetStorageUnit(ev)->GetDraft(ev);
  361.     
  362.     // Externalize the part's display frame list.
  363.     storageUnit->Focus(ev, kODPropDisplayFrames, kODPosUndefined,
  364.                                 kODWeakStorageUnitRefs, 0, kODPosUndefined);
  365.     
  366.     // Persistent object references are stored in a side table, rather than
  367.     // in the property/value stream. Thus, deleting the contents of a value
  368.     // will not "delete" the references previously written to that value. To
  369.     // completely "delete" all references written to the value, we must
  370.     // remove the value and add it back.
  371.     storageUnit->Remove(ev);
  372.     storageUnit->AddValue(ev, kODWeakStorageUnitRefs);
  373.  
  374.     for (FrameLink* link = fDisplayFrames.First(); link->Frame(); link = link->Next() )
  375.     {
  376.         frame = (ODFrame*) link->Frame();
  377.         frameID = frame->GetID(ev);
  378.         
  379.         // If a draft key exists, then we are being cloned to another draft.
  380.         // We must "weak" clone our display frame and reference the cloned
  381.         // frame. The part re-uses the frameID variable so there aren't two
  382.         // different GetWeakStorageUnitRef calls.
  383.         if ( key )
  384.             frameID = fromDraft->WeakClone(ev, key, frameID, 0, scopeFrameID);
  385.         
  386.         // Write out weak references to each of the part's display frames.
  387.         storageUnit->GetWeakStorageUnitRef(ev, frameID, weakRef);
  388.         TRY
  389.             StorageUnitSetValue(storageUnit, ev, sizeof(ODStorageUnitRef), (ODPtr)&weakRef);
  390.         SOM_ENDTRY
  391.     }
  392. }
  393.  
  394. //----------------------------------------------------------------------------------------
  395.  
  396. void CPProcessMap::PrivExternalizeContent(Environment* ev, ODStorageUnit* storageUnit)
  397. {
  398.     // Description:    This method is called during externalization of the
  399.     //                part. The content of the part should be written out.
  400.     EnteringMethod("\pPrivExternalizeContent");
  401.  
  402.     storageUnit->Focus(ev, kODPropContents, kODPosSame,
  403.                        kProcessMapKind, 0, kODPosSame);
  404.         // Focus on content property.
  405.  
  406.     StorageUnitSetValue(fStorageUnit, ev, fTextData[0], &fTextData[1]);
  407.         // Now we write out the property.
  408. }
  409.  
  410. //----------------------------------------------------------------------------------------
  411.  
  412. void CPProcessMap::PrivSetDirty(Environment* ev)
  413. {
  414.     fDirty = kODTrue;
  415.     fStorageUnit->GetDraft(ev)->SetChangedFromPrev(ev);
  416. }
  417.  
  418.