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 / Internet / SLCyPart.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  14.9 KB  |  429 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                SLCyPart.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //    Implementation of FW_OCyberPartExtension.
  9. //    Redirects all methods into C callbacks provided by the client.
  10. //
  11. //========================================================================================
  12.  
  13. #ifndef SOM_ODF_FW_OCyberPartExtension_xih
  14. #define ODF_FW_OCyberPartExtension_Class_Source
  15. #include <SLCyPart.xih>
  16. #endif
  17.  
  18. //
  19. // Cyberdog
  20. //
  21.  
  22. #ifndef SOM_CyberSession_xh
  23. #include <CyberSession.xh>
  24. #endif
  25.  
  26. #ifndef SOM_ParameterSet_xh
  27. #include <ParameterSet.xh>
  28. #endif
  29.  
  30. //
  31. // OpenDoc
  32. //
  33.  
  34. #ifndef _MEMMGR_
  35. #include <MemMgr.h>
  36. #endif
  37.  
  38. //========================================================================================
  39. // SOM Utilities
  40. //========================================================================================
  41. #pragma mark SOM Utilities
  42.  
  43. /*
  44.     Since we have a SOM interface, we have to make sure we don't try to
  45.     throw any C++ exceptions out of here; we need to catch them and convert
  46.     them into SOM exceptions.
  47. */
  48.  
  49. static const char FW_kInvalidException[] = "Unknown Exception!"; 
  50.  
  51. #define FW_SOM_CALLBACK_TRY            \
  52.     FW_TRY                            \
  53.     {
  54.  
  55. #define FW_SOM_CALLBACK_ENDTRY        \
  56.     }                                \
  57.     FW_CATCH_BEGIN                    \
  58.     FW_CATCH_REFERENCE(FW_XException, exception)\
  59.     {                                \
  60.         FW_SetException(ev, exception);\
  61.     }                                \
  62.     FW_CATCH_EVERYTHING()            \
  63.     {                                \
  64.         FW_DEBUG_MESSAGE(FW_kInvalidException);\
  65.         FW_SetEvError(ev, kODErrUndefined);\
  66.     }                                \
  67.     FW_CATCH_END
  68.  
  69. /*
  70.     We should not do anything if our base part has been removed (IsValid).
  71.     Also make sure we have a callback struct and callback.
  72.     
  73.     NOTE: Some preprocessors do not accept null parameters. In that case we
  74.     pass in a "(void)" as the first parameter. [sfu]
  75. */
  76.  
  77. #define SAFECALL(RESULT,METHOD,PARAMETERS)    \
  78.     if (somSelf->IsValid(ev)                 \
  79.             && somThis->fCallbacks             \
  80.             && somThis->fCallbacks->METHOD)    \
  81.         (RESULT (somThis->fCallbacks->METHOD) PARAMETERS, SOMCHKEXCEPT)
  82.  
  83. #pragma mark -
  84. //========================================================================================
  85. // Class ODF_FW_OCyberPartExtension (SOM)
  86. //========================================================================================
  87. #pragma mark Class ODF_FW_OCyberPartExtension (SOM)
  88.  
  89. /*
  90.     SOM Subclass of CyberPartExtension
  91.     
  92.     These methods generally call C methods which have been exported from a
  93.     client. These C methods must not throw C++ exceptions. Most of these
  94.     methods here don't call C++ methods or somSelf methods and so do not
  95.     need to guard against exceptions being thrown via SOMCHKEXCEPT.
  96. */
  97.  
  98.  
  99. //-----------------------------------------------------------------------------
  100. // SLCyPart::Release
  101. //-----------------------------------------------------------------------------
  102.  
  103. SOM_Scope void  SOMLINK SLCyPart__Release (ODF_FW_OCyberPartExtension *somSelf, Environment *ev)
  104. {
  105.     FW_SOM_CALLBACK_TRY
  106.     
  107.     ODBoolean isOwned = somSelf->IsValid (ev);
  108.     ODF_FW_OCyberPartExtension_parent_CyberPartExtension_Release(somSelf,ev);
  109.     
  110.     if (!isOwned && somSelf->GetRefCount(ev) == 0)
  111.         delete somSelf;
  112.     
  113.     FW_SOM_CALLBACK_ENDTRY
  114. }
  115.  
  116. //-----------------------------------------------------------------------------
  117. // SLCyPart::OpenCyberItem
  118. //-----------------------------------------------------------------------------
  119.  
  120. SOM_Scope void  SOMLINK 
  121. SLCyPart__OpenCyberItem(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, CyberItem* item, ODPart* openerPart, ParameterSet* openParams)
  122. {
  123.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  124.     FW_SOM_CALLBACK_TRY
  125.     
  126.     // The base class implements the default behavior, which is to call 
  127.     // somSelf->SetCyberItem(item), and then to either tell the openerPart
  128.     // (if it is not kODNULL) to open the associated base part, or to tell
  129.     // the base part to open itself.
  130.     // Developers may call inherited.
  131.     
  132.     // mlanett 4/18/96 In order to make it possible for developer to call inherited, the
  133.     // call to ODF_FW_OCyberPartExtension_parent_CyberPartExtension_OpenCyberItem has been
  134.     // moved to DefaultOpenCyberItem. FW_CCyberdogHelper calls this by default. Developers
  135.     // can override, and by calling inherited from C++, will get the actual inherited SOM 
  136.     // functionality. See FW_CCyberdogHelper::HandleOpenCyberItem.
  137.     ODBoolean callInherited = false;
  138.     
  139.     SAFECALL((void),openCyberItem,(ev, somThis->fCallbacks, item, openerPart, openParams));
  140.     
  141.     if (callInherited)
  142.         ODF_FW_OCyberPartExtension_parent_CyberPartExtension_OpenCyberItem(somSelf,ev,item,openerPart,openParams);
  143.     
  144.     FW_SOM_CALLBACK_ENDTRY
  145. }
  146.  
  147. //-----------------------------------------------------------------------------
  148. // SLCyPart::SetCyberItem
  149. //-----------------------------------------------------------------------------
  150.  
  151. SOM_Scope void  SOMLINK 
  152. SLCyPart__SetCyberItem(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, CyberItem* item, ParameterSet* openParams)
  153. {
  154.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  155.     
  156.     // This method is called to notify the extension that it is now 
  157.     // responsible for displaying a new CyberItem. Developers will 
  158.     // typically override this method to notify the associated part.
  159.     // Base class releases the old CyberItem (if any) and acquires the new
  160.     // CyberItem. Subsequent calls to GetCyberItem will return this item.
  161.     
  162.     FW_SOM_CALLBACK_TRY
  163.     
  164.     ODF_FW_OCyberPartExtension_parent_CyberPartExtension_SetCyberItem(somSelf,ev,item,openParams);
  165.     
  166.     SAFECALL((void),setCyberItem,(ev, somThis->fCallbacks, item, openParams));
  167.     
  168.     // Add the current item to the log.
  169.     CyberItem* parent = kODNULL;
  170.     if (openParams)
  171.         openParams->GetParameter (ev, kCDParentItemKey, (void**) &parent);
  172.     CyberSession* session = somSelf->GetCyberSession (ev);
  173.     if (session)
  174.         session->AddCyberItemToLog (ev, parent, item);
  175.     
  176.     FW_SOM_CALLBACK_ENDTRY
  177. }
  178.  
  179. //-----------------------------------------------------------------------------
  180. // SLCyPart::CanShowCyberItem
  181. //-----------------------------------------------------------------------------
  182.  
  183. SOM_Scope ODBoolean  SOMLINK 
  184. SLCyPart__CanShowCyberItem(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  185.         CyberItem* item)
  186. {
  187.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  188.     
  189.     // Returns kODTrue if this CyberPart is displaying the specified item. 
  190.     // Base class checks whether the item is equal to the value of 
  191.     // GetCyberItem(). Note that in some cases developers may wish to use a 
  192.     // less stringent test. For example, a web browser may return kODTrue 
  193.     // if the item that is passed is a link to a location on that same page 
  194.     // that it is displaying. In this case the URL of the item passed in is 
  195.     // not the same as the URL of current page, but it is contained in that 
  196.     // window.
  197.     
  198.     // This is like an object equality test. x == y is true if x and y
  199.     // are the same object, or if they are similar objects. So, even if the
  200.     // base class returns false (not equal) we still need to test for
  201.     // similarity. Obviously if it returns true then we don't need to
  202.     // test further.
  203.     
  204.     // I think this method is rather badly named.
  205.     
  206.     ODBoolean isSimilar = ODF_FW_OCyberPartExtension_parent_CyberPartExtension_CanShowCyberItem(somSelf,ev,item);
  207.     if (!isSimilar)
  208.         SAFECALL(isSimilar=,canShowCyberItem,(ev, somThis->fCallbacks, item));
  209.     
  210.     return isSimilar;
  211. }
  212.  
  213. //-----------------------------------------------------------------------------
  214. // SLCyPart::ShowCyberItem
  215. //-----------------------------------------------------------------------------
  216.  
  217. SOM_Scope void  SOMLINK 
  218. SLCyPart__ShowCyberItem(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, CyberItem* item)
  219. {
  220.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  221.     
  222.     // Tells the part to display the given CyberItem. This differs from 
  223.     // SetCyberItem in that the extension has already indicated (through 
  224.     // CanShowCyberItem or GetCyberItemWindow) that it is already 
  225.     // displaying a cyberitem equal to (or, for example, on the same page 
  226.     // as) the item parameter.
  227.     // Developers must not call inherited.
  228.     
  229.     SAFECALL((void),showCyberItem,(ev, somThis->fCallbacks, item));
  230. }
  231.  
  232. //-----------------------------------------------------------------------------
  233. // SLCyPart::GetCyberItemWindow
  234. //-----------------------------------------------------------------------------
  235.  
  236. SOM_Scope ODWindow*  SOMLINK 
  237. SLCyPart__GetCyberItemWindow (ODF_FW_OCyberPartExtension *somSelf, Environment* ev, CyberItem* item)
  238. {
  239.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  240.     ODWindow* window = kODNULL;
  241.     FW_SOM_CALLBACK_TRY
  242.     
  243.     // Returns the ODWindow (if any) in which this CyberPart is displaying 
  244.     // the specified item. This is useful e.g. when the client wants to 
  245.     // bring an existing window to the front rather than opening a new 
  246.     // window. GetCyberItemWindow should use the same algorithm as in 
  247.     // CanShowCyberItem method to determine whether an item is displayed in 
  248.     // a window.
  249.     
  250.     ODBoolean isShowingSimilar;
  251.         isShowingSimilar = somSelf->CanShowCyberItem (ev, item);
  252.     
  253.     if (isShowingSimilar)
  254.         SAFECALL(window=,getCyberItemWindow,(ev, somThis->fCallbacks, item));
  255.     
  256.     FW_SOM_CALLBACK_ENDTRY
  257.     return window;
  258. }
  259.  
  260. //-----------------------------------------------------------------------------
  261. // SLCyPart::IsCyberItemSelected
  262. //-----------------------------------------------------------------------------
  263.  
  264. SOM_Scope ODBoolean  SOMLINK 
  265. SLCyPart__IsCyberItemSelected(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, ODFrame* frame)
  266. {
  267.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  268.     ODBoolean isAnySelected = false;
  269.     FW_SOM_CALLBACK_TRY
  270.     
  271.     SAFECALL(isAnySelected=,isCyberItemSelected,(ev, somThis->fCallbacks, frame));
  272.     
  273.     FW_SOM_CALLBACK_ENDTRY
  274.     return isAnySelected;
  275. }
  276.  
  277. //-----------------------------------------------------------------------------
  278. // SLCyPart::AcquireSelectedCyberItems
  279. //-----------------------------------------------------------------------------
  280.  
  281. SOM_Scope void  SOMLINK 
  282. SLCyPart__AcquireSelectedCyberItems(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, ODFrame* frame, CyberItemList* cyberItems)
  283. {
  284.     // XXX should change this to pass an STL list?
  285.     // Note: If I do it has to be exception-safe.
  286.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  287.     FW_SOM_CALLBACK_TRY
  288.     
  289.     SAFECALL((void),acquireSelectedCyberItems,(ev, somThis->fCallbacks, frame, cyberItems));
  290.     
  291.     FW_SOM_CALLBACK_ENDTRY
  292. }
  293.  
  294. //-----------------------------------------------------------------------------
  295. // SLCyPart::IsURLSelected
  296. //-----------------------------------------------------------------------------
  297.  
  298. SOM_Scope ODBoolean  SOMLINK 
  299. SLCyPart__IsURLSelected(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, ODFrame* frame)
  300. {
  301.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  302.     ODBoolean isSelected = FALSE;
  303.     FW_SOM_CALLBACK_TRY
  304.     
  305.     SAFECALL(isSelected=,isURLSelected,(ev, somThis->fCallbacks, frame));
  306.     
  307.     FW_SOM_CALLBACK_ENDTRY
  308.     return isSelected;
  309. }
  310.  
  311. //-----------------------------------------------------------------------------
  312. // SLCyPart::GetSelectedURL
  313. //-----------------------------------------------------------------------------
  314.  
  315. SOM_Scope char*  SOMLINK 
  316. SLCyPart__GetSelectedURL(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  317.         ODFrame* frame)
  318. {
  319.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  320.     char* urld = kODNULL;
  321.     FW_SOM_CALLBACK_TRY
  322.     
  323.     FW_CString surl;
  324.     SAFECALL((void),getSelectedURL,(ev, somThis->fCallbacks, frame, surl));
  325.     
  326.     // Note: this code has been arranged so it does not throw any C++ exceptions.
  327.     FW_ByteCount size = surl.GetByteLength();
  328.     if (size) {
  329.         urld = (char*) ::MMAllocate (size + 1);
  330.         if (urld) {
  331.             const char* privates = surl.RevealBuffer();
  332.             memcpy (urld, privates, size);
  333.             urld[size] = 0;
  334.         }
  335.         else
  336.             FW_SetException (ev, kODErrOutOfMemory);
  337.     }
  338.     
  339.     FW_SOM_CALLBACK_ENDTRY
  340.     
  341.     return urld;
  342. }
  343.  
  344. //-----------------------------------------------------------------------------
  345. // SLCyPart::HandleCommand
  346. //-----------------------------------------------------------------------------
  347.  
  348. SOM_Scope ODBoolean  SOMLINK 
  349. SLCyPart__HandleCommand(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  350.         long commandSuite,
  351.         long commandID,
  352.         ODFrame* frame,
  353.         void* commandData)
  354. {
  355.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  356.     ODBoolean wasHandled = false;
  357.     FW_SOM_CALLBACK_TRY
  358.     
  359.     // Intended as an extensibility mechanism for Cyber parts where clients 
  360.     // can send commands to the part/extension. The function result 
  361.     // indicates whether or not the command was handled.
  362.     // Cyberdog defines some commands in Cyberdog.h. The commandCreator 
  363.     // associated with Cyberdogs commands is kCyberdogCreator.
  364.     // Developers may call inherited.
  365.     
  366.     // mlanett 4/18/96 see comment for OpenCyberItem. Removed call to inherited. See FW_CCyberdogHelper::HandleCyberCommand.
  367.     ODBoolean callInherited = false;
  368.     
  369.     SAFECALL(wasHandled=,handleCommand,(ev, somThis->fCallbacks, commandSuite, commandID, frame, commandData));
  370.     if (callInherited)
  371.         wasHandled |= ODF_FW_OCyberPartExtension_parent_CyberPartExtension_HandleCommand (somSelf,ev,commandSuite,commandID,frame,commandData);
  372.     
  373.     FW_SOM_CALLBACK_ENDTRY
  374.     return wasHandled;
  375. }
  376.  
  377. //-----------------------------------------------------------------------------
  378. // SLCyPart::SetCallbacks
  379. //-----------------------------------------------------------------------------
  380.  
  381. SOM_Scope void  SOMLINK 
  382. SLCyPart__SetCallbacks(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  383.         FW_HCyberPartInterfaceCallbacks callbacks)
  384. {
  385.     // Note: No exception handling here.
  386.     FW_UNUSED(ev);
  387.     
  388.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  389.     somThis->fCallbacks = callbacks;
  390. }
  391.  
  392. //-----------------------------------------------------------------------------
  393. // SLCyPart::DefaultOpenCyberItem
  394. //-----------------------------------------------------------------------------
  395.  
  396. SOM_Scope void  SOMLINK SLCyPart__DefaultOpenCyberItem(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  397.         CyberItem* item,
  398.         ODPart* openerPart,
  399.         ParameterSet* openParams)
  400. {
  401.     FW_SOM_CALLBACK_TRY
  402.     
  403.     // This method enabled us to call "inherited" OpenCyberItem from the C++ class.
  404.     ODF_FW_OCyberPartExtension_parent_CyberPartExtension_OpenCyberItem(somSelf,ev,item,openerPart,openParams);
  405.     
  406.     FW_SOM_CALLBACK_ENDTRY
  407. }
  408.  
  409. //-----------------------------------------------------------------------------
  410. // SLCyPart::DefaultHandleCommand
  411. //-----------------------------------------------------------------------------
  412.  
  413. SOM_Scope ODBoolean  SOMLINK SLCyPart__DefaultHandleCommand(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  414.         long commandCreator,
  415.         long commandID,
  416.         ODFrame* frame,
  417.         void* commandData)
  418. {
  419.     ODBoolean handled = FALSE;
  420.     FW_SOM_CALLBACK_TRY
  421.     
  422.     // This method enabled us to call "inherited" HandleCommand from the C++ class.
  423.     handled = ODF_FW_OCyberPartExtension_parent_CyberPartExtension_HandleCommand (somSelf,ev,commandCreator,commandID,frame,commandData);
  424.     
  425.     FW_SOM_CALLBACK_ENDTRY
  426.     return handled;
  427. }
  428.  
  429.