home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / Sample Editors⁄Viewers / Text Editor / Source / TextEditorMain.cpp < prev    next >
Encoding:
Text File  |  1995-12-13  |  35.7 KB  |  1,219 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2.  
  3.     File:            TextEditorMain.cpp
  4.     
  5.     Description:    TextEditor's initialization protocol methods.
  6.     
  7.     Written by:        Steve Smith
  8.     
  9.     Copyright:        © 1994 - 1995 by Apple Computer, Inc., all rights reserved.
  10.     
  11. ------------------------------------------------------------------------------*/
  12.  
  13. // Notification that this is the "main" SOM source file
  14. #define SampleCode_TextEditor_Class_Source
  15. // define underscore (_) field names
  16. #define VARIABLE_MACROS
  17.  
  18. #ifndef _COMPILERDEFS_
  19. #include "CompDefs.h"
  20. #endif
  21.  
  22. // -- OpenDoc Utilities --
  23.  
  24. #ifndef _EXCEPT_
  25. // Exceptions define several important macros (e.g. CHECKENV)
  26. // which are used in the SOM method dispatch glue. If Except.h
  27. // is not included early enough, exceptions may not be thrown
  28. // correctly when returning from a SOM method with "ev" parameter set.
  29. #include <Except.h>
  30. #endif
  31.  
  32. // -- TextEditor Includes
  33.  
  34. #ifndef SOM_SampleCode_TextEditor_xih
  35. #include "TextEditor.xih"
  36. #endif
  37.  
  38. #ifndef SOM_TextEditorSemIntf_xh
  39. #include "TextEditorSemIntf.xh"
  40. #endif
  41.  
  42. #ifndef SOM_TextEditorSettingsExt_xh
  43. #include "TextEditorSettingsExt.xh"
  44. #endif
  45.  
  46. #ifndef SOM_TextEditorTransferExt_xh
  47. #include "TextEditorTransferExt.xh"
  48. #endif
  49.  
  50. #ifndef _TEXTEDITORDEF_
  51. #include "TextEditorDef.h"
  52. #endif
  53.  
  54. #ifndef _TEXTEDITORUTILS_
  55. #include "TextEditorUtils.h"
  56. #endif
  57.  
  58. #ifndef _TEXTEDITORGLOBALS_
  59. #include "TextEditorGlobals.h"
  60. #endif
  61.  
  62. #ifndef _TEXTEDITORPREFS_
  63. #include "TextEditorPrefs.h"
  64. #endif
  65.  
  66. #ifndef _STDTEXTPROPERTIES_
  67. #include "StdTextProps.h"
  68. #endif
  69.  
  70. // -- OpenDoc Includes --
  71.  
  72. #ifndef _ODTYPES_
  73. #include <ODTypes.h>
  74. #endif
  75.  
  76. #ifndef SOM_ODPart_xh
  77. #include <Part.xh>
  78. #endif
  79.  
  80. #ifndef SOM_ODStorageUnit_xh
  81. #include <StorageU.xh>
  82. #endif
  83.  
  84. #ifndef SOM_ODDraft_xh
  85. #include <Draft.xh>
  86. #endif
  87.  
  88. #ifndef SOM_ODSession_xh
  89. #include <ODSessn.xh>
  90. #endif
  91.  
  92. #ifndef SOM_ODArbitrator_xh
  93. #include <Arbitrat.xh>
  94. #endif
  95.  
  96. #ifndef SOM_ODFocusSet_xh
  97. #include <FocusSet.xh>
  98. #endif
  99.  
  100. #ifndef SOM_Module_OpenDoc_Foci_defined
  101. #include <Foci.xh>
  102. #endif
  103.  
  104. #ifndef SOM_ODMenuBar_xh
  105. #include <MenuBar.xh>
  106. #endif
  107.  
  108. #ifndef SOM_ODNameSpaceManager_xh
  109. #include <NmSpcMg.xh>
  110. #endif
  111.  
  112. #ifndef SOM_ODObjectNameSpace_xh
  113. #include <ObjectNS.xh>
  114. #endif
  115.  
  116. #ifndef SOM_ODTranslation_xh
  117. #include <Translt.xh>
  118. #endif
  119.  
  120. #ifndef SOM_Module_OpenDoc_StandardExtensions_defined
  121. #include <StdExts.xh>
  122. #endif
  123.  
  124. #ifndef SOM_ODSettingsExtension_xh
  125. #include <Settings.xh>
  126. #endif
  127.  
  128. #ifndef SOM_ODSemanticInterface_xh
  129. #include <SemtIntB.xh>
  130. #endif
  131.  
  132. #ifndef SOM_ODWindowState_xh
  133. #include <WinStat.xh>
  134. #endif
  135.  
  136. // -- OpenDoc Utilities --
  137.  
  138. #ifndef _ODMEMORY_
  139. #include <ODMemory.h>
  140. #endif
  141.  
  142. #ifndef _USERSRCM_
  143. #include <UseRsrcM.h>
  144. #endif
  145.  
  146. #ifndef _ISOSTR_
  147. #include <ISOStr.h>
  148. #endif
  149.  
  150. #ifndef _ODUTILS_
  151. #include <ODUtils.h>
  152. #endif
  153.  
  154. // -- Macintosh Includes --
  155.  
  156. #ifndef __ERRORS__
  157. #include <Errors.h>
  158. #endif
  159.  
  160. #ifndef __RESOURCES__
  161. #include <Resources.h>
  162. #endif
  163.  
  164. #ifndef __MENUS__
  165. #include <Menus.h>
  166. #endif
  167.  
  168. // -- Textension Includes --
  169.  
  170. #ifndef _Textension_
  171. #include "Textension.h"
  172. #endif
  173.  
  174. #ifndef _TSMTextension_
  175. #include "TSMTextension.h"
  176. #endif
  177.  
  178. #ifndef _QDTextRun_
  179. #include "QDTextRun.h"
  180. #endif
  181.  
  182. #ifndef _TSMRun_
  183. #include "TSMRun.h"
  184. #endif
  185.  
  186. #ifndef _RulerObject_
  187. #include "RulerObject.h"
  188. #endif
  189.  
  190. #ifndef _RunObject_
  191. #include "RunObject.h"
  192. #endif
  193.  
  194. #ifndef _LinkedFrames_
  195. #include "LinkedFrames.h"
  196. #endif
  197.  
  198. #ifndef _AttrObject_
  199. #include "AttrObject.h"
  200. #endif
  201.  
  202. #ifndef _FileStream_
  203. #include "FileStream.h"
  204. #endif
  205.  
  206. // -- Script Runner --
  207.  
  208. #ifndef SCRIPTRUNNERSUPPORT
  209. #include "ScriptRunnerSupport.h"
  210. #endif
  211.  
  212. #ifndef SOM_PaletteExt_xh
  213. #include "PaletteExt.xh"
  214. #endif
  215.  
  216.  
  217. //------------------------------------------------------------------------------
  218. // Method:        somInit
  219. // Origin:        SOMObject
  220. //
  221. // Description:    This is the SOM equivalent of a C++ class constructor.
  222. //
  223. // Warnings:    You are not allowed to throw an exception from this method.
  224. //------------------------------------------------------------------------------
  225. #pragma segment TextEditorInitialization
  226.  
  227. SOM_Scope    void
  228. SOMLINK        TextEditor__somInit
  229.             (
  230.                 SampleCode_TextEditor*        somSelf
  231.             )
  232. {
  233.     SOMMethodDebug("TextEditor","somInit");
  234.  
  235.     // somInit and somUninit methods behave like C++ constructors in that the
  236.     // inherited methods are called automatically. Thus, there is no need to
  237.     // call the parent class' somInit or somUninit.
  238.     
  239.     // There is also no need to set instance variables to zero/NULL
  240.     // since SOM guarantees that a newly constructed object is zeroed.
  241. }
  242.  
  243. //------------------------------------------------------------------------------
  244. // Method:        somUninit
  245. // Origin:        SOMObject
  246. //
  247. // Description:    This is the SOM equivalent of a C++ class destructor.
  248. //
  249. // Warnings:    You are not allowed to throw an exception from this method.
  250. //------------------------------------------------------------------------------
  251. #pragma segment TextEditorInitialization
  252.  
  253. SOM_Scope    void
  254. SOMLINK        TextEditor__somUninit
  255.             (
  256.                 SampleCode_TextEditor*        somSelf
  257.             )
  258. {
  259.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  260.     SOMMethodDebug("TextEditor","somUninit");
  261. }
  262.  
  263. //------------------------------------------------------------------------------
  264. // Method:        InitPart
  265. // Origin:        ODPart
  266. //
  267. // Description:    This method is called when a new instance of this part is being
  268. //                created. The part should prepare itself to run.
  269. //
  270. // Warning:        It is not appropriate to require user interaction while
  271. //                stationery is being created. Do not present the user with error
  272. //                dialogs or splash screens from this method.
  273. //------------------------------------------------------------------------------
  274. #pragma segment TextEditorInitialization
  275.  
  276. SOM_Scope    void
  277. SOMLINK        TextEditor__InitPart
  278.             (
  279.                 SampleCode_TextEditor*        somSelf,
  280.                 Environment*                ev,
  281.                 ODStorageUnit*                storageUnit,
  282.                 ODPart*                        partWrapper
  283.             )
  284. {
  285.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  286.     SOMMethodDebug("TextEditor","InitPart");
  287.  
  288.     SOM_TRY
  289.         // We must call the initialize method of our parent
  290.         // class to allow OpenDoc to annotate our part's storageUnit, to 
  291.         // set our refcount, and to change our "initialized" flag to true.
  292.         SampleCode_TextEditor_parent_ODPart_InitPart(somSelf, ev, storageUnit, partWrapper);
  293.  
  294.         // To allow editor swapping (translation) at runtime, OpenDoc requires
  295.         // that we pass in a "reference" to ourselves when interacting with the
  296.         // API (e.g. WindowState::RegisterWindow(), Dispatcher::RegisterIdle, etc).
  297.         // The "partWrapper" passed to us here and in InitPartFromStorage is the
  298.         // "reference" OpenDoc is asking us to use.
  299.         _fSelf = partWrapper;
  300.             
  301.         // We are being created, either as part of generating stationery or
  302.         // by some editor instantiating the part, so the destination storage
  303.         // must be writeable.
  304.         _fReadOnlyStorage = kODFalse;
  305.                     
  306.         // Call the common initialization code to get set up.
  307.         somSelf->Initialize(ev);
  308.         
  309.         // We need to set up a default preferred kind value for our
  310.         // stationery file.
  311.         _fPreferredKind = gGlobals->fNativeData;
  312.             
  313.         // Since we have just been created, our state/content info has
  314.         // never been written out, so setting our "dirty" flag will
  315.         // give us a chance to do that.
  316.         somSelf->SetDirty(ev);
  317.     SOM_CATCH_ALL
  318.         // Clean up will occur in the destructor which will be called
  319.         // shortly after we THROW the error.
  320.     SOM_ENDTRY
  321. }
  322.  
  323. //------------------------------------------------------------------------------
  324. // Method:        InitPartFromStorage
  325. // Origin:        ODPart
  326. //
  327. // Description:    This method is called when a document/stationery is being opened
  328. //                or when the part is internalized by its containing part. The
  329. //                part should merely read in the saved state/content and
  330. //                initialize itself. The part must not alter its storage unit;
  331. //                otherwise, the "Save" menu item becomes enabled without the user
  332. //                actually having made a change to the document.
  333. //------------------------------------------------------------------------------
  334. #pragma segment TextEditorInitialization
  335.  
  336. SOM_Scope    void
  337. SOMLINK        TextEditor__InitPartFromStorage
  338.             (
  339.                 SampleCode_TextEditor*        somSelf,
  340.                 Environment*                ev,
  341.                 ODStorageUnit*                storageUnit,
  342.                 ODPart*                        partWrapper
  343.             )
  344. {
  345.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  346.     SOMMethodDebug("TextEditor","InitPartFromStorage");
  347.  
  348.     SOM_TRY
  349.         // Call the initialize method of our parent PersistentObject class to generate
  350.         // the appropriate time/date stamp on our part's storage unit.
  351.         SampleCode_TextEditor_parent_ODPart_InitPartFromStorage(somSelf, ev, storageUnit, partWrapper);
  352.         
  353.         // To allow editor swapping (translation) at runtime, OpenDoc requires
  354.         // that we pass in a reference to ourselves when interacting with the
  355.         // API (e.g. WindowState::RegisterWindow(), Dispatcher::RegisterIdle, etc).
  356.         // The "partWrapper" passed to us here and in InitPart is the
  357.         // "reference" OpenDoc is asking us to use.
  358.         _fSelf = partWrapper;
  359.         
  360.         // Are we being opened from a read-only draft? If so, we cannot
  361.         // write anything back out to our storage unit.
  362.         _fReadOnlyStorage = (ODGetDraft(ev, storageUnit)->
  363.                                 GetPermissions(ev) < kODDPSharedWrite );
  364.         
  365.         // Call the common initialization code to get set up.
  366.         somSelf->Initialize(ev);
  367.         
  368.         // Read in the state the part was in when it was last Externalized.
  369.         // This allows the part to present the same environment the user
  370.         // had the part set up in the last time it was displayed.
  371.         somSelf->InternalizeStateInfo(ev, storageUnit);
  372.         
  373.         // The TextEditor needs to know about the "graphic" environment
  374.         // before it internalizes the content. Internalization will occur
  375.         // after the first facet is added.
  376.  
  377.     SOM_CATCH_ALL
  378.         // Clean up will occur in the destructor which will be called
  379.         // shortly after we THROW the error.
  380.     SOM_ENDTRY
  381. }
  382.  
  383. //------------------------------------------------------------------------------
  384. // Method:        Initialize
  385. // Origin:        TextEditor
  386. //
  387. // Description:    This method is called during the initialization of the part. The
  388. //                method is used to initialize all fields of the part and to
  389. //                convert ISO types to tokens for faster comparisons throughout
  390. //                the code.
  391. //
  392. //                If an exception is thrown in this method, it will be propogated
  393. //                back to OpenDoc which will call our ReleaseAll() method and the
  394. //                class destructor. All memory allocated here will be cleaned up
  395. //                in the ReleaseAll() method.
  396. //------------------------------------------------------------------------------
  397. #pragma segment TextEditorInitialization
  398.  
  399. SOM_Scope    void
  400. SOMLINK        TextEditor__Initialize
  401.             (
  402.                 SampleCode_TextEditor*        somSelf,
  403.                 Environment*                ev
  404.             )
  405. {
  406.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  407.     SOMMethodDebug("TextEditor","Initialize");
  408.  
  409.     SOM_TRY
  410.         // Allow Textension to allocate its global structures and
  411.         // analyze the runtime environment.    
  412.         somSelf->StartTextension(ev);
  413.             
  414.         // Grab a reference to the Session object. This is merely for
  415.         // convenience.
  416.         ODSession* session = ODGetSession(ev, somSelf);
  417.             
  418.         // Create a list to keep track of the facets we are being
  419.         // displayed in. Also used for maintenance (i.e., Purging memory).
  420.         _fDisplayFrames = new CList;
  421.     
  422.         if (gGlobalsUsageCount == 0)
  423.         {
  424.             gGlobals = new TextEditorGlobals;
  425.     
  426.             // We will be using the above foci (shared resources) in this
  427.             // part. For convenience, we tokenize the values here and store
  428.             // them for equivalence tests in the activation methods.
  429.             gGlobals->fSelectionFocus = session->Tokenize(ev, kODSelectionFocus);
  430.             gGlobals->fClipboardFocus = session->Tokenize(ev, kODClipboardFocus);
  431.             gGlobals->fMenuFocus      = session->Tokenize(ev, kODMenuFocus);
  432.             gGlobals->fModalFocus     = session->Tokenize(ev, kODModalFocus);
  433.             gGlobals->fKeyFocus          = session->Tokenize(ev, kODKeyFocus);
  434.     
  435.             // Tokenize our part's presentations and the view types we support.
  436.             gGlobals->fMainPresentation        = session->Tokenize(ev, kMainPresentation);
  437.             gGlobals->fRulerPresentation    = session->Tokenize(ev, kRulerPresentation);
  438.             
  439.             gGlobals->fFrameView       = session->Tokenize(ev, kODViewAsFrame);
  440.             gGlobals->fLargeIconView  = session->Tokenize(ev, kODViewAsLargeIcon);
  441.             gGlobals->fSmallIconView  = session->Tokenize(ev, kODViewAsSmallIcon);
  442.             gGlobals->fThumbnailView  = session->Tokenize(ev, kODViewAsThumbnail);
  443.             
  444.             // This part supports PICT data files, so we must get the value types
  445.             // OpenDoc associates with each. We do this through the Translation object.
  446.             gGlobals->fScrapTextValue = session->GetTranslation(ev)->
  447.                             GetISOTypeFromPlatformType(ev, kTextDataKind, kODPlatformDataType);
  448.                 // Value type for TEXT scrap data
  449.             
  450.             gGlobals->fTextFileValue = session->GetTranslation(ev)->
  451.                             GetISOTypeFromPlatformType(ev, kTextFileKind, kODPlatformFileType);
  452.                 // Value type for TEXT files
  453.             
  454.             gGlobals->fStyledTextKind = session->GetTranslation(ev)->
  455.                             GetISOTypeFromPlatformType(ev, kSTXTDataKind, kODPlatformDataType);
  456.                 // Value type for 'stxt' styled text scrap data
  457.             
  458.             gGlobals->fAppleHFSFlavor = session->GetTranslation(ev)->
  459.                             GetISOTypeFromPlatformType(ev, 'hfs ', kODPlatformDataType);
  460.                 // Value type for file information
  461.             
  462.             // Tokenize the content value types that our part supports to
  463.             // facilitate writing data in the preferred kind.
  464.             gGlobals->fNativeData = session->Tokenize(ev, kTextEditorKind);
  465.             gGlobals->fImportedData = session->Tokenize(ev, gGlobals->fScrapTextValue);
  466.             gGlobals->fStyledTextData = session->Tokenize(ev, gGlobals->fStyledTextKind);
  467.             
  468.             _fPreferredKind    = kODNullTypeToken;
  469.             
  470.             // We will also package the keyboard, menu, and selection focus
  471.             // so that we can request the "set" at activation time.
  472.             gGlobals->fUIFocusSet = session->GetArbitrator(ev)->CreateFocusSet(ev);
  473.             gGlobals->fUIFocusSet->Add(ev, gGlobals->fMenuFocus);
  474.             gGlobals->fUIFocusSet->Add(ev, gGlobals->fSelectionFocus);
  475.             gGlobals->fUIFocusSet->Add(ev, gGlobals->fKeyFocus);
  476.         
  477.             // Determine what Script/Language the part is localized for.
  478.             // This is important/necessary for creating OpenDoc's text objects.
  479.             GetEditorScriptLanguage(ev, &gGlobals->fEditorsScript, &gGlobals->fEditorsLanguage);
  480.             
  481.             // Add the editor specific menu items.
  482.             somSelf->LoadMenus(ev);
  483.                     
  484.             // The first client of the global variables is running.
  485.             gGlobalsUsageCount = 1;
  486.         }
  487.         else
  488.         // If the globals have been initialized, we keep a "usage" count so that we 
  489.         // can null out the global variables when we are finished using them.
  490.         {
  491.             gGlobalsUsageCount++;
  492.         }
  493.     
  494.         // Set default margins
  495.         _fPageMargins.top = _fPageMargins.left = _fPageMargins.bottom
  496.                 = _fPageMargins.right = kDefaultDocMargin;  /* pixels */
  497.     
  498.         // Set the document justification based on the script the part is
  499.         // localized for.
  500.         _fTextAlignment = (GetScriptVariable(gGlobals->fEditorsScript, smScriptJust) == 0)
  501.                                 ? left : right;
  502.         
  503.         // ScriptRunner support.
  504.         _fIsScriptRunnerOn     = kODFalse;
  505.         _fIsScriptRunnerHidden = kODFalse;
  506.         
  507.         // Printing.        
  508.         PrOpen();
  509.         TRY
  510.             if ( PrError() == noErr )
  511.             {
  512.                 _fPrintRecord = ODNewHandle(sizeof(TPrint));
  513.                 
  514.                 PrintDefault((THPrint)_fPrintRecord);
  515.                 
  516.                 // Determine the current paper size and printable area
  517.                 // for the selected printer (or output device).    
  518.                 _fPageSize = (**(THPrint)_fPrintRecord).prInfo.rPage;
  519.                 _fPaperSize = (**(THPrint)_fPrintRecord).rPaper;
  520.             }
  521.             else
  522.             {
  523.                 // Set default page size to 8.5" x 11"
  524.                 // $$$$$ NOT LOCALIZABLE
  525.                 SetRect(&_fPageSize, 0, 0, 612, 792);
  526.                 SetRect(&_fPaperSize, 0, 0, 612, 792);
  527.             }
  528.         CATCH_ALL
  529.             PrClose();
  530.             RERAISE;
  531.         ENDTRY
  532.         PrClose();
  533.     SOM_CATCH_ALL
  534.         // Clean up will occur in the destructor which will be called
  535.         // shortly after we THROW the error.
  536.     SOM_ENDTRY
  537. }
  538.  
  539. //------------------------------------------------------------------------------
  540. // Method:        StartTextension
  541. // Origin:        TextEditor
  542. //
  543. // Description:    This method is called during the initialization of the part. 
  544. //------------------------------------------------------------------------------
  545. #pragma segment TextEditorInitialization
  546.  
  547. SOM_Scope    void
  548. SOMLINK        TextEditor__StartTextension
  549.             (
  550.                 SampleCode_TextEditor*        somSelf,
  551.                 Environment*                ev
  552.             )
  553. {
  554.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  555.     SOMMethodDebug("TextEditor","StartTextension");
  556.     
  557.     SOM_TRY
  558.  
  559.         OSErr        error;
  560.         ODUShort    fontSize;
  561.         Str255        fontName;
  562.         ODSShort    fontNum;
  563.     
  564.         // Start Textension. This gives it a chance to set up its global
  565.         // tables and survey the machine. "True" tells Textension that we
  566.         // will be installing AppleEvent handlers for TSM; it should not.
  567.         error = CTSMTextension::TSMTextensionStart(kODTrue);
  568.  
  569.         // The "tsmAlreadyRegisteredErr" occurs if OpenDoc has created
  570.         // a TSM document for this window already. We can ignore the error.
  571.         if (error == tsmAlreadyRegisteredErr)
  572.             error = noErr;
  573.  
  574.         THROW_IF_ERROR(error);
  575.         
  576.         CTSMRun* textRun = new CTSMRun;
  577.         textRun->ITSMRun();
  578.         CTextension::RegisterRun(textRun);
  579.  
  580.         CBasicRuler* ruler = new CBasicRuler;
  581.         ruler->IBasicRuler();
  582.         ruler->SetDefaults();
  583.         CTextension::RegisterRuler(ruler);        
  584.  
  585.         // set default font, font size
  586.         
  587.         {
  588.             CUsingLibraryResources res;
  589.             ReadPreferences(ev, ODGetSession(ev, somSelf), (StringPtr) &fontName,
  590.                                 &fontSize);
  591.         }
  592.         
  593.         GetFNum(fontName, &fontNum);
  594.         
  595.         CRunObject* defaultRun = CTextension::GetNewRunObject();
  596.         
  597.         defaultRun->SetAttributeValue(kFontAttr, &fontNum);
  598.         defaultRun->SetAttributeValue(kFontSizeAttr, &fontSize);
  599.     
  600.         CTextension::SetDefaultRun(defaultRun);
  601.  
  602.         _fTextensionInitialized = kODFalse;
  603.  
  604.     SOM_CATCH_ALL
  605.     SOM_ENDTRY
  606. }
  607.  
  608. //------------------------------------------------------------------------------
  609. // Method:        InitializeTextension
  610. // Origin:        TextEditor
  611. //
  612. // Description:    This method is called during the initialization of the part. 
  613. //------------------------------------------------------------------------------
  614. #pragma segment TextEditorInitialization
  615.  
  616. SOM_Scope    void
  617. SOMLINK        TextEditor__InitializeTextension
  618.             (
  619.                 SampleCode_TextEditor*        somSelf,
  620.                 Environment*                ev,
  621.                 ODBoolean                    isRoot
  622.             )
  623. {
  624.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  625.     SOMMethodDebug("TextEditor","InitializeTextension");
  626.     
  627.     SOM_TRY
  628.     
  629.         TTextensionHandlers handlers;
  630.         TSize                approxDocSize;
  631.         
  632.         if ( isRoot )
  633.         {
  634.             // If we are the root part, then we need to present the user
  635.             // with a "page/document".
  636.             
  637.             CPageFrames* pageFrames = new CPageFrames;
  638.             pageFrames->IPageFrames();
  639.             
  640.             handlers.framesHandler = pageFrames;
  641.             
  642.             approxDocSize = kLargeSize;        // Textension const
  643.         }
  644.         else
  645.         {
  646.             // If we are not the root part, then we need to support multiple
  647.             // text blocks (unfortunately called "frames" by Textension) of
  648.             // varying size and position.
  649.             
  650.             CVariableSizeFrames* varFrames = new CVariableSizeFrames;
  651.             varFrames->IVariableSizeFrames();
  652.                     
  653.             handlers.framesHandler = varFrames;
  654.             
  655.             approxDocSize = kMediumSize;    // Textension const
  656.         }
  657.     
  658.         _fTextension = new CTSMTextension;
  659.         ((CTSMTextension*)_fTextension)->ITSMTextension(kODNULL, &handlers, approxDocSize);
  660.         
  661.         // Set up its autoscrolling (or lack thereof).
  662.         _fTextension->SetAutoScroll(isRoot);
  663.         
  664.         _fTextensionInitialized = kODTrue;
  665.  
  666.     SOM_CATCH_ALL
  667.     SOM_ENDTRY
  668. }
  669.  
  670. //------------------------------------------------------------------------------
  671. // Method:        LoadMenus
  672. // Origin:        TextEditor
  673. //
  674. // Description:    This method is called during the initialization of the part. 
  675. //------------------------------------------------------------------------------
  676. #pragma segment TextEditorInitialization
  677.  
  678. SOM_Scope    void
  679. SOMLINK        TextEditor__LoadMenus
  680.             (
  681.                 SampleCode_TextEditor*        somSelf,
  682.                 Environment*                ev
  683.             )
  684. {
  685.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  686.     SOMMethodDebug("TextEditor","LoadMenus");
  687.     
  688.     SOM_TRY
  689.     
  690.         if (gGlobals->fMenuBar == kODNULL || !gGlobals->fMenuBar->IsValid(ev))
  691.         {
  692.             ODBoolean changingBaseMenuBar = (gGlobals->fMenuBar != kODNULL);
  693.             
  694.             if (changingBaseMenuBar)
  695.             {
  696.                 // Remove our menus from the old menubar.
  697.                 for (ODSShort index = 0; index < kNumMenus; index++)
  698.                 {
  699.                     ODSShort id = kBaseMenuID + index;
  700.                     gGlobals->fMenuBar->RemoveMenu(ev, id);
  701.                 }
  702.             }
  703.             
  704.             ODReleaseObject(ev, gGlobals->fMenuBar);
  705.     
  706.             // It is required that parts instantiate their menu bars from 
  707.             // the base OpenDoc menu bar. This maintains consistency in the
  708.             // default menu items and their placement.
  709.             // Since the object is a copy, we can add and subtract menus and
  710.             // items without affecting other running parts.
  711.             gGlobals->fMenuBar = ODGetSession(ev, somSelf)->GetWindowState(ev)->CopyBaseMenuBar(ev);
  712.             
  713.             // For convenience:
  714.             ODMenuBar* mbar = gGlobals->fMenuBar;
  715.             
  716.             // Load and insert our resource-based menus.
  717.  
  718.             MenuHandle fontMenu;
  719.             {
  720.                 CUsingLibraryResources res;
  721.                 
  722.                 fontMenu = GetMenu(kFontMenuID);
  723.                 
  724.                 // Remove all the old items before adding back on.
  725.                 while ( CountMItems(fontMenu) > 0 )
  726.                 {
  727.                     DeleteMenuItem(fontMenu, 1);
  728.                 }
  729.                 
  730.                 AppendResMenu(fontMenu, 'FONT');
  731.                 
  732.                 mbar->AddMenuLast(ev, kFontMenuID, fontMenu, _fSelf);
  733.                 
  734.                 // Add the other menus to the menubar.
  735.                 mbar->AddMenuLast(ev, kSizeMenuID,   GetMenu(kSizeMenuID),   _fSelf);
  736.                 mbar->AddMenuLast(ev, kStyleMenuID,  GetMenu(kStyleMenuID),  _fSelf);
  737.                 mbar->AddMenuLast(ev, kFormatMenuID, GetMenu(kFormatMenuID), _fSelf);
  738.                 mbar->AddMenuLast(ev, kToolsMenuID,  GetMenu(kToolsMenuID),  _fSelf);
  739.             }
  740.             
  741.             // Issue command numbers for the items in the font menu.
  742.             // The command number is equal to the FOND id + kBaseFontCmdID.
  743.             
  744.             for (int i=1; i <= CountMItems(fontMenu); i++)
  745.             {
  746.                 Str255         fontName;
  747.                 ODSShort    fontNum;
  748.                 
  749.                 GetMenuItemText(fontMenu, i, fontName);
  750.                 GetFNum(fontName, &fontNum);
  751.                 
  752.                 mbar->RegisterCommand(ev, kBaseFontCmdID + fontNum, kFontMenuID, i);
  753.             }
  754.             
  755.             // Register command numbers for the Size, Style, and Format menus.
  756.             
  757.             mbar->RegisterCommand(ev, kBaseFontSizeCmdID +  9, kSizeMenuID, 1);
  758.             mbar->RegisterCommand(ev, kBaseFontSizeCmdID + 10, kSizeMenuID, 2);
  759.             mbar->RegisterCommand(ev, kBaseFontSizeCmdID + 12, kSizeMenuID, 3);
  760.             mbar->RegisterCommand(ev, kBaseFontSizeCmdID + 14, kSizeMenuID, 4);
  761.             mbar->RegisterCommand(ev, kBaseFontSizeCmdID + 18, kSizeMenuID, 5);
  762.             mbar->RegisterCommand(ev, kBaseFontSizeCmdID + 24, kSizeMenuID, 6);
  763.             mbar->RegisterCommand(ev, kBaseFontSizeCmdID + 36, kSizeMenuID, 7);
  764.             mbar->RegisterCommand(ev, kBaseFontSizeCmdID + 48, kSizeMenuID, 8);
  765.             mbar->RegisterCommand(ev, kBaseFontSizeCmdID + 72, kSizeMenuID, 9);
  766.             mbar->RegisterCommand(ev, kOtherFontSizeCmdID,     kSizeMenuID,11);
  767.             
  768.             mbar->RegisterCommand(ev, kBaseFontStyleCmdID + normal,    kStyleMenuID, 1);
  769.             mbar->RegisterCommand(ev, kBaseFontStyleCmdID + bold,      kStyleMenuID, 3);
  770.             mbar->RegisterCommand(ev, kBaseFontStyleCmdID + italic,    kStyleMenuID, 4);
  771.             mbar->RegisterCommand(ev, kBaseFontStyleCmdID + underline, kStyleMenuID, 5);
  772.             mbar->RegisterCommand(ev, kBaseFontStyleCmdID + outline,   kStyleMenuID, 6);
  773.             
  774.             mbar->RegisterCommand(ev, kShowHideRulerCmdID,    kFormatMenuID, 1);
  775.             mbar->RegisterCommand(ev, kSettingsCmdID,            kFormatMenuID, 3);
  776.             
  777.             mbar->RegisterCommand(ev, kToggleScriptRunnerCmdID,         kToolsMenuID, 1);
  778.  
  779.             // If we're a read-only part, disable the font menus.
  780.             mbar->EnableCommand(ev, mbar->GetCommand(ev, kFontMenuID, 0),   !_fReadOnlyStorage);
  781.             mbar->EnableCommand(ev, mbar->GetCommand(ev, kSizeMenuID, 0),   !_fReadOnlyStorage);
  782.             mbar->EnableCommand(ev, mbar->GetCommand(ev, kStyleMenuID, 0),  !_fReadOnlyStorage);
  783.             mbar->EnableCommand(ev, mbar->GetCommand(ev, kFormatMenuID, 0), !_fReadOnlyStorage);
  784.             mbar->EnableCommand(ev, mbar->GetCommand(ev, kToolsMenuID, 0),  !_fReadOnlyStorage);
  785.         }
  786.         
  787.     SOM_CATCH_ALL
  788.     SOM_ENDTRY
  789. }
  790.  
  791. //------------------------------------------------------------------------------
  792. // Method:        Release
  793. // Origin:        ODRefCntObj
  794. //
  795. // Description:    This method is called each time an object releases a reference
  796. //                to the part. If the refcount falls to 0, the part should
  797. //                release the fSelf part reference.
  798. //
  799. // Warning:        If the part releases any other object when the refcount falls to
  800. //                zero, it will need to override the Acquire method so
  801. //                that the object can be referenced again if the parts refcount
  802. //                should be incremented before it is deleted.
  803. //------------------------------------------------------------------------------
  804. #pragma segment TextEditorStorage
  805.  
  806. SOM_Scope    void
  807. SOMLINK        TextEditor__Release
  808.             (
  809.                 SampleCode_TextEditor*        somSelf,
  810.                 Environment*                ev
  811.             )
  812. {
  813.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  814.     SOMMethodDebug("TextEditor","Release");
  815.  
  816.     SOM_TRY
  817.     
  818.         SampleCode_TextEditor_parent_ODPart_Release(somSelf, ev);
  819.     
  820.         if (somSelf->GetRefCount(ev) == 0)
  821.             ODGetDraft(ev, somSelf)->ReleasePart(ev, _fSelf);
  822.     
  823.     SOM_CATCH_ALL
  824.     SOM_ENDTRY
  825. }
  826.  
  827. //------------------------------------------------------------------------------
  828. // Method:        ReleaseAll
  829. // Origin:        ODPart
  830. //
  831. // Description:    This method is called just prior to the part being deleted by
  832. //                the Draft. The part must release all references to all
  833. //                refcounted objects it has stored internally; not doing so, will
  834. //                cause an "invalid ref count" exception/error at some later time.
  835. //------------------------------------------------------------------------------
  836. #pragma segment TextEditorStorage
  837.  
  838. SOM_Scope    void
  839. SOMLINK        TextEditor__ReleaseAll
  840.             (
  841.                 SampleCode_TextEditor*        somSelf,
  842.                 Environment*                ev
  843.             )
  844. {
  845.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  846.     SOMMethodDebug("TextEditor","ReleaseAll");
  847.  
  848.     SOM_TRY
  849.     
  850.         // Release the reference counted objects we are holding onto.
  851.  
  852.         // Release our extensions.  Note: we can't use ODReleaseObject or 
  853.         // ODFinalReleaseObject here because they null out the field before the
  854.         // call to Release, but we need the field intact when ReleaseExtension is 
  855.         // called back upon the last reference being released.
  856.         ODRelease(ev, _fSemanticIntf);
  857.         ODRelease(ev, _fSettingsExt);
  858.         ODRelease(ev, _fTextTransferExt);
  859.         
  860.         // Release this instance's Textension interface.
  861.         if ( _fTextension )
  862.             _fTextension->Free();
  863.             
  864.         // Release the ScriptRunner extension, if we have acquired it.
  865.         ODReleaseObject(ev, _fScriptPaletteExt);
  866.  
  867.         // If the last part instance using the globals is released,
  868.         // we need to NULL out the globals.
  869.         
  870.         if ( --gGlobalsUsageCount == 0 )
  871.         {
  872.             // On the other hand, the FocusSet is not shared and deleting it
  873.             // is the right thing to do.
  874.             ODDeleteObject(gGlobals->fUIFocusSet);
  875.             
  876.             // We can't shutdown Textension until all instances of the
  877.             // Text Editor are finished using it.
  878.             CTSMTextension::TSMTextensionTerminate();
  879.             
  880.             ODDisposePtr(gGlobals->fScrapTextValue);
  881.             ODDisposePtr(gGlobals->fTextFileValue);
  882.             ODDisposePtr(gGlobals->fAppleHFSFlavor);
  883.             
  884.             // We need to remove our menus from the menubar and dispose of
  885.             // them to free up their memory.
  886.             {
  887.                 CUsingLibraryResources res;
  888.                 for (ODSShort index = 0; index < kNumMenus; index++)
  889.                 {
  890.                     ODSShort id = kBaseMenuID + index;
  891.                     
  892.                     MenuHandle menu = gGlobals->fMenuBar->GetMenu(ev, id);
  893.                     gGlobals->fMenuBar->RemoveMenu(ev, id);
  894.                     if (menu)
  895.                         ReleaseResource((Handle) menu);
  896.                 }
  897.             }
  898.             
  899.             ODReleaseObject(ev, gGlobals->fMenuBar);
  900.  
  901.             // Dispose the thumbnail picture.
  902.             if ( gGlobals->fThumbnail != kODNULL )
  903.                 ReleaseResource(gGlobals->fThumbnail);
  904.             
  905.             // Delete the globals struct.
  906.             ODDeleteObject(gGlobals);
  907.         }
  908.     
  909.         // Remove and release our display frames.
  910.         if ( _fDisplayFrames )
  911.         {
  912.             CListIterator fiter(_fDisplayFrames);
  913.             for ( CFrameProxy* proxy = (CFrameProxy*) fiter.First();
  914.                     fiter.IsNotComplete(); proxy = (CFrameProxy*) fiter.Next() )
  915.             {
  916.                 // Delete the proxy object and its contents. The frame's
  917.                 // refcount will be decremented in the proxy destructor.
  918.                 fiter.RemoveCurrent();
  919.                 delete proxy;
  920.             }
  921.         
  922.             // Delete the display frame collection.
  923.             ODDeleteObject(_fDisplayFrames);
  924.         }
  925.         
  926.         SampleCode_TextEditor_parent_ODPart_ReleaseAll(somSelf, ev);
  927.  
  928.     SOM_CATCH_ALL
  929.         // If something goes wrong while we are cleaning up, we must
  930.         // let the Draft now because there may be some refcounted objects
  931.         // which did not get released. Not to mention, possible memory
  932.         // leaks.
  933.     SOM_ENDTRY
  934. }
  935.  
  936. //------------------------------------------------------------------------------
  937. // Method:        Purge
  938. // Origin:        ODObject
  939. //
  940. // Description:    This method is called when the OpenDoc requires more memory for
  941. //                allocating objects and just before a part is deleted. The part
  942. //                should free up as much memory as it can.
  943. //
  944. //                The part determines which views are being "used" in its display
  945. //                frames. The resources for the unused view types are then purged.
  946. //------------------------------------------------------------------------------
  947. #pragma segment TextEditorStorage
  948.  
  949. SOM_Scope    ODSize
  950. SOMLINK        TextEditor__Purge
  951.             (
  952.                 SampleCode_TextEditor*        somSelf,
  953.                 Environment*                ev,
  954.                 ODSize                        size
  955.             )
  956. {
  957.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  958.     SOMMethodDebug("TextEditor","Purge");
  959.  
  960.     ODSize bytesFreed = 0;
  961.  
  962.     SOM_TRY
  963.     
  964.         ODBoolean usingThumbnail = kODFalse;
  965.         
  966.         // Iterate over the frames we are displayed through and determine which
  967.         // view types are currently in use.
  968.         
  969.         if ( _fDisplayFrames != kODNULL )
  970.         {
  971.             CListIterator fiter(_fDisplayFrames);
  972.             for ( CFrameProxy* proxy = (CFrameProxy*) fiter.First();
  973.                     fiter.IsNotComplete(); proxy = (CFrameProxy*) fiter.Next() )
  974.             {
  975.                 // If the display frame is real (has been "connected" or was "added")
  976.                 // get its view type; otherwise, ignore it.
  977.                 if ( proxy->FrameIsLoaded(ev) )
  978.                 {
  979.                     ODTypeToken    frameView = proxy->GetFrame(ev)->GetViewType(ev);
  980.                     
  981.                     if ( frameView == gGlobals->fThumbnailView )
  982.                         usingThumbnail = kODTrue;
  983.             
  984.                     // Release the frame reference, but don't get rid of the
  985.                     // proxy object because we're not done with the frame. If
  986.                     // all parts release their references the frame will be
  987.                     // purged from memory.
  988.                     proxy->Purge(ev);
  989.                 }
  990.             }
  991.         }
  992.         
  993.         // Based on the usage of the supported view types, free up as much
  994.         // memory as possible.
  995.     
  996.         if ( !usingThumbnail && gGlobals->fThumbnail != kODNULL )
  997.         {
  998.             bytesFreed += ODGetHandleSize(gGlobals->fThumbnail);
  999.             ReleaseResource(gGlobals->fThumbnail);
  1000.             gGlobals->fThumbnail = kODNULL;
  1001.         }
  1002.         
  1003.         bytesFreed += SampleCode_TextEditor_parent_ODPart_Purge(somSelf, ev, size);
  1004.         
  1005.     SOM_CATCH_ALL
  1006.     SOM_ENDTRY
  1007.  
  1008.     return bytesFreed;
  1009. }
  1010.  
  1011. //------------------------------------------------------------------------------
  1012. // Method:        HandleChange
  1013. // Origin:        TextEditor
  1014. //
  1015. // Description:    This method is called by the part when the content or state of
  1016. //                the part has been modified by the user and the "Save" menu item
  1017. //                should be enabled.
  1018. //------------------------------------------------------------------------------
  1019. #pragma segment TextEditorStorage
  1020.  
  1021. SOM_Scope    void
  1022. SOMLINK        TextEditor__HandleChange
  1023.              (
  1024.                 SampleCode_TextEditor*        somSelf,
  1025.                 Environment*                ev
  1026.             )
  1027. {
  1028.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1029.     SOMMethodDebug("TextEditor","HandleChange");
  1030.  
  1031.     SOM_TRY
  1032.     
  1033.         // Tell ourselves that we're now dirty.
  1034.         somSelf->SetDirty(ev);
  1035.         
  1036.         ODUpdateID updateID = ODGetSession(ev, somSelf)->UniqueUpdateID(ev);
  1037.     
  1038.         // Iterate over our display frames.
  1039.         CListIterator fiter(_fDisplayFrames);
  1040.         for ( CFrameProxy* proxy = (CFrameProxy*) fiter.First();
  1041.                 fiter.IsNotComplete(); proxy = (CFrameProxy*) fiter.Next() )
  1042.         {
  1043.             // If the display frame is real (has been "connected" or was "added")
  1044.             // call ContentUpdated for the frame; otherwise, ignore it.
  1045.             if ( proxy->FrameIsLoaded(ev) )
  1046.             {
  1047.                 ODFrame* frame = proxy->GetFrame(ev);
  1048.                 
  1049.                 // Call ContentUpdated to tell any potential container
  1050.                 // that we have made a change to our content in case we
  1051.                 // are in a link.
  1052.                 frame->ContentUpdated(ev, updateID);
  1053.             }
  1054.         }
  1055.         
  1056.     SOM_CATCH_ALL
  1057.     SOM_ENDTRY
  1058. }
  1059.  
  1060. //------------------------------------------------------------------------------
  1061. // Method:        HasExtension
  1062. // Origin:        ODObject
  1063. //
  1064. // Description:    This method is called during the initialization of the part. 
  1065. //------------------------------------------------------------------------------
  1066. #pragma segment TextEditorInitialization
  1067.  
  1068. SOM_Scope    ODBoolean
  1069. SOMLINK        TextEditor__HasExtension
  1070.             (
  1071.                 SampleCode_TextEditor*        somSelf,
  1072.                 Environment*                ev,
  1073.                 ODType                        extensionName
  1074.             )
  1075. {
  1076.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1077.     SOMMethodDebug("TextEditor","HasExtension");
  1078.  
  1079.     ODBoolean result = kODFalse;
  1080.     
  1081.     TRY
  1082.     
  1083.         if (    ODISOStrEqual(extensionName, kODExtSemanticInterface)
  1084.             || (ODISOStrEqual(extensionName, kODSettingsExtension) && !_fReadOnlyStorage)
  1085.             ||  ODISOStrEqual(extensionName, kDataTransferExtension)
  1086.             ||  ODISOStrEqual(extensionName, kTextTransferExtension) )
  1087.         {
  1088.             return kODTrue;
  1089.         }
  1090.         else
  1091.         {
  1092.             result = SampleCode_TextEditor_parent_ODPart_HasExtension(somSelf, ev, extensionName);
  1093.         }
  1094.         
  1095.     SOM_CATCH_ALL
  1096.     SOM_ENDTRY
  1097.  
  1098.     return result;
  1099. }
  1100.  
  1101. //------------------------------------------------------------------------------
  1102. // Method:        AcquireExtension
  1103. // Origin:        ODObject
  1104. //
  1105. // Description:    This method is called during the initialization of the part. 
  1106. //------------------------------------------------------------------------------
  1107. #pragma segment TextEditorInitialization
  1108.  
  1109. SOM_Scope    ODExtension*
  1110. SOMLINK        TextEditor__AcquireExtension
  1111.             (
  1112.                 SampleCode_TextEditor*        somSelf,
  1113.                 Environment*                ev,
  1114.                 ODType                        extensionName
  1115.             )
  1116. {
  1117.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1118.     SOMMethodDebug("TextEditor","AcquireExtension");
  1119.  
  1120.     ODExtension* result = kODNULL;
  1121.  
  1122.     SOM_TRY
  1123.         
  1124.         if ( ODISOStrEqual(extensionName, kODExtSemanticInterface) )
  1125.         {
  1126.             if ( !_fSemanticIntf )
  1127.             {
  1128.                 ODSession* session = ODGetSession(ev, somSelf);
  1129.                 
  1130.                 _fSemanticIntf = new TextEditorSemIntf;
  1131.                 THROW_IF_NULL(_fSemanticIntf);        // SOM constructors don’t throw.
  1132.                 _fSemanticIntf->InitSemanticInterface(ev, _fSelf, session);
  1133.                 _fSemanticIntf->RegisterTextension(ev, _fTextension);
  1134.             }
  1135.             
  1136.             ODAcquireObject(ev, _fSemanticIntf);
  1137.             result = _fSemanticIntf;
  1138.         }
  1139.         else if ( ODISOStrEqual(extensionName, kODSettingsExtension) )
  1140.         {
  1141.             if ( !_fSettingsExt )
  1142.             {
  1143.                 _fSettingsExt = new TextEditorSettingsExt;
  1144.                 THROW_IF_NULL(_fSettingsExt);
  1145.                 _fSettingsExt->InitSettingsExtension(ev, _fSelf);
  1146.             }
  1147.             
  1148.             ODAcquireObject(ev, _fSettingsExt);
  1149.             result = _fSettingsExt;
  1150.         }
  1151.         else if ( ODISOStrEqual(extensionName, kDataTransferExtension)
  1152.                || ODISOStrEqual(extensionName, kTextTransferExtension) )
  1153.         {
  1154.             if ( !_fTextTransferExt )
  1155.             {
  1156.                 _fTextTransferExt = new TextEditorTransferExt;
  1157.                 THROW_IF_NULL(_fTextTransferExt);
  1158.                 _fTextTransferExt->InitTextEditorTransferExt(ev, _fSelf);
  1159.             }
  1160.             
  1161.             ODAcquireObject(ev, _fTextTransferExt);
  1162.             result = _fTextTransferExt;
  1163.         }
  1164.         else
  1165.         {
  1166.             result = SampleCode_TextEditor_parent_ODPart_AcquireExtension(somSelf, ev, extensionName);
  1167.         }
  1168.         
  1169.     SOM_CATCH_ALL
  1170.     SOM_ENDTRY
  1171.         
  1172.     return result;
  1173. }
  1174.  
  1175.  
  1176. //------------------------------------------------------------------------------
  1177. // Method:        ReleaseExtension
  1178. // Origin:        ODObject
  1179. //
  1180. // Description:    This method is called during the initialization of the part. 
  1181. //------------------------------------------------------------------------------
  1182. #pragma segment TextEditorInitialization
  1183.  
  1184. SOM_Scope    void
  1185. SOMLINK        TextEditor__ReleaseExtension
  1186.             (
  1187.                 SampleCode_TextEditor*        somSelf,
  1188.                 Environment*                ev,
  1189.                 ODExtension*                extension
  1190.             )
  1191. {
  1192.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1193.     SOMMethodDebug("TextEditor","ReleaseExtension");
  1194.  
  1195.     SOM_TRY
  1196.     
  1197.         if ( ODObjectsAreEqual(ev, extension, _fSemanticIntf) )
  1198.         {
  1199.             ODDeleteObject(_fSemanticIntf);
  1200.         }
  1201.         else if ( ODObjectsAreEqual(ev, extension, _fSettingsExt) )
  1202.         {
  1203.             ODDeleteObject(_fSettingsExt);
  1204.         }
  1205.         else if ( ODObjectsAreEqual(ev, extension, _fTextTransferExt) )
  1206.         {
  1207.             ODDeleteObject(_fTextTransferExt);
  1208.         }
  1209.         else
  1210.         {
  1211.             SampleCode_TextEditor_parent_ODPart_ReleaseExtension(somSelf, ev, extension);
  1212.         }
  1213.     
  1214.     SOM_CATCH_ALL
  1215.     SOM_ENDTRY
  1216. }
  1217.  
  1218.  
  1219.