home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODF & Cyberdog / ODFCyberLibrary / Sources / FWCyPart.cpp next >
Encoding:
Text File  |  1996-08-16  |  15.6 KB  |  500 lines  |  [TEXT/MPS ]

  1. //-----------------------------------------------------------------------------
  2. //    FWCyPart.cpp
  3. //    Support for FW_OCyberPartExtension. Wraps it so that the developer
  4. //    never needs to deal with SOM. Also implements basic recipes.
  5. //    
  6. //    Copyright (c) 1995 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //-----------------------------------------------------------------------------
  8.  
  9. #include "FWFrameW.hpp"
  10. #include "FWCyPart.h"
  11. #include "FWEventH.h"
  12. #include "FWEvent.h"
  13. #include "FWEventD.h"
  14. #include "FWPart.h"
  15. #include "FWFrame.h"
  16. #include "FWExtMgr.h"
  17. #include "Cyberdog.h"
  18. #include <CyberSession.xh>
  19.  
  20. //-----------------------------------------------------------------------------
  21. // Since we have a SOM interface, we have to make sure we don't try to
  22. // throw any C++ exceptions out of here; we need to catch them and convert
  23. // them into SOM exceptions.
  24. //-----------------------------------------------------------------------------
  25.  
  26. static const char FW_kInvalidException[] = "Unknown Exception!"; 
  27.  
  28. #define BEGIN_SOM_CALLBACK            \
  29.     FW_TRY                            \
  30.     {
  31.  
  32. #define END_SOM_CALLBACK            \
  33.     }                                \
  34.     FW_CATCH_BEGIN                    \
  35.     FW_CATCH_REFERENCE(FW_XException, exception)\
  36.     {                                \
  37.         FW_SetException(ev, exception);\
  38.     }                                \
  39.     FW_CATCH_EVERYTHING()            \
  40.     {                                \
  41.         FW_DEBUG_MESSAGE(FW_kInvalidException);\
  42.         FW_SetEvError(ev, kODErrUndefined);\
  43.     }                                \
  44.     FW_CATCH_END
  45.  
  46. //-----------------------------------------------------------------------------
  47. // Glue Functions Prototypes
  48. // We fill in a struct with pointers to these functions, and pass it to the
  49. // extension. When it calls them, it passes in a pointer to that struct.
  50. // We've subclassed the struct, so we just cast it to a pointer
  51. // to our real C++ classes, and call equivalent virtual methods for
  52. // each function.
  53. //-----------------------------------------------------------------------------
  54. #pragma mark Global Callback Prototypes
  55.  
  56. void         FW_CallbackOpenCyberItem         (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*, ODPart*, ParameterSet*);
  57. void         FW_CallbackSetCyberItem         (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*, ParameterSet*);
  58. ODBoolean     FW_CallbackCanShowCyberItem        (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*);
  59. void         FW_CallbackShowCyberItem         (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*);
  60. ODWindow *     FW_CallbackGetCyberItemWindow     (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*);
  61. ODBoolean     FW_CallbackIsCyberItemSelected     (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*);
  62. void         FW_CallbackAcquireSelectedCyberItems (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*, CyberItemList*);
  63. ODBoolean    FW_CallbackIsURLSelected         (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*);
  64. void         FW_CallbackGetSelectedURL         (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*, FW_CString& url);
  65. ODBoolean     FW_CallbackHandleCommand         (Environment*, FW_SCyberPartExtensionCallbacks*, long, long, ODFrame*, somToken);
  66.  
  67. //-----------------------------------------------------------------------------
  68. // FW_CCyberDispatcher intercepts Window Close-Box events.
  69. //-----------------------------------------------------------------------------
  70. #pragma mark -
  71.  
  72. class FW_CCyberDispatcher: public FW_CEventDispatcher {
  73. public:
  74.     FW_DECLARE_AUTO(FW_CCyberDispatcher)
  75.                         FW_CCyberDispatcher (FW_CPart* part, FW_CMenuBar* theMenuBar);
  76.                         ~FW_CCyberDispatcher();
  77.     FW_Boolean             DispatchWindowEvent (Environment* ev, ODEventData* event, ODFacet* odFacet);
  78. private:
  79.     FW_CPart*             fPart;
  80.     FW_TAcquiredODRefCntObject<CyberPartExtension> fExtension;
  81. };
  82.  
  83. FW_DEFINE_AUTO(FW_CCyberDispatcher)
  84.  
  85. FW_CCyberDispatcher::FW_CCyberDispatcher (FW_CPart* part, FW_CMenuBar* theMenuBar)
  86. :    FW_CEventDispatcher (part, theMenuBar)
  87. ,    fPart (part)
  88. {
  89. }
  90.  
  91. FW_CCyberDispatcher::~FW_CCyberDispatcher()
  92. {
  93. }
  94.  
  95. FW_Boolean 
  96. FW_CCyberDispatcher::DispatchWindowEvent (Environment* ev, ODEventData* event, ODFacet* odFacet)
  97. {
  98.     ODBoolean handled = false;
  99.     
  100.     if (event->what == kODEvtWindow && event->message == inGoAway) {
  101.         FW_CExtensionManager* manager = fPart->GetExtensionManager(ev);
  102.         FW_ASSERT (manager);
  103.         ODExtension* ext = manager->AcquireExtension (ev, kCyberPartExtension, FW_kDontCreateExtension);
  104.         if (ext) {
  105.             CyberPartExtension* cext = (CyberPartExtension*) ext;
  106.             CyberSession* cyberSession = cext->GetCyberSession (ev);
  107.             FW_ASSERT (cyberSession);
  108.             if (cyberSession)
  109.                 handled = cyberSession->CloseCyberDraftWindow (ev, fPart->GetODPart(ev));
  110.         }
  111.     }
  112.     
  113.     if (!handled)
  114.         handled = FW_CEventDispatcher::DispatchWindowEvent (ev, event, odFacet);
  115.     
  116.     return handled;
  117. }
  118.  
  119. //-----------------------------------------------------------------------------
  120. // FW_CCyberDogWindowHandler intercepts Command-W events.
  121. //-----------------------------------------------------------------------------
  122. #pragma mark -
  123.  
  124. class FW_CCyberDogWindowHandler: public FW_MEventHandler {
  125. public:
  126. //    FW_DECLARE_CLASS
  127.     FW_DECLARE_AUTO(FW_CCyberDogWindowHandler)
  128.                     FW_CCyberDogWindowHandler (CyberPartExtension* cyberdog, ODPart* part);
  129.                     ~FW_CCyberDogWindowHandler ();
  130.     FW_Boolean         DoWindowEvent (Environment* ev, const FW_CMacWindowEvent& event);
  131.     FW_Boolean         DoMenu (Environment* ev, const FW_CMenuEvent& event);
  132. private:
  133.     FW_TAcquiredODRefCntObject<CyberPartExtension> fExtension;
  134.     ODPart*         fPart;
  135. };
  136.  
  137. //FW_DEFINE_CLASS_M1(FW_CCyberDogWindowHandler, FW_MEventHandler)
  138. FW_DEFINE_AUTO(FW_CCyberDogWindowHandler)
  139.  
  140. FW_CCyberDogWindowHandler::FW_CCyberDogWindowHandler (CyberPartExtension* cyberdog, ODPart* part)
  141. //:    FW_MEventHandler (somGetGlobalEnvironment(), 0, parent, TRUE, 0)
  142. :    fExtension (cyberdog)
  143. ,    fPart (part)
  144. {
  145. }
  146.  
  147. FW_CCyberDogWindowHandler::~FW_CCyberDogWindowHandler ()
  148. {
  149. }
  150.  
  151. FW_Boolean FW_CCyberDogWindowHandler::DoWindowEvent (Environment* ev, const FW_CMacWindowEvent& event)
  152. {
  153.     ODBoolean handled = FALSE;
  154.     if (event.GetMessage() == inGoAway) {
  155.     /*    FW_CWindow* window = frame->GetWindow(ev);*/
  156.         /*if (!window->IsFloating())*/ {
  157.     // Only do Cyberdog stuff if we still have the extension?
  158.     // XXX
  159.             CyberSession* cyberSession = fExtension->GetCyberSession(ev);
  160.             handled = cyberSession->CloseCyberDraftWindow(ev, fPart);
  161.         }
  162.     }
  163.     
  164.     return handled;
  165. }
  166.  
  167. FW_Boolean FW_CCyberDogWindowHandler::DoMenu (Environment* ev, const FW_CMenuEvent& event)
  168. {
  169.     ODBoolean handled = FALSE;
  170.     if (event.GetCommandID(ev) == kODCommandClose) {
  171.     /*    FW_CWindow* window = frame->GetWindow(ev);*/
  172.         /*if (!window->IsFloating())*/ {
  173.             CyberSession* cyberSession = fExtension->GetCyberSession(ev);
  174.             handled = cyberSession->CloseCyberDraftWindow(ev, fPart);
  175.         }
  176.     }
  177.     
  178.     return handled;
  179. }
  180.  
  181. #pragma mark -
  182. //-----------------------------------------------------------------------------
  183. // Wrapper Class Definition
  184. //-----------------------------------------------------------------------------
  185.  
  186. FW_MCyberPart::FW_MCyberPart (FW_CPart* part)
  187. :    fPart (part)
  188. ,    fExtension (NULL)
  189. {
  190. #if !FW_CyberUseUPPsFlag
  191.     openCyberItem = &FW_CallbackOpenCyberItem;
  192.     setCyberItem = &FW_CallbackSetCyberItem;
  193.     canShowCyberItem = &FW_CallbackCanShowCyberItem;
  194.     showCyberItem = &FW_CallbackShowCyberItem;
  195.     getCyberItemWindow = &FW_CallbackGetCyberItemWindow;
  196.     isCyberItemSelected = &FW_CallbackIsCyberItemSelected;
  197.     acquireSelectedCyberItems = &FW_CallbackAcquireSelectedCyberItems;
  198.     isURLSelected = &FW_CallbackIsURLSelected;
  199.     getSelectedURL = &FW_CallbackGetSelectedURL;
  200.     handleCommand = &FW_CallbackHandleCommand;
  201. #else
  202. #    error obsolete
  203. #endif
  204. }
  205.  
  206. FW_MCyberPart::~FW_MCyberPart ()
  207. {
  208. //    if (fExtension) {
  209.         // If the C++ object gets deleted, remove it from the SOM object
  210.         // However we don't call Release on it; it is still owned by the Part.
  211. //        ODF_FW_OCyberPartExtension* extension = fExtension;
  212. //        fExtension = nil;
  213. //        extension->SetCallbacks (somGetGlobalEnvironment(), NULL);
  214. //    }
  215. }
  216.  
  217. void FW_MCyberPart::Initialize (Environment* ev)
  218. {
  219.     // I need to regster with the extension manager but at part construction time it
  220.     // doesn't exist yet. I can't just create it because the "normal" creation method
  221.     // will not check. Delayed initialization is forced.
  222.     FW_CExtensionManager* manager = fPart->GetExtensionManager(ev);
  223.     FW_ASSERT (manager);
  224.     manager->RegisterExtension (ev, kCyberPartExtension, &CreateCyberExtension, this, FALSE);
  225. }
  226.  
  227. CyberItem* 
  228. FW_MCyberPart::GetCyberItem ()
  229. {
  230.     if (fExtension != nil)
  231.         return fExtension->GetCyberItem (somGetGlobalEnvironment());
  232.     else
  233.         return nil;
  234. }
  235.  
  236. CyberSession* 
  237. FW_MCyberPart::GetCyberSession ()
  238. {
  239.     Environment* ev = somGetGlobalEnvironment();
  240.     
  241.     if (fExtension != nil)
  242.         return fExtension->GetCyberSession (ev);
  243.     else {
  244.         // Create our extension, which will create the CyberSession
  245.         FW_TAcquiredODRefCntObject<CyberExtension> extension = (CyberExtension*) fPart->GetExtensionManager(ev)->AcquireExtension (ev, kCyberPartExtension, FW_kCreateExtension);
  246.         return extension->GetCyberSession (ev);
  247.     }
  248. }
  249.  
  250. CyberPartExtension* 
  251. FW_MCyberPart::AcquireCyberExtension()
  252. {
  253.     Environment* ev = somGetGlobalEnvironment();
  254.     if (fExtension != nil) {
  255.         fExtension->Acquire (ev);
  256.         return fExtension;
  257.     }
  258.     else
  259.         return (CyberPartExtension*) fPart->GetExtensionManager(ev)->AcquireExtension (ev, kCyberPartExtension, FW_kCreateExtension);
  260. }
  261.  
  262. FW_CEventDispatcher* FW_MCyberPart::MakeEventDispatcher (Environment *ev)
  263. {
  264.     return FW_NEW (FW_CCyberDispatcher, (fPart, fPart->GetMenuBar(ev)));
  265. }
  266.  
  267. /*
  268.     Behavior Delegated from CyberPartExtension
  269. */
  270.  
  271. void FW_MCyberPart::HandleOpenCyberItem (Environment* ev, CyberItem* item, ODPart* openerPart, ParameterSet* parameters)
  272. {
  273.     // By default call the default ("inherited") OpenCyberItem in CyberPartExtension.
  274.     fExtension->DefaultOpenCyberItem (ev, item, openerPart, parameters);
  275. }
  276.  
  277. void FW_MCyberPart::DoSetCyberItem (Environment* ev, CyberItem* newItem, ParameterSet* parameters)
  278. {
  279.     FW_UNUSED (ev);
  280.     FW_UNUSED (newItem);
  281.     FW_UNUSED (parameters);
  282.     
  283.     // Should be customized by Developer
  284.     // Must call inherited (done in extension)
  285. }
  286.  
  287. ODBoolean FW_MCyberPart::DoCanShowCyberItem (Environment* ev, CyberItem* item)
  288. {
  289.     FW_UNUSED (ev);
  290.     FW_UNUSED (item);
  291.     
  292.     // This is a test for equality (not identity). If you are showing
  293.     // some variant of the given item, return true. For example,
  294.     // http://Where/ is similar to http://Where/index.html
  295.     // Also, http://Here#Bookmark is similar to http://Here
  296.     
  297.     // You don't need to test for identity; it's handled by the FW
  298.     // SOM extension for you.
  299.     
  300.     return FALSE;
  301. }
  302.  
  303. void FW_MCyberPart::DoShowCyberItem (Environment* ev, CyberItem* item)
  304. {
  305.     FW_UNUSED (ev);
  306.     FW_UNUSED (item);
  307. }
  308.  
  309. ODWindow* FW_MCyberPart::DoGetCyberItemWindow (Environment* ev, CyberItem* item)
  310. {
  311.     FW_UNUSED (item);
  312.     
  313.     // I think this API is a Cyberdog bug: it is not acquiring the window!
  314.     // This is not properly thread-safe.
  315.     
  316.     FW_CFrame* active = fPart->GetLastActiveFrame (ev);
  317.     if (active) {
  318.         FW_TAcquiredODRefCntObject<ODWindow> theWindow = active->AcquireODWindow (ev);
  319.         return theWindow;
  320.     }
  321.     
  322.     return kODNULL;
  323. }
  324.  
  325. ODBoolean FW_MCyberPart::DoIsCyberItemSelected (Environment* ev, ODFrame* frame)
  326. {
  327.     FW_UNUSED (ev);
  328.     FW_UNUSED (frame);
  329.     
  330.     return FALSE;
  331. }
  332.  
  333. void FW_MCyberPart::DoAcquireSelectedCyberItems (Environment* ev, ODFrame* frame, CyberItemList* items)
  334. {
  335.     FW_UNUSED (ev);
  336.     FW_UNUSED (frame);
  337.     FW_UNUSED (items);
  338. }
  339.  
  340. ODBoolean FW_MCyberPart::DoIsURLSelected (Environment* ev, ODFrame* frame)
  341. {
  342.     FW_UNUSED (ev);
  343.     FW_UNUSED (frame);
  344.     
  345.     return FALSE;
  346. }
  347.  
  348. void FW_MCyberPart::DoGetSelectedURL (Environment* ev, ODFrame* frame, FW_CString & url)
  349. {
  350.     FW_UNUSED (ev);
  351.     FW_UNUSED (frame);
  352.     
  353.     url = "";
  354. }
  355.  
  356. ODBoolean FW_MCyberPart::HandleCyberCommand (Environment* ev, long commandSuite, long command, ODFrame* frame, somToken parameters)
  357. {
  358.     // By default call the default ("inherited") HandleCommand in CyberPartExtension.
  359.     return fExtension->DefaultHandleCommand (ev, commandSuite, command, frame, parameters);
  360. }
  361.  
  362. ODExtension* FW_MCyberPart::CreateCyberExtension (Environment* ev, FW_CPart *part, const char* name, void* selfAPI)
  363. {
  364.     FW_UNUSED (name);
  365.     
  366.     FW_MCyberPart* self = (FW_MCyberPart*) selfAPI;
  367.     
  368.     ODPart* odpart = part->GetODPart(ev);
  369.     ODF_FW_OCyberPartExtension* cyberPartExtension = new ODF_FW_OCyberPartExtension;
  370.     cyberPartExtension->ICyberPartExtension (ev, odpart);
  371.     cyberPartExtension->SetCallbacks (ev, self);
  372.     
  373.     cyberPartExtension->Acquire(ev);
  374.     self->fExtension = cyberPartExtension;
  375.     
  376.     // CyberDog hackism support. See FW_CCyberDogWindowHandler above.
  377.     cyberPartExtension->Acquire(ev);
  378.     FW_CCyberDogWindowHandler* eventHacker = FW_NEW (FW_CCyberDogWindowHandler, (cyberPartExtension, odpart));
  379.     part->AdoptEventHandler (ev, eventHacker);
  380.     
  381.     return cyberPartExtension;
  382. }
  383.  
  384. #pragma mark -
  385. //-----------------------------------------------------------------------------
  386. // Glue Functions Definition
  387. //-----------------------------------------------------------------------------
  388.  
  389. // Should I use RTTI here? Hardly seems necessary.
  390. #define FINDSELF(SELF,CALLBACKS)     FW_MCyberPart* SELF = (FW_MCyberPart*) CALLBACKS
  391.  
  392. void         FW_CallbackOpenCyberItem         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item, ODPart* openerPart, ParameterSet* data)
  393. {
  394.     BEGIN_SOM_CALLBACK
  395.         FINDSELF(self,callbacks);
  396.         self->HandleOpenCyberItem (ev, item, openerPart, data);
  397.     END_SOM_CALLBACK
  398. }
  399.  
  400. void         FW_CallbackSetCyberItem         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item, ParameterSet* data)
  401. {
  402.     BEGIN_SOM_CALLBACK
  403.         FINDSELF(self,callbacks);
  404.         self->DoSetCyberItem (ev, item, data);
  405.     END_SOM_CALLBACK
  406. }
  407.  
  408. ODBoolean     FW_CallbackCanShowCyberItem     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item)
  409. {
  410.     ODBoolean similar = false;
  411.     BEGIN_SOM_CALLBACK
  412.         FINDSELF(self,callbacks);
  413.         similar = self->DoCanShowCyberItem (ev, item);
  414.     END_SOM_CALLBACK
  415.     
  416.     return similar;
  417. }
  418.  
  419. void         FW_CallbackShowCyberItem         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item)
  420. {
  421.     BEGIN_SOM_CALLBACK
  422.         FINDSELF(self,callbacks);
  423.         self->DoShowCyberItem (ev, item);
  424.     END_SOM_CALLBACK
  425. }
  426.  
  427. ODWindow*     FW_CallbackGetCyberItemWindow     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item)
  428. {
  429.     BEGIN_SOM_CALLBACK
  430.         FINDSELF(self,callbacks);
  431.         return self->DoGetCyberItemWindow (ev, item);
  432.     END_SOM_CALLBACK
  433.     
  434.     return NULL;
  435. }
  436.  
  437. ODBoolean     FW_CallbackIsCyberItemSelected     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame)
  438. {
  439.     ODBoolean selected = false;
  440.     
  441.     BEGIN_SOM_CALLBACK
  442.         FINDSELF(self,callbacks);
  443.         selected = self->DoIsCyberItemSelected (ev, frame);
  444.     END_SOM_CALLBACK
  445.     
  446.     return selected;
  447. }
  448.  
  449. void         FW_CallbackAcquireSelectedCyberItems     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame, CyberItemList* list)
  450. {
  451.     BEGIN_SOM_CALLBACK
  452.         FINDSELF(self,callbacks);
  453.         self->DoAcquireSelectedCyberItems (ev, frame, list);
  454.     END_SOM_CALLBACK
  455. }
  456.  
  457. ODBoolean    FW_CallbackIsURLSelected         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame)
  458. {
  459.     ODBoolean selected = false;
  460.     
  461.     BEGIN_SOM_CALLBACK
  462.         FINDSELF(self,callbacks);
  463.         selected = self->DoIsURLSelected (ev, frame);
  464.     END_SOM_CALLBACK
  465.     
  466.     return selected;
  467. }
  468.  
  469. void         FW_CallbackGetSelectedURL         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame, FW_CString& url)
  470. {
  471.     BEGIN_SOM_CALLBACK
  472.         FINDSELF(self,callbacks);
  473.         self->DoGetSelectedURL (ev, frame, url);
  474. #if 0
  475.         // all this has been moved into SLCyPart.cpp
  476.         int length = url.GetByteLength();
  477.         if (length == 0)
  478.             return NULL;
  479.         corbastring curl = (corbastring) SOMMalloc (length + 1);
  480.         if (!curl)
  481.             FW_Failure(FW_xMemoryExhausted);
  482.         strcpy (curl, url);
  483.         return curl;
  484. #endif
  485.     END_SOM_CALLBACK
  486. }
  487.  
  488. ODBoolean     FW_CallbackHandleCommand         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, long commandSuite, long command, ODFrame* frame, somToken parameters)
  489. {
  490.     ODBoolean handled = false;
  491.     
  492.     BEGIN_SOM_CALLBACK
  493.         FINDSELF(self,callbacks);
  494.         handled = self->HandleCyberCommand (ev, commandSuite, command, frame, parameters);
  495.     END_SOM_CALLBACK
  496.     
  497.     return handled;
  498. }
  499.  
  500.